diff --git a/e2e-tests/attach_image.spec.ts b/e2e-tests/attach_image.spec.ts index 6ff887f..219bd36 100644 --- a/e2e-tests/attach_image.spec.ts +++ b/e2e-tests/attach_image.spec.ts @@ -1,4 +1,5 @@ import { test } from "./helpers/test_helper"; +import * as fs from "fs"; // attach image is implemented in two separate components // - HomeChatInput @@ -20,6 +21,7 @@ test("attach image - chat", async ({ po }) => { await po.setUp({ autoApprove: true }); await po.sendPrompt("basic"); + // attach via file input (click-to-upload) await po .getChatInputContainer() .locator("input[type='file']") @@ -28,3 +30,41 @@ test("attach image - chat", async ({ po }) => { await po.snapshotServerDump({ onlyLastMessage: true }); await po.snapshotMessages({ replaceDumpPath: true }); }); + +// attach image via drag-and-drop to chat input container +test("attach image via drag - chat", async ({ po }) => { + await po.setUp({ autoApprove: true }); + await po.sendPrompt("basic"); + // read fixture and convert to base64 for browser context + const fileBase64 = fs.readFileSync( + "e2e-tests/fixtures/images/logo.png", + "base64", + ); + // locate the inner drop target (first child div of the container) + const dropTarget = po.getChatInputContainer().locator("div").first(); + // simulate dragenter, dragover, and drop with a File + await dropTarget.evaluate((element, fileBase64) => { + // convert base64 to Uint8Array + const binary = atob(fileBase64); + const len = binary.length; + const array = new Uint8Array(len); + for (let i = 0; i < len; i++) array[i] = binary.charCodeAt(i); + // create file and dataTransfer + const blob = new Blob([array], { type: "image/png" }); + const file = new File([blob], "logo.png", { type: "image/png" }); + const dt = new DataTransfer(); + dt.items.add(file); + // dispatch drag events + ["dragenter", "dragover", "drop"].forEach((eventType) => { + element.dispatchEvent( + new DragEvent(eventType, { dataTransfer: dt, bubbles: true }), + ); + }); + }, fileBase64); + + // submit and verify + await po.sendPrompt("[dump]"); + // Note: this should match EXACTLY the server dump from the previous test. + await po.snapshotServerDump({ onlyLastMessage: true }); + await po.snapshotMessages({ replaceDumpPath: true }); +}); diff --git a/e2e-tests/helpers/test_helper.ts b/e2e-tests/helpers/test_helper.ts index 3eadb98..870cf7d 100644 --- a/e2e-tests/helpers/test_helper.ts +++ b/e2e-tests/helpers/test_helper.ts @@ -245,6 +245,10 @@ class PageObject { await closeButtons.nth(i).click(); } } + + async sleep(ms: number) { + await new Promise((resolve) => setTimeout(resolve, ms)); + } } // From https://github.com/microsoft/playwright/issues/8208#issuecomment-1435475930 diff --git a/e2e-tests/snapshots/attach_image.spec.ts_attach-image-via-drag---chat-1.aria.yml b/e2e-tests/snapshots/attach_image.spec.ts_attach-image-via-drag---chat-1.aria.yml new file mode 100644 index 0000000..7b84ebe --- /dev/null +++ b/e2e-tests/snapshots/attach_image.spec.ts_attach-image-via-drag---chat-1.aria.yml @@ -0,0 +1,25 @@ +- paragraph: basic +- 'button "Thinking `<dyad-write>`: I''ll think about the problem and write a bug report. <dyad-write> <dyad-write path=\"file1.txt\"> Fake dyad write </dyad-write>"': + - img + - img + - paragraph: + - code: "`<dyad-write>`" + - text: ": I'll think about the problem and write a bug report." + - paragraph: <dyad-write> + - paragraph: <dyad-write path="file1.txt"> Fake dyad write </dyad-write> +- img +- text: file1.txt +- img +- text: file1.txt +- paragraph: More EOM +- img +- text: Approved +- paragraph: "[dump]" +- paragraph: "Attachments:" +- list: + - listitem: logo.png (image/png) +- paragraph: "[[dyad-dump-path=*]]" +- img +- text: Approved +- button "Retry": + - img \ No newline at end of file