Claude Code Plugins

Community-maintained marketplace

Feedback

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.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

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.
version 1.0.0
category specialized-testing
tags i18n, l10n, localization, internationalization, translations, rtl, locale
difficulty intermediate
estimated_time 60 minutes
author agentic-qe

Localization & Internationalization Testing

Core Principle

Global products must work globally.

i18n testing ensures software supports multiple languages, regions, and cultures without code changes.

i18n vs l10n

Internationalization (i18n): Building software to support localization Localization (l10n): Adapting software for specific locale

Testing Translation Coverage

test('all strings are translated', () => {
  const enKeys = Object.keys(translations.en);
  const frKeys = Object.keys(translations.fr);
  const esKeys = Object.keys(translations.es);

  // All locales have same keys
  expect(frKeys).toEqual(enKeys);
  expect(esKeys).toEqual(enKeys);
});

test('no missing translation placeholders', () => {
  const text = await page.locator('button').textContent();

  // Should not see placeholder keys
  expect(text).not.toContain('translation.missing');
  expect(text).not.toMatch(/\{\{.*\}\}/); // {{key}} format
});

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, 'USD')).toBe('$1,234.56');
  expect(formatCurrency(amount, 'EUR')).toBe('€1.234,56');
  expect(formatCurrency(amount, 'JPY')).toBe('¥1,235'); // No decimals
});

RTL (Right-to-Left) Testing

test('layout flips for RTL languages', async () => {
  await page.goto('/?lang=ar'); // Arabic

  const dir = await page.locator('html').getAttribute('dir');
  expect(dir).toBe('rtl');

  // Navigation should be on right
  const nav = await page.locator('nav');
  const styles = await nav.evaluate((el) => 
    window.getComputedStyle(el)
  );
  expect(styles.direction).toBe('rtl');
});

Character Encoding

test('supports unicode characters', async () => {
  // Japanese
  await page.fill('#name', '山田太郎');

  // Arabic
  await page.fill('#name', 'محمد');

  // Emoji
  await page.fill('#name', '👋🌍');

  // Verify saved correctly
  const saved = await db.users.findOne({ id: userId });
  expect(saved.name).toBe('👋🌍');
});

Remember

Don't hardcode. Externalize all user-facing strings.

Test:

  • Translation completeness
  • Locale-specific formats (date, time, currency)
  • RTL layout (Arabic, Hebrew)
  • Character encoding (UTF-8)
  • Cultural appropriateness

With Agents: Agents validate translation coverage, detect hardcoded strings, and test locale-specific formatting automatically across all supported languages.