Attaching Screenshots and Logs in Cucumber
What Is Attaching Screenshots and Logs?
Attaching screenshots and logs is the process of capturing visual evidence and technical execution details during automation execution and embedding them into reports. In a Cucumber framework, attachments make reports more useful because they explain what happened when a scenario passed, failed, or stopped unexpectedly. A screenshot shows the visible application state. A log explains the execution flow, API interaction, database activity, browser console error, or exception that occurred during the test.
Without attachments, a report may only say that a scenario failed. That is not enough for quick debugging. The tester still needs to reproduce the issue, inspect the browser, read console output, check API responses, or ask another team member for context. With screenshots and logs attached, the report becomes evidence. It can show what failed, where it failed, why it likely failed, what the application looked like, and what technical details were available at the time of failure.
In simple terms, screenshots show what happened visually, while logs explain what happened technically. Together, they reduce guesswork and make automation failures easier to understand.
Why Attach Screenshots and Logs?
Automation failures are useful only when the team can interpret them quickly. A failed scenario without evidence often creates delay. The tester has to rerun the test, watch the execution, search through console logs, and manually collect proof. A report with attachments shortens this process because the failure evidence is already captured during execution.
Without Attachments
Test Failed
-> Unknown Reason
With Attachments
Test Failed
-> Screenshot
-> Logs
-> Error
-> Quick Debugging
The benefits are practical. Attachments support faster root cause analysis, easier bug reporting, better communication between QA and developers, reduced debugging time, and stronger execution evidence. They also help distinguish between product defects, automation issues, test data problems, environment failures, and timing issues.
Types of Attachments
Attachments can include many types of evidence. In Selenium automation, screenshots and browser console logs are common. In REST Assured automation, API requests, responses, headers, payloads, and status details are useful. In database validation, SQL queries or selected result data may help. In framework-level failures, stack traces and execution logs are important.
Attachments
|-- Screenshots
|-- Browser Logs
|-- Application Logs
|-- API Requests
|-- API Responses
|-- Stack Traces
|-- JSON Payloads
|-- Console Logs
|-- SQL Queries
|-- Environment Information
The goal is not to attach everything. The goal is to attach the evidence that helps explain the result. A focused screenshot, a clear exception message, a sanitized API response, and useful environment information are usually better than a large dump of unrelated data.
Screenshot Capture Flow
The screenshot capture flow usually starts when a failure occurs. The framework detects that the Cucumber scenario failed, captures the current browser screen through Selenium, saves the screenshot or captures it as bytes, attaches it to the report, and then allows teardown to continue. This is usually handled in an after hook so every failed scenario follows the same process.
Test Execution
-> Failure Occurs
-> Capture Screenshot
-> Save Screenshot
-> Attach to Report
-> View in Report
Centralizing screenshot capture in hooks is important. If every step definition tries to capture screenshots manually, the framework becomes inconsistent and difficult to maintain. A hook-based approach ensures failure evidence is collected automatically whenever a scenario fails.
When Should Screenshots Be Taken?
Screenshots should usually be taken on test failure, assertion failure, unexpected exception, validation failure, or important business milestones. Failure screenshots are the most valuable because they show the application at the moment something went wrong. Optional milestone screenshots can be useful for high-value flows such as order placement, payment completion, or account creation, but they should be used carefully.
Avoid taking screenshots after every successful step unless there is a specific reporting requirement. Too many screenshots make reports large, slow, and harder to review. A report with hundreds of passing screenshots may look detailed, but it often becomes noisy. The best screenshot strategy balances evidence with report performance.
Capturing Screenshots in Selenium
Selenium captures screenshots using the TakesScreenshot interface. The WebDriver instance is cast to TakesScreenshot, and getScreenshotAs() captures the current browser state. The screenshot can be captured as a file, bytes, or base64 string depending on the reporting need.
TakesScreenshot ts =
(TakesScreenshot) driver;
File source =
ts.getScreenshotAs(OutputType.FILE);
This captures the browser viewport at that moment. It does not automatically capture the entire scrolling page in all cases. If full-page screenshots are required, the framework may need browser-specific support or additional utilities. For most failure debugging, a normal viewport screenshot is enough to show modals, error messages, wrong pages, disabled buttons, or missing elements.
Saving Screenshots
When screenshots are stored as files, the framework should copy the captured source file to a predictable destination. The destination should usually be under a generated report or target folder. Screenshot files should not be stored inside source code folders because they are build artifacts.
File destination =
new File("screenshots/login.png");
Files.copy(
source.toPath(),
destination.toPath()
);
Saving screenshots as files is useful for Extent Reports because Extent often references image paths. It is also useful when screenshots need to be archived separately. If the framework uses Cucumber native reports or Allure, byte attachments may be simpler because the report can embed the image directly.
Screenshot Naming Strategy
Screenshot names should be unique and meaningful. Names such as image.png, test.png, or screenshot.png are poor because they can be overwritten and provide no context. Better names include scenario names, timestamps, test IDs, browser names, or failure status.
LoginFailure_20260628_101530.png
OrderCreation_001.png
Scenario_Login_Failed.png
A strong naming strategy helps local debugging and CI archiving. If a report references an image path, the path must remain valid after the report is published. For CI/CD, screenshots should be stored in folders that are archived with the report, otherwise the report may show broken image links.
Capture Screenshot in Cucumber Hook
Cucumber hooks are commonly used for centralized failure screenshot logic. An @After hook can inspect the scenario status. If the scenario failed, the hook captures a screenshot and attaches it to the report. This ensures consistent screenshot behavior across all scenarios.
@After
public void tearDown(Scenario scenario) {
if (scenario.isFailed()) {
// Capture screenshot
}
}
The after hook should run before the browser is closed. If the driver is quit first, the screenshot cannot be captured. Hook ordering matters when a framework has separate hooks for reporting, cleanup, and browser teardown. Screenshot capture should happen while the browser session is still alive.
Attaching Screenshot to Cucumber
Cucumber supports attaching screenshots directly to the scenario when the screenshot is captured as bytes. This approach embeds the screenshot into supported Cucumber reports and avoids path problems caused by moved files or missing image folders.
byte[] screenshot =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
scenario.attach(
screenshot,
"image/png",
"Failure Screenshot"
);
This is a clean option for Cucumber-native reporting. The attachment name should be meaningful. Instead of a generic name, use something that explains why the attachment exists, such as Failure Screenshot, Checkout Failure Screenshot, or Login Error Screenshot.
Attaching Screenshot to Allure
Allure supports screenshot attachments through its attachment API. A screenshot can be added as an input stream or through an annotated attachment method. Once attached, it appears inside the failed scenario or test case in the Allure report.
Allure.addAttachment(
"Failure Screenshot",
new ByteArrayInputStream(screenshotBytes)
);
Allure works well when screenshots are combined with step details, logs, API data, and environment information. This gives the user a complete view of the failure. As with other reporting tools, screenshots should be attached in a controlled way to avoid excessive report size.
Attaching Screenshot to Extent Report
Extent Reports commonly attaches screenshots from a saved file path. The framework captures the screenshot, stores it in a known location, and then adds that path to the Extent test entry. The generated HTML report displays the image as part of the test evidence.
test.addScreenCaptureFromPath(screenshotPath);
When using path-based attachments, make sure the image path remains valid relative to the report location. If the report is moved without the screenshot folder, images may not display. This is a common CI/CD artifact problem. Archive the report and screenshot folders together.
Logging Basics
Logs record what happened during execution. They explain the sequence of actions, data used, validations performed, API calls made, exceptions thrown, and cleanup completed. Logs are useful because screenshots show only visual state, while logs explain the technical path that led to that state.
Typical logs include test start, test end, browser launch, application navigation, API request, API response, database operation, exception details, validation result, retry attempt, and cleanup status. The log should help a reader understand the flow without reading the source code.
Types of Logs
Different automation layers produce different logs. Framework logs explain what the test framework did. Browser logs show JavaScript errors and browser console messages. Application logs explain server-side behavior if available. API logs show requests and responses. Database logs show queries or validation details. Custom logs explain business steps.
Logs
|-- Framework Logs
|-- Browser Logs
|-- Application Logs
|-- API Logs
|-- Database Logs
|-- Console Logs
|-- Custom Logs
A mature framework does not treat all logs the same. It collects the right type of log for the failure being investigated. A UI rendering issue may need browser console logs. An API failure may need request and response logs. A data validation failure may need query details or test data identifiers.
Logging with Log4j or SLF4J
Java automation frameworks commonly use logging libraries such as SLF4J with Logback or Log4j. These libraries provide log levels and flexible configuration. The framework can log information during execution and write logs to files, console, or reporting attachments.
logger.info("Opening Login Page");
logger.info("Entering Username");
logger.error("Login Failed");
Use log levels carefully. INFO is useful for normal major events. DEBUG can be used for deeper troubleshooting. WARN can indicate unexpected but non-failing behavior. ERROR should describe actual failures. Overusing error logs for normal activity makes reports harder to interpret.
Browser Console Logs
Browser console logs are useful for UI automation failures. A Selenium test may fail because a button is not visible, a page is not interactive, or a script error stopped rendering. Browser console logs can reveal JavaScript errors, failed resources, CORS errors, or frontend exceptions that are not visible in WebDriver stack traces.
LogEntries logs =
driver.manage()
.logs()
.get(LogType.BROWSER);
for (LogEntry log : logs) {
System.out.println(log.getMessage());
}
Browser log support can vary by browser and driver configuration. When available, it is a useful addition to failure evidence. Attach browser logs mainly when UI failures need frontend debugging context.
REST Assured Request Logging
REST Assured provides request logging that can show URI, headers, parameters, cookies, and body. This is useful when an API scenario fails because the request may not match the expected contract. A missing header, wrong payload field, incorrect endpoint, or invalid token can be identified from request logs.
given()
.log().all()
.when()
.post("/users");
In report attachments, request logs should be sanitized. Authentication tokens, passwords, API keys, session IDs, and personal information should be masked before being written to reports. Debugging value should never come at the cost of exposing sensitive information.
REST Assured Response Logging
Response logging shows status code, headers, cookies, and response body. It is useful when validations fail because the actual response often explains what went wrong. A response may show validation errors, server exceptions, missing data, unauthorized access, or business rule violations.
response.then()
.log().all();
Response logs should also be controlled. Large responses can make reports heavy. Sensitive response data should be masked. A good API framework may attach complete response details only on failure and keep passing scenario logs concise.
Attaching API Request
When testing APIs with Cucumber and REST Assured, attaching the request is often essential. The request tells the developer exactly what the automation sent to the service. It can include method, endpoint, headers, parameters, and payload. This helps determine whether the failure is caused by test data, request construction, authentication, or application logic.
Allure.addAttachment(
"API Request",
requestJson
);
For Extent Reports, the same information may be added as an info log or formatted block. The presentation differs by reporting tool, but the goal is the same: preserve useful request evidence in the report.
Attaching API Response
The API response is the other half of the failure evidence. When an assertion fails, the response body and status code often explain why. Attaching the response allows the reader to inspect actual behavior without rerunning the test.
Allure.addAttachment(
"API Response",
response.asPrettyString()
);
test.info(response.asPrettyString());
API response attachments are especially useful for negative tests, schema validation, authentication testing, and business rule validation. They also help developers reproduce the issue using tools such as Postman, curl, or internal API clients.
Attaching Stack Traces
Stack traces explain where an exception occurred in the automation code. They are useful for distinguishing product failures from automation framework failures. For example, a NoSuchElementException may indicate a locator problem, page timing issue, or application UI change. A null pointer may indicate framework code failure. A timeout may indicate synchronization or environment issues.
Allure.addAttachment(
"Exception",
exception.toString()
);
Stack traces should be available somewhere, but they should not be the only failure evidence. A screenshot, failed step name, and stack trace together tell a stronger story than any one item alone.
Attaching Environment Information
Environment information helps reproduce failures. Useful details include environment name, browser, browser version, operating system, Java version, Cucumber version, Selenium version, API base URL, build number, branch, and execution timestamp. Without this context, a report may be hard to interpret later.
Environment: QA
Browser: Chrome
OS: Windows 11
Java: 21
Framework: Cucumber
Environment data is especially important when tests run in multiple browsers, grids, environments, or pipelines. A failure in one environment may not reproduce in another. Context makes the report actionable.
Logging Execution Flow
Execution flow logs should describe major actions in a readable order. For a UI scenario, logs may show that the browser opened, the user navigated to the application, actions were performed, validations ran, and the browser closed. For an API scenario, logs may show that test data was prepared, a request was sent, a response was received, and assertions were performed.
Scenario Started
-> Open Browser
-> Navigate
-> Perform Actions
-> Validate
-> Close Browser
The best logs are written for future readers. A useful log should make sense to someone who did not write the test. Avoid cryptic messages and internal-only abbreviations. Logs are part of the report, so they should be treated as communication.
Screenshot and Log Flow
The full failure evidence flow combines screenshots and logs. When a test fails, the framework captures a screenshot, collects relevant logs, attaches evidence to the report, generates the report, and allows the team to analyze the failure. This flow should be automatic and consistent across scenarios.
Test Fails
-> Capture Screenshot
-> Capture Logs
-> Attach
-> Generate Report
-> Analyze Failure
Automation engineers should test this flow intentionally. Do not wait for a real defect to discover that screenshots are missing or logs are not archived. Create a controlled failing scenario and verify that the report contains the expected evidence.
Common Mistakes
One common mistake is capturing screenshots only on success. Passing screenshots may be useful in limited cases, but failure screenshots are more important. Another mistake is using generic screenshot names that overwrite previous files. Unique names are necessary for reliable reports and CI artifacts.
Logging sensitive data is a serious mistake. Passwords, access tokens, API keys, session cookies, and personal information should be masked or omitted. Excessive logging is another problem. If every insignificant action is logged, the report becomes difficult to read. The report should highlight meaningful events.
For API failures, teams often forget to include request and response details. Without them, developers cannot easily reproduce the issue. At minimum, API failure evidence should include request, response, status code, useful headers, and error message.
Best Practices
Capture screenshots automatically on failures using Cucumber hooks. Use centralized screenshot and attachment logic instead of scattering it across step definitions. Use meaningful screenshot filenames with scenario names, timestamps, or IDs. Attach screenshots to Allure or Extent Reports in a way that remains valid after CI publishing.
Log important business and technical actions. Attach API requests and responses for API tests. Capture browser console logs when debugging UI issues. Never log passwords, tokens, or sensitive data. Keep logs concise and readable. Include environment information in reports. Archive report files, screenshots, and logs together so report links do not break.
Enterprise Framework Architecture
In an enterprise framework, attachment logic is usually centralized. Feature files describe behavior. Step definitions call automation code. Selenium or REST Assured performs actions. Reporting utilities capture screenshots, logs, API payloads, and environment details. Allure or Extent Reports displays the final evidence in a dashboard.
Feature File
-> Step Definition
-> Automation Code
-> Selenium / REST Assured
-> Screenshot
-> Logs
-> Allure / Extent Report
-> HTML Dashboard
This separation keeps the framework maintainable. Step definitions should not be filled with repeated screenshot and logging code. A clean framework uses hooks, utilities, listeners, or wrappers to collect evidence consistently.
Screenshot vs Logs
Screenshots and logs solve different problems. Screenshots provide visual evidence. They show UI state, error messages, layout issues, popups, overlays, and user-facing behavior. Logs provide technical details. They show execution flow, request data, response data, exception messages, browser console issues, and framework actions.
| Screenshots | Logs |
|---|---|
| Visual evidence | Technical details |
| Show UI state | Show execution flow |
| Best for UI failures | Best for UI and API debugging |
| Easy for anyone to understand | More detailed for developers |
| Capture browser screen | Capture actions, requests, responses, and errors |
They work best together. A screenshot may show that an error banner appeared. Logs may show the API response or exception that caused it. Together, they give a fuller explanation.
Allure vs Extent Attachments
Allure and Extent Reports both support attachments, but their APIs and presentation styles differ. Allure commonly uses Allure.addAttachment() or annotated attachment methods. Extent commonly uses screenshot path attachments and log entries such as info(), pass(), and fail().
| Allure | Extent Report |
|---|---|
| Allure.addAttachment() | addScreenCaptureFromPath() / info() |
| Supports screenshots | Supports screenshots |
| Supports logs | Supports logs |
| Supports API requests and responses | Supports API requests and responses |
| Rich attachment viewer | Rich HTML presentation |
The tool choice matters less than the attachment strategy. Both tools can be useful if the framework captures the right evidence consistently and safely.
Using Attachments in Defect Reports
Attachments are useful beyond automation reports. When a tester raises a defect, the screenshot, failed step, request payload, response payload, browser log, and environment details can be referenced as evidence. This reduces back-and-forth between QA and developers because the failure context is already available.
A good defect report should still explain the issue clearly. Attachments support the defect; they do not replace the defect description. The best workflow is to use the automation report as evidence and then write a concise defect summary with expected result, actual result, environment, and reproduction context.
Handling Attachments in Parallel Execution
Parallel execution requires careful attachment handling. If multiple scenarios run at the same time and write screenshots with the same filename, files can be overwritten. If logs are shared incorrectly across threads, one scenario's logs may appear in another scenario's report. This makes reports unreliable.
Use unique filenames and scenario-specific report nodes. Store screenshots in thread-safe or scenario-specific folders when needed. For logging, use context that associates messages with the correct scenario. A report must be trustworthy; incorrect attachments are worse than missing attachments because they can mislead debugging.
Managing Report Size
Attachments increase report size. Screenshots, response bodies, logs, and browser console output can become large, especially in regression suites. Large reports may take longer to generate, open, upload, download, or archive. Teams should manage report size deliberately.
A practical approach is to attach detailed evidence mainly on failures, attach milestone evidence only for critical flows, trim large payloads, compress images when appropriate, and avoid duplicate logs. The report should remain useful and fast enough for everyday use.
Security and Privacy in Attachments
Security is one of the most important concerns in attachments. Reports may be stored in CI systems, shared by email, uploaded to artifact repositories, or attached to defects. Screenshots may contain personal data. API logs may include credentials, tokens, cookies, headers, or customer information. Database logs may expose internal records.
A secure framework masks sensitive values before writing them to reports. It avoids attaching full data when a smaller sanitized excerpt is enough. It restricts report access when reports contain internal evidence. Good reporting should improve debugging without creating data leakage risk.
Assertion Logs
Assertion logs are useful because many failures happen during validation. A screenshot may show the page, and an API response may show the payload, but the assertion log explains exactly what the automation expected and what it actually found. For example, instead of logging only "validation failed," a better log says that the expected order status was Confirmed but the actual status was Pending.
Good assertion messages save debugging time. They should include the field being validated, the expected value, the actual value, and the business meaning when useful. For UI automation, this may include page title, visible message, table value, button state, or URL. For API automation, it may include status code, response field, schema rule, header value, or business error code.
Assertion logs should be readable in reports. A future reader should understand the failure without opening the source code. This is especially important when reports are shared with developers or attached to defects. Clear assertion logs turn failed validations into actionable evidence.
Negative Test Evidence
Negative scenarios need careful evidence because they intentionally test invalid inputs, blocked actions, rejected requests, or error handling. A negative test may pass because the application correctly displays an error. It may fail because the application accepts invalid data or shows the wrong error. The report should make that distinction clear.
For UI negative tests, attach the screen that shows the validation message or unexpected behavior. For API negative tests, attach the request and response showing the invalid input and the returned error. This helps reviewers understand that the test was not failing randomly; it was checking a specific rule.
Negative test evidence is also useful in interviews and real projects because it shows disciplined validation. A strong automation suite does not only prove happy paths. It proves that the system rejects invalid behavior correctly, and reports should preserve that evidence.
Report Portability
Report portability means the report should still work after it is moved, downloaded, archived, or opened from a CI artifact. This is especially important for screenshot paths. If an Extent report references a screenshot using an absolute path from one machine, the image may not display on another machine. If the screenshot folder is not archived with the HTML report, the report may show broken images.
To improve portability, store screenshots inside or near the report output folder. Use relative paths when the reporting tool supports them. Archive the report file and attachment folders together. For Cucumber and Allure byte attachments, portability is often simpler because attachments are embedded or stored within the report result structure.
Portable reports are important for collaboration. A report should be useful to a developer, tester, lead, or interviewer who did not run the test locally. If images and logs disappear after download, the report loses much of its value.
Retention and Cleanup Strategy
Attachments should be retained according to project need. Local reports can usually be overwritten frequently. CI reports for pull requests may be kept for a shorter period. Nightly regression and release reports may need longer retention because they provide evidence for quality review and historical analysis.
Cleanup is also necessary. Screenshots and logs can consume large amounts of disk space over time. A framework or pipeline can clean old local reports before execution, while CI can use artifact retention rules to preserve important reports for a defined period. The strategy should be deliberate rather than accidental.
A good retention strategy answers simple questions: which reports are kept, where they are stored, how long they remain available, who can access them, and how old attachments are removed. Without this, report folders grow until they become hard to manage.
Troubleshooting Missing Attachments
If screenshots or logs are missing from reports, start by checking whether the capture code actually runs. For Cucumber, confirm that the hook is registered and that it executes before the browser is closed. If the scenario fails but the driver is already quit, screenshot capture will fail. Hook order can be the root cause.
Next, check file paths. If screenshots are saved to one location but the report references another, images will not appear. In CI, confirm that both the report and screenshot folders are archived. For Allure, confirm that attachments are written into the correct result directory. For Extent, confirm that the image path passed to the report is valid from the final HTML report location.
If logs are missing, confirm that the logging configuration writes to the expected file or report object. Also check parallel execution. Shared log variables can cause one scenario's logs to overwrite another's. Troubleshooting should follow the full path: capture, save, attach, generate, archive, and open.
Using Attachments for Learning and Review
Attachments are not useful only for defects. They also help learners understand automation execution. A screenshot attached to a scenario can show what the browser looked like at a key step. API request and response attachments can show how REST Assured communicates with the service. Logs can show the order in which framework components run.
For training, attachments should be intentionally selected. Too much evidence can overwhelm beginners, but focused evidence teaches the relationship between Gherkin, step definitions, automation code, and reports. A learner can read the scenario, open the report, inspect the screenshot or response, and understand how behavior was validated.
This is useful for interview preparation too. Candidates who can explain screenshots, logs, hooks, REST Assured request logging, and report attachments usually demonstrate practical framework understanding, not just syntax knowledge.
Interview-Ready Summary
Screenshots provide visual evidence of the application state during test execution, while logs capture technical execution details. Cucumber hooks are commonly used to capture screenshots automatically after failed scenarios. Selenium captures screenshots using the TakesScreenshot interface, while REST Assured provides request and response logging for API tests.
Reporting frameworks such as Allure and Extent Reports support attaching screenshots, logs, API requests, responses, stack traces, and environment information directly to reports. Effective attachment and logging strategies reduce debugging time, improve defect reporting, and strengthen collaboration between QA and development teams.
Golden Rules
Capture screenshots automatically for failed UI scenarios using Cucumber hooks. Attach API requests, responses, and relevant logs for API failures. Use meaningful filenames and centralized attachment logic. Log important events without exposing sensitive information such as passwords or tokens. Use screenshots for visual context and logs for technical diagnostics because they work best together.
The practical takeaway is simple: a failure without evidence creates delay, while a failure with screenshots and logs creates actionable insight. A strong Cucumber framework captures the right evidence automatically, attaches it to the right report, and keeps it safe, readable, and useful.