108 lines
4.1 KiB
TypeScript
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);
|
|
}
|
|
});
|