7deb46aeae
On a typical page the console showed 25-30 duplicate 'Failed to load resource' errors because every consumer hook fired its own copy of the same network request: - useDictionaries: once per `useCityName`/`useStationDisplayName` call (6-10x per render across StationDisplay, PopularRequestItem, mini-list rows, etc.) — now a module-level WeakMap<ApiClient> single-flight cache returns the same in-flight Promise. - usePopularRequests: same pattern across start-page and search- history dropdowns — cached via the same mechanism. - useAppSettings: 7+ callers — cached. Dropped console error count on /ru-ru/ from 29 to 5 (the remaining 5 are WAF 403 infra issues from the dev:full proxy cookie, not code). Also updates e2e specs: - schedule-details-mini-list-scoped: asserts the new single-card rail behaviour (was still checking for the old 3-row flat list). - smoke /xx/smoke: targets `[data-testid=error-page-404]` instead of `text=404` — the latter matches both the <title> tag (hidden by user-agent CSS) and multiple DOM nodes, tripping strict-mode.
67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
test.describe("Smoke tests", () => {
|
|
test("root / redirects to /ru/onlineboard", async ({ page }) => {
|
|
await page.goto("/");
|
|
await page.waitForLoadState("domcontentloaded");
|
|
|
|
// The root loader uses redirect() from Modern.js router.
|
|
// Depending on SSR/CSR mode, this may be a server 302 or a client-side
|
|
// navigation. Wait up to 15s for either outcome.
|
|
try {
|
|
await page.waitForURL("**/ru/onlineboard", { timeout: 15000 });
|
|
expect(page.url()).toContain("/ru/onlineboard");
|
|
} catch {
|
|
// If the redirect doesn't fire (e.g. loader not invoked in dev SSR mode),
|
|
// verify the page at least rendered the online board content.
|
|
// TODO: Fix root redirect — loader may not fire in current dev config.
|
|
const hasOnlineBoard = await page
|
|
.locator('[data-testid="online-board-start"]')
|
|
.isVisible()
|
|
.catch(() => false);
|
|
if (!hasOnlineBoard) {
|
|
// Accept the page rendered without error as a minimal pass
|
|
await expect(page.locator("body")).not.toBeEmpty();
|
|
}
|
|
}
|
|
});
|
|
|
|
test("/ru/smoke renders with Russian text", async ({ page }) => {
|
|
await page.goto("/ru/smoke");
|
|
await page.waitForLoadState("domcontentloaded");
|
|
|
|
// The smoke page heading uses i18n key SMOKE.HEADING = "Страница проверки"
|
|
const heading = page.locator("h1");
|
|
await expect(heading).toBeVisible({ timeout: 10000 });
|
|
await expect(heading).toHaveText("Страница проверки");
|
|
|
|
// Locale should be displayed
|
|
await expect(page.locator("text=ru")).toBeVisible();
|
|
});
|
|
|
|
test("/en/smoke renders with English text", async ({ page }) => {
|
|
await page.goto("/en/smoke");
|
|
await page.waitForLoadState("domcontentloaded");
|
|
|
|
const heading = page.locator("h1");
|
|
await expect(heading).toBeVisible({ timeout: 10000 });
|
|
await expect(heading).toHaveText("Smoke test page");
|
|
|
|
await expect(page.locator("text=en")).toBeVisible();
|
|
});
|
|
|
|
test("/xx/smoke shows 404 or unknown locale message", async ({ page }) => {
|
|
await page.goto("/xx/smoke");
|
|
await page.waitForLoadState("domcontentloaded");
|
|
|
|
// The lang layout renders a 404 page. Target the visible page-body
|
|
// copy (the `.error-page__code` "404" badge or the Russian/English
|
|
// description) rather than `text=404` alone — the latter matches
|
|
// the <title> tag which is `hidden` by user-agent CSS, and matches
|
|
// multiple unrelated DOM nodes, tripping strict-mode.
|
|
await expect(page.getByTestId("error-page-404")).toBeVisible({
|
|
timeout: 10000,
|
|
});
|
|
});
|
|
});
|