inputfile-uploadelectronplaywrightplaywright-test

Playwright upload file on non-input element


So I'm currently trying to automate uploading a profile photo on an Electron App using Playwright and I'm running into issues with 'filechooser' event.

 await windowA.click('data-testid');

  const [fileChooser] = await Promise.all([
    windowA.waitForEvent('filechooser'),
    // windowA.locator('text=Edit').click(),
    windowA.waitForTimeout(3000),

    windowA.locator(selector).click(),
  ]);

The element used to upload a photo isn't an input type so I'm using

   await fileChooser.setFiles(
    [filepath],
    { timeout: 1000 }
   );

The issue is trying to get playwright to select an image from the input dialog box that pops up and it just won't select any files. I've also been trying to get playwright to select an image in my fixtures folder, which is in a relative path to the test, but haven't had success in either case.

The error that Playwright is displaying is

page.waitForEvent: Timeout while waiting for event "filechooser"

waiting for event "filechooser"

Any know what the issue is?


Solution

  • If you are using the window.showOpenFilePicker() to get a file from the user, you won't get the filechooser event at all. This is because internally, the showOpenFilePicker is not triggering an event as it is still a WIP.

    More info can be found in playwright issue #8850 but I don't think there is a workaround for now. (Pupetter actually has the same issue)

    One fix would be to not use the showOpenFilePicker() at all, but instead rely on the <input> element to gather the file. This is a bit more cumbersome for the dev but is more supported and should trigger the filechooser event.

    Another fix could be to add a function you can override when running in test mode for it to not even need to open the file chooser, something like:

    const getFileFromPicker = () => { 
      if(!isRunningInTest) { 
        // do the showOpenFilePicker logic as usual in the app
        // and the user will need to choose a file from it
      } else {
        // provide synchronously a buffer to use as file content,
        // and so do not even show the picker to the testing user.
      }
    }