test(e2e): golden-master Playwright net for the Platform refactor
Locks the five flows the refactor must not break (feed, channel, player, settings, nav) so later sprints can prove they changed nothing. Adds a thin data-testid layer and a dedicated seeded non-demo account; the suite runs on the baked :8080 stack (authoritative) or :5173. No product-behaviour change.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { openApp } from "./helpers";
|
||||
|
||||
// Locks the feed's core contract: it renders cards, a filter re-queries it and surfaces a
|
||||
// removable chip, and its virtualized list windows in fresh rows as you scroll.
|
||||
test.describe("feed", () => {
|
||||
test("a filter re-queries the feed and surfaces a removable chip", async ({ page }) => {
|
||||
await openApp(page);
|
||||
await expect(page.getByTestId("video-card").first()).toBeVisible();
|
||||
|
||||
const count = page.getByTestId("feed-result-count");
|
||||
await expect(count).toHaveText(/\d/);
|
||||
const baseline = await count.innerText();
|
||||
|
||||
// Clean baseline: default filters, so no chips and "unwatched" is the active show.
|
||||
await expect(page.getByTestId("active-filter-chip")).toHaveCount(0);
|
||||
await expect(page.getByTestId("feed-show-unwatched")).toHaveAttribute("aria-pressed", "true");
|
||||
|
||||
// Narrow to "watched" — the seed guarantees exactly one, a real deterministic change.
|
||||
await page.getByTestId("feed-show-watched").click();
|
||||
await expect(page.getByTestId("active-filter-chip")).toHaveCount(1);
|
||||
await expect(count).not.toHaveText(baseline);
|
||||
|
||||
// Remove the chip → default show restored, chips gone.
|
||||
await page.getByTestId("active-filter-chip").click();
|
||||
await expect(page.getByTestId("active-filter-chip")).toHaveCount(0);
|
||||
await expect(page.getByTestId("feed-show-unwatched")).toHaveAttribute("aria-pressed", "true");
|
||||
});
|
||||
|
||||
test("scrolling virtualizes in fresh cards", async ({ page }) => {
|
||||
await openApp(page);
|
||||
await expect(page.getByTestId("video-card").first()).toBeVisible();
|
||||
|
||||
const renderedIds = () =>
|
||||
page
|
||||
.getByTestId("video-card")
|
||||
.evaluateAll((els) => els.map((e) => e.getAttribute("data-video-id")));
|
||||
|
||||
const before = await renderedIds();
|
||||
expect(before.length).toBeGreaterThan(0);
|
||||
|
||||
// The feed scrolls inside <main> (role="main"), not the window.
|
||||
await page.getByRole("main").evaluate((el) => el.scrollBy(0, 5000));
|
||||
|
||||
// A windowed list renders different rows once scrolled.
|
||||
await expect
|
||||
.poll(async () => (await renderedIds()).some((id) => id && !before.includes(id)))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user