The pushed copy pass renames the library heading to "Your freezer"
("Tvůj mrazák" in Czech) and reworks the gate subtitle plus several
Czech strings. Five suites pinned the old heading — regression, i18n,
native, wizard and providers — and now assert the new one; the README
prose and project tree follow. Key parity is unchanged.
Version 0.5.9, SW -> freezmo-v81.
71 lines
3.6 KiB
JavaScript
71 lines
3.6 KiB
JavaScript
/**
|
|
* i18n suite: EN/CS dictionary parity, the locale switch, Czech copy on the
|
|
* desktop shell and the phone tab bar, and Czech plurals.
|
|
*/
|
|
import { readFileSync } from "node:fs";
|
|
import path from "node:path";
|
|
|
|
import { BASE, DECK, REPO, launchBrowser, makeChecker, makePage, seed } from "./lib.mjs";
|
|
|
|
const { check, finish } = makeChecker();
|
|
const browser = await launchBrowser();
|
|
|
|
/* 1. dictionary parity ----------------------------------------------- */
|
|
{
|
|
const source = readFileSync(path.join(REPO, "lib/i18n-dict.ts"), "utf8");
|
|
const split = source.indexOf("const cs");
|
|
const pattern = /^\s{2}"([^"]+)":/gm;
|
|
const en = [...source.slice(0, split).matchAll(pattern)].map((match) => match[1]);
|
|
const cs = [...source.slice(split).matchAll(pattern)].map((match) => match[1]);
|
|
const missingInCs = en.filter((key) => !cs.includes(key));
|
|
const missingInEn = cs.filter((key) => !en.includes(key));
|
|
check("key parity: same keys in both dictionaries", missingInCs.length === 0 && missingInEn.length === 0, JSON.stringify({ missingInCs, missingInEn }).slice(0, 200));
|
|
check("dictionary is substantial", en.length > 700, String(en.length));
|
|
}
|
|
|
|
/* 2. Czech desktop shell --------------------------------------------- */
|
|
{
|
|
const { context, page } = await makePage(browser, { width: 1280, height: 900, deviceScaleFactor: 1 });
|
|
await seed(page, { locale: "cs", decks: [DECK] });
|
|
await page.goto(BASE, { waitUntil: "networkidle" });
|
|
await page.waitForTimeout(900);
|
|
check("library title is Czech", await page.getByRole("heading", { name: "Tvůj mrazák" }).isVisible());
|
|
check("sidebar says Všechny sady", await page.getByRole("button", { name: /Všechny sady/ }).first().isVisible());
|
|
check("sidebar says Nezařazené", await page.getByRole("button", { name: /Nezařazené/ }).first().isVisible());
|
|
check("deck card CTA is Studovat", (await page.getByRole("link", { name: "Studovat" }).count()) === 1);
|
|
check("Czech plural on the card (2 aktivity)", (await page.getByText("2 aktivity").filter({ visible: true }).count()) >= 1);
|
|
check("review card is Czech", await page.getByText("Chytré opakování").isVisible());
|
|
check("desktop has no tab bar visible", !(await page.locator("nav.tabbar").isVisible()));
|
|
|
|
// Locale switch from the settings dialog (desktop footer).
|
|
await page.locator("aside").getByRole("button", { name: "Nastavení" }).click();
|
|
const dialog = page.getByRole("dialog");
|
|
await dialog.waitFor({ timeout: 6000 });
|
|
await page.waitForTimeout(600);
|
|
await dialog.locator(".segmented").first().getByRole("button", { name: /English/ }).click();
|
|
await page.waitForTimeout(500);
|
|
await page.keyboard.press("Escape");
|
|
await page.waitForTimeout(600);
|
|
check("locale switch to English updates the UI", await page.getByRole("heading", { name: "Your freezer" }).isVisible());
|
|
await context.close();
|
|
}
|
|
|
|
/* 3. Czech phone tab bar + review card ------------------------------- */
|
|
{
|
|
const { context, page } = await makePage(browser);
|
|
await seed(page, { locale: "cs", decks: [DECK] });
|
|
await page.goto(BASE, { waitUntil: "networkidle" });
|
|
await page.waitForTimeout(900);
|
|
const tabTexts = (await page.locator("nav.tabbar").locator("a, button").allInnerTexts()).map((text) => text.trim());
|
|
check(
|
|
"cs tab labels are the short ones",
|
|
JSON.stringify(tabTexts) === JSON.stringify(["Knihovna", "Pokrok", "Nová sada", "Zkouška", "Nastavení"]),
|
|
JSON.stringify(tabTexts),
|
|
);
|
|
check("cs review card present", await page.getByText("Chytré opakování").isVisible());
|
|
check("cs exam tab label is not the long one", !tabTexts.includes("Zkouškový režim"));
|
|
await context.close();
|
|
}
|
|
|
|
await browser.close();
|
|
finish();
|