Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#1,453 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
25/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
java
Ambito
testing

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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
Lingua principale
Java
Stelle
390
Fork
243
Merge medio
2g 14h
PR unite (30g)
13

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di allure-framework/allure-java

Tutte le issue di allure-framework/allure-java

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.