Files
buzz/desktop/tests/e2e/welcome-agent-modal-screenshots.spec.ts
T
cls 9dfa06ffee
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
feat: import Chinese-localized Buzz source snapshot
Signed-off-by: cls_宁波本机 <908705107@qq.com>
2026-08-13 18:34:25 +08:00

295 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test, type Page } from "@playwright/test";
import { waitForAnimations } from "../helpers/animations";
import { installMockBridge, openCreateChannelDialog } from "../helpers/bridge";
const SHOTS = "test-results/welcome-agent-modal";
const FIZZ_PUBKEY = "f".repeat(64);
const SCOUT_PUBKEY = "a".repeat(64);
const EDITOR_PUBKEY = "b".repeat(64);
const scoutPersona = {
id: "personal:scout",
displayName: "Scout",
systemPrompt: "Research a topic, verify sources, and return a concise brief.",
};
const editorPersona = {
id: "personal:editor",
displayName: "Editor",
systemPrompt: "Turn rough writing into clear, confident prose.",
};
async function openChannel(page: Page, name: string) {
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByTestId(`channel-${name}`).click();
await expect(page.getByTestId("chat-title")).toHaveText(name);
}
async function readCommandLog(page: Page) {
return page.evaluate(() => {
const commands = (window as Window & { __BUZZ_E2E_COMMANDS__?: string[] })
.__BUZZ_E2E_COMMANDS__;
if (!commands) {
throw new Error("E2E bridge command log is not installed");
}
return commands;
});
}
function commandCount(commands: string[], command: string) {
return commands.filter((entry) => entry === command).length;
}
async function openAgentPicker(page: Page, channel = "random") {
await openChannel(page, channel);
await page.getByTestId("channel-intro-action-create-agent").click();
const dialog = page.getByTestId("add-channel-bot-dialog");
await expect(dialog).toBeVisible();
await waitForAnimations(page);
return dialog;
}
test.describe("welcome and channel agent entry points", () => {
test("welcome offers chat-first creation", async ({ page }) => {
await installMockBridge(page, {
activePersonaIds: ["builtin:fizz"],
managedAgents: [
{
pubkey: FIZZ_PUBKEY,
name: "Fizz",
personaId: "builtin:fizz",
status: "running",
channelNames: ["Welcome"],
},
],
});
await page.goto("/", { waitUntil: "domcontentloaded" });
await openCreateChannelDialog(page);
await page.getByTestId("create-channel-name").fill("Welcome");
await page
.getByTestId("create-channel-description")
.fill("A private channel for getting oriented in this workspace.");
await page.getByTestId("create-channel-permissions").click();
await page.getByTestId("create-channel-permissions-option-private").click();
await page.getByTestId("create-channel-submit").click();
await expect(page.getByTestId("chat-title")).toHaveText("Welcome");
await expect(
page.getByTestId("message-channel-intro").getByRole("button"),
).toHaveText(["Browse channels", "Create a channel", "Create an agent"]);
await page.getByTestId("welcome-intro-action-create-agent").click();
const dialog = page.getByRole("dialog");
await expect(
dialog.getByRole("heading", { name: "Create an agent" }),
).toBeVisible();
await waitForAnimations(page);
await dialog.screenshot({ path: `${SHOTS}/01-welcome-create-choice.png` });
await page.getByTestId("welcome-create-agent-in-chat").click();
await expect(dialog).not.toBeVisible();
await expect(page.getByTestId("message-timeline")).toContainText(
"Fizz, help me create a new agent.",
);
});
test("welcome manual creation opens the canonical agent form", async ({
page,
}) => {
await installMockBridge(page, {
activePersonaIds: ["builtin:fizz"],
managedAgents: [
{
pubkey: FIZZ_PUBKEY,
name: "Fizz",
personaId: "builtin:fizz",
status: "running",
channelNames: ["Welcome"],
},
],
});
await page.goto("/", { waitUntil: "domcontentloaded" });
await openCreateChannelDialog(page);
await page.getByTestId("create-channel-name").fill("Welcome");
await page.getByTestId("create-channel-permissions").click();
await page.getByTestId("create-channel-permissions-option-private").click();
await page.getByTestId("create-channel-submit").click();
await expect(page.getByTestId("chat-title")).toHaveText("Welcome");
await page.getByTestId("welcome-intro-action-create-agent").click();
await page.getByTestId("welcome-create-agent-manually").click();
await expect(page).toHaveURL(/#\/channels\//);
await expect(page.getByTestId("chat-title")).toHaveText("Welcome");
await expect(
page.getByRole("dialog").getByRole("heading", { name: "Create agent" }),
).toBeVisible();
await expect(
page.getByRole("button", { name: "Advanced", exact: true }),
).toHaveAttribute("aria-expanded", "false");
await page.getByRole("button", { name: "Cancel" }).click();
await expect(page.getByTestId("chat-title")).toHaveText("Welcome");
});
test("channel-targeted creation preserves the agent when attachment fails", async ({
page,
}) => {
await installMockBridge(page, {
addChannelMembersErrors: ["Relay unavailable.", null],
});
await openChannel(page, "random");
await page.getByTestId("channel-intro-action-create-agent").click();
await page.getByTestId("add-channel-create-agent").click();
await expect(page).toHaveURL(/#\/channels\//);
await expect(page.getByTestId("chat-title")).toHaveText("random");
await page.locator("#persona-display-name").fill("Scout");
await page
.locator("#persona-system-prompt")
.fill("Research a topic and return a concise brief.");
await page.getByRole("tab", { name: "Customize for this agent" }).click();
const provider = page.locator("#persona-llm-provider");
await provider.press("Enter");
await page
.getByRole("menuitemradio", { exact: true, name: "Anthropic" })
.click();
await page.locator("#persona-model").click();
await page
.getByRole("button", { name: "Custom model...", exact: true })
.click();
await page.getByLabel("Custom model ID").fill("claude-opus-4-5");
await page.getByLabel("Anthropic API Key").fill("sk-test-api-key-for-e2e");
await expect(page.getByTestId("persona-dialog-submit")).toBeEnabled();
await page.getByTestId("persona-dialog-submit").click();
const createdToast = page
.locator("[data-sonner-toast][data-removed='false']")
.filter({ hasText: "Agent created" });
await expect(createdToast).toBeVisible({ timeout: 10_000 });
await expect(createdToast).toContainText(
"Scout couldnt be added to #random. Relay unavailable.",
);
await expect(page.getByRole("dialog")).toHaveCount(0);
await waitForAnimations(page);
await createdToast.screenshot({
path: `${SHOTS}/05-agent-channel-attachment-failed.png`,
});
const commandsBeforeRetry = await readCommandLog(page);
const createCount = commandCount(
commandsBeforeRetry,
"create_managed_agent",
);
const addCount = commandCount(commandsBeforeRetry, "add_channel_members");
await createdToast.getByRole("button", { name: "Try again" }).click();
await expect
.poll(async () => {
const commands = await readCommandLog(page);
return commandCount(commands, "add_channel_members");
})
.toEqual(addCount + 1);
const attachedToast = page
.locator("[data-sonner-toast][data-removed='false']")
.filter({ hasText: "Added Scout to #random" });
await expect(attachedToast).toBeVisible();
await expect(
attachedToast.getByRole("button", { name: "Try again" }),
).toHaveCount(0);
const commandsAfterRetry = await readCommandLog(page);
expect(commandCount(commandsAfterRetry, "create_managed_agent")).toEqual(
createCount,
);
expect(commandCount(commandsAfterRetry, "add_channel_members")).toEqual(
addCount + 1,
);
await expect(page.getByTestId("chat-title")).toHaveText("random");
});
test("only Fizz is already in the channel", async ({ page }) => {
await installMockBridge(page, {
activePersonaIds: ["builtin:fizz"],
managedAgents: [
{
pubkey: FIZZ_PUBKEY,
name: "Fizz",
personaId: "builtin:fizz",
status: "running",
channelNames: ["random"],
},
],
});
const dialog = await openAgentPicker(page);
await expect(dialog).toContainText(
"All of your agents are already in this channel.",
);
await dialog.screenshot({ path: `${SHOTS}/02-only-fizz-in-channel.png` });
});
test("some personal agents are available", async ({ page }) => {
await installMockBridge(page, {
activePersonaIds: ["builtin:fizz"],
personas: [scoutPersona, editorPersona],
managedAgents: [
{
pubkey: FIZZ_PUBKEY,
name: "Fizz",
personaId: "builtin:fizz",
status: "running",
channelNames: ["random"],
},
{
pubkey: SCOUT_PUBKEY,
name: "Scout",
personaId: scoutPersona.id,
status: "stopped",
},
{
pubkey: EDITOR_PUBKEY,
name: "Editor",
personaId: editorPersona.id,
status: "stopped",
},
],
});
const dialog = await openAgentPicker(page);
await expect(dialog).toContainText("Your agents");
await expect(dialog).toContainText("Scout");
await expect(dialog).toContainText("Editor");
await dialog.screenshot({ path: `${SHOTS}/03-agents-available.png` });
});
test("all personal agents are already in the channel", async ({ page }) => {
await installMockBridge(page, {
activePersonaIds: ["builtin:fizz"],
personas: [scoutPersona, editorPersona],
managedAgents: [
{
pubkey: FIZZ_PUBKEY,
name: "Fizz",
personaId: "builtin:fizz",
status: "running",
channelNames: ["random"],
},
{
pubkey: SCOUT_PUBKEY,
name: "Scout",
personaId: scoutPersona.id,
status: "running",
channelNames: ["random"],
},
{
pubkey: EDITOR_PUBKEY,
name: "Editor",
personaId: editorPersona.id,
status: "running",
channelNames: ["random"],
},
],
});
const dialog = await openAgentPicker(page);
await expect(dialog).toContainText(
"All of your agents are already in this channel.",
);
await dialog.screenshot({ path: `${SHOTS}/04-all-agents-in-channel.png` });
});
});