Today I want to show you how you can attach your screenshots directly to Playwright's test reports.
Imagine you have a simple Playwright test that navigates to Checkly. You take a screenshot and store it in screenshots/home.png
.
test('home page screenshot', async ({ page }, testInfo) => {
await page.goto('https://checklyhq.com');
const homeScreenshot = await page.screenshot({path: "screenshots/home.png"});
await page.getByRole('link', { name: 'Customers' }).first().click();
const customerScreenshot = await page.screenshot({path: "screenshots/customers.png"});
await expect(page.locator('h1')).toContainText('Hear it from our customers');
});
Then, you click a link in the main navigation, expect a specific heading to be visible, and take another screenshot. When you run this test using npx playwright test
, the test passes, and you find the screenshots in the /screenshots directory. However, if you check the generated HTML report, you'll see that while there are calls for screenshots, the images themselves aren't included in the report.
One option for viewing whole-page screenshots is a Playwright trace, this would gather screenshots from around each action, and we can kick off a test with the command npx playwright test --trace
option
But if we want to highlight a single screenshot, or grab things like .svg or JSON data and add it to the report, or if we want to keep only a few images because our test reports are being uploaded to CI/CD; it would be more convenient to add screenshots to the report directly in our code.
Here's how to do it.
Use the testInfo
Object
First, go back to your test case and access the testInfo
object, which is available in every Playwright test case as the second argument. With testInfo
, you can call the attach
method to include your screenshots in the report.
To attach your screenshots, you would do something like this:
test('home page screenshot', async ({ page }, testInfo) => {
await page.goto('https://checklyhq.com');
const homeScreenshot = await page.screenshot();
testInfo.attach('Home Page', {
body: homeScreenshot,
contentType: 'image/png',
});
await page.click('nav a[href="/some-link"]');
const customersScreenshot = await page.screenshot();
testInfo.attach('Customers Page', {
body: customersScreenshot,
contentType: 'image/png',
});
});
Here, instead of just calling page.screenshot()
, you also attach the result to the test report using testInfo.attach
. You give each attachment a name, provide the screenshot as the body, and specify the content type (image/png
).
Run and Review the Report
Now, when you run your test case again, everything still passes as before, but when you open the HTML report, you'll see the screenshots directly included. This makes it easy to access all your attachments in one place, right from the report.
Bonus: Attach Other File Types
This approach isn't limited to screenshots. For example, you can attach a JSON file from an API response, if you followed my last article on testing your APIs with Playwright.
//see the article linked above for how to get this API response
const allCountries = await response.json();
testInfo.attach('Sample JSON', {
body: Buffer.from(JSON.stringify(allCountries)),
contentType: 'application/json',
});
After running the test, the JSON or any other attachment will be included in the report.
Watch in action: attaching screenshots to your Playwright reports
See Stefan demonstrate the screenshot-to-reports process in the video below.
Conclusion
With test attachments, you can centralize all your screenshots, SVGs, or other files in one place within your Playwright report. This approach not only declutters your repository by potentially eliminating the need for separate directories for screenshots but also provides a more integrated view of your test results.
Of course, if you want not only screenshots, but visual regression tests and traces in a shared web dashboard, along with CLI-based management tools for your CI/CD workflow, check out how Checkly uses Playwright to build synthetic monitoring for your pages and APIs.