ScreenshotNeo

BlogHow-to

How to Ignore Timestamps and Ads in Visual Regression Screenshots

Use Playwright masks or screenshot-time CSS to ignore timestamps and ads while keeping visual regression checks useful. Includes runnable examples and troubleshooting.

By the ScreenshotNeo team4 October 20267 min read

In Playwright Test, pass timestamp and ad locators to toHaveScreenshot({ mask }). Playwright masks those regions in the captured screenshot while keeping their layout in place, so changing text or imagery does not create pixel diffs. Use screenshot-time CSS instead when you want the elements hidden; choose visibility: hidden to preserve their space or display: none only when its layout changes are acceptable.

1. Mask timestamps and ads with Playwright

Use stable, narrow selectors that identify only the changing components. Test IDs are usually a good choice because they are owned by your application and do not depend on visible copy.

import { test, expect } from '@playwright/test';

test('page visual check', async ({ page }) => {
  await page.goto('/');
  await expect(page.getByRole('main')).toBeVisible();

  await expect(page).toHaveScreenshot({
    mask: [
      page.getByTestId('timestamp'),
      page.locator('[data-testid="ad-slot"]'),
    ],
  });
});

On the first run, Playwright creates a reference screenshot. On later runs it compares the new capture with that reference. When establishing a baseline, the runner captures repeatedly until two consecutive screenshots match, then saves the last one. Commit and review reference files with your code. To intentionally refresh them, run npx playwright test --update-snapshots and inspect the changed images before accepting them. See the official Playwright visual comparisons guide and toHaveScreenshot API.

Keep masks small and meaningful

  • Mask the timestamp element, not its whole header or page section.
  • If the ad changes inside a reserved slot, mask that slot container. Avoid masking surrounding content whose spacing or styling should still be checked.
  • Prefer application-owned test IDs or stable component selectors over brittle selectors based on generated class names or ad text.
  • A mask suppresses visual differences in the matched screenshot area. It does not validate the timestamp value, ad delivery, or application data; cover those behaviors with separate assertions if they matter.

A broad mask can hide a real regression if the affected pixels fall inside it. Keep the masked area limited to the genuinely volatile content.

2. Hide volatile content with screenshot-time CSS

Use screenshot-time CSS when the changing element should not appear in the baseline at all. Playwright’s screenshot assertion accepts a stylesheet for this purpose; its screenshot API documents that the style reaches Shadow DOM and inner frames.

import { test, expect } from '@playwright/test';

test('page visual check with volatile content hidden', async ({ page }) => {
  await page.goto('/');
  await expect(page.getByRole('main')).toBeVisible();

  await expect(page).toHaveScreenshot({
    style: `
      [data-testid="timestamp"],
      [data-testid="ad-slot"] {
        visibility: hidden !important;
      }
    `,
  });
});

visibility: hidden preserves the element’s layout space while hiding its pixels. display: none removes it from layout and can shift nearby content, which may produce a different screenshot from the one you intended. Use it only if that changed layout is acceptable for the check. The stylesheet affects the capture; it does not change what your application displays to a normal visitor.

3. Choose masks, CSS, or a tolerance

Approach What changes in the capture Use it when
mask The selected pixels are covered; layout remains represented. You want to ignore changing content but still compare the page around it.
Screenshot-time visibility: hidden The element’s pixels disappear while its space remains. You want a clean region with stable surrounding geometry.
Screenshot-time display: none The element and its layout space disappear. The resulting layout is intentionally what the visual test should compare.
Pixel-difference tolerance Small pixel-level variation is allowed according to the configured tolerance. You have known, small rendering noise after addressing dynamic regions.

A tolerance is not a substitute for targeting timestamps and ads. A loose threshold can make meaningful visual changes harder to catch. Start with precise masks or capture CSS, then use only the smallest tolerance that addresses known rendering noise. Consult the visual comparison options for the supported assertion settings in your installed Playwright version.

4. Make the check stable and diagnostic

  1. Wait for the state under test. Navigate to the relevant page state and wait for a meaningful application condition, such as the main content becoming visible. Masking does not make unfinished page loads reliable.
  2. Control data and time where practical. If the timestamp itself is part of another test, control the clock or data for that test instead of masking it. The visual test can ignore the timestamp while a functional assertion checks it separately.
  3. Use the same capture environment. Keep browser version, operating system, rendering settings, and headless configuration consistent between baseline creation and comparison. Playwright notes that rendering can vary with host OS, browser version, settings, hardware, power source, headless mode, and other factors. Use separate baselines for materially different environments where needed.
  4. Review baseline updates. Update snapshots intentionally and inspect the diff. Do not treat a passing update command as proof that the new appearance is correct.
  5. Keep different checks focused. A masked visual test checks the stable appearance around volatile regions. Use separate assertions or tests for ad-slot dimensions, content behavior, and timestamp correctness when those requirements matter.

Masking and screenshot CSS add capture configuration, but the dossier provides no benchmark for their runtime cost. Keep the comparison focused and avoid repeated full-page captures when a smaller screenshot assertion covers the behavior you need.

5. Troubleshoot common failures

Symptom Likely cause Fix
The timestamp or ad still creates a diff. The locator does not match the rendered element, or the volatile pixels extend outside the matched region. Confirm the selector against the loaded page, use a stable test ID, and mask the smallest container that fully contains the changing pixels.
A large part of the page changed after hiding an ad. display: none removed the ad’s space and moved neighboring content. Use a mask or visibility: hidden to preserve geometry, or assert the intentional reflow separately.
The test passes but a real issue near the ad is missed. The mask includes neighboring content or an entire section. Narrow the locator and keep the mask limited to the volatile component.
The screenshot differs between local and CI. Browser or host rendering environments differ. Align browser versions and capture settings, and generate and compare baselines in a consistent environment. Maintain separate baselines if the target environments materially differ.
The baseline changes on every run. There is still an uncontrolled dynamic region, an unstable page state, or environmental variation. Wait for the intended state, control test data or time where practical, identify other volatile pixels, and standardize the capture environment.
A selector works in the app but not in the test. The screenshot runs before the component is rendered, or the selector is not stable in the test page. Wait for a relevant locator or application condition before taking the screenshot, and prefer a test ID maintained by the app.

6. Hosted visual review options

Native Playwright masking and screenshot styling are enough for the core task. Hosted review products may suit teams that want shared visual review workflows:

  • Chromatic: Its documentation supports .chromatic-ignore, data-chromatic="ignore", and CSS selector lists. Ignored pixels are disregarded, while changes to an ignored element’s dimensions can still produce a diff. See Chromatic’s ignore-elements guide and Chromatic for Playwright.
  • Percy: Its Playwright documentation describes ignoring areas with CSS selectors, XPath, or rectangle coordinates, plus screenshot-time Percy CSS. Check the documentation for the version in your project: Percy Playwright README.

Compare these approaches by whether they mask pixels or alter captured layout, whether dimension changes remain detectable, how maintainable the selectors are, and whether your team needs a hosted review workflow. These products are optional; they are not required to ignore timestamps or ad pixels in Playwright.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call API can return an image or PDF, while its capture pipeline accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Each cleanup step can be turned off. This is useful when you need a clean capture of a live page; it does not replace Playwright’s baseline comparison or targeted masks for application-owned timestamps and ad slots.

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Replace YOUR_API_KEY with your key. See the ScreenshotNeo API documentation for the request options and response details. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status. An MCP server gives AI agents, including Claude and Cursor, tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, no card required.

8. FAQ

Does masking remove the timestamp from the page?

No. It covers the selected screenshot area during comparison. The page content and layout are still present in the browser.

Should I mask the ad or hide it?

Mask it when you want to preserve and compare its reserved area. Hide it with visibility: hidden when you want no ad pixels but want to keep the space. Removing it with display: none changes layout.

Can I ignore an element but still detect size changes?

Playwright’s mask is intended to cover screenshot pixels; for tools with explicit ignored-element semantics, check their documented dimension behavior. Chromatic documents that ignored-element dimension changes can still trigger a diff.

Do I need a hosted screenshot service for this?

No. Playwright Test supports masks and screenshot-time styles directly. A hosted review product is optional when its collaboration workflow fits your team.