Files
ThothII/frontend/e2e/administration-embed-layout.spec.ts
T

108 lines
4.1 KiB
TypeScript

import { expect, test, type Page, type Route } from "@playwright/test";
import { createAuthenticationStack } from "./fixtures/auth-stack.mjs";
test.describe.configure({ mode: "serial" });
test.use({ viewport: { width: 1660, height: 822 } });
let stack: Awaited<ReturnType<typeof createAuthenticationStack>>;
function json(route: Route, body: unknown) {
return route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(body),
});
}
async function signInAsAdmin(page: Page) {
const account = stack.localAccount("admin");
await page.getByLabel("Username").fill(account.username);
await page.locator('input[name="password"]').fill(account.password);
await page.getByRole("button", { name: "Sign in", exact: true }).click();
await expect(page.getByTestId("app-shell")).toBeVisible({ timeout: 30_000 });
}
test.beforeAll(async () => {
stack = await createAuthenticationStack({ withF1Workspace: true });
await stack.useLocalMode();
});
test.afterAll(async () => {
await stack?.close();
});
test("Administration stays within its rail when hosted by the Omics portal", async ({ page }) => {
await page.route("**/api/settings", (route) => json(route, {
workspace: "fixture-workspace",
provider: "zai",
model: "glm-5.2",
thinking: "medium",
}));
await page.route("**/api/workspaces", (route) => json(route, [{
id: "fixture-workspace",
name: "fixture-workspace",
file: "fixture-workspace/workspace.yaml",
displayName: "Fixture workspace",
configurationState: "ready",
revision: {
id: "fixture-workspace",
commit: "a".repeat(40),
blob: "b".repeat(40),
snapshotPath: `/snapshots/${"a".repeat(40)}/fixture-workspace.yaml`,
},
}]));
await page.route("**/api/workspaces/fixture-workspace/preprocessing", (route) => json(route, {
schemaVersion: 1,
workspaceId: "fixture-workspace",
state: "running",
actionable: false,
clearable: false,
detail: "Building schema and LSH.",
progress: {
stage: "schema_index",
step: 2,
totalSteps: 4,
},
}));
await page.goto(stack.publicUrl);
await signInAsAdmin(page);
await expect(page.getByRole("combobox", { name: "Workspace" })).toHaveValue("fixture-workspace");
// Hyper/Bootstrap and Thoth currently share the portal document. These
// utility names are therefore resolved with the portal's !important values.
await page.addStyleTag({ content: `
.px-2 { padding-right: 0.75rem !important; padding-left: 0.75rem !important; }
.px-3 { padding-right: 1.5rem !important; padding-left: 1.5rem !important; }
.px-4 { padding-right: 2.25rem !important; padding-left: 2.25rem !important; }
` });
const rail = page.getByRole("complementary", { name: "Session navigation" });
await rail.getByRole("button", { name: "Administration", exact: true }).click();
const administration = rail.getByRole("region", { name: "Administration" });
const boundary = rail.getByTestId("administration-boundary");
await expect(administration).toBeVisible();
await expect(rail.getByText("2 / 4", { exact: true })).toBeVisible();
const containment = await administration.evaluate((panel) => {
const elements = Array.from(panel.querySelectorAll<HTMLElement>('button, [role="progressbar"], span'))
.filter((element) => element.matches('button, [role="progressbar"]') || element.textContent?.trim() === "2 / 4");
return elements.map((element) => {
const box = element.getBoundingClientRect();
return {
label: element.textContent?.trim() || element.getAttribute("aria-label") || element.tagName,
left: box.left,
right: box.right,
};
});
});
const boundaryBox = await boundary.boundingBox();
expect(boundaryBox).not.toBeNull();
if (!boundaryBox) return;
for (const item of containment) {
expect.soft(item.left, `${item.label} crosses the Administration left edge`).toBeGreaterThanOrEqual(boundaryBox.x - 1);
expect.soft(item.right, `${item.label} crosses the Administration right edge`).toBeLessThanOrEqual(boundaryBox.x + boundaryBox.width + 1);
}
});