Handle beforeunload dialogs by implementing Page.handleJavaScriptDialog and Page.javascriptDialogOpening
Categories
(Remote Protocol :: CDP, enhancement, P1)
Tracking
(Not tracked)
People
(Reporter: ochameau, Assigned: jdescottes)
References
Details
Attachments
(1 file, 9 obsolete files)
When the test page registers a beforeunload
event, a confirmation dialog appears whenever we navigates away from the current document. As a side effect, various APIs ends up being blocked and freeze JS execution call synchronously (for example docshell.loadURI
and docshell.reload
will freeze).
It looks like Puppeteer/chromium doesn't disable them.
Instead, there is some API to know when a dialog is emitted and another one to control the dialogs.
Here is how Wordpress test suite handles these dialogs:
https://github.com/WordPress/gutenberg/blob/master/packages/e2e-test-utils/src/enable-page-dialog-accept.js#L7-L14
This ends up relying on the two following CDP method and event:
https://chromedevtools.github.io/devtools-protocol/tot/Page#method-handleJavaScriptDialog
Page.handleJavaScriptDialog
Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).
https://chromedevtools.github.io/devtools-protocol/tot/Page#event-javascriptDialogOpening
Page.javascriptDialogOpening
Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.
Comment 1•6 years ago
|
||
It would be better if Puppeteer would prevent these from opening
in the first place, as it seems like a decently sized footgun to
push the responsibility of manually handling UA specific chrome-level
popup dialogues on to the user.
In any case, I suppose setting dom.disable_beforeunload
will help
you circumvent this problem if you don’t want to implement
Page.handleJavaScriptDialog
and Page.javascriptDialogOpening
right now.
I hope this helps.
Reporter | ||
Comment 2•6 years ago
|
||
(In reply to Andreas Tolfsen ⦗:ato⦘ from comment #1)
It would be better if Puppeteer would prevent these from opening
in the first place, as it seems like a decently sized footgun to
push the responsibility of manually handling UA specific chrome-level
popup dialogues on to the user.In any case, I suppose setting
dom.disable_beforeunload
will help
you circumvent this problem if you don’t want to implement
Page.handleJavaScriptDialog
andPage.javascriptDialogOpening
right now.
Well, that's what I did locally to make some progress on getting the test greener.
We may do if we want to ignore that API for now.
But I'm not convinced that's what we should do in the long run as Puppeteer:
- exposes an API to know about and control these dialogs (I imagine that setting this pref will prevent implementing this API?),
- do not try to disable these dialogs.
You can see puppeteer's test against this API here:
https://github.com/GoogleChrome/puppeteer/blob/e3abb0aa32e38660abffad22d6446473be4b13cd/test/page.spec.js#L54-L64
Now, if you feel Puppeteer shouldn't do that, we should propobly open an issue against Puppeteer?
Comment 3•6 years ago
|
||
Indeed, in the long run I don’t see it as a viable option to ignore
a deployed, user-facing API.
Since it is relatively easy for us to support this API, I don’t
feel like making a case for its removal from Puppeteer for no better
reason than “API cleanliness”.
Updated•6 years ago
|
Updated•6 years ago
|
Reporter | ||
Comment 4•6 years ago
|
||
Actually, there is various other tests that depend on this, but for regular dialogs: alert() and prompt().
For example, the two following tests are dismissing one prompt and an alert:
https://github.com/WordPress/gutenberg/blob/master/packages/e2e-tests/specs/change-detection.test.js#L30-L39
https://github.com/WordPress/gutenberg/blob/master/packages/e2e-tests/specs/reusable-blocks.test.js#L13-L17
Reporter | ||
Comment 5•6 years ago
|
||
Here is a few example of tests mocking the prompts:
https://searchfox.org/mozilla-central/source/toolkit/components/search/tests/xpcshell/test_addEngine_callback.js#12-25
https://searchfox.org/mozilla-central/source/toolkit/mozapps/extensions/test/browser/head.js#1490-1503
https://searchfox.org/mozilla-central/source/browser/base/content/test/general/browser_bug356571.js#8-35
I'm wondering if there is something more lightweight, integrated into browser frontend?
Assignee | ||
Updated•6 years ago
|
Assignee | ||
Updated•6 years ago
|
Assignee | ||
Comment 6•5 years ago
|
||
Just an example patch that notifies the page when an alert appears and knows how to close dialogs as well.
Assignee | ||
Comment 7•5 years ago
|
||
Can I get your opinion on the WIP at https://phabricator.services.mozilla.com/D34931 ?
The approach I took here was to listen to dialog events and to allow to interact with the dialog, rather than mocking it.
In terms of interaction for now it only supports closing the dialog.
I had to listen to the events in the parent process. I initially wanted to attach the listeners in the parent page domain, but since it is lazily instantiated, I can't do that. That's why I used the TabSession for now.
Let me know what you think
Reporter | ||
Comment 8•5 years ago
|
||
(In reply to Julian Descottes [:jdescottes] from comment #7)
Can I get your opinion on the WIP at https://phabricator.services.mozilla.com/D34931 ?
Sorry for not getting back to you sooner, I completely ignored this feedback request (I now tend to only look at phabricator).
The approach I took here was to listen to dialog events and to allow to interact with the dialog, rather than mocking it.
I can only agree with that. The mocking done by tests are a pure nightmare. I didn't knew there was existing event to listen for dialogs.
It would be great to have a review from the peers maitaining this code for the additional tweaks.
We may want to expose high level API in order to prevent manipulating DOM elements directly from /remote/ codebase.
I had to listen to the events in the parent process. I initially wanted to attach the listeners in the parent page domain, but since it is lazily instantiated, I can't do that. That's why I used the TabSession for now.
These Page.javascriptDialogOpening
events should only be emitted when Page.enable
is called.
So you should be able to register the listener from this method.
So far, I've not seen any Domain emitting events before its related enable
method is called.
Assignee | ||
Comment 9•5 years ago
|
||
Assignee | ||
Comment 10•5 years ago
|
||
Depends on D36623
Very WIP. All domains are now parent domains by default.
Added a ParentProcessDomain base class. The parent domain is now responsible for checking if the method should be called on parent domain or on content domain.
Detection of unsupported methods slightly regressed here to simplify things. Also don't detect missing content domains at the moment.
Assignee | ||
Comment 11•5 years ago
|
||
Depends on D36625
Not actually related to 1545724, should be 1562740, just here to illustrate usage of parent->content domain communication
Assignee | ||
Comment 12•5 years ago
|
||
Depends on D36625
Updated•5 years ago
|
Updated•5 years ago
|
Comment 13•5 years ago
|
||
Comment on attachment 9075412 [details]
Bug 1545724 - Wait for key event in the content and wait for next tick
Revision D36626 was moved to bug 1562740. Setting attachment 9075412 [details] to obsolete.
Assignee | ||
Comment 14•5 years ago
|
||
Depends on D36626
In theory the mochitest no longer needs to wait for so many events
Assignee | ||
Comment 15•5 years ago
|
||
Depends on D36727
Comment 16•5 years ago
|
||
Comment on attachment 9075605 [details]
Bug 1545724 - Simplify dispatchKeyEvent test and stop waiting for content events in the test
Revision D36727 was moved to bug 1562740. Setting attachment 9075605 [details] to obsolete.
Comment 17•5 years ago
|
||
Comment on attachment 9075606 [details]
Bug 1545724 - Add test for race condition when using dispatchKeyEvent
Revision D36728 was moved to bug 1562740. Setting attachment 9075606 [details] to obsolete.
Assignee | ||
Comment 18•5 years ago
|
||
Hi Gijs,
I just added a question for you related to CommonDialog.jsm on https://phabricator.services.mozilla.com/D36678#inline-222164,
Thanks!
Assignee | ||
Comment 20•5 years ago
|
||
Depends on D36625
Support all dialog types, only works with tabmodal dialogs.
No change needed in CommonDialog.
Assignee | ||
Comment 21•5 years ago
|
||
Depends on D37000
Tests for all supported javascript dialogs (alert, confirm, prompt and beforeunload)
Updated•5 years ago
|
Assignee | ||
Comment 22•5 years ago
|
||
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 23•5 years ago
|
||
Comment 24•5 years ago
|
||
bugherder |
Updated•5 years ago
|
Updated•4 years ago
|
Description
•