Search code examples
javascripttypescriptfile-uploaddrag-and-dropplaywright

How to drag a file to a drag-zone input element using Playwright


I have a drag-zone input element for uploading files, and I'm looking for a way to simulate this action using Playwright and TS. I need to upload many file types such as txt, json, png.

enter image description here

there is not any mention to this action in Playwright docs.


Solution

  • Here is a solution I've found on this Playwright issue on GitHub

    import { Page } from '@playwright/test';
    import { readFileSync } from 'fs';
    
    const dragAndDropFile = async (
      page: Page,
      selector: string,
      filePath: string,
      fileName: string,
      fileType = ''
    ) => {
      const buffer = readFileSync(filePath).toString('base64');
    
      const dataTransfer = await page.evaluateHandle(
        async ({ bufferData, localFileName, localFileType }) => {
          const dt = new DataTransfer();
    
          const blobData = await fetch(bufferData).then((res) => res.blob());
    
          const file = new File([blobData], localFileName, { type: localFileType });
          dt.items.add(file);
          return dt;
        },
        {
          bufferData: `data:application/octet-stream;base64,${buffer}`,
          localFileName: fileName,
          localFileType: fileType,
        }
      );
    
      await page.dispatchEvent(selector, 'drop', { dataTransfer });
    };
    

    Usage Example: (using this demo-site)

    test("simulate drag and drop file", async ({ page }) => {
      await page.goto("https://www.dragdrop.com/test/");
      await dragAndDropFile(page, "#demo-upload", "./image1.png", "image1");
    });