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.
40 lines
1.8 KiB
TypeScript
40 lines
1.8 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
// On the schedule details page the left mini-list renders a SINGLE
|
|
// card for the currently-open flight — matching Angular's
|
|
// `schedule-flights-mini-list`, which only falls into the
|
|
// multi-day-accordion branch when `schedule.length > 1`. Previously
|
|
// the rail showed day-±1 siblings that read as visual duplicates of
|
|
// the open flight, and before that it dumped the whole route search.
|
|
//
|
|
// For a connecting itinerary the single card must surface BOTH
|
|
// flight numbers ("SU 6188, SU 6341") and the combined
|
|
// Moscow→Murmansk origin/destination, not just the first leg.
|
|
|
|
const URL =
|
|
"/ru-ru/schedule/VKO/SU6188-20260426/LED/SU6341-20260427/MMK?request=schedule-route-MOW-MMK-20260427-20260503";
|
|
|
|
test("mini-list — one combined card for the open SU 6188+SU 6341 itinerary", async ({ page }) => {
|
|
await page.goto(URL);
|
|
|
|
const miniList = page.locator(".schedule-mini-list");
|
|
await expect(miniList).toBeVisible({ timeout: 15000 });
|
|
|
|
// No day-grouping accordion headers, no day-siblings — just one row.
|
|
await expect(miniList.locator("[data-testid^='mini-list-day-header-']")).toHaveCount(0);
|
|
const items = miniList.locator("[data-testid^='mini-list-item-']");
|
|
await expect(items).toHaveCount(1);
|
|
|
|
const railText = (await miniList.innerText()).replace(/\s+/g, " ");
|
|
// Both flight numbers present (Angular surfaces the whole chain).
|
|
expect(railText).toContain("SU 6188");
|
|
expect(railText).toContain("SU 6341");
|
|
// Combined Moscow → Murmansk endpoints — NOT first-leg-only
|
|
// Moscow → St Petersburg.
|
|
expect(railText).toContain("Мурманск");
|
|
expect(railText).not.toContain("Санкт-Петербург");
|
|
// No unrelated route-mates from the parent search.
|
|
expect(railText).not.toMatch(/SU\s*6190/);
|
|
expect(railText).not.toMatch(/SU\s*6699/);
|
|
});
|