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,120 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
import { installMockBridge } from "../helpers/bridge";
|
||||
|
||||
// The mock identity's own pre-seeded message in #general (authored by
|
||||
// DEFAULT_MOCK_IDENTITY.pubkey in e2eBridge.ts). Editing/deleting one's own
|
||||
// message is exactly Sam's workflow: "delete a message by clearing its edit."
|
||||
const OWN_MESSAGE_ID = "mock-general-welcome";
|
||||
const ORIGINAL_CONTENT = "Welcome to #general";
|
||||
|
||||
// Open the more-actions menu for a message row and wait for the menu to mount.
|
||||
async function openMoreActionsMenu(
|
||||
page: import("@playwright/test").Page,
|
||||
messageId: string,
|
||||
) {
|
||||
const row = page.locator(`[data-message-id="${messageId}"]`);
|
||||
await row.hover();
|
||||
await page.getByTestId(`more-actions-${messageId}`).click();
|
||||
await expect(page.locator('[role="menuitem"]').first()).toBeVisible({
|
||||
timeout: 5_000,
|
||||
});
|
||||
}
|
||||
|
||||
// Enter edit mode for a message, clear it to empty, and submit — the gesture
|
||||
// that triggers the empty-edit delete confirmation.
|
||||
async function submitEmptyEdit(
|
||||
page: import("@playwright/test").Page,
|
||||
messageId: string,
|
||||
) {
|
||||
await openMoreActionsMenu(page, messageId);
|
||||
await page.getByTestId(`edit-message-${messageId}`).click();
|
||||
await expect(page.getByTestId("edit-target")).toBeVisible({ timeout: 5_000 });
|
||||
// Edit mode sets the editor content via Tiptap's async transaction pipeline;
|
||||
// wait for it to populate before we clear it.
|
||||
const input = page.getByTestId("message-input");
|
||||
await expect(input).not.toBeEmpty({ timeout: 5_000 });
|
||||
await input.click();
|
||||
await page.keyboard.press("ControlOrMeta+A");
|
||||
await page.keyboard.press("Backspace");
|
||||
await expect(input).toBeEmpty();
|
||||
await page.keyboard.press("Enter");
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await installMockBridge(page);
|
||||
await page.goto("/");
|
||||
await page.getByTestId("channel-general").click();
|
||||
await expect(page.getByTestId("chat-title")).toHaveText("general");
|
||||
});
|
||||
|
||||
test("clearing an edit to empty prompts to delete, then deletes on confirm", async ({
|
||||
page,
|
||||
}) => {
|
||||
const row = page.locator(`[data-message-id="${OWN_MESSAGE_ID}"]`);
|
||||
await expect(row).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
await submitEmptyEdit(page, OWN_MESSAGE_ID);
|
||||
|
||||
// The same "Delete message?" confirmation the Delete menu action shows — an
|
||||
// empty edit is routed through it, not silently deleted.
|
||||
const dialog = page.getByRole("alertdialog");
|
||||
await expect(dialog).toBeVisible({ timeout: 10_000 });
|
||||
await expect(dialog).toContainText("Delete message?");
|
||||
// Edit mode stays active while the dialog is open — it exits only on confirm.
|
||||
await expect(page.getByTestId("edit-target")).toBeVisible();
|
||||
|
||||
// Confirm → the message row is removed and edit mode has exited.
|
||||
await dialog.getByRole("button", { name: "Delete" }).click();
|
||||
await expect(dialog).toBeHidden({ timeout: 5_000 });
|
||||
await expect(page.getByTestId("edit-target")).toBeHidden();
|
||||
await expect(row).toBeHidden({ timeout: 5_000 });
|
||||
});
|
||||
|
||||
test("cancelling the empty-edit delete keeps the message", async ({ page }) => {
|
||||
const row = page.locator(`[data-message-id="${OWN_MESSAGE_ID}"]`);
|
||||
await expect(row).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
await submitEmptyEdit(page, OWN_MESSAGE_ID);
|
||||
|
||||
const dialog = page.getByRole("alertdialog");
|
||||
await expect(dialog).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
// Cancel → nothing is deleted, the original message survives, and the user is
|
||||
// left in edit mode (the editing session is preserved, not discarded).
|
||||
await dialog.getByRole("button", { name: "Cancel" }).click();
|
||||
await expect(dialog).toBeHidden({ timeout: 5_000 });
|
||||
await expect(page.getByTestId("edit-target")).toBeVisible();
|
||||
await expect(row).toBeVisible();
|
||||
await expect(page.getByTestId("message-timeline")).toContainText(
|
||||
ORIGINAL_CONTENT,
|
||||
);
|
||||
});
|
||||
|
||||
test("a non-empty edit still edits and never deletes", async ({ page }) => {
|
||||
const row = page.locator(`[data-message-id="${OWN_MESSAGE_ID}"]`);
|
||||
await expect(row).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
await openMoreActionsMenu(page, OWN_MESSAGE_ID);
|
||||
await page.getByTestId(`edit-message-${OWN_MESSAGE_ID}`).click();
|
||||
await expect(page.getByTestId("edit-target")).toBeVisible({ timeout: 5_000 });
|
||||
const input = page.getByTestId("message-input");
|
||||
await expect(input).not.toBeEmpty({ timeout: 5_000 });
|
||||
const editedContent = `Edited, not deleted ${Date.now()}`;
|
||||
|
||||
await input.click();
|
||||
await page.keyboard.press("ControlOrMeta+A");
|
||||
await page.keyboard.type(editedContent);
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
// No delete confirmation, edit mode exits, the row survives with new text.
|
||||
await expect(page.getByRole("alertdialog")).toHaveCount(0);
|
||||
await expect(page.getByTestId("edit-target")).toBeHidden({ timeout: 10_000 });
|
||||
await expect(row).toBeVisible();
|
||||
await expect(page.getByTestId("message-timeline")).toContainText(
|
||||
editedContent,
|
||||
);
|
||||
await expect(page.getByTestId("message-timeline")).not.toContainText(
|
||||
ORIGINAL_CONTENT,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user