mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
test(desktop): synchronize upload edit smoke test (#7903)
## Summary Fix the upload/edit smoke-test race observed on main at `6410e685a80d42db0645fadc9bbe710559ef911e`. - Hold the mock upload at the Tauri IPC boundary and release it explicitly after checking edit rejection, rather than assuming menu interaction finishes within one second. - Wait for the Radix menu to unmount: edit dispatch happens in `onCloseAutoFocus`, after the click. Without that wait, the negative assertion can pass before the edit callback actually runs. - Keep the existing attachment-preservation and subsequent successful-edit assertions. No production code or CI coverage is changed. ## Evidence and scope - [Main failure](https://github.com/block/buzz/actions/runs/36189213149/job/108250341388): `opening edit during an immediate photo upload preserves the draft`, including an upload-progress timeout on retry. - Investigated from #7791, which changes only `docs/nips/NIP-AR.md`. Its PostgreSQL failures and video-menu timeout are separate; PostgreSQL passed on this main run, and the video spec passed locally. This PR does not claim to fix those failures or the separate pointer-interception failure seen in the main job. - #7843 already addresses unrelated runtime suites being selected for docs-only PRs. ## Validation - Full desktop `pnpm test`: 6,676 Node tests + 92 jsdom tests passed. - Upload/edit regression repeated 5 times: passed. Holding the upload without waiting for menu teardown failed all 5 runs, demonstrating the second race. - Complete file-attachment and video-attachment Playwright specs: 30 passed. - Pre-push desktop lint, typecheck, full desktop tests, and file-size gate passed at `46e3d4392e5b56dcb74ea864aa19aa10287f27d3`. - `just ci` attempted: initial formatting issue corrected; second run exceeded the 5-minute local limit during Tauri clippy. Not claiming full repository CI green. ## Review / human verification Self-reviewed the diff against the test contract; no production behavior changes. Draft pending human verification and CI. To verify: activate Hermit, then `cd desktop && pnpm test:e2e:smoke file-attachment.spec.ts --grep "opening edit during" --repeat-each=5`. Expect all five runs to pass, retaining the upload in the draft and allowing edit only after upload release. Originating conversation: buzz://message?channel=aa7f2b48-d367-4ca1-be09-116a2eb45b99&id=1b68585ba4483a87f5a453fd7bbdd11d434e332dcb4aff8acfe1f5d2601b6561 Signed-off-by: Smartie <fb3185faacfc3760b6b4fe0085a8878d8dd537f7a7671c7d3184fe1aa1b04df4@buzz.block.builderlab.xyz> Co-authored-by: Smartie <fb3185faacfc3760b6b4fe0085a8878d8dd537f7a7671c7d3184fe1aa1b04df4@buzz.block.builderlab.xyz>
This commit is contained in:
@@ -166,25 +166,49 @@ test("opening edit during an immediate photo upload preserves the draft", async
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/");
|
||||
await page.evaluate(() => {
|
||||
const e2e = (
|
||||
window as Window & {
|
||||
__BUZZ_E2E__?: { mock?: { uploadDelayMs?: number } };
|
||||
}
|
||||
).__BUZZ_E2E__;
|
||||
if (e2e?.mock) e2e.mock.uploadDelayMs = 1_000;
|
||||
});
|
||||
await page.getByTestId("channel-general").click();
|
||||
await expect(page.getByTestId("chat-title")).toHaveText("general");
|
||||
// Hold the upload at the IPC boundary until the edit assertion completes.
|
||||
// A fixed delay races menu interaction and CI scheduling, so it can test
|
||||
// an already-completed upload instead of the in-flight draft guard.
|
||||
await page.evaluate(() => {
|
||||
const w = window as Window & {
|
||||
__RELEASE_PHOTO_UPLOAD__?: () => void;
|
||||
__TAURI_INTERNALS__: {
|
||||
invoke: (
|
||||
command: string,
|
||||
payload: unknown,
|
||||
options: unknown,
|
||||
) => Promise<unknown>;
|
||||
};
|
||||
};
|
||||
const original = w.__TAURI_INTERNALS__.invoke.bind(w.__TAURI_INTERNALS__);
|
||||
const gate = new Promise<void>((resolve) => {
|
||||
w.__RELEASE_PHOTO_UPLOAD__ = resolve;
|
||||
});
|
||||
w.__TAURI_INTERNALS__.invoke = async (command, payload, options) => {
|
||||
if (command === "upload_media_bytes_raw") await gate;
|
||||
return original(command, payload, options);
|
||||
};
|
||||
});
|
||||
await choosePhoto(page);
|
||||
await expect(page.getByTestId("upload-progress")).toBeVisible();
|
||||
|
||||
await openMoreActionsMenu(page, "mock-general-welcome");
|
||||
await page.getByTestId("edit-message-mock-general-welcome").click();
|
||||
// Edit is dispatched by onCloseAutoFocus after Radix unmounts the menu,
|
||||
// not by the click itself. Keep the upload held through that handoff.
|
||||
await expect(page.getByRole("menu")).toHaveCount(0);
|
||||
|
||||
// Edit entry is rejected while the compacted draft cannot represent the
|
||||
// reserved upload slot. The upload remains current and lands in the draft.
|
||||
await expect(page.getByTestId("edit-target")).toHaveCount(0);
|
||||
await expect(page.getByTestId("upload-progress")).toBeVisible();
|
||||
await page.evaluate(() => {
|
||||
(
|
||||
window as Window & { __RELEASE_PHOTO_UPLOAD__: () => void }
|
||||
).__RELEASE_PHOTO_UPLOAD__();
|
||||
});
|
||||
await expect(page.getByTestId("upload-progress")).toHaveCount(0, {
|
||||
timeout: 5_000,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user