Skip to content

Instantly share code, notes, and snippets.

@gladnik
Last active October 18, 2022 07:25
Show Gist options
  • Save gladnik/99793dbaa29dd3b8feef909de7639fc3 to your computer and use it in GitHub Desktop.
Save gladnik/99793dbaa29dd3b8feef909de7639fc3 to your computer and use it in GitHub Desktop.
Allure2 allure.report.remove.attachments

Attachments remover for Allure 2

Removes attachments that match a regexp from successful tests

Usage

  1. Put AllureAttachmentsRemover.java to the project sources
  2. Put a file named io.qameta.allure.listener.TestLifecycleListener to resources/META-INF/services/ (this file should contain the qualified name of AllureAttachmentsRemover.java (name with package))
  3. Add allure.report.remove.attachments to allure.properties file (the property value should contain a regexp for attachment names)
package ru.yandex.autotests.tools.log;
import io.qameta.allure.AllureResultsWriteException;
import io.qameta.allure.listener.TestLifecycleListener;
import io.qameta.allure.model.Attachment;
import io.qameta.allure.model.Status;
import io.qameta.allure.model.StepResult;
import io.qameta.allure.model.TestResult;
import io.qameta.allure.util.PropertiesUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
/**
* @author gladnik (Nikolai Gladkov)
*/
public class AllureAttachmentsRemover implements TestLifecycleListener {
private static final Properties properties = PropertiesUtils.loadAllureProperties();
private static final Path outputDirectory = Paths.get(properties.getProperty("allure.results.directory", "allure-results"));
private static final String patternForRemove = properties.getProperty("allure.report.remove.attachments", "");
@Override
public void beforeTestWrite(TestResult testResult) {
if (testResult.getStatus().equals(Status.PASSED)) {
removeMatchingAttachments(testResult.getAttachments());
testResult.getSteps().stream()
.flatMap(this::getSubsteps)
.map(StepResult::getAttachments)
.forEach(this::removeMatchingAttachments);
}
}
private Stream<StepResult> getSubsteps(StepResult step) {
if (step.getSteps().isEmpty()) {
return Stream.of(step);
}
return step.getSteps().stream().flatMap(this::getSubsteps);
}
private void removeMatchingAttachments(Collection<Attachment> attachments) {
List<Attachment> attachmentsToRemove = attachments.stream()
.filter(attachment -> attachment.getName().matches(patternForRemove))
.collect(toList());
attachmentsToRemove.forEach(this::deleteAttachmentFile);
attachments.removeAll(attachmentsToRemove);
}
private void deleteAttachmentFile(Attachment attachment) {
Path filePath = outputDirectory.resolve(attachment.getSource());
try {
Files.delete(filePath);
} catch (IOException e) {
throw new AllureResultsWriteException("Could not remove Allure attachment", e);
}
}
}
# this file should be placed at resources/META-INF/services/
# it should contain the name of AllureAttachmentsRemover including package
ru.yandex.autotests.tools.log.AllureAttachmentsRemover
@dtuchs
Copy link

dtuchs commented Mar 22, 2019

I think that method getSubsteps(StepResult step) should concat stream of current step and sub-steps.

    private Stream<StepResult> getSubSteps(StepResult step) {
        return Stream.concat(Stream.of(step), step.getSteps().stream().flatMap(this::getSubSteps));
    }

Also, attachment names probably wont match by any regexp, because file extension stored in attachment.getType() and usually attachment.getName() will return just a String "Screenshot on fail", "Screen opened page" etc.

@cookieMr
Copy link

Can I vote +gazillion for this item to be in Allure the 2nd?
At this moment I have ~5k tests and all of them are logging some small'ish attachments. Allure report builds for ~12min.

Anyway, thx to you @gladnik for this temporary solution. I will copy-paste it for my tests.

@vrajasg
Copy link

vrajasg commented Dec 8, 2020

@cookieMr did it worked for you?
Added the code to my project and when I do testResult.getAttachments().size() then it returns zero though I see screenshots under target/allure-results folder. Am I missing anything here please?

btw, am using AllureCucumber4Jvm (cucumber + TestNg), allure-2.13.3

@cookieMr
Copy link

cookieMr commented Dec 8, 2020

@vrajasg yes it did work for me, i copied & pasted most of the code from here and i kinda hardcoded it into my testing framework, so it still works

did you put this AllureAttachmentsRemover class into a resources/META-INF/services in io.qameta.allure.listener.TestLifecycleListener file (it's actually a full name of an interface)?

@vrajasg
Copy link

vrajasg commented Dec 8, 2020

thanks for the quick response @cookieMr.
Yes, have placed AllureAttachmentsRemover path in TestLifecycleListener file.
AllureAttachmentsRemover is under /src/main/java/reports/allure/AllureAttachmentsRemover.java
io.qameta.allure.listener.TestLifecycleListener is under src/test/resources/META-INF/services

Our goal is to remove files/screenshots that match regExp when the test fails. So have changed beforeTestWrite accordingly.

Please refer to the attachments for better clarity.
AllureAttachmentsRemover
TestLifecycleListener

@cookieMr
Copy link

cookieMr commented Dec 8, 2020

I don't see anything wrong with your code. But a hold on repo would be better as I could debug.
I don't think this is a good place for such talk. Please, post this issue on StackOverflow.

@OleksandraMakovoz
Copy link

Won't work with nested steps (on each level with attachments).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment