Skip to main content

How to Test Localization and i18n Flows

Short answer

i18n failures ship as raw translation keys, clipped RTL navigation, wrong currency decimals, and locale-unaware validation messages—not missing language toggles. Seed user locale preferences, assert no i18n key patterns in DOM, run ExploreChimp on RTL and long-string locales, and compare prod locale traffic to test coverage via TrueCoverage.

Part of Testing Guides by UI patterns.

Who this is for

Teams shipping global SaaS, ecommerce, or mobile web with language switchers, RTL layouts (ar, he), currency/locale number formats, and translated error strings. Typical stacks: i18next, react-intl, FormatJS, Crowdin/Lokalise pipelines.

Why testing localization matters

i18n bugs erode trust and revenue:

  • Raw keys in prodcheckout.title visible during failed deploy; conversion drops.
  • RTL layout breaks — fixed sidebars overlap checkout in ar-SA; unusable without manual QA.
  • Wrong currency — EUR shown with USD amounts; charge disputes and regulatory scrutiny.
  • Validation mismatch — server errors English-only while UI is localized; support cannot help users.
  • SEO and legal — missing translated policy pages; GDPR consent text wrong language.

Test locale persistence, format correctness, and layout at longest locale strings—not just that French appears once.

Complexity map

ScenarioEdge caseWhy tests breakApproach
Missing translation keyFallback brokenKey in DOMRegex assert no foo.bar.baz
Locale switch mid-flowCart locale driftWrong taxProbe cart currency after switch
RTL mirrorIcons not flippedWrong affordancedir=rtl + ExploreChimp
Long German stringsButton overflowClipped CTASnapshot optional; role visible
Currency format1.234,56 vs 1,234.56Parse errorsProbe numeric value
Date formatDD/MM vs MM/DDWrong stored datePair with datetime guide
Plural rulesone/otherGrammar wrongFixture counts 0,1,2
Timezone + localeIndependent prefsDisplay mismatchSeed both in Arrange
Accept-LanguageServer-driven localeClient switch ignoredProbe HTML lang attribute
Lazy-loaded bundlesFlash of default langFOUCwaitForResponse i18n chunk
Number inputComma decimalInvalid submitkeyboard type locale sep
hreflang routesWrong canonicalSEOAssert path prefix /de/

Locale Arrange patterns

// Seed user preference
await request.post('/api/test/seed-user', {
data: { runId, locale: 'de-DE', currency: 'EUR' },
});

// Or set cookie / localStorage before goto
await context.addCookies([{ name: 'locale', value: 'ar-SA', domain: 'localhost', path: '/' }]);
await page.goto('/dashboard');
await expect(page.locator('html')).toHaveAttribute('dir', 'rtl');
await expect(page.locator('html')).toHaveAttribute('lang', 'ar');

Assert no missing keys

await expect(page.locator('body')).not.toHaveText(/\b[a-z]+\.[a-z]+\.[a-z]+\b/); // tune regex
await expect(page.getByRole('heading', { level: 1 })).not.toContainText('dashboard.title');

Combine with pseudo-locale (en-XA) in staging to visually spot unwrapped strings during ExploreChimp sessions (explorations).

Currency and numbers

await page.goto('/pricing?locale=de-DE');
await expect(page.getByTestId('price')).toContainText('€');
const probe = await request.get(`/api/test/cart?runId=${runId}`);
expect((await probe.json()).currency).toBe('EUR');
expect((await probe.json()).totalCents).toBe(1999); // authoritative

ExploreChimp for UX/i18n

Automated asserts catch keys and currency; ExploreChimp finds navigation overlap, modal cutoff, and icon direction bugs in RTL—especially on checkout and settings wizards. Convert high-value manual paths to SmartTests with locale in test title // @Scenario: checkout ar-SA RTL.

Compare locale × currency in TrueCoverage—when ar-SA is 12% prod traffic but 0% test runs, run /testchimp evolve.

CI checklist

  1. Matrix project: en-US, one RTL, one long-word locale (de-DE)
  2. No raw key regex on critical pages post-switch
  3. Probe currency/locale on transactional endpoints
  4. Lazy bundle: waitForResponse before string asserts
  5. ExploreChimp scheduled on RTL after major UI releases
  6. Link scenarios to requirement traceability for market launch gates

Anti-patterns

Anti-patternWhy it failsBetter approach
Test English onlyRTL/clipping untestedLocale project matrix
Assert full translated sentenceCopy changes flakeKey absence + probe
Manual screenshot every localeUnmaintainableExploreChimp sampling
Ignore server localeSwitcher cosmeticProbe API Accept-Language
Skip currency probeWrong chargetotalCents assert
One short string localeOverflow hiddende-DE or pseudo-locale

Example scenario

Situation: Arabic-speaking user completes checkout with RTL layout and SAR pricing.

Expected outcome: RTL dir correct; prices in SAR; order probe currency=SAR; no English keys.

Why UI-only automation breaks: UI shows SAR symbol but probe charges USD—FX compliance failure.

  1. Arrange: Seed user locale ar-SA, currency SAR, runId cart.
  2. Act: Walk checkout with RTL navigation.
  3. Assert: html dir=rtl; no i18n keys; probe order currency SAR and localized receipt PDF lang.

TestChimp workflow: Compare locale × currency prod vs test; evolve ar-SA checkout if gap >5% traffic.

Same Arrange/Act/Assert pattern as expired-coupon checkout.

Connect scenarios to your QA workflow

Capture business rules in markdown test plans and enforce them with seed routes and probe Assert. Link SmartTests with // @Scenario: for requirement traceability. Use /testchimp test on PRs; /testchimp explore on SmartTest paths for non-functional gaps (ExploreChimp).

External references

Frequently asked questions

Which locales drive prod traffic but lack tests?

Compare locale × currency in TrueCoverage prod vs test-run. When gaps appear, run /testchimp evolve and ExploreChimp on RTL/long-string paths—link // @Scenario: in markdown plans.

How do I detect missing translation keys in E2E?

Assert DOM does not match key patterns like segment.segment.name and does not contain known default keys. Pseudo-locale in staging helps manual ExploreChimp passes.

How do I test RTL layouts in Playwright?

Set locale ar-SA, assert html dir=rtl, run critical flows. Use ExploreChimp to find clipped nav and misaligned icons automation misses.

Should I assert translated button labels?

Prefer stable roles and probe transactional data. Exact copy asserts break when translators update strings—use regex only for legally mandated phrases.

How do currency display and charge differ in tests?

Display may show € symbol while probe must assert ISO currency and integer cents on order API—never UI symbol alone.

How does locale switching mid-session work?

Switch language, assert URL or cookie persistence, complete transaction, probe server records locale/currency—not just document.lang snapshot.

Can manual i18n QA become SmartTests?

Yes—record ExploreChimp session on problematic locale, convert steps to SmartTests with locale in Arrange seed; avoids re-recording entire suite per language.

Apply these patterns in your repo

Run `/testchimp init` to connect TestChimp to your repo, then `/testchimp test` on PRs to turn these patterns into maintained SmartTests. Use `/testchimp evolve` when you want to expand coverage as your app grows.

Start free on TestChimp · Book a demo