test(apps): follow streamlined connection UI

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-21 01:55:23 +00:00
1 parent 9fd0a1b9c7
commit ca1696bfcd
3 files changed
+11 -35

No files matched your search

+3 -3
View File
@@ -84,7 +84,7 @@ test.describe.serial("applications lifecycle", () => {
await gotoApps(page, seed.prefix);
// The connected app starts with a "Healthy" pill and an "Open" action. A
// The connected app starts with a "Healthy" pill and an "Edit" action. A
// background health sweep then probes the connection endpoint. The test
// endpoint is an unreachable fixture URL, so the probe fails and the pill
// becomes "Needs attention" and the action becomes "Reconnect". Both are
@@ -96,7 +96,7 @@ test.describe.serial("applications lifecycle", () => {
const connectedRow = page.locator("tbody tr", { hasText: connectedName });
await expect(connectedRow).toBeVisible();
await expect(connectedRow.getByText(/^(Healthy|Needs attention)$/)).toBeVisible({ timeout: 30_000 });
await expect(connectedRow.getByRole("button", { name: /^(Open|Reconnect)$/ })).toBeVisible();
await expect(connectedRow.getByRole("button", { name: /^(Edit|Reconnect)$/ })).toBeVisible();
// The not-connected app has no connection, so the health sweep never touches
// it and its "Not connected" pill and "Connect" action stay deterministic.
@@ -106,7 +106,7 @@ test.describe.serial("applications lifecycle", () => {
await expect(notConnectedRow.getByRole("button", { name: "Connect" })).toBeVisible();
await page.screenshot({ path: `${SCREENSHOT_DIR}/applications-crud-current-list.png`, fullPage: true });
await connectedRow.getByRole("button", { name: /^(Open|Reconnect)$/ }).click();
await connectedRow.getByRole("button", { name: /^(Edit|Reconnect)$/ }).click();
await expect(page).toHaveURL(
new RegExp(`/${seed.prefix}/apps/app/${connected.applicationId}/setup$`),
{ timeout: 20_000 },
+2 -1
View File
@@ -161,7 +161,8 @@ test.describe.serial("dark-mode Apps surfaces", () => {
await forceDark(page);
await page.goto(`/${seed.prefix}/apps/advanced/profiles`);
await expect(page.getByRole("heading", { name: "Access profiles" })).toBeVisible({ timeout: 30_000 });
await expect(page.locator('a[href$="/apps/advanced/runtime"]', { hasText: "Health" })).toBeVisible();
await expect(page.locator('a[href$="/apps/advanced/gateways"]', { hasText: "Gateways" })).toBeVisible();
await expect(page.locator('a[href$="/apps/advanced/profiles"]', { hasText: "Profiles" })).toBeVisible();
await expect(page.locator('a[href$="/apps/advanced/audit"]', { hasText: "Activity" })).toBeVisible();
await expect(page.getByRole("link", { name: "Applications", exact: true })).toHaveCount(0);
// Apps section lives in the same sidebar now.
+6 -31
View File
@@ -145,7 +145,7 @@ test.describe.serial("prosumer MCP flow prosumer MCP flow", () => {
await mock?.close();
});
test("Connect wizard happy path: link mode → actions → who → success", async ({ page, request }) => {
test("Connect wizard happy path: link mode → access → install → success", async ({ page, request }) => {
const seed = await newCompany(request, "connect");
await gotoConnect(page, seed.prefix);
@@ -167,36 +167,11 @@ test.describe.serial("prosumer MCP flow prosumer MCP flow", () => {
// Submit (button label is "Check link").
await page.getByRole("button", { name: /Check link/i }).click();
// Actions step — read-only enabled, write disabled by default.
await expect(page.getByText(/Read only/i)).toBeVisible({ timeout: 30_000 });
await expect(page.getByText(/Can make changes/i)).toBeVisible();
await page.screenshot({ path: `${SCREENSHOT_DIR}/prosumer-mcp-03-actions-step.png`, fullPage: true });
// Verify our seeded tool labels appear (display name is the descriptor title).
await expect(page.getByText("List widgets")).toBeVisible();
await expect(page.getByText("Create widget")).toBeVisible();
// namespaced tool names: the namespaced write action ("qa10864:create_widget") must be
// classified write and land under "Can make changes" — NOT pre-enabled under
// "Read only". Scope the assertions to each action group.
const readOnlyGroup = page.locator("div.rounded-xl").filter({ hasText: "Read only" });
const canChangeGroup = page.locator("div.rounded-xl").filter({ hasText: "Can make changes" });
await expect(canChangeGroup.getByText("Create widget")).toBeVisible();
await expect(readOnlyGroup.getByText("Create widget")).toHaveCount(0);
await expect(readOnlyGroup.getByText("List widgets")).toBeVisible();
// Toggle the write action on so an Ask-first badge appears + the Continue button enables it.
const createToggle = page.getByRole("switch").last();
await createToggle.click();
await expect(page.getByText(/Ask first/i)).toBeVisible({ timeout: 5_000 });
await page.screenshot({ path: `${SCREENSHOT_DIR}/prosumer-mcp-03b-ask-first-on.png`, fullPage: true });
// Continue to who-can-use.
await page.getByRole("button", { name: /Continue with .* on/ }).click();
// Who-can-use step — defaults to All agents.
await expect(page.getByRole("heading", { name: /Who can use/i })).toBeVisible({ timeout: 15_000 });
await page.screenshot({ path: `${SCREENSHOT_DIR}/prosumer-mcp-04-who-step.png`, fullPage: true });
// The streamlined wizard enables discovered actions and applies its
// risk-based ask-first defaults when setup finishes, then goes directly to
// the access step. Classification remains covered by the server suite.
await expect(page.getByRole("heading", { name: /Who can use/i })).toBeVisible({ timeout: 30_000 });
await page.screenshot({ path: `${SCREENSHOT_DIR}/prosumer-mcp-03-who-step.png`, fullPage: true });
await page.getByRole("button", { name: /Continue to install/i }).click();
await expect(page.getByRole("heading", { name: /Install .* tools\?/i })).toBeVisible({ timeout: 15_000 });