| name | localization-testing |
| description | Internationalization (i18n) and localization (l10n) testing for global products including translations, locale formats, RTL languages, and cultural appropriateness. Use when launching in new markets or building multi-language products. |
| category | specialized-testing |
| priority | medium |
| tokenEstimate | 800 |
| agents | ["qe-test-generator","qe-test-executor","qe-visual-tester"] |
| implementation_status | optimized |
| optimization_version | 1 |
| last_optimized | "2025-12-02T00:00:00.000Z" |
| dependencies | [] |
| quick_reference_card | true |
| tags | ["localization","i18n","l10n","translation","rtl","unicode","locale"] |
| trust_tier | 3 |
| validation | {"schema_path":"schemas/output.json","validator_path":"scripts/validate-config.json","eval_path":"evals/localization-testing.yaml"} |
Localization & Internationalization Testing
Browser engine
Browser-driven locale checks (RTL layout diffs, language-switching flows, locale-specific screenshots) should go through the qe-browser fleet skill. Example:
vibium go "$BASE_URL?lang=ar"
vibium wait load
node .claude/skills/qe-browser/scripts/visual-diff.js --name homepage-ar-rtl
vibium go "$BASE_URL?lang=ja"
node .claude/skills/qe-browser/scripts/visual-diff.js --name homepage-ja
See .claude/skills/qe-browser/SKILL.md for the full reference.
<default_to_action>
When testing multi-language/region support:
- VERIFY translation coverage (all strings translated)
- TEST locale-specific formats (date, time, currency, numbers)
- VALIDATE RTL layout (Arabic, Hebrew)
- CHECK character encoding (UTF-8, unicode)
- CONFIRM cultural appropriateness (icons, colors, content)
Quick i18n Checklist:
- All user-facing strings externalized
- No hardcoded text in code
- Date/time/currency formatted per locale
- RTL languages flip layout correctly
- Unicode characters display properly
Critical Success Factors:
- Don't hardcode strings - externalize everything
- Test with real speakers, not just translation files
- RTL requires mirrored UI layout
</default_to_action>
Quick Reference Card
When to Use
- Launching in new markets
- Adding language support
- Before international releases
- After UI changes
Translation Coverage Testing
test('all strings are translated', () => {
const enKeys = Object.keys(translations.en);
const frKeys = Object.keys(translations.fr);
const esKeys = Object.keys(translations.es);
expect(frKeys).toEqual(enKeys);
expect(esKeys).toEqual(enKeys);
});
test('no missing translation placeholders', async ({ page }) => {
await page.goto('/?lang=fr');
const text = await page.textContent('body');
expect(text).not.toContain('translation.missing');
expect(text).not.toMatch(/\{\{.*\}\}/);
});
Date/Time/Currency Formats
test('date formats by locale', () => {
const date = new Date('2025-10-24');
expect(formatDate(date, 'en-US')).toBe('10/24/2025');
expect(formatDate(date, 'en-GB')).toBe('24/10/2025');
expect(formatDate(date, 'ja-JP')).toBe('2025/10/24');
});
test('currency formats by locale', () => {
const amount = 1234.56;
expect(formatCurrency(amount, 'en-US', 'USD')).toBe('$1,234.56');
expect(formatCurrency(amount, 'de-DE', 'EUR')).toBe('1.234,56 €');
expect(formatCurrency(amount, 'ja-JP', 'JPY')).toBe('¥1,235');
});
RTL (Right-to-Left) Testing
test('layout flips for RTL languages', async ({ page }) => {
await page.goto('/?lang=ar');
const dir = await page.locator('html').getAttribute('dir');
expect(dir).toBe('rtl');
const nav = await page.locator('nav');
const styles = await nav.evaluate(el =>
window.getComputedStyle(el)
);
expect(styles.direction).toBe('rtl');
});
test('icons/images appropriate for RTL', async ({ page }) => {
await page.goto('/?lang=he');
const backIcon = await page.locator('.back-icon');
expect(await backIcon.getAttribute('class')).toContain('rtl-flipped');
});
Unicode Character Support
test('supports unicode characters', async ({ page }) => {
await page.fill('#name', '山田太郎');
await page.click('#submit');
const saved = await db.users.findOne({ });
expect(saved.name).toBe('山田太郎');
await page.fill('#name', 'محمد');
await page.fill('#bio', '👋🌍');
expect(saved.bio).toBe('👋🌍');
});
Agent-Driven Localization Testing
await Task("Localization Testing", {
url: 'https://example.com',
locales: ['en-US', 'fr-FR', 'de-DE', 'ja-JP', 'ar-SA'],
checks: ['translations', 'formats', 'rtl', 'unicode'],
detectHardcodedStrings: true
}, "qe-test-generator");
Agent Coordination Hints
Memory Namespace
aqe/localization-testing/
├── translations/* - Translation coverage
├── formats/* - Locale-specific formats
├── rtl-validation/* - RTL layout checks
└── unicode/* - Character encoding tests
Fleet Coordination
const l10nFleet = await FleetManager.coordinate({
strategy: 'localization-testing',
agents: [
'qe-test-generator',
'qe-test-executor',
'qe-visual-tester'
],
topology: 'parallel'
});
Related Skills
Remember
With Agents: Agents validate translation coverage, detect hardcoded strings, test locale-specific formatting, and verify RTL layouts automatically across all supported languages.