Files
openworker/surfaces/gui/e2e/sources-channels.spec.ts
T
Rohit C PrasadandDevika 2b45018ffa OpenWorker: initial import
Imported from andrewyng/aisuite@1b4bbf303e
(contents of its platform/ directory, hoisted to the repo root).
Development history prior to this commit lives in that repository.

Co-authored-by: Devika <devikaverma11@gmail.com>
2026-07-21 11:09:41 -07:00

101 lines
4.9 KiB
TypeScript

import { test, expect } from "./fixtures";
// Guards the per-session Slack channels drill-down (§14, hosted in the rail's Access section
// since §32): the "Channels" affordance is gated to two-way connectors, opens an inline child
// view, and add/remove round-trip through the subscribe APIs.
test("Slack channels drill-down: gating, add (auto-prefixed), remove", async ({ page }) => {
await page.goto("/");
// Open the pinned cowork session, then expand the rail's Access section.
await page.getByText("Draft the launch note").first().click();
await page.getByTestId("access-toggle").click();
const body = page.getByRole("region", { name: "Session access" });
await expect(body.getByText("Slack", { exact: true })).toBeVisible();
// Gating: only the two-way connector (Slack) gets a Channels affordance — not Browser.
await expect(page.getByRole("button", { name: /Channels ·/ })).toHaveCount(1);
await expect(page.getByRole("button", { name: /Channels · 0/ })).toBeVisible();
// Drill in.
await page.getByRole("button", { name: /Channels · 0/ }).click();
await expect(page.getByText("Slack channels")).toBeVisible();
await expect(page.getByText(/Not listening to any Slack channel yet/)).toBeVisible();
// Add a bare channel id — the panel scopes it to the connector (→ "slack:C0123").
await page.getByPlaceholder("slack:C0123 or channel link").fill("C0123");
await page.getByRole("button", { name: "Add", exact: true }).click();
await expect(page.getByText("slack:C0123", { exact: true })).toBeVisible();
await expect(page.getByText(/Subscribed channels · 1/)).toBeVisible();
// Remove it → back to the empty state.
await page.getByTitle("Stop listening").click();
await expect(page.getByText(/Not listening to any Slack channel yet/)).toBeVisible();
// Back returns to the Sources list.
await page.getByRole("button", { name: "Back to sources" }).click();
await expect(body.getByText("Slack", { exact: true })).toBeVisible();
});
// The recent-channels dropdown is a hand-rolled popover (NOT a <datalist> — WKWebView renders
// none), fed by /v1/channels/recent: focus opens it, typing filters, picking fills the input.
test("recent channels popover: opens on focus, filters, picks", async ({ page }) => {
await page.goto("/");
await page.getByText("Draft the launch note").first().click();
await page.getByTestId("access-toggle").click();
await page.getByRole("button", { name: /Channels · 0/ }).click();
const input = page.getByPlaceholder("slack:C0123 or channel link");
await input.click();
const pop = page.getByTestId("channel-suggestions");
// Named channels show "#name" with the address as a sub-label; unnamed fall back to the address.
await expect(pop.getByText("#ocw-test")).toBeVisible();
await expect(pop.getByText("slack:C0AAA111")).toBeVisible();
await expect(pop.getByText("bob: deploy failed")).toBeVisible();
// Typing part of the channel NAME filters too…
await input.fill("ocw");
await expect(pop.getByText("#ocw-test")).toBeVisible();
await expect(pop.getByText("slack:C0BBB222")).toHaveCount(0);
await input.fill("");
// Typing filters (matches address or message text)…
await input.fill("deploy");
await expect(pop.getByText("slack:C0AAA111")).toHaveCount(0);
await expect(pop.getByText("slack:C0BBB222")).toBeVisible();
// …and picking fills the input and closes the popover.
await pop.getByText("slack:C0BBB222").click();
await expect(input).toHaveValue("slack:C0BBB222");
await expect(page.getByTestId("channel-suggestions")).toHaveCount(0);
await page.getByRole("button", { name: "Add", exact: true }).click();
await expect(page.getByText(/Subscribed channels · 1/)).toBeVisible();
});
// Address-form fixes: a pasted Copy-link URL resolves to the id; a bare #name is rejected
// with the paste-the-ID hint instead of storing a dead subscription.
test("channel add: link URLs resolve, bare #names are rejected with a hint", async ({
page,
}) => {
await page.goto("/");
await page.getByText("Draft the launch note").first().click();
await page.getByTestId("access-toggle").click();
await page.getByRole("button", { name: /Channels · 0/ }).click();
const input = page.getByPlaceholder("slack:C0123 or channel link");
await input.fill("#general");
await page.getByRole("button", { name: "Add", exact: true }).click();
await expect(page.getByTestId("channel-add-error")).toContainText(
"paste the channel ID",
);
await expect(page.getByText(/Subscribed channels · 1/)).toHaveCount(0);
await input.fill("https://acme.slack.com/archives/C0123ABC");
// Typing again clears the rejection.
await expect(page.getByTestId("channel-add-error")).toHaveCount(0);
await page.getByRole("button", { name: "Add", exact: true }).click();
await expect(page.getByText("slack:C0123ABC")).toBeVisible();
await expect(page.getByText(/Subscribed channels · 1/)).toBeVisible();
});