feat: consolidate shared UI and harden browser authority for release

This commit is contained in:
2026-09-08 01:35:05 +02:00
parent ac40774785
commit b75ca34295
143 changed files with 8664 additions and 752 deletions
@@ -0,0 +1,62 @@
import { expect, test } from "@playwright/test";
for (const initiallyEmpty of [false, true]) {
test(`Files ignores a late ${initiallyEmpty ? "space discovery" : "folder listing"} Reload after session change`, async ({ page }) => {
let release!: () => void;
const heldReload = new Promise<void>((resolve) => { release = resolve; });
let holdNextRead = false;
let holdingRead = false;
const unexpected: string[] = [];
await page.route((url) => url.pathname.startsWith("/api/"), async (route) => {
const request = route.request();
const path = new URL(request.url()).pathname;
if (request.method() !== "GET") {
unexpected.push(`${request.method()} ${path}`);
await route.fulfill({ status: 403, json: { detail: "Fixture forbids writes" } });
return;
}
const next = request.headers().authorization === "Bearer fixture-next-session";
const actor = next ? "fixture-next-user" : "fixture-user";
const name = next ? "new-session.zip" : "old-session.zip";
const delayed = holdNextRead && !next && path === (initiallyEmpty ? "/api/v1/files/spaces" : "/api/v1/files");
if (delayed) {
holdNextRead = false;
holdingRead = true;
await heldReload;
}
if (path === "/api/v1/files/spaces") {
await route.fulfill({ json: { spaces: initiallyEmpty && !next && !delayed ? [] : [
{ id: `user:${actor}`, label: next ? "New session files" : "Old session files", owner_type: "user", owner_id: actor, space_type: "managed" }
] } });
} else if (path === "/api/v1/files/folders") {
await route.fulfill({ json: { folders: [], total: 0, next_cursor: null } });
} else if (path === "/api/v1/files") {
await route.fulfill({ json: { files: [{ id: `${actor}-archive`, tenant_id: "fixture-tenant", owner_type: "user", owner_id: actor,
display_path: name, filename: name, size_bytes: 42, content_type: "application/zip", checksum_sha256: "a".repeat(64), version_id: "fixture-version",
created_at: "2026-01-01T12:00:00Z", updated_at: "2026-01-01T12:00:00Z", audit_relevant: false, shares: [], metadata: {}, deleted_at: null
}], total: 1, next_cursor: null } });
} else {
unexpected.push(`${request.method()} ${path}`);
await route.fulfill({ status: 404, json: { detail: "Unconfigured fixture read" } });
}
});
await page.goto("/?files-toolbar&session-switch&language=en");
if (initiallyEmpty) await expect(page.getByText("No file spaces available.", { exact: true })).toBeVisible();
else await expect(page.locator(".file-row").filter({ hasText: "old-session.zip" })).toBeVisible();
const reload = page.locator('[data-interface-id="files.workspace.actions"]').getByRole("button", { name: "Reload", exact: true });
await expect(reload).toBeEnabled();
holdNextRead = true;
await reload.click();
await expect.poll(() => holdingRead).toBe(true);
await page.getByRole("button", { name: "Switch fixture session", exact: true }).click();
await expect(page.locator(".file-row").filter({ hasText: "new-session.zip" })).toBeVisible();
const oldResponse = page.waitForResponse((response) => response.url().includes(initiallyEmpty ? "/api/v1/files/spaces" : "/api/v1/files?") && response.request().headers().authorization !== "Bearer fixture-next-session");
release();
await oldResponse;
await expect(page.locator(".file-tree-root")).toHaveText(["New session files"]);
await expect(page.locator(".file-row")).toHaveCount(1);
await expect(page.locator(".file-row")).toContainText("new-session.zip");
await expect(reload).toBeEnabled();
expect(unexpected).toEqual([]);
});
}