Q10 of 37 · Selenium
How do you take a screenshot on test failure?
Short answer
Short answer: Cast the driver to `TakesScreenshot`, call `getScreenshotAs(OutputType.FILE)`, and copy to disk. Wire it into your test framework's failure hook — `@AfterMethod` (TestNG) inspecting `ITestResult`, or pytest's `pytest_runtest_makereport`.
Detail
Screenshots-on-failure are the cheapest, highest-leverage debug aid in Selenium tests. The mechanism is simple; the integration with your test runner is what makes it useful.
The capture call (Java):
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(src.toPath(), Paths.get("screenshots/" + testName + ".png"));
getScreenshotAs returns whatever you asked for: OutputType.FILE, OutputType.BYTES, or OutputType.BASE64. BASE64 is handy for embedding directly in HTML reports.
Wiring to failures (TestNG):
@AfterMethod(alwaysRun = true)
public void onTestEnd(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
captureScreenshot(result.getName());
}
}
pytest equivalent uses a hook in conftest.py:
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
if rep.when == "call" and rep.failed:
driver = item.funcargs["driver"]
driver.save_screenshot(f"screenshots/{item.name}.png")
Two refinements that separate juniors from mids:
- Attach to the report, not just save to disk. Allure / Extent / pytest-html can embed the image.
- Capture page source and console logs too — a screenshot tells you what's visible, not why.