Language Agnostic Testing 
Language agnostic testing in @shopware-ag/acceptance-test-suite allows you to write acceptance tests that work across different languages without hard-coding text strings. Tests use translation keys instead of hard-coded strings and automatically adapt to different locales via environment variables.
translate() Function 
Use the translate() function in page objects to replace hardcoded strings with translation keys.
Usage in Page Objects 
import { translate } from '../../services/LanguageHelper';
export class CategoryListing implements PageObject {
    constructor(page: Page) {
        this.createButton = page.getByRole('button', {
            name: translate('administration:category:actions.createCategory'),
        });
    }
}Translate Fixture 
The Translate fixture provides translation functionality in tests.
Usage in Tests 
import { test, expect } from '@shopware-ag/acceptance-test-suite';
test('Category creation', async ({ AdminPage, Translate }) => {
    const saveText = Translate('administration:category:general.save');
    await AdminPage.getByRole('button', { name: saveText }).click();
});Environment Control 
Switch test language using environment variables:
LANG=de-DE npm run test  # German
LANG=en-GB npm run test  # English (default)Translation Keys 
Translation keys follow the pattern: area:module:section.key
Examples 
'administration:category:general.save';
'administration:category:actions.createCategory';
'storefront:account:fields.firstName';
'storefront:checkout:payment.invoice';Locale Files 
Translations are stored in JSON files organized by language and area:
locales/en/administration/category.jsonlocales/de/administration/category.jsonlocales/en/storefront/account.jsonlocales/de/storefront/account.json
Example Translation Files 
English (locales/en/administration/category.json):
{
    "general": {
        "save": "Save",
        "cancel": "Cancel"
    },
    "actions": {
        "createCategory": "Create category"
    }
}German (locales/de/administration/category.json):
{
    "general": {
        "save": "Speichern",
        "cancel": "Abbrechen"
    },
    "actions": {
        "createCategory": "Kategorie erstellen"
    }
}Supported Locales 
Translation Resources: en (English), de (German)
Browser UI: en, de, fr, es, it, nl, pt
Common Issues 
Translation key not found:
- Verify key exists in both EN/DE locale files
 - Check import in 
locales/index.ts - Ensure proper namespace structure
 
Tests fail with LANG changes:
- Move 
translate()calls inside constructors/functions, not at module level - Ensure translation resources are properly loaded
 
JSON import errors:
- Always use 
with { type: 'json' }import attribute - Check file paths and naming conventions
 
Browser locale not matching:
- Verify locale mapping in 
playwright.config.ts - Check browser args configuration
 - Ensure language detection is working correctly
 
Using in Your Own Project 
If you want to use the @shopware-ag/acceptance-test-suite in your own project with custom translations, you can extend the base test suite with your own translation fixture.
Installation 
First, install the required dependencies:
npm install @shopware-ag/acceptance-test-suite @playwright/test
npm install -D @types/nodeCreate Custom Translation Fixture 
Create a new fixture file (e.g., fixtures/CustomTranslation.ts):
import {
    test as base,
    LanguageHelper,
    TranslationKey,
    TranslateFn,
    BUNDLED_RESOURCES,
    baseNamespaces,
} from '@shopware-ag/acceptance-test-suite';
import { LOCALE_RESOURCES, enNamespaces } from '../locales';
// Merge base BUNDLED_RESOURCES with your custom LOCALE_RESOURCES
const MERGED_RESOURCES = {
    en: { ...BUNDLED_RESOURCES.en, ...LOCALE_RESOURCES.en },
    de: { ...BUNDLED_RESOURCES.de, ...LOCALE_RESOURCES.de },
} as const;
// Merge base and custom namespaces
const mergedNamespaces = {
    ...baseNamespaces,
    ...enNamespaces,
} as const;
type CustomTranslationKey = TranslationKey<typeof mergedNamespaces>;
interface CustomTranslateFixture {
    Translate: TranslateFn<CustomTranslationKey>;
}
export const test = base.extend<CustomTranslateFixture>({
    Translate: async ({}, use) => {
        let lang = process.env.lang || process.env.LANGUAGE || process.env.LANG || 'en';
        let language = lang.split(/[_.-]/)[0].toLowerCase();
        if (!MERGED_RESOURCES[language as keyof typeof MERGED_RESOURCES]) {
            console.warn(
                `⚠️  Translation resources for '${language}' not available. Supported: ${Object.keys(
                    MERGED_RESOURCES
                ).join(', ')}. Falling back to 'en'.`
            );
            language = 'en';
        }
        const languageHelper = await LanguageHelper.createInstance(
            language,
            MERGED_RESOURCES as unknown as typeof BUNDLED_RESOURCES
        );
        const translate: TranslateFn<CustomTranslationKey> = (key, options) => {
            return languageHelper.translate(key as TranslationKey, options);
        };
        await use(translate);
    },
});
export * from '@shopware-ag/acceptance-test-suite';
export type { CustomTranslationKey };Create Locale Files Structure 
Organize your translation files by language and area:
project-root/
├── locales/
│   ├── en/
│   │   ├── administration/
│   │   │   ├── common.json
│   │   │   └── product.json
│   │   └── storefront/
│   │       ├── account.json
│   │       └── checkout.json
│   ├── de/
│   │   ├── administration/
│   │   │   ├── common.json
│   │   │   └── product.json
│   │   └── storefront/
│   │       ├── account.json
│   │       └── checkout.json
│   └── index.ts
├── fixtures/
│   └── CustomTranslation.ts
├── types/
│   └── TranslationTypes.ts
└── tests/
    └── your-test.spec.tsCreate Locales Index 
Create locales/index.ts to import and export your translation files:
// Import all locale files
import enAdministrationCommon from './en/administration/common.json' with { type: 'json' };
import enStorefrontAccount from './en/storefront/account.json' with { type: 'json' };
import deAdministrationCommon from './de/administration/common.json' with { type: 'json' };
import deStorefrontAccount from './de/storefront/account.json' with { type: 'json' };
// Export the bundled resources for i18next
export const LOCALE_RESOURCES = {
    en: {
        'administration/common': enAdministrationCommon,
        'storefront/account': enStorefrontAccount,
    },
    de: {
        'administration/common': deAdministrationCommon,
        'storefront/account': deStorefrontAccount,
    },
} as const;
export const enNamespaces = {
    administration: {
        common: enAdministrationCommon,
    },
    storefront: {
        account: enStorefrontAccount,
    },
} as const;Create Translation Types 
Create types/TranslationTypes.ts to define your custom translation types. This provides:
- Type Safety: Ensures translation keys exist in your locale files
 - IntelliSense: Auto-completion for available translation keys
 - Compile-time Validation: Catches typos and missing keys before runtime
 
import { TranslationKey, TranslateFn } from '@shopware-ag/acceptance-test-suite';
import { enNamespaces } from '../locales';
export type CustomTranslationKey = TranslationKey<typeof enNamespaces>;
export type CustomTranslateFn = TranslateFn<CustomTranslationKey>;Merge with Base Test Suite 
Create your main test fixture that merges the base test suite with your custom translation:
import { test as ShopwareTestSuite, mergeTests } from '@shopware-ag/acceptance-test-suite';
import { test as CustomTranslation } from './fixtures/CustomTranslation';
export * from '@shopware-ag/acceptance-test-suite';
export const test = mergeTests(ShopwareTestSuite, CustomTranslation);Note: Save this as test.ts or index.ts in your project root and import it in your test files.
Usage in Your Tests 
Now you can use the Translate fixture in your tests:
import { test } from './your-main-test-fixture';
test('My localized test', async ({ Translate, AdminPage }) => {
    const saveText = Translate('administration:common:button.save');
    await AdminPage.getByRole('button', { name: saveText }).click();
});Environment Configuration 
Set up your Playwright configuration to support language switching:
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
const LOCALES = { de: 'de-DE', en: 'en-US', fr: 'fr-FR' };
function getLanguage(): string {
    let lang = process.env.lang || process.env.LANGUAGE || process.env.LANG || 'en';
    return lang.split(/[_.-]/)[0].toLowerCase();
}
function getLocaleConfig() {
    const lang = getLanguage();
    const browserLocale = LOCALES[lang as keyof typeof LOCALES] || 'en-US';
    const browserArgs =
        lang !== 'en' && LOCALES[lang as keyof typeof LOCALES]
            ? [`--lang=${browserLocale}`, `--accept-lang=${browserLocale},${lang};q=0.9,en;q=0.8`]
            : [];
    return { lang, browserLocale, browserArgs };
}
export default defineConfig({
    use: {
        locale: getLocaleConfig().browserLocale,
    },
    projects: [
        {
            name: 'Platform',
            use: {
                ...devices['Desktop Chrome'],
                launchOptions: {
                    args: [...getLocaleConfig().browserArgs],
                },
            },
        },
    ],
});Running Tests with Different Languages 
# German
LANG=de-DE npx playwright test
# English (default)
npx playwright test