Make consent state explicit in every screenshot test. Use a fresh, isolated context to test a first visit; seed the application’s real consent cookie or storage value before navigation to test a returning visitor; and keep a separate test for the consent controls themselves. This prevents one test’s choice from silently changing another test’s screenshot.
Choose the consent state the screenshot should show
Before writing setup code, decide what the image is meant to represent. A banner screenshot, a normal page after consent, and a test of the consent interaction are different cases and should not depend on the same implicit browser state.
| Test intent | Starting state | What to verify |
|---|---|---|
| First visit | Fresh isolated context with no saved consent | The banner appears; capture it or exercise its controls. |
| Returning visitor | Application’s actual saved consent state configured before navigation | The banner is absent if that is the application’s expected behavior; capture the page. |
| Consent interaction | Clean state, with the banner visible | Choose an option through the UI and verify the resulting state and page. |
Playwright recommends isolated tests with their own cookies and storage. Its non-persistent BrowserContext supports cookie setup and clearing. The built-in Playwright Test fixtures provide an isolated context for each test by default; avoid sharing a persistent browser profile unless the test specifically requires it. See Playwright’s best practices.
As an Amazon Associate I earn from qualifying purchases.
Seed the application’s real consent state
Use the persistence mechanism the application actually reads. If consent is stored in a cookie, set the correct name, value, domain, and path. If it is stored in localStorage or sessionStorage, set the exact origin, key, and value before the application’s consent code runs. Do not guess a key from a consent vendor’s usual conventions: inspect the application or perform a real consent action and observe what it stores.
Cookie-based consent
Add the cookie to the test’s context before navigating to the page. The following is an adaptable pattern, not a real cookie name or value; replace every example value with the application’s documented implementation.
#1 Best Overall
import { test, expect } from '@playwright/test';
test('returning visitor sees the page without the banner', async ({ page }) => {
await page.context().addCookies([{
name: 'consent-cookie-name',
value: 'documented-consent-value',
domain: 'localhost',
path: '/',
}]);
await page.goto('/');
await expect(page.getByRole('dialog', { name: /cookie|privacy/i })).toBeHidden();
await expect(page).toHaveScreenshot('home-consented.png');
});
Cookie scope matters: a cookie for the wrong host or path will not be sent with the page request, and an incorrect value may not represent the state the application expects. Playwright documents cookie operations in its BrowserContext API.
Local or session storage
Storage belongs to an origin, so setup must target the same scheme, host, and port as the application. A call that sets localStorage through a page requires that origin to be available. If the application checks consent during its initial navigation, setting storage after page.goto() may be too late. Arrange initialization before the consent code runs, or use a supported storage-state setup. Playwright’s current WebStorage API documents local and session storage operations; its webStorage.clear method is documented as added in v1.61.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
Keep consent behavior tests separate from page screenshots
When the consent UI itself is under test, begin with a clean context and interact with controls using accessible roles and names. Assert both the visible outcome and any relevant saved state before capturing. This tests what a user can see and do rather than hiding the feature in setup.
import { test, expect } from '@playwright/test';
test('first visit shows the consent banner', async ({ page }) => {
await page.goto('/');
const banner = page.getByRole('dialog', { name: /cookie|privacy/i });
await expect(banner).toBeVisible();
await expect(page).toHaveScreenshot('home-first-visit.png');
});
The dialog role, accessible name, button names, and expected behavior depend on the application. Replace the example locator with accessible selectors that match its real interface. For a choice test, locate the intended button by role and name, click it, and assert the resulting page or banner state. Keep that interaction test separate from screenshots of unrelated pages, which are usually more predictable with a fixed seeded state than with an opportunistic click.
Do not globally auto-dismiss consent if any test is supposed to verify that consent works. An automatic click can fail when a banner is absent, delayed, or redesigned—and can conceal a genuine regression.
Make visual comparisons repeatable
Use Playwright Test’s expect(page).toHaveScreenshot() for screenshot assertions. It waits for two consecutive screenshots to match before comparing against the reference image, but that wait does not establish the application’s consent state or guarantee identical rendering across machines. See Playwright’s visual comparison guidance and the PageAssertions reference.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- Generate and compare baselines in a consistent browser and operating-system environment. Playwright warns that the host OS, browser version, settings, hardware, power source, and headless mode can affect rendering.
- Keep application data and consent state deterministic; screenshot matching cannot fix content that changes between runs.
- Use screenshot
styleorstylePathnarrowly to suppress unrelated volatile elements, such as rotating content, when appropriate. Playwright documents screenshot styling in the Page API. - Never hide the consent banner in a screenshot test whose purpose is to verify that banner or its controls.
Troubleshoot common consent screenshot failures
| Symptom | Likely cause | What to check |
|---|---|---|
| Banner appears in a returning-visitor screenshot | The state was set too late, or the cookie/storage details do not match the application. | Set state before navigation; verify the actual key or cookie, value, origin, domain, and path. |
| Banner is missing in a first-visit test | The context is not clean, or test setup has retained or seeded consent. | Use the isolated test context and remove consent setup from that test; check that no shared persistent profile is being used. |
| Storage setup has no effect | It targets the wrong origin or runs after consent code has already checked storage. | Match the page origin and initialize storage before the relevant application code executes. |
| Consent interaction test flakes | The banner may be delayed or absent, or the locator does not match the current accessible interface. | Start from clean state, wait for the intended visible control, use its actual role and accessible name, and assert the result. |
| Screenshot differs across machines | Rendering environment or application content differs. | Align OS, browser version, settings, and headless mode; stabilize changing content and data. |
| Screenshot passes but consent is wrong | A matching image does not prove the intended persistence behavior was exercised. | Assert banner visibility and the relevant post-choice state explicitly, in addition to taking the screenshot. |
Or skip the browser setup
For screenshots outside a Playwright consent-behavior test, ScreenshotNeo offers a screenshot API and MCP server. Its capture flow accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status in headers. AI agents can use its MCP server tools, including take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.
One GET request returns an image or PDF. This cURL example saves a WebP screenshot of the target URL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for authentication and request options. For a screenshot that must show a specific consent state, the target site still needs to receive the relevant state through a supported mechanism; a screenshot API is not a substitute for testing your application’s consent UI and persistence in Playwright.
Rank #4
Sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Should I click Accept on the banner in every screenshot test?
No. Click a consent control in tests that verify the consent interaction. For unrelated screenshots, configure the intended saved state as test setup.
Does `toHaveScreenshot()` make cookie state deterministic?
No. It stabilizes consecutive captures before comparison; consent state must be established and asserted separately.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




