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,62 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { openApp, gotoPage } from "./helpers";
|
||||
|
||||
// Locks the Settings draft/dirty-save machine: an edit raises the save bar, Save persists via
|
||||
// PUT /me/preferences, and leaving with unsaved changes is guarded. The dirty-guard is one of
|
||||
// the behaviors the god-component refactor must preserve exactly.
|
||||
test.describe("settings dirty-save", () => {
|
||||
const TOGGLE = "Performance mode"; // an Appearance switch (locale pinned to en)
|
||||
|
||||
async function putPrefs(page: import("@playwright/test").Page) {
|
||||
return page.waitForResponse(
|
||||
(r) => r.url().includes("/me/preferences") && r.request().method() === "PUT",
|
||||
);
|
||||
}
|
||||
|
||||
test("edit raises the bar and Save persists via PUT /me/preferences", async ({ page }) => {
|
||||
await openApp(page);
|
||||
await gotoPage(page, "settings");
|
||||
|
||||
const bar = page.getByTestId("draft-save-bar");
|
||||
const status = page.getByTestId("draft-save-status");
|
||||
const toggle = page.getByRole("switch", { name: TOGGLE });
|
||||
|
||||
// Clean: the bar renders nothing.
|
||||
await expect(bar).toHaveCount(0);
|
||||
|
||||
// Edit → the bar appears.
|
||||
await toggle.click();
|
||||
await expect(bar).toBeVisible();
|
||||
|
||||
// Save → the PUT fires and the status flips to "saved".
|
||||
const [saved] = await Promise.all([putPrefs(page), page.getByTestId("draft-save").click()]);
|
||||
expect(saved.ok()).toBeTruthy();
|
||||
await expect(status).toHaveAttribute("data-state", "saved");
|
||||
|
||||
// Restore the baseline (toggle back and save) so the shared account stays clean. Assert the
|
||||
// restore's own PUT (not the lingering "saved" from the first save, which shows for 2.5s).
|
||||
await toggle.click();
|
||||
const [restored] = await Promise.all([putPrefs(page), page.getByTestId("draft-save").click()]);
|
||||
expect(restored.ok()).toBeTruthy();
|
||||
});
|
||||
|
||||
test("leaving with unsaved changes is guarded", async ({ page }) => {
|
||||
await openApp(page);
|
||||
await gotoPage(page, "settings");
|
||||
|
||||
await page.getByRole("switch", { name: TOGGLE }).click();
|
||||
await expect(page.getByTestId("draft-save-bar")).toBeVisible();
|
||||
|
||||
// Navigating away raises the confirm guard instead of leaving.
|
||||
await page.getByTestId("nav-feed").click();
|
||||
await expect(page.getByText("You have unsaved settings")).toBeVisible();
|
||||
|
||||
// Cancel → stay on Settings, still dirty.
|
||||
await page.getByRole("button", { name: "Cancel" }).click();
|
||||
await expect(page.getByTestId("draft-save-bar")).toBeVisible();
|
||||
|
||||
// Discard → clean, so the account is left at baseline.
|
||||
await page.getByTestId("draft-discard").click();
|
||||
await expect(page.getByTestId("draft-save-bar")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user