59 lines
2.6 KiB
TypeScript
59 lines
2.6 KiB
TypeScript
import { expect, test } from "./utils/test";
|
|
import { waitForHydration } from "./utils/navigation";
|
|
|
|
// #72 i18n — verifies locale resolution and the public locale picker.
|
|
// The locale is resolved server-side by remix-i18next (Accept-Language header
|
|
// or the signed `_i18n` cookie) and surfaced on `<html lang>` / `<html dir>`
|
|
// from root.tsx.
|
|
|
|
test.describe("locale switching", () => {
|
|
test("serves German with ltr direction for a German Accept-Language", async ({ browser }) => {
|
|
const context = await browser.newContext({ locale: "de-DE" });
|
|
const page = await context.newPage();
|
|
await page.goto("/", { waitUntil: "domcontentloaded" });
|
|
|
|
await expect(page.locator("html")).toHaveAttribute("lang", "de");
|
|
await expect(page.locator("html")).toHaveAttribute("dir", "ltr");
|
|
|
|
await context.close();
|
|
});
|
|
|
|
test("serves English with ltr direction for an English Accept-Language", async ({ browser }) => {
|
|
const context = await browser.newContext({ locale: "en-US" });
|
|
const page = await context.newPage();
|
|
await page.goto("/", { waitUntil: "domcontentloaded" });
|
|
|
|
await expect(page.locator("html")).toHaveAttribute("lang", "en");
|
|
await expect(page.locator("html")).toHaveAttribute("dir", "ltr");
|
|
|
|
await context.close();
|
|
});
|
|
|
|
test("switches locale through the public locale picker and persists it", async ({ browser }) => {
|
|
const context = await browser.newContext({ locale: "en-US" });
|
|
const page = await context.newPage();
|
|
// "/" redirects to /login on this deployment, which has no locale picker; the
|
|
// public footer (e.g. /privacy-policy) renders the LocaleSelector dropdown.
|
|
await page.goto("/privacy-policy", { waitUntil: "domcontentloaded" });
|
|
await expect(page.locator("html")).toHaveAttribute("lang", "en");
|
|
|
|
// This test drives its own context/page, so the hydration-aware fixture does
|
|
// not apply; wait for hydration before clicking the JS-only dropdown.
|
|
await waitForHydration(page);
|
|
|
|
// The public header/footer render a LocaleSelector dropdown; its trigger
|
|
// is labelled with the translated "Language" string.
|
|
await page.getByRole("button", { name: "Language" }).first().click();
|
|
await page.getByRole("menuitem", { name: "German" }).click();
|
|
|
|
await expect(page.locator("html")).toHaveAttribute("lang", "de");
|
|
|
|
// The chosen locale is persisted in the signed `_i18n` cookie so it
|
|
// survives the next request regardless of the Accept-Language header.
|
|
const cookie = (await context.cookies()).find((entry) => entry.name === "_i18n");
|
|
expect(cookie, "expected the _i18n locale cookie to be set").toBeTruthy();
|
|
|
|
await context.close();
|
|
});
|
|
});
|