microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.23k stars 3.7k forks source link

[BUG] filechooser event not raised when using window.showOpenFilePicker #8850

Open davdiv opened 3 years ago

davdiv commented 3 years ago

Context:

Code Snippet

const { chromium } = require("playwright");

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto("https://davdiv.github.io/playwright-filechooser-issue/");
  // Note: it does not fail if we force to fallback to <input type="file"> with this:
  // await page.evaluate("window.showOpenFilePicker = null");
  console.log(
    "has window.showOpenFilePicker =",
    await page.evaluate("!!window.showOpenFilePicker")
  );
  const [fileChooser] = await Promise.all([
    page.waitForEvent("filechooser"),
    page.click("text=Open a file"),
  ]);
  console.log("Success!");
  // ... fileChooser.setFiles(/*...*/) ...
  await page.close();
})();

Describe the bug

If a web page uses window.showOpenFilePicker (such as, for example, this sample web page: https://davdiv.github.io/playwright-filechooser-issue/), it is not possible to test it with playwright, because the filechooser event is never raised. When not using headless mode, the file chooser dialog is visible and blocks the test.

The above code snippet never reaches the Success! log, unless we fall back to <input type="file"> instead of window.showOpenFilePicker.

pavelfeldman commented 3 years ago

This feature is not standard, has not been shipped outside Chromium. Our experience suggests that it can disappear at any moment via Blink's Intent to deprecate and remove. I'll leave it open to collect upvotes, but we won't be working on it right away.

oeway commented 3 years ago

+1 for supporting this important feature. It is a game changer for many web apps that operate files. For example, we are running the browser on the server side, being able to control the file chooser will make a total difference since it means our web apps can directly write to disk instead of trigger a download.

It is true that Chromium and other browsers has been trying different file access api and ended up in deprecation, but this time they seems to put much more efforts into the design, it passed the original trial and developers are positive. It seems also they want to push it as a W3C standard: https://wicg.github.io/file-system-access/.

amunhoz commented 3 years ago

It seems it does not support every situation when the filechooser is activated. Same problem here with firefox + linux + latest playwright version + no headless.

You can test in this website (go to demo): https://pqina.nl/filepond/

DaleLuce commented 2 years ago

+1

pontusnyman commented 2 years ago

+1

pontusnyman commented 1 year ago

How is it going with this bug?

dh0d commented 1 year ago

is there a chance this bug will be fixed?

NathanGostelowGlobal commented 1 year ago

Looks like showOpenFilePicker is going to no longer be experimental. is there any plans to support this?
https://wicg.github.io/file-system-access/

tokeeffe9 commented 1 year ago

Any update on if this will be looked in to? All the upload file components have been updated to react dropzone on a project I'm working on. Looking into alternative solutions until window.showOpenFilePicker is supported

fibonacid commented 11 months ago

If anyone is having problems with this when using react-dropzone I recommend doing this workaround:

  useDropzone({
    useFsAccessApi: false, // playwright event doesn't work with this
  });
antonelapisciolari commented 6 months ago

+1

Raven0uss commented 3 months ago

Do we have any updates regarding that issue ? Triggering a hidden input type file instead of clicking on the button which triggers it doesn't reflect the real user behavior.

A workaround I did is to simulate click on the element with trial option to be sure that the button is stable and clickable. Then targeting the hidden input and set the file :

    await page.getByTestId('upload_button').click({ trial: true });
    // Fill the image manually throught the input
    await page.getByTestId('upload_hidden_input').setInputFiles('file.jpg');

Using that in a Promise and resolve with a isVisible from the expected element after upload make the trick to know if the element has been load successfully. However it is still not expected solution since we are not using showOpenFilePicker.