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
Signed-off-by: cls_宁波本机 <908705107@qq.com>
537 lines
18 KiB
TypeScript
537 lines
18 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import {
|
|
installMockBridge,
|
|
createMockAgentMemoryListing,
|
|
TEST_IDENTITIES,
|
|
} from "../helpers/bridge";
|
|
import { waitForAnimations } from "../helpers/animations";
|
|
|
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
type CommandLogEntry = { command: string; payload: unknown };
|
|
|
|
async function readCommandLog(page: import("@playwright/test").Page) {
|
|
return page.evaluate(() => {
|
|
return (
|
|
(
|
|
window as Window & {
|
|
__BUZZ_E2E_COMMAND_LOG__?: CommandLogEntry[];
|
|
}
|
|
).__BUZZ_E2E_COMMAND_LOG__ ?? []
|
|
);
|
|
});
|
|
}
|
|
|
|
async function gotoAgentsPage(page: import("@playwright/test").Page) {
|
|
await page.goto("/");
|
|
await page.getByTestId("open-agents-view").click();
|
|
}
|
|
|
|
// Minimal .team.json bytes — the bridge returns a canned preview/result
|
|
// regardless of content; these just need to be non-empty so the file-input
|
|
// handler invokes handleImportTeamSnapshotFile.
|
|
const TEAM_SNAPSHOT_BYTES = new Uint8Array([
|
|
0x7b, 0x22, 0x74, 0x22, 0x3a, 0x31, 0x7d,
|
|
]); // {"t":1}
|
|
|
|
const MOCK_UPLOAD_DESCRIPTOR = {
|
|
url: `https://mock.relay/media/${"a".repeat(64)}.png`,
|
|
sha256: "a".repeat(64),
|
|
size: 1234,
|
|
type: "image/png",
|
|
uploaded: Math.floor(Date.now() / 1000),
|
|
filename: "team.team.png",
|
|
};
|
|
|
|
// Seeded persona ID used across tests.
|
|
const ANALYST_PERSONA_ID = "test-analyst";
|
|
const ANALYST_PUBKEY =
|
|
"953d3363262e86b770419834c53d2446409db6d918a57f8f339d495d54ab001f";
|
|
|
|
// ── (a) Confirm-fail + retry ────────────────────────────────────────────────
|
|
|
|
test("team_snapshot_import_confirm_fail_renders_error_and_retry_succeeds", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
},
|
|
],
|
|
// First confirm throws, second succeeds.
|
|
teamSnapshotConfirmErrors: ["Relay rejected the import.", null],
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
// Trigger import via the hidden file input.
|
|
const fileInput = page.getByTestId("team-snapshot-import-input");
|
|
await fileInput.setInputFiles({
|
|
name: "test.team.json",
|
|
mimeType: "application/json",
|
|
buffer: Buffer.from(TEAM_SNAPSHOT_BYTES),
|
|
});
|
|
|
|
// The import dialog must appear with the preview.
|
|
const dialog = page.getByTestId("team-snapshot-import-dialog");
|
|
await expect(dialog).toBeVisible({ timeout: 5000 });
|
|
|
|
// Click Import — first confirm fails.
|
|
await dialog.getByTestId("team-snapshot-import-confirm").click();
|
|
|
|
// The confirm error banner must be visible in the preview phase.
|
|
const errorBanner = dialog.getByTestId("team-snapshot-import-confirm-error");
|
|
await expect(errorBanner).toBeVisible({ timeout: 5000 });
|
|
await expect(errorBanner).toContainText("Relay rejected the import.");
|
|
|
|
// The Import button must still be visible (we're back to preview, not stuck).
|
|
const importBtn = dialog.getByTestId("team-snapshot-import-confirm");
|
|
await expect(importBtn).toBeVisible();
|
|
|
|
// Click Import again — second confirm succeeds.
|
|
await importBtn.click();
|
|
|
|
// The error banner must disappear (cleared before retry).
|
|
await expect(errorBanner).not.toBeVisible({ timeout: 5000 });
|
|
|
|
// The dialog transitions to the result phase — "Team imported" title.
|
|
await expect(dialog.getByText("Team imported")).toBeVisible({
|
|
timeout: 5000,
|
|
});
|
|
});
|
|
|
|
// ── (b) Allowlist payload passthrough ───────────────────────────────────────
|
|
|
|
test("team_snapshot_import_clear_allowlist_sends_keepAllowlist_false", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
},
|
|
],
|
|
teamSnapshotPreviewHasSourceAllowlist: true,
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
const fileInput = page.getByTestId("team-snapshot-import-input");
|
|
await fileInput.setInputFiles({
|
|
name: "test.team.json",
|
|
mimeType: "application/json",
|
|
buffer: Buffer.from(TEAM_SNAPSHOT_BYTES),
|
|
});
|
|
|
|
const dialog = page.getByTestId("team-snapshot-import-dialog");
|
|
await expect(dialog).toBeVisible({ timeout: 5000 });
|
|
|
|
// The allowlist section must be visible.
|
|
await expect(
|
|
dialog.getByTestId("team-snapshot-import-allowlist-section"),
|
|
).toBeVisible();
|
|
|
|
// Select Clear (default) and click Import.
|
|
await dialog.getByTestId("team-snapshot-import-allowlist-clear").click();
|
|
await dialog.getByTestId("team-snapshot-import-confirm").click();
|
|
|
|
// Wait for result phase.
|
|
await expect(dialog.getByText("Team imported")).toBeVisible({
|
|
timeout: 5000,
|
|
});
|
|
|
|
// Verify the command log shows confirm_team_snapshot_import with keepAllowlist: false.
|
|
const log = await readCommandLog(page);
|
|
const confirmEntry = log.find(
|
|
(e) => e.command === "confirm_team_snapshot_import",
|
|
);
|
|
expect(confirmEntry).toBeTruthy();
|
|
const confirmPayload = confirmEntry?.payload as
|
|
| { input?: { keepAllowlist?: boolean } }
|
|
| undefined;
|
|
expect(confirmPayload?.input?.keepAllowlist).toBe(false);
|
|
});
|
|
|
|
test("team_snapshot_import_keep_allowlist_sends_keepAllowlist_true", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
},
|
|
],
|
|
teamSnapshotPreviewHasSourceAllowlist: true,
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
const fileInput = page.getByTestId("team-snapshot-import-input");
|
|
await fileInput.setInputFiles({
|
|
name: "test.team.json",
|
|
mimeType: "application/json",
|
|
buffer: Buffer.from(TEAM_SNAPSHOT_BYTES),
|
|
});
|
|
|
|
const dialog = page.getByTestId("team-snapshot-import-dialog");
|
|
await expect(dialog).toBeVisible({ timeout: 5000 });
|
|
|
|
// Select Keep.
|
|
await dialog.getByTestId("team-snapshot-import-allowlist-keep").click();
|
|
await dialog.getByTestId("team-snapshot-import-confirm").click();
|
|
|
|
// Wait for result phase.
|
|
await expect(dialog.getByText("Team imported")).toBeVisible({
|
|
timeout: 5000,
|
|
});
|
|
|
|
// Verify keepAllowlist: true in the command log.
|
|
const log = await readCommandLog(page);
|
|
const confirmEntry = log.find(
|
|
(e) => e.command === "confirm_team_snapshot_import",
|
|
);
|
|
expect(confirmEntry).toBeTruthy();
|
|
const confirmPayload = confirmEntry?.payload as
|
|
| { input?: { keepAllowlist?: boolean } }
|
|
| undefined;
|
|
expect(confirmPayload?.input?.keepAllowlist).toBe(true);
|
|
});
|
|
|
|
// ── (c) Sharing parity ──────────────────────────────────────────────────────
|
|
|
|
test("team sharing uses the people picker and gates memory before sending", async ({
|
|
page,
|
|
}) => {
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
status: "running",
|
|
},
|
|
],
|
|
agentMemory: createMockAgentMemoryListing(),
|
|
searchProfiles: [
|
|
{
|
|
pubkey: TEST_IDENTITIES.charlie.pubkey,
|
|
displayName: "Charlie",
|
|
},
|
|
],
|
|
uploadDescriptors: [MOCK_UPLOAD_DESCRIPTOR],
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
await page.getByLabel("Engineering team actions").click();
|
|
await page.getByRole("menuitem", { name: "Share" }).click();
|
|
const shareDialog = page.getByTestId("team-share-dialog");
|
|
await expect(shareDialog).toBeVisible();
|
|
await expect(
|
|
shareDialog.getByRole("heading", { name: "Share Engineering" }),
|
|
).toBeVisible();
|
|
|
|
const search = shareDialog.getByTestId("team-share-recipient-search");
|
|
await expect(search).toBeEnabled({ timeout: 5_000 });
|
|
await search.fill("charlie");
|
|
await page
|
|
.getByTestId(
|
|
`team-share-recipient-option-${TEST_IDENTITIES.charlie.pubkey}`,
|
|
)
|
|
.click();
|
|
await shareDialog.getByTestId("team-share-share-level").click();
|
|
await page.getByRole("menuitemradio", { name: "Team + core memory" }).click();
|
|
await shareDialog.getByTestId("team-share-send").click();
|
|
|
|
const memoryConfirmation = page.getByTestId("team-share-memory-confirmation");
|
|
await expect(memoryConfirmation).toBeVisible();
|
|
await expect(memoryConfirmation).toContainText("This team includes");
|
|
await expect(memoryConfirmation).toContainText("plaintext core memory");
|
|
const logBeforeConfirmation = await readCommandLog(page);
|
|
const encodeLevelsBeforeConfirmation = logBeforeConfirmation
|
|
.filter((entry) => entry.command === "encode_team_snapshot_for_send")
|
|
.map(
|
|
(entry) =>
|
|
(entry.payload as { memoryLevel?: string } | undefined)?.memoryLevel,
|
|
);
|
|
expect(encodeLevelsBeforeConfirmation).toEqual([]);
|
|
|
|
await memoryConfirmation.getByTestId("team-share-memory-confirm").click();
|
|
await expect(page.getByText("Sent a copy of Engineering")).toBeVisible({
|
|
timeout: 8_000,
|
|
});
|
|
|
|
const log = await readCommandLog(page);
|
|
expect(
|
|
log.filter(
|
|
(entry) =>
|
|
entry.command === "encode_team_snapshot_for_send" &&
|
|
(entry.payload as { memoryLevel?: string } | undefined)?.memoryLevel ===
|
|
"core",
|
|
),
|
|
).toHaveLength(1);
|
|
const sendEntry = log.find(
|
|
(entry) => entry.command === "send_channel_message",
|
|
);
|
|
expect(sendEntry).toBeTruthy();
|
|
const sendPayload = sendEntry?.payload as { content?: string } | undefined;
|
|
expect(sendPayload?.content).toContain("[Engineering](");
|
|
expect(sendPayload?.content).not.toContain(";
|
|
});
|
|
|
|
test("team share level carries memories onto the link path too", async ({
|
|
page,
|
|
}) => {
|
|
await page.context().grantPermissions(["clipboard-read", "clipboard-write"]);
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
status: "running",
|
|
},
|
|
],
|
|
agentMemory: createMockAgentMemoryListing(),
|
|
uploadDescriptors: [MOCK_UPLOAD_DESCRIPTOR],
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
await page.getByLabel("Engineering team actions").click();
|
|
await page.getByRole("menuitem", { name: "Share" }).click();
|
|
const shareDialog = page.getByTestId("team-share-dialog");
|
|
await expect(shareDialog).toBeVisible();
|
|
|
|
// No recipient selected — the copy-link path alone must still honour the
|
|
// shared selector and gate plaintext memories behind the confirmation.
|
|
await shareDialog.getByTestId("team-share-share-level").click();
|
|
await page.getByRole("menuitemradio", { name: "Team + core memory" }).click();
|
|
await expect(
|
|
shareDialog.getByTestId("team-share-memory-warning"),
|
|
).toBeVisible();
|
|
await shareDialog.getByTestId("team-share-copy-link").click();
|
|
|
|
const memoryConfirmation = page.getByTestId("team-share-memory-confirmation");
|
|
await expect(memoryConfirmation).toBeVisible();
|
|
await expect(memoryConfirmation).toContainText("plaintext core memory");
|
|
await expect(memoryConfirmation).toContainText(
|
|
"Anyone with the link can view it.",
|
|
);
|
|
const encodeLevelsBeforeConfirmation = (await readCommandLog(page))
|
|
.filter((entry) => entry.command === "encode_team_snapshot_for_send")
|
|
.map(
|
|
(entry) =>
|
|
(entry.payload as { memoryLevel?: string } | undefined)?.memoryLevel,
|
|
);
|
|
expect(encodeLevelsBeforeConfirmation).toEqual([]);
|
|
|
|
await memoryConfirmation.getByTestId("team-share-memory-confirm").click();
|
|
await expect(shareDialog.getByTestId("team-share-copy-link")).toContainText(
|
|
"Copied",
|
|
);
|
|
expect(
|
|
(await readCommandLog(page)).filter(
|
|
(entry) =>
|
|
entry.command === "encode_team_snapshot_for_send" &&
|
|
(entry.payload as { memoryLevel?: string } | undefined)?.memoryLevel ===
|
|
"core",
|
|
),
|
|
).toHaveLength(1);
|
|
});
|
|
|
|
test("team sharing keeps link copy and export in the shared surface", async ({
|
|
page,
|
|
}) => {
|
|
await page.context().grantPermissions(["clipboard-read", "clipboard-write"]);
|
|
await installMockBridge(page, {
|
|
personas: [
|
|
{
|
|
id: ANALYST_PERSONA_ID,
|
|
displayName: "Analyst",
|
|
systemPrompt: "You are an analyst.",
|
|
},
|
|
],
|
|
managedAgents: [
|
|
{
|
|
pubkey: ANALYST_PUBKEY,
|
|
name: "Analyst",
|
|
personaId: ANALYST_PERSONA_ID,
|
|
},
|
|
],
|
|
uploadDescriptors: [MOCK_UPLOAD_DESCRIPTOR],
|
|
uploadDelayMs: 800,
|
|
});
|
|
await gotoAgentsPage(page);
|
|
|
|
await page.getByLabel("Engineering team actions").click();
|
|
const menu = page.getByRole("menu");
|
|
await expect(
|
|
menu.getByRole("menuitem", { name: "Export snapshot" }),
|
|
).toHaveCount(0);
|
|
await menu.getByRole("menuitem", { name: "Share" }).click();
|
|
|
|
const shareDialog = page.getByTestId("team-share-dialog");
|
|
await expect(shareDialog.getByTestId("team-share-share-level")).toHaveText(
|
|
"Team only",
|
|
);
|
|
const exportTeamRow = shareDialog.getByTestId("team-share-export");
|
|
const copyLinkButton = shareDialog.getByTestId("team-share-copy-link");
|
|
const recipientSearch = shareDialog.getByTestId(
|
|
"team-share-recipient-search",
|
|
);
|
|
const shareLevel = shareDialog.getByTestId("team-share-share-level");
|
|
const closeButton = shareDialog.getByRole("button", { name: "Close" });
|
|
await waitForAnimations(page);
|
|
await expect(
|
|
copyLinkButton.getByTestId("team-share-copy-link-stage"),
|
|
).toHaveCSS("position", "relative");
|
|
const idleCopyLinkButtonBox = await copyLinkButton.boundingBox();
|
|
await copyLinkButton.click();
|
|
await expect(copyLinkButton.locator(".sprout-arc-spinner")).toBeVisible();
|
|
await expect(copyLinkButton).toContainText("Copying…");
|
|
await expect(copyLinkButton).toHaveCSS("opacity", "1");
|
|
await expect(recipientSearch).toBeEnabled();
|
|
await expect(shareLevel).toBeEnabled();
|
|
await expect(closeButton).toBeDisabled();
|
|
await expect(exportTeamRow).toBeDisabled();
|
|
await expect(exportTeamRow).toHaveCSS("opacity", "1");
|
|
await page.keyboard.press("Escape");
|
|
await expect(shareDialog).toBeVisible();
|
|
await expect(copyLinkButton).toContainText("Copied");
|
|
await expect(copyLinkButton).toHaveAttribute("data-copy-status", "copied");
|
|
await expect(closeButton).toBeEnabled();
|
|
await expect(exportTeamRow).toBeEnabled();
|
|
await waitForAnimations(page);
|
|
const copiedButtonBox = await copyLinkButton.boundingBox();
|
|
const copiedStateColors = await copyLinkButton
|
|
.getByTestId("team-share-copy-link-state")
|
|
.evaluate((element) => {
|
|
const icon = element.querySelector("svg");
|
|
const label = element.querySelector("span");
|
|
return {
|
|
icon: icon ? getComputedStyle(icon).color : null,
|
|
label: label ? getComputedStyle(label).color : null,
|
|
};
|
|
});
|
|
expect(copiedStateColors.icon).toBe(copiedStateColors.label);
|
|
expect(copiedButtonBox?.width).toBeLessThan(
|
|
idleCopyLinkButtonBox?.width ?? 0,
|
|
);
|
|
expect(
|
|
Math.abs(
|
|
(copiedButtonBox?.x ?? 0) +
|
|
(copiedButtonBox?.width ?? 0) -
|
|
((idleCopyLinkButtonBox?.x ?? 0) + (idleCopyLinkButtonBox?.width ?? 0)),
|
|
),
|
|
).toBeLessThanOrEqual(1);
|
|
await expect(copyLinkButton).toContainText("Copy link", { timeout: 4_000 });
|
|
await expect(copyLinkButton).toHaveAttribute("data-copy-status", "idle");
|
|
|
|
const log = await readCommandLog(page);
|
|
const encodeEntry = log.find(
|
|
(entry) => entry.command === "encode_team_snapshot_for_send",
|
|
);
|
|
expect(encodeEntry?.payload).toEqual(
|
|
expect.objectContaining({ memoryLevel: "none", format: "png" }),
|
|
);
|
|
|
|
const copiedTeam = await page.evaluate(() => {
|
|
const commands =
|
|
(
|
|
window as Window & {
|
|
__BUZZ_E2E_COMMAND_LOG__?: Array<{
|
|
command: string;
|
|
payload: { html?: string; text?: string };
|
|
}>;
|
|
}
|
|
).__BUZZ_E2E_COMMAND_LOG__ ?? [];
|
|
return commands.findLast(
|
|
(entry) => entry.command === "copy_text_to_clipboard",
|
|
)?.payload;
|
|
});
|
|
|
|
await page.keyboard.press("Escape");
|
|
await expect(shareDialog).toHaveCount(0);
|
|
await page.getByTestId("channel-general").click();
|
|
await page.evaluate(async ({ html, text }) => {
|
|
await navigator.clipboard.write([
|
|
new ClipboardItem({
|
|
"text/html": new Blob([html ?? ""], { type: "text/html" }),
|
|
"text/plain": new Blob([text ?? ""], { type: "text/plain" }),
|
|
}),
|
|
]);
|
|
}, copiedTeam ?? {});
|
|
await page
|
|
.getByTestId("message-composer")
|
|
.locator("[contenteditable='true']")
|
|
.click();
|
|
await page.keyboard.press("ControlOrMeta+V");
|
|
|
|
const composerTeamCard = page.getByTestId("composer-team-snapshot-card");
|
|
await expect(composerTeamCard).toBeVisible();
|
|
await expect(composerTeamCard).toContainText("Engineering");
|
|
await expect(composerTeamCard.locator("img")).toHaveCount(0);
|
|
await page.getByTestId("send-message").click();
|
|
|
|
const sentTeamCard = page.getByTestId("agent-snapshot-card").last();
|
|
await expect(sentTeamCard).toBeVisible();
|
|
await expect(sentTeamCard).toContainText("Engineering");
|
|
await expect(sentTeamCard).toContainText("Add team");
|
|
await expect(sentTeamCard.locator("img")).toHaveCount(0);
|
|
|
|
await page.getByTestId("open-agents-view").click();
|
|
await page.getByLabel("Engineering team actions").click();
|
|
await page.getByRole("menuitem", { name: "Share" }).click();
|
|
await page.getByTestId("team-share-export").click();
|
|
const exportDialog = page.getByTestId("team-snapshot-export-dialog");
|
|
await expect(exportDialog).toBeVisible();
|
|
await expect(
|
|
exportDialog.getByRole("heading", { name: "Export Engineering" }),
|
|
).toBeVisible();
|
|
await expect(
|
|
exportDialog.getByTestId("team-snapshot-memory-trigger"),
|
|
).toHaveText("Team only");
|
|
await expect(
|
|
exportDialog.getByTestId("team-snapshot-format-trigger"),
|
|
).toHaveText("PNG");
|
|
});
|