Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

AllureSelenide attaches Screenshot and Page source once per nesting level of SelenideLogger.step

Abierto
#1,453 0 comentarios 1 reacción 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
java
Área
testing

Línea de trabajo

The duplicate capture happens in AllureSelenide.afterEvent, which attaches a Screenshot and Page source on every FAIL event, and SelenideLogger.wrap() commits a FAIL for each enclosing step as the exception propagates. Read both before anything else. The maintainers have not chosen between a default fix and an opt-in deduplicateAttachments(boolean), so confirm that direction in the thread first. Done means one attachment pair per failure, with the reproduction in the issue producing a single pair.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

What happened?

Summary

AllureSelenide.afterEvent attaches Screenshot and Page source on every SelenideLogger
event with status FAIL. It never checks whether the same failure was already captured, so a
single failure inside nested steps produces one pair of attachments per nesting level.

Why it happens

afterEvent captures unconditionally on FAIL:

public void afterEvent(final LogEvent event) {
    if (event.getStatus().equals(LogEvent.EventStatus.FAIL)) {
        lifecycle.getCurrentExecutableKey().ifPresent(owner -> {
            if (saveScreenshots) { ... addAttachment(owner, "Screenshot", ...) }
            if (savePageHtml)   { ... addAttachment(owner, "Page source", ...) }

SelenideLogger.step(...) is itself a SelenideLogger event, and SelenideLogger.wrap()
commits it as FAIL again while the exception propagates outwards:

catch (RuntimeException | Error e) {
    SelenideLogger.commitStep(log, e);   // -> afterEvent(FAIL) -> another screenshot
    throw e;
}

So the number of attachment pairs is (number of enclosing SelenideLogger.step calls) + 1.

How to reproduce

SelenideLogger.addListener("allure", new AllureSelenide().screenshots(true));
SelenideLogger.step("outer step", () -> SelenideLogger.step("inner step", () -> $("#missing").shouldBe(visible)));
Actual

Three Screenshot + Page source pairs for one failure:

  • [failed] $("outer step") <- Screenshot, Page source
    • [failed] $("inner step") <- Screenshot, Page source
      • [failed] $("#missing") should be(visible) <- Screenshot, Page source
Expected

One Screenshot and one Page source, attached to the innermost step where the failure
actually happened.

Impact

The duplicates are not copies — each one is a separate getScreenshotAs + getPageSource
round trip to the driver. On a mobile/Appium setup that costs seconds per failure, and the
later screenshots are taken after the Selenide timeout has already elapsed, so they show a
different (less useful) state than the one that caused the failure. The report also becomes
noticeably harder to read: the reader has to figure out which of the identical-looking
attachments is the relevant one.

Reproduces on 2.24.0 as well — the body of afterEvent is unchanged between 2.24.0 and
3.0.0, only the lifecycle API around it has moved.

Note on the obvious workaround

Skipping attachments for step wrappers (for example when event.getSubject() is empty) is
not sufficient. When non-Selenide code fails inside a step() — an assertion, an NPE, an API
or messaging error — the wrapper's FAIL event is the only one, and that is exactly the case
where a screenshot is most valuable. Deduplicating by the Throwable instead handles both
cases, because SelenideLogger.wrap() rethrows the same instance (walking the getCause()
chain also covers failures that get wrapped on the way out).

I have a working implementation of this as a subclass in our own project, with tests for all
four cases (Selenide failure through a wrapper, wrapped-in-cause failure, assertion failure
inside a wrapper, two distinct failures in one test).

Question before I send a PR

Which direction would you prefer?

  1. Fix the default — one attachment pair per failure, no new API. Cleaner, but changes
    behaviour for everyone on upgrade.
  2. Add an opt-in deduplicateAttachments(boolean), default false. Safe, but users have
    to discover it.

I'm ready to send a PR with unit tests for either — just let me know which one you'd accept.

Related: #1439 / #1440 touch getScreenshotBytes() in the same method, so there may be a
small conflict; happy to rebase on top of that PR.

What Allure Integration are you using?

allure-selenide

What version of Allure Integration you are using?

3.0.0

What version of Allure Report you are using?

2.19.0

Code of Conduct
  • I agree to follow this project's Code of Conduct
Lenguaje dominante
Java
Estrellas
390
Forks
242
Merge medio
2 d 14 h
PR fusionados (30 d)
13

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de allure-framework/allure-java

Todos los issues de allure-framework/allure-java

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.