From 1aa0128d4e068243a76cd227a52694e4b4896ea1 Mon Sep 17 00:00:00 2001 From: vishwajeet-13 Date: Tue, 8 Sep 2026 00:35:51 +0530 Subject: [PATCH] test(e2e): stop paste-upload test depending on navigator.clipboard.readText CI serves the app from http://vms.test:8000, which is not a secure context, so navigator.clipboard is undefined and the readText() call threw. The app's own copy path already falls back to a textarea, so the copied link was never observable through the async clipboard API here. Capture what the app writes instead: stub navigator.clipboard.writeText (or define it when missing) before navigation and read the recorded value. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01N6kPRDGo6QbcVcc8DPkMTf --- e2e/tests/paste-upload.spec.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/e2e/tests/paste-upload.spec.ts b/e2e/tests/paste-upload.spec.ts index 14ae090..52668cd 100644 --- a/e2e/tests/paste-upload.spec.ts +++ b/e2e/tests/paste-upload.spec.ts @@ -55,7 +55,22 @@ test.describe("Paste to upload", () => { page, context, }) => { - await context.grantPermissions(["clipboard-read", "clipboard-write"]); + // Headless CI exposes no readable clipboard, so capture what the app writes. + await page.addInitScript(() => { + const store = window as unknown as { __lastCopy?: string }; + const record = (text: string) => { + store.__lastCopy = text; + return Promise.resolve(); + }; + if (navigator.clipboard) { + navigator.clipboard.writeText = record; + } else { + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: { writeText: record }, + }); + } + }); await new Shell(page).goto(`/vms/projects/${projectName}`); await pasteFile(page, { @@ -74,7 +89,9 @@ test.describe("Paste to upload", () => { { timeout: 30000 }, ); - const copied = await page.evaluate(() => navigator.clipboard.readText()); + const copied = await page.evaluate( + () => (window as unknown as { __lastCopy?: string }).__lastCopy ?? "", + ); expect(copied).toMatch(/\/vms\/review\/[^?]+\?token=\w+$/); // The link is public, so it opens without a session.