ScreenshotNeo

BlogHow-to

How to Compare Screenshots of a Hindi and English Website in Playwright

Compare Hindi and English pages in Playwright with matching capture conditions, separate visual baselines, and a reviewable diff.

By the ScreenshotNeo team4 October 20267 min read

Use Playwright Test’s screenshot assertion to capture each language under the same browser and viewport conditions. Keep a separate approved baseline for each language when checking regressions; capture the same route in both locales and inspect the images side by side when you want to understand how the layouts differ. Playwright does not provide a dedicated Hindi-versus-English comparator or diagnose localization defects for you.

1. Set up a visual test

Install Playwright Test if the project does not already use it, then create a test file such as tests/localized-visual.spec.ts. Replace the example paths and readiness selectors with the routes and signals your application actually uses. Setting a browser-context locale does not necessarily make your application switch languages; your app may use locale-specific routes, cookies, or its own language selector.

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

const cases = [
  { name: 'English', locale: 'en-US', path: '/en/home' },
  { name: 'Hindi', locale: 'hi-IN', path: '/hi/home' },
];

test.describe('localized home page visual baselines', () => {
  for (const item of cases) {
    test(`${item.name} page matches its baseline`, async ({ browser }) => {
      const context = await browser.newContext({
        locale: item.locale,
        viewport: { width: 1440, height: 900 },
        deviceScaleFactor: 1,
      });
      const page = await context.newPage();

      await page.goto(`https://example.com${item.path}`, {
        waitUntil: 'networkidle',
      });
      // Replace this with an application-specific signal that the localized
      // content is ready. Verify the language through the rendered page too.
      await page.locator('main').waitFor({ state: 'visible' });

      await expect(page).toHaveScreenshot(`${item.name.toLowerCase()}-home.png`, {
        fullPage: true,
      });
      await context.close();
    });
  }
});

Use your actual locale identifiers and routing conventions. hi-IN is an example context locale, not a universal requirement for Hindi sites. Confirm that each route really renders the intended language before accepting its baseline.

Run the test with npx playwright test tests/localized-visual.spec.ts. On its first run, Playwright creates expected screenshots. Review those files before treating them as approved references. Later runs compare new captures with those references.

2. Make the comparison meaningful

For regression testing, the Hindi capture should be checked against the approved Hindi baseline and the English capture against the approved English baseline. This catches a change within either localized experience. For a direct layout comparison, use the same route and state in both contexts, then inspect both resulting screenshots side by side. That side-by-side comparison is a review workflow; Playwright’s baseline assertion is not a language-to-language comparator.

  • Match capture conditions: use the same browser engine and version, operating system, viewport, device scale, page state, and screenshot scope. Rendering can vary with the host environment, so keep baseline creation and comparison in the same environment.
  • Choose scope consistently: compare full-page to full-page, viewport to viewport, or the same element to the same element. Playwright supports page and element screenshots as well as full-page capture.
  • Check the rendered language: verify route, selected language, and visible content. A locale setting configures the browser context; it does not guarantee your site will translate itself.
  • Check Hindi glyphs and fonts: confirm the intended Hindi text and web fonts appear in the actual page before trusting the image. Font setup and readiness are application-specific.
  • Review layout risks: inspect wrapping, component height, clipping, overlap, alignment, and horizontal overflow. These are useful human review targets, not defects Playwright automatically identifies.

Playwright’s screenshot assertion waits until two consecutive screenshots match before comparing the final image with the expected one. Screenshot assertions disable animations by default, which can reduce capture noise.

3. Tune screenshot stability and tolerance

Keep the test focused on meaningful visual differences. If timestamps, rotating content, or other volatile regions make captures unstable, use a narrowly scoped stylesheet with the screenshot assertion’s stylePath option to hide or normalize those regions. The stylesheet can affect content in frames and Shadow DOM. Do not suppress localized text or layout that the test is meant to check.

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

test('English account page is stable', async ({ page }) => {
  await page.goto('https://example.com/en/account');
  await page.locator('main').waitFor({ state: 'visible' });

  await expect(page).toHaveScreenshot('english-account.png', {
    fullPage: true,
    stylePath: './tests/visual-stability.css',
    threshold: 0.2,
    maxDiffPixels: 0,
  });
});
/* tests/visual-stability.css: suppress only known volatile content */
[data-visual-test-clock], .rotating-promotion {
  visibility: hidden !important;
}

threshold controls acceptable perceived color difference; the documented default is 0.2. maxDiffPixels allows a specified number of differing pixels and is unset by default. The example sets it to zero to require no differing pixels within the color threshold. Start with strict settings, inspect real diffs, and adjust only when you understand which harmless variation is being allowed.

4. Review and update baselines deliberately

  1. Run the visual test and inspect the reported expected, actual, and diff images.
  2. Decide whether the change is an intended design update or a regression. Pay special attention to differences in Hindi wrapping and component height.
  3. For an intended update, run npx playwright test tests/localized-visual.spec.ts --update-snapshots.
  4. Review the newly written screenshots in source control. Do not accept baseline changes without inspecting them.
  5. Use Playwright UI mode when you want to review expected, actual, and diff images interactively.

Playwright advises using the same environment where baselines were generated. Browser version, OS, settings, hardware, power source, and headless mode can affect rendering; separate snapshots may be needed for different browsers or platforms.

5. Capture an element or a full page

Use the same capture scope for both locales. A locator assertion is useful when the question is whether a particular translated component fits correctly. A page assertion can cover the viewport, while fullPage: true captures the whole page.

// Compare a specific localized heading and its surrounding component.
await expect(page.locator('[data-testid="hero"]')).toHaveScreenshot('hero.png');

// Compare the entire rendered page.
await expect(page).toHaveScreenshot('page.png', { fullPage: true });

Give the English and Hindi captures distinct baseline names, such as english-home.png and hindi-home.png. This keeps each language’s expected design explicit and makes review easier.

6. Troubleshooting

Symptom Likely cause What to do
The Hindi test captures English, or both tests show the same language. The app does not use the context locale to select its translation, or the test routes are wrong. Use the app’s real locale route, cookie, or language-selection mechanism. Check rendered text before capturing.
Hindi characters appear as boxes or fallback glyphs. The intended font or glyphs are not available or have not rendered in the page. Check the application’s font assets and rendered output. Wait for an app-specific readiness signal before capture; verify the screenshot itself.
The same test differs across machines. Browser, OS, rendering settings, or hardware differ from the baseline environment. Generate and compare snapshots in a consistent environment, including the same browser version and platform.
Diffs change between runs. Dynamic page content, animation, or capture timing is adding noise. Wait for the relevant content, rely on the assertion’s stabilization, and use a narrowly scoped stylePath for truly volatile regions.
Only one language fails after a copy change. Text length changed wrapping or component geometry in that locale. Inspect that locale’s actual, expected, and diff images; update only the baseline whose design intentionally changed.
The diff is unexpectedly large. Capture scope, viewport, page state, or locale route differs, or the page has a real layout change. Confirm parity first, then inspect the images and rendered language. Avoid loosening thresholds before identifying the cause.
Snapshot update changes many files. The update ran under a different browser, platform, or set of test conditions. Review each changed image and restore unintended changes. Update baselines in the agreed environment.

7. Performance, reliability, and cost

Playwright’s stabilization step and page readiness waits add time to each capture. Full-page images cover more content than element or viewport captures, so use the smallest scope that answers the test question while keeping paired captures identical in scope. The research sources provide no numerical runtime or performance benchmark for this workflow.

For reliability, keep routes and page state deterministic, wait on an application-specific ready condition, and use the same capture environment. Treat visual snapshots as reviewable artifacts: intended design changes still need inspection and deliberate baseline updates.

Playwright is the browser-based testing workflow described here. No third-party price or cost claim is needed to use it; this guide makes no quantified estimate of CI cost.

8. Or skip the browser setup

If you need screenshot files without setting up browser automation, ScreenshotNeo provides a website screenshot API and MCP server for developers. Its request accepts a URL and returns an image or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/hi/home -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com/hi/home"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com/hi/home',
});
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())));
  • Cookie banners, popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed. Responses identify the page verdict and billing status in headers.
  • An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.

9. FAQ

Does changing Playwright’s locale translate my website?

No. It configures the browser context. Your application’s routes and language-selection behavior determine what language is rendered.

Should Hindi and English share one expected screenshot?

No. For regression checks, keep a baseline for each language. Compare captures side by side when you want to review their layout differences.

Will a passing screenshot assertion prove that the translation is correct?

No. It checks visual similarity against an expected image. Verify text and translation quality separately.

Can the snapshots match exactly on every computer?

Not necessarily. Rendering can vary across environments. Keep baseline generation and comparison consistent.