keepcalculator

06 Numbers and Powers

Playwright Consent Banner Screenshots Across Locales

Card No. 06·62986 · Updated · Standard formula, shown below

To capture consent banner screenshots in Playwright across locales, you need to handle the banner’s dynamic content, cookie consent state, and locale-specific text before taking the screenshot. This article explains how to reliably capture these screenshots using Playwright’s built-in features, including locale emulation, cookie management, and screenshot options.

Why Consent Banners Are Tricky to Screenshot

Consent banners are dynamic elements that appear based on user interaction, cookie state, and regional privacy laws (like GDPR in Europe or CCPA in California). They often load asynchronously, vary in position and size, and contain localized text. A simple page.screenshot() call may capture the banner mid-animation, miss it entirely if it hasn’t loaded, or show a previously accepted state. Additionally, the banner’s appearance can differ across locales due to translated strings, different layout lengths, and even different legal requirements.

Setting Up Playwright for Multiple Locales

Playwright allows you to emulate a specific locale by passing the locale option when creating a browser context. This affects the Accept-Language header and the default language used by navigator.language. To capture screenshots across locales, you’ll typically loop over an array of locale strings, creating a fresh context for each one.

const { chromium } = require('playwright');

const locales = ['en-US', 'de-DE', 'fr-FR', 'ja-JP'];

(async () => {
  const browser = await chromium.launch();
  for (const locale of locales) {
    const context = await browser.newContext({ locale });
    const page = await context.newPage();
    await page.goto('https://example.com');
    // Wait for banner to be visible, then screenshot
    await page.waitForSelector('#consent-banner', { state: 'visible' });
    await page.screenshot({ path: `consent-${locale}.png` });
    await context.close();
  }
  await browser.close();
})();

This basic approach works if the banner appears immediately. However, real-world sites often use cookie consent managers (like OneTrust or Cookiebot) that load the banner via JavaScript after a short delay. You’ll need to wait for the banner to be fully rendered, not just present in the DOM.

Waiting for the Banner to Be Ready

Use Playwright’s waitForSelector with the state: 'visible' option to ensure the banner is actually displayed, not just present in the DOM. For banners that animate in, you might also want to wait for the animation to finish—either by using a fixed delay or by checking that the banner’s bounding box is stable.

await page.waitForSelector('#cookie-banner', { state: 'visible' });
// Optionally wait for animation to complete
await page.waitForTimeout(500); // Adjust based on your site's animation

If the banner appears after a network request, you can use page.waitForResponse() to wait for the specific API call that returns the banner content, then wait for the selector. This is more robust than a fixed timeout.

Handling Cookie States

Consent banners often remember user choices via cookies. If you don’t clear cookies between contexts, the banner might not appear on the second locale. Always create a new context for each locale, as shown above, to ensure a clean state. Alternatively, you can clear cookies explicitly:

await context.clearCookies();

But creating a new context is simpler and also resets localStorage and other session data, which is often necessary.

Capturing the Screenshot Correctly

Once the banner is visible, you can capture the full page or just the banner element. For full-page screenshots, use fullPage: true in the screenshot options. For element-only screenshots, use locator.screenshot():

const banner = page.locator('#cookie-banner');
await banner.screenshot({ path: `banner-${locale}.png` });

If the banner is sticky (fixed position), a full-page screenshot will show it at the top or bottom, which is usually fine. For a consistent look, you might want to set a specific viewport size for all locales:

const context = await browser.newContext({ locale, viewport: { width: 1280, height: 720 } });

Dealing with Locale-Specific Variations

Different locales may have different banner layouts—text length can cause wrapping, buttons may resize, and some locales might have additional elements (like a “More information” link). To ensure your screenshots are comparable, consider:

  • Setting a fixed viewport size across all locales.
  • Waiting for the banner to be fully loaded and stable (no layout shift).
  • If the banner is very tall, you might want to capture only the top portion of the page, or use element screenshots.

Also, some consent managers use iframes. If the banner is inside an iframe, you’ll need to switch to that frame before interacting or screenshotting. Playwright’s frameLocator() can help:

const frame = page.frameLocator('#consent-iframe');
await frame.locator('#accept-button').waitFor();
await frame.locator('#consent-banner').screenshot({ path: `banner-${locale}.png` });

Common Pitfalls and How to Avoid Them

  • Banner not appearing: Ensure cookies are cleared and you’re using a fresh context. Also, some sites only show banners to users in certain regions—you may need to emulate geolocation or use a proxy.
  • Banner appears after a delay: Use waitForSelector with a generous timeout, or wait for a network response that indicates the banner loaded.
  • Screenshot captures banner in mid-animation: Add a small delay after the banner becomes visible, or wait for the animation to finish by checking the banner’s position or opacity.
  • Locale not applied: Verify that the locale is correctly set by checking navigator.language in the page. Some sites require the Accept-Language header, which Playwright sets automatically based on the locale.
  • Banner uses iframes: Use frameLocator to interact with content inside the iframe.

Frequently Asked Questions

How do I take a full-page screenshot with the consent banner?

Use page.screenshot({ path: 'full.png', fullPage: true }) after waiting for the banner to be visible. This will capture the entire page, including the banner if it’s in the viewport. If the banner is sticky, it will appear in the screenshot at its fixed position.

Can I screenshot just the banner element?

Yes, use page.locator('#banner-id').screenshot({ path: 'banner.png' }). This captures only the element, which is useful for comparing banner designs across locales without other page content.

Why is my banner not showing in the screenshot?

This usually happens because the banner is loaded asynchronously or because cookies from a previous session are present. Create a new browser context for each locale, and use waitForSelector with a timeout to ensure the banner is visible before screenshotting.

How do I handle consent banners that are inside an iframe?

Use Playwright’s frameLocator to access the iframe content. For example: const frame = page.frameLocator('#iframe-id'); await frame.locator('#banner').waitFor(); await frame.locator('#banner').screenshot().

Do I need to set the locale for each context?

Yes, pass the locale option when creating a new context. This ensures the browser sends the correct Accept-Language header and sets navigator.language, which most sites use to localize content.

Can I capture screenshots of the banner after clicking “Accept”?

Yes, after clicking the accept button, the banner usually disappears. You can take a screenshot to show the state after consent. Use page.click('#accept-button') then wait for the banner to be hidden, then screenshot.

Conclusion

Capturing consent banner screenshots across locales in Playwright is straightforward if you handle the dynamic nature of the banner and ensure a clean state for each locale. By creating a new context per locale, waiting for the banner to be visible, and using the appropriate screenshot method, you can produce consistent and accurate screenshots for your documentation or testing needs.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →