fix(ui): complete P5-00 shell readiness gates

This commit is contained in:
cesnimda
2026-09-21 21:38:11 +02:00
parent c325eb68c6
commit 926f2e5164
52 changed files with 6630 additions and 64 deletions
+52 -2
View File
@@ -1,10 +1,10 @@
import { expect, test as base, type APIRequestContext, type Playwright, type Page } from "@playwright/test";
import { expect, test as base, type APIRequestContext, type PlaywrightWorkerArgs, type Page } from "@playwright/test";
const apiUrl = "http://localhost:5302/api";
const password = "E2ePassword123!";
type Account = { api: APIRequestContext; email: string; id: string; sessionContext?: string; headers: Record<string, string> };
async function signIn(playwright: Playwright, email: string): Promise<Account> {
async function signIn(playwright: PlaywrightWorkerArgs["playwright"], email: string): Promise<Account> {
const api = await playwright.request.newContext();
expect((await api.post(`${apiUrl}/auth/login`, { data: { email, password } })).status()).toBe(200);
const me = await (await api.get(`${apiUrl}/auth/me`)).json();
@@ -114,6 +114,56 @@ async function uiLogin(page: Page, email: string) {
await expect(page).toHaveURL(/\/dashboard$/);
}
test("[P5-00 PRES-E05 E07 E08] account switch disposes open command, account and notification surfaces", async ({ context, accounts }) => {
test.setTimeout(90_000);
const { a, b } = accounts;
const company = await a.api.post(`${apiUrl}/companies`, { headers: a.headers, data: { name: "Private A shell company" } });
expect(company.status()).toBe(201);
await context.route("**/*", route => {
const url = new URL(route.request().url());
return ["localhost", "127.0.0.1"].includes(url.hostname) || ["data:", "blob:", "about:"].includes(url.protocol) ? route.continue() : route.abort();
});
await context.addInitScript(() => localStorage.setItem("uiLanguage", "en"));
const session = await context.newPage();
await uiLogin(session, a.email);
const command = await context.newPage();
await command.goto("/dashboard");
await command.getByRole("button", { name: /Quick Search/ }).click();
await command.getByRole("textbox", { name: "Quick Search", exact: true }).fill("Private A shell");
await expect(command.getByRole("button", { name: /Private A shell company/ })).toBeVisible();
const account = await context.newPage();
await account.goto("/dashboard");
await account.getByRole("button", { name: "User", exact: true }).click();
await expect(account.getByRole("menu")).toBeVisible();
const notification = await context.newPage();
// Only notification content is a fixture; authentication/logout/switch and company search are native.
await notification.route(`${apiUrl}/notifications?limit=10`, route => route.fulfill({ json: [{
id: "p500-private-a", kind: "info", title: "Private A shell notice", message: "Account A only", createdAtUtc: new Date().toISOString(),
}] }), { times: 1 });
await notification.goto("/dashboard");
await notification.getByRole("button", { name: "Notifications", exact: true }).click();
await expect(notification.getByText("Private A shell notice", { exact: true })).toBeVisible();
await session.getByRole("button", { name: "User", exact: true }).click();
await session.getByRole("menuitem", { name: "Sign out", exact: true }).click();
await expect(session).toHaveURL(/\/login\?sessionChanged=1$/);
await uiLogin(session, b.email);
for (const tab of [command, account, notification]) {
await expect(tab.getByRole("dialog")).toHaveCount(0);
await expect(tab.getByRole("menu")).toHaveCount(0);
await expect(tab.getByText(/Private A shell/)).toHaveCount(0);
await tab.goto("/dashboard");
await expect(tab.getByText(a.email, { exact: true })).toHaveCount(0);
await expect(tab.getByTestId("admin-version-badge")).toHaveCount(0);
}
await command.getByRole("button", { name: /Quick Search/ }).click();
await command.getByRole("textbox", { name: "Quick Search", exact: true }).fill("Private A shell");
await expect(command.getByText("No matching commands or records.", { exact: true })).toBeVisible();
await notification.getByRole("button", { name: "Notifications", exact: true }).click();
await expect(notification.getByText("Private A shell notice", { exact: true })).toHaveCount(0);
expect(await storedName(a)).toBe("Private A");
expect(await storedName(b)).toBe("Private B");
});
test("two tabs discard A's private form before B can use it, including Back navigation", async ({ context, accounts }) => {
test.setTimeout(90_000);
const { a, b } = accounts;