Your bug reports attach screenshots and steps — evidence is what makes them actionable.
Automated failures need the same evidence: a report humans can read, and a screenshot from the moment of death.
A failing test at 3 a.m. in CI is only useful if the morning human can diagnose it without re-running. Two upgrades deliver that: readable reports and automatic screenshots on failure.
Every mvn test writes reports to target/surefire-reports/ — a .txt per class and XML that CI systems parse into dashboards (that's how GitHub Actions will show you red/green per test):
target/surefire-reports/
├─ LoginTest.txt
├─ TEST-LoginTest.xml
└─ InvalidLoginTest.txt
# inside LoginTest.txt after a failure:
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0
validLogin Time elapsed: 3.41 s <<< FAILURE!
org.opentest4j.AssertionFailedError:
expected: <Products> but was: <Swag Labs>Selenium can photograph the browser at any moment. JUnit can detect that a test failed. Glue them in BaseTest and every failure leaves evidence:
import org.junit.jupiter.api.extension.*; import org.openqa.selenium.*; import java.nio.file.*; public class BaseTest { protected WebDriver driver; @RegisterExtension TestWatcher watcher = new TestWatcher() { @Override public void testFailed(ExtensionContext ctx, Throwable cause) { try { byte[] png = ((TakesScreenshot) driver) .getScreenshotAs(OutputType.BYTES); Path path = Paths.get("screenshots", ctx.getDisplayName() + ".png"); Files.createDirectories(path.getParent()); Files.write(path, png); System.out.println("Saved failure evidence: " + path); } catch (Exception ignored) {} } }; /* @BeforeEach / @AfterEach as before */ }
LoginTest > Valid user lands on Products page FAILED Saved failure evidence: screenshots\Valid user lands on Products page.png [INFO] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0

images/failure-screenshot-example.pngNow every red test comes with a picture of exactly what the browser showed — usually enough to diagnose in seconds ("the error banner! the app was down") instead of a re-run.
Fix: Three checks: the watcher must be a field annotated @RegisterExtension (not static, not a local variable); evidence only appears on failures — a passing run produces nothing; and take the screenshot before anything quits the driver.
Fix: Display names can contain characters Windows paths forbid. Sanitize before saving: ctx.getDisplayName().replaceAll("[^a-zA-Z0-9 -]", "_").
mvn test.screenshots/ and the class .txt in target/surefire-reports/. Diagnose the failure using only those two artifacts, as the morning human would. Fix the test.