Files
buzz/desktop/tests/e2e/reaction-names.spec.ts
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

171 lines
5.2 KiB
TypeScript

import { expect, test } from "@playwright/test";
import * as fs from "node:fs";
import * as path from "node:path";
import { waitForAnimations } from "../helpers/animations";
import { installMockBridge } from "../helpers/bridge";
const REACTION_TARGET_CONTENT = "React to me with a custom emoji";
const REACTION_TARGET_EVENT_ID = "d".repeat(64);
const BOB_PUBKEY =
"bb22a5299220cad76ffd46190ccbeede8ab5dc260faa28b6e5a2cb31b9aff260";
const MAX_REACTION_NAME =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl";
const MAX_REACTION_AVATAR_URL =
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Crect width="16" height="16" rx="4" fill="%23e5484d"/%3E%3C/svg%3E';
const SHORT_REACTION_AVATAR_URL =
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Crect width="16" height="16" rx="4" fill="%2300a36c"/%3E%3C/svg%3E';
const SCREENSHOT_DIR =
process.env.REACTION_POPOVER_SCREENSHOT_DIR ??
"test-results/reaction-popover-screenshots";
function reactionTargetRow(page: import("@playwright/test").Page) {
return page
.getByTestId("message-row")
.filter({ hasText: REACTION_TARGET_CONTENT })
.last();
}
async function waitForImage(
image: import("@playwright/test").Locator,
): Promise<void> {
await expect(image).toBeVisible();
await expect
.poll(() =>
image.evaluate(
(element) =>
element instanceof HTMLImageElement &&
element.complete &&
element.naturalWidth > 0,
),
)
.toBe(true);
}
async function capturePopover(
page: import("@playwright/test").Page,
popover: import("@playwright/test").Locator,
filename: string,
): Promise<void> {
fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
await waitForAnimations(page);
await popover.screenshot({
animations: "disabled",
path: path.join(SCREENSHOT_DIR, filename),
});
}
test.beforeEach(async ({ page }) => {
await installMockBridge(page, {
searchProfiles: [
{
pubkey: BOB_PUBKEY,
displayName: "bob",
avatarUrl: SHORT_REACTION_AVATAR_URL,
},
],
});
});
test("reaction popover resolves a reactor with no authored message in the window", async ({
page,
}) => {
await page.goto("/");
await page.getByTestId("channel-general").click();
await expect(page.getByTestId("chat-title")).toHaveText("general");
await page.waitForFunction(
() =>
window.__BUZZ_E2E_HAS_MOCK_LIVE_SUBSCRIPTION__?.({
channelName: "general",
kind: 7,
}) === true,
);
await page.evaluate(
({ pubkey, targetId, avatarUrl }) => {
window.__BUZZ_E2E_EMIT_MOCK_MESSAGE__?.({
channelName: "general",
content: ":react:",
extraTags: [
["e", targetId],
["emoji", "react", avatarUrl],
],
kind: 7,
pubkey,
});
},
{
avatarUrl: SHORT_REACTION_AVATAR_URL,
pubkey: BOB_PUBKEY,
targetId: REACTION_TARGET_EVENT_ID,
},
);
const row = reactionTargetRow(page);
const pill = row.getByRole("button", { name: "Toggle :react: reaction" });
await expect(pill).toBeVisible();
await pill.hover();
await expect(page.getByText("bob reacted with")).toBeVisible();
const popover = page
.locator("[data-radix-popper-content-wrapper]")
.filter({ hasText: "bob reacted with" });
const avatar = popover.locator("img");
await expect(avatar).toHaveAttribute("src", SHORT_REACTION_AVATAR_URL);
await waitForImage(avatar);
await capturePopover(page, popover, "short-name-after.png");
});
test("maximum-length reaction name wraps inside a fixed-width popover", async ({
page,
}) => {
await page.goto("/");
await page.getByTestId("channel-general").click();
await expect(page.getByTestId("chat-title")).toHaveText("general");
await page.waitForFunction(
() =>
window.__BUZZ_E2E_HAS_MOCK_LIVE_SUBSCRIPTION__?.({
channelName: "general",
kind: 7,
}) === true,
);
const reaction = `:${MAX_REACTION_NAME}:`;
await page.evaluate(
({ content, targetId, avatarUrl }) => {
window.__BUZZ_E2E_EMIT_MOCK_MESSAGE__?.({
channelName: "general",
content,
extraTags: [
["e", targetId],
["emoji", content.slice(1, -1), avatarUrl],
],
kind: 7,
});
},
{
avatarUrl: MAX_REACTION_AVATAR_URL,
content: reaction,
targetId: REACTION_TARGET_EVENT_ID,
},
);
const pill = reactionTargetRow(page).getByRole("button", {
name: `Toggle ${reaction} reaction`,
});
await expect(pill).toBeVisible();
await pill.focus();
const popover = page
.locator("[data-radix-popper-content-wrapper]")
.filter({ hasText: reaction });
await expect(popover).toBeVisible();
await expect(popover).toHaveCSS("width", "288px");
const reactionName = popover.getByTestId("reaction-popover-name");
await expect(reactionName).toHaveCSS("word-break", "break-all");
await expect(reactionName).toHaveText(reaction);
const avatar = popover.locator("img");
await expect(avatar).toHaveAttribute("src", MAX_REACTION_AVATAR_URL);
await waitForImage(avatar);
await capturePopover(page, popover, "max-length-after.png");
});