Screenshots and visual regression testing
Learn how to take some pictures and implement visual regression tests.
Even though Playwright provides stellar tools to debug your tests, sometimes you might want to take screenshots while running your headless tests.
Page screenshots
import { test, expect } from "@playwright/test";
test("get started link", async ({ page }) => {
await page.goto("https://playwright.dev/");
// take a page screenshot
await page.screenshot({ path: "./home.png" });
});
Use page.screenshot() to capture the state of the page.
Locator screenshots
If you're only interested in a particular DOM element, locators provide screenshots, too.
import { test, expect } from "@playwright/test";
test("get started link", async ({ page }) => {
await page.goto("https://playwright.dev/");
// take a screenshot of a particular element
await page
.getByRole("link", { name: "Docs" })
.screenshot({ path: "./docs.png" });
How to leverage browser names in your screenshot path
If you're running parallel tests with multiple browsers, including the browserName in the screenshot path avoids that all the screenshots overwrite each other.
test("get started link", async ({ page, browserName }) => {
await page.goto("https://playwright.dev/");
await page
.getByRole("link", { name: "Docs" })
.screenshot({ path: `./docs-${browserName}.png` });
});
The page, browserName and other test variables are called test fixtures.
Playwright provides many
fixtures for different use
cases and we'll look at them later.
Visual regression snapshots
Even though screenshots are handy to evaluate what your tests are doing you can level it up a notch and implement visual regression testing with a single assertion — toHaveScreenshot().
test("get started link", async ({ page, browserName }) => {
await page.goto("https://playwright.dev/");
// visual regression works on a page level...
await expect(page).toHaveScreenshot("home.png");
// but also on a locator level
await expect(page.getByRole("link", { name: "Docs" })).toHaveScreenshot(
"docs.png",
);
});
toHaveScreenshot() will create page and component screenshots next to your test files and perform visual regression tests in future runs. Additionally, it automatically captures the browser and OS in use to take the screenshot ([test-name]-[browser]-[os].png). 💪
Note that when you run a test with visual regression for the first time, it'll fail becomes there's nothing to compare. 😅
Playwright by default disables animations and transitions when taking screenshots to avoid flakiness because of moving elements.
Screenshot configuration
screenshot() and toHaveScreenshot() provide multiple configuration options:
maskmaxDiffRatioscale- ...
Familialize yourself with all these options to get the most out of your screenshots!
Screenshots as test attachments
If trace files and the UI mode don't provide you essential info, you can also attach images (and other media) to the test results with testInfo.attach().
test("basic test", async ({ page }, testInfo) => {
await page.goto("https://playwright.dev");
const screenshot = await page.screenshot();
await testInfo.attach("screenshot", {
body: screenshot,
contentType: "image/png",
});
});
Test attachments can be very valuable when you tests are dealing with file up and downloads.
💡 If you're stuck, find a working example on GitHub.