tests/e2e/a11y-names.spec.ts
Rama main · réplica de lectura del repositorio original.
import AxeBuilder from "@axe-core/playwright";
import { expect, test, type Page, type TestInfo } from "@playwright/test";
import { enableScopedE2EAuth, scopedPath } from "./helpers/auth";
import type { Connection } from "@/lib/types";
import {
buildUiMessageStreamBody,
fulfillJson,
initializeTrackedEvents,
mockActivationFlow,
} from "./helpers/activation-fixtures";
import {
mockBaseChrome,
mockControlSessionBootstrap,
} from "./helpers/automation-control-plane-fixtures";
async function checkNames(page: Page, info: TestInfo, surface: string) {
const result = await new AxeBuilder({ page })
.withRules(["button-name", "aria-dialog-name"])
.analyze();
await info.attach(`${surface}-accessible-names`, {
body: JSON.stringify(result, null, 2),
contentType: "application/json",
});
expect(result.violations).toEqual([]);
}
test("Control code actions have accessible names", async ({ page }, info) => {
await enableScopedE2EAuth(page);
await mockBaseChrome(page);
await mockControlSessionBootstrap(page);
await page.route("**/api/connections**", (route) =>
fulfillJson(route, { connections: [] })
);
await page.route("**/api/control/chat", (route) =>
route.fulfill({
status: 200,
headers: {
"content-type": "text/event-stream",
"x-vercel-ai-ui-message-stream": "v1",
},
body: buildUiMessageStreamBody(
"```typescript\nconst accessible = true;\n```"
),
})
);
await page.goto(scopedPath("control"));
await page
.getByPlaceholder("Ask anything or run a command...")
.fill("Show an example");
await page.getByRole("button", { name: "Start mission" }).click();
await expect(
page.getByRole("button", { name: /^Copy code$/i })
).toBeVisible();
await checkNames(page, info, "control");
});
test("workspace announces sandbox and connection status without colour", async ({
page,
}, info) => {
await initializeTrackedEvents(page);
await enableScopedE2EAuth(page);
await mockActivationFlow(page);
await page.route("**/api/integrations/slack/installations", (route) =>
fulfillJson(route, { installations: [] })
);
await page.route("**/api/control/sessions**", (route) =>
fulfillJson(route, [])
);
let connections: Connection[] = [];
await page.route(/\/api\/(?:repos\/[^/]+\/)?connections(?:\?.*)?$/, (route) =>
fulfillJson(route, { connections, overrides: [] })
);
await page.route(/\/api\/chat(?:\?.*)?$/, (route) =>
route.fulfill({
status: 200,
headers: {
"content-type": "text/event-stream",
"x-vercel-ai-ui-message-stream": "v1",
},
body: buildUiMessageStreamBody(
"```typescript\nconst accessible = true;\n```"
),
})
);
await page.goto(scopedPath("projects/workspace"));
await page.getByTestId("home-sync-repos").click();
await page.getByTestId("home-open-workspace-repo-1").click();
await expect(
page
.getByRole("status")
.filter({ hasText: /^ready$/ })
.first()
).toBeVisible();
await expect(
page.getByRole("status").filter({ hasText: "No connections" })
).toHaveCount(1);
const composer = page.getByRole("textbox", {
name: "Ask the agent what to build, fix, or explain. Type / for commands or drop files here.",
});
await composer.fill("Show an example");
await composer.press("Enter");
await expect(
page.getByRole("button", { name: /^Copy code$/i })
).toBeVisible();
await checkNames(page, info, "workspace");
connections = [
{
id: "connection-1",
user_id: "user-1",
name: "Example tools",
type: "mcp_server",
base_url: null,
auth_type: "none",
auth_header: null,
mcp_transport: "http",
mcp_url: "https://example.com/mcp",
description: null,
is_enabled: true,
approval_mode: "auto",
health_status: "healthy",
scope: "global",
repo_id: null,
oauth_client_id: null,
oauth_authorize_url: null,
oauth_token_url: null,
oauth_scopes: null,
oauth_authorized_at: null,
oauth_token_expires_at: null,
source_preset: null,
last_tested_at: null,
last_test_error: null,
last_test_http_status: null,
last_test_tool_count: null,
created_at: "2026-10-04T00:00:00Z",
updated_at: "2026-10-04T00:00:00Z",
},
];
await page.getByRole("button", { name: /^Tools:/ }).click();
const connectionsDialog = page.getByRole("dialog", { name: "MCP servers" });
await connectionsDialog
.getByRole("button", { name: "Refresh", exact: true })
.click();
await expect(
page.getByRole("status").filter({ hasText: "All connections healthy" })
).toHaveCount(1);
await expect(connectionsDialog.getByRole("status")).toHaveText("Healthy");
connections[0] = { ...connections[0], health_status: "unreachable" };
await connectionsDialog
.getByRole("button", { name: "Refresh", exact: true })
.click();
await expect(
page.getByRole("status").filter({ hasText: "Some connections failed" })
).toHaveCount(1);
await expect(connectionsDialog.getByRole("status")).toHaveText("Unreachable");
await checkNames(page, info, "workspace-connections");
await page.keyboard.press("Escape");
await page.keyboard.press("Meta+k");
const palette = page.getByRole("dialog");
await palette.getByRole("combobox").fill("acme/demo-app");
const openWorkspace = palette.getByRole("option", {
name: /Open workspace.*acme\/demo-app/,
});
await expect(openWorkspace).toBeVisible();
await expect(openWorkspace.getByRole("status")).toHaveText("Running");
await expect(
palette.getByRole("status").filter({ hasText: "Running" }).first()
).toHaveCount(1);
await checkNames(page, info, "workspace-palette");
});