feat: import Chinese-localized Buzz source snapshot
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
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
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
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 couldn’t 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` });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user