test: add route matrix (11F) and hardcoded-JSX-text check (11D)
- fleet-ops-correction.spec.ts: opens every main route in all 3 languages, asserting no console errors, correct html[lang], and a real non-empty page heading (key parity across locale files is already proven structurally elsewhere, so this focuses on what only a live render can catch). - i18n-coverage.spec.ts: a static scan for hardcoded JSX text bypassing t(...). A naive `>text<` regex falsely flagged TypeScript generics everywhere (`useState<string | null>(null)` was read as a "JSX tag" spanning to the next unrelated `>`) -- fixed by requiring the closing tag name to backreference the opening one (`<Tag>...</Tag>`), which generics can never satisfy. Verified against both false positives (passes clean on the current codebase) and false negatives (deliberately injected and reverted a hardcoded string to confirm it's caught). Known pre-existing flake (unrelated to this branch, not touched by it): "logout invalidates the server session so a refresh returns to login" in interactive-elements.spec.ts occasionally fails only in the full sequential run, never in isolation -- AuthContext.logout() clears local state and redirects before awaiting the server-side cookie-clearing POST, a narrow race no human interaction speed would ever hit. Noted as a known limitation, not fixed (out of this branch's scope). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a7ac5ed9d0
commit
7851e807fa
@@ -295,3 +295,58 @@ test("automation shows a localized error explanation with the raw error only und
|
||||
await page.getByText("Technische details").first().click();
|
||||
await expect(page.getByText("Synthetic connection timeout to n8n")).toBeVisible();
|
||||
});
|
||||
|
||||
test.describe("route matrix (section 11F)", () => {
|
||||
// Opens every main route in all 3 languages: no console errors, correct html[lang],
|
||||
// and a real, non-empty page heading (proving the route actually rendered content
|
||||
// instead of silently falling back to a raw i18next key or a blank screen). Key
|
||||
// parity across locale files is already proven structurally by i18n-coverage.spec.ts
|
||||
// (every key that exists in nl-BE also exists, non-empty, in en-GB/fr-BE), so this
|
||||
// matrix focuses on what only a live render can catch.
|
||||
const routes = [
|
||||
"/dashboard",
|
||||
"/vehicles",
|
||||
"/vehicles/MO-001",
|
||||
"/bookings",
|
||||
"/bookings/BK-DEMO-RETURN",
|
||||
"/data-quality",
|
||||
"/data-quality/DQ-DEMO-STATUS",
|
||||
"/automation",
|
||||
"/knowledge",
|
||||
"/audit",
|
||||
"/scenarios",
|
||||
"/about",
|
||||
];
|
||||
|
||||
for (const lang of ["nl-BE", "en-GB", "fr-BE"]) {
|
||||
test(`every main route renders correctly with no console errors (${lang})`, async ({ page, request }) => {
|
||||
await resetDemoData(request);
|
||||
|
||||
const errors: string[] = [];
|
||||
page.on("console", (msg) => {
|
||||
if (msg.type() !== "error") return;
|
||||
if (msg.text().includes("401") && msg.text().includes("Unauthorized")) return;
|
||||
errors.push(msg.text());
|
||||
});
|
||||
page.on("pageerror", (err) => errors.push(err.message));
|
||||
|
||||
await loginAsOpsManager(page, lang);
|
||||
|
||||
for (const route of routes) {
|
||||
await page.goto(route);
|
||||
await expect(page.locator("html")).toHaveAttribute("lang", lang);
|
||||
const heading = page.getByRole("heading", { level: 1 });
|
||||
await expect(heading, `${route} (${lang})`).toBeVisible();
|
||||
const headingText = (await heading.first().textContent())?.trim() ?? "";
|
||||
expect(headingText, `${route} (${lang}) heading text`).not.toBe("");
|
||||
// A raw, unresolved i18next key looks like "namespace:some.key.path" -- real
|
||||
// page headings never contain a colon followed by a dotted identifier.
|
||||
expect(headingText, `${route} (${lang}) heading looks like a raw i18n key`).not.toMatch(
|
||||
/^[a-zA-Z]+:[\w.]+$/,
|
||||
);
|
||||
}
|
||||
|
||||
expect(errors, `Console errors across the route matrix (${lang}):\n${errors.join("\n")}`).toEqual([]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user