Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core(driver): wait for Page.frameNavigated for about:blank #6446

Merged
merged 3 commits into from
Nov 2, 2018

Conversation

patrickhulce
Copy link
Collaborator

@patrickhulce patrickhulce commented Nov 1, 2018

Summary
I'll want to put this through the DZL wringer and maybe someone sanity check this with the DevTools folks, but it seems like we should be able to just wait for the frameNavigated event instead of 300ms all the time.

On my machine it drives down about:blank times from...

300ms -> 200ms
300ms -> 16ms
300ms -> 14ms

If this gets cursory 👍 I'll remove references to blankDuration elsewhere, or we can keep it but just update the minimum to be 0

Related Issues/PRs
#6442

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I remember seeing frameNavigated as a reliable indicator here.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove references to blankDuration elsewhere

love this, let's do it :)

I guess we'll want to test this over a variety of types of pages (similar to what caught the data URL issue) to make sure we're good here? If only we had a runner in the works for that :)

No idea what problems we could possibly run into, though...maybe things like evaluateScriptOnNewDocument might have difficulty?

* @return {Promise<void>}
*/
static async loadBlank(
driver,
url = constants.defaultPassConfig.blankPage,
duration = constants.defaultPassConfig.blankDuration
url = constants.defaultPassConfig.blankPage
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this go back to being one line now :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep! 🎉

@@ -843,6 +854,10 @@ class Driver {
this.setNextProtocolTimeout(30 * 1000);
this.sendCommand('Page.navigate', {url});

if (waitForNavigated) {
await this._waitForFrameNavigated();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any concerns about racing here? i.e. should we get the promise before Page.navigate and then await it here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, any concerns about delaying _waitForFullyLoaded until after Page.frameNavigated fires?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dgozman convinced me that so long as the listener is attached synchronously (which it is inside this._waitForFrameNavigated), it is impossible for the event to be received too early.

Longer explanation was that the earliest possible resolution of the promise would be the next microtask and because the listener is installed before that microtask is executed there's no way to miss the event

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, any concerns about delaying _waitForFullyLoaded until after Page.frameNavigated fires?

definitely, they should not be used together I'll add a throw

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dgozman convinced me that so long as the listener is attached synchronously (which it is inside this._waitForFrameNavigated), it is impossible for the event to be received too early.

yeahhhh, good point. As long as no one sticks an await in front of that sendCommand, I guess?

* @return {Promise<void>}
*/
static async loadBlank(
driver,
url = constants.defaultPassConfig.blankPage,
duration = constants.defaultPassConfig.blankDuration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget when we've actually used a different blankDuration. Was it just for tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests and once upon a time WPT used it for video recording, but for past year or so he's just run LH straight outta the box

https://github.com/WPO-Foundation/wptagent/blob/14d8c49e3139625fd31fa12efd6a3ab7632dd323/internal/devtools_browser.py#L466-L476

Copy link
Member

@exterkamp exterkamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

I'm kind of surprised our tests just work. Do any of them slow significantly? I was afraid it was going to take firing some synthetic Page.frameNavigated events to make the mocks work the sme

@@ -843,6 +843,10 @@ class Driver {
const passContext = /** @type {Partial<LH.Gatherer.PassContext>} */ (options.passContext || {});
const disableJS = passContext.disableJavaScript || false;

if (waitForNavigated && waitForLoad) {
throw new Error('Cannot use both waitForNavigated and waitForLoad, pick just one');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆

* Used for detecting that our about:blank reset has been completed.
*/
_waitForFrameNavigated() {
return new Promise(resolve => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at some point we should add a driver method that wraps once with a promise. Seems like a lot of our uses of it end up like this

@paulirish paulirish merged commit 394468b into master Nov 2, 2018
@paulirish paulirish deleted the blank_calls branch November 2, 2018 19:43
@patrickhulce patrickhulce mentioned this pull request Nov 21, 2018
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants