puppeteer: Unable to intercept FileChooser when invoked from window.chooseFileSystemEntries

This is both an issue with puppeteer and Chromium. I am raising an issue here in the hope that it gets more eyes than in the Chromium issue tracker.

Steps to reproduce

Tell us about your environment:

  • Puppeteer version:2.0.0
  • Chromium: 78.0.3904.70 and 80.0.3982.0
  • Platform / OS version:Ubuntu 4.15.0-45
  • URLs (if applicable):
  • Node.js version:10.16.3

Basically, I am calling window.chooseFileSystemEntries which is a new functionality introduced in Chrome 78 to access the native filesystem. (https://web.dev/native-file-system/). And then I want to intercept the opening of the file dialog, and pass a file path to it.

Unfortunately, the event does not get intercepted. Whereas, it clearly does, when I manually invoke a file opener dialog from an input[type="file"].

I think since this is a bleeding edge feature, perhaps this follows a different code path from inside Chrome, due to which the event handler is unable to intercept it.

What steps will reproduce the problem?

Please include code that reproduces the issue.

HTML file:

<!doctype html>
<html>

<head>
	<meta charset="utf-8">
	<title>File access</title>
</head>

<body>
	<input type="file" name="ff" id="open2">
	<button id="openFile">Open file</button>
	<script>
	document.getElementById("openFile").addEventListener('click', async (e) => {
  	const fileHandle = await window.chooseFileSystemEntries();
  	const file = await fileHandle.getFile();
  	const contents = await file.text();
  	console.log(contents);
	});
	</script>
</body>
</html>

Serve this HTML file using any local web server.

JS Code

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
  	headless: false, 
  	executablePath: '/path/to/chromium_tip',
  	args: [
  		'--flag-switches-begin',
  		'--enable-features=NativeFileSystemAPI',
  		'--flag-switches-end',
  	]
  });
  const page = await browser.newPage();
  await page.goto('http://localhost:8080/file.html');

  const [fileChooser] = await Promise.all([
	  page.waitForFileChooser(),
	  page.click('#openFile'), // trying to #open2 works
	]);
	// await fileChooser.accept(['/home/agniva/Desktop/sticky_note.txt']);
	console.log(fileChooser);
	await page.waitFor(1000);
  await browser.close();
})();

What is the expected result?

There are couple of issues here.

When I click #openFile, the filechooser dialog does not get intercepted at all. I can see the dialog, and after 30 secs, it times out with:

(node:11168) UnhandledPromiseRejectionWarning: TimeoutError: waiting for waiting for file chooser failed: timeout 30000ms exceeded

But if I change it to click #open2, everything works perfectly fine. And fileChooser gets logged properly.

This is a problem with Chromium.

The page.handleFileChooser API is removed from Chromium 80 at https://github.com/chromium/chromium/commit/41361e490363590c21250dfd94554f8200e041f1. So therefore, using fileChooser.accept with Chromium 80 raises an error. This is something to be fixed at puppeteer. The API needs to use the new fields at https://chromedevtools.github.io/devtools-protocol/tot/Page#event-fileChooserOpened to call the https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setFileInputFiles method.

The commit also moved the dialog interception from browser-side to blink-side. I hoped that it will make a difference in intercepting dialogs invoked from window.chooseFileSystemEntries but it does not. The same failure to interception occurs with Chrome 78 too.

/cc @pavelfeldman who made the commit.

For further context: I work on WebAssembly with the Go team. Not being able to read/write files has prevented us from running the Go test suite inside the browser, which has failed to catch several bugs. Currently, we run tests inside Node. But resolving this issue will allow us to run the test suite inside the browser too.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 13
  • Comments: 20

Most upvoted comments

We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it!

This issue still exist and the only fix to this is downgrading to 4 years old chrome ver 78. Please re-open and start investigation to solve

We’re marking this issue as unconfirmed because it has not had recent activity and we weren’t able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

I’m getting

Error: Evaluation failed: TypeError: Failed to fetch
at __puppeteer_evaluation_script__:4:32

somewhere within JSHandle.js.

I assume it tries to upload file. However, the Angular app I’m trying to automate with puppeteer does not do that.

@koresar fileChooser works fine for me with puppeteer 2.0.0 with HeadlessChrome/79.0.3945.0 (wich is part of puppeteer)

Hey all, the original issue was about FileChooser not being intercepted if invoked from window.chooseFileSystemEntries. FileChooser not working at all is a regression in puppeteer which got fixed at tip recently. Let’s keep this thread on track 😃