fix(Navigation): correctly wait for navigation in Page.goto (#1355)

This patch:
- starts persisting lifecycle state for every frame
- migrates NavigationWatcher to rely on these lifecycle events
- refactors Page.goto to properly return navigation errors

Fixes #1218.
This commit is contained in:
Andrey Lushnikov
2017-11-10 15:33:14 -08:00
committed by GitHub
parent 9b907b9ada
commit 44d1e834a4
4 changed files with 128 additions and 73 deletions

View File

@@ -41,10 +41,22 @@ class FrameManager extends EventEmitter {
this._client.on('Page.frameNavigated', event => this._onFrameNavigated(event.frame));
this._client.on('Page.frameDetached', event => this._onFrameDetached(event.frameId));
this._client.on('Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context));
this._client.on('Page.lifecycleEvent', event => this._onLifecycleEvent(event));
this._handleFrameTree(frameTree);
}
/**
* @param {!Object} event
*/
_onLifecycleEvent(event) {
const frame = this._frames.get(event.frameId);
if (!frame)
return;
frame._onLifecycleEvent(event.loaderId, event.name);
this.emit(FrameManager.Events.LifecycleEvent, frame);
}
/**
* @param {{frame: Object, childFrames: ?Array}} frameTree
*/
@@ -171,20 +183,14 @@ class FrameManager extends EventEmitter {
this._frames.delete(frame._id);
this.emit(FrameManager.Events.FrameDetached, frame);
}
/**
* @return {?string}
*/
unreachableMainFrameURL() {
return this._mainFrame._unreachableURL || null;
}
}
/** @enum {string} */
FrameManager.Events = {
FrameAttached: 'frameattached',
FrameNavigated: 'framenavigated',
FrameDetached: 'framedetached'
FrameDetached: 'framedetached',
LifecycleEvent: 'lifecycleevent'
};
/**
@@ -205,6 +211,9 @@ class Frame {
this._context = null;
/** @type {!Set<!WaitTask>} */
this._waitTasks = new Set();
this._loaderId = '';
/** @type {!Set<string>} */
this._lifecycleEvents = new Set();
/** @type {!Set<!Frame>} */
this._childFrames = new Set();
@@ -523,7 +532,18 @@ class Frame {
_navigated(framePayload) {
this._name = framePayload.name;
this._url = framePayload.url;
this._unreachableURL = framePayload.unreachableUrl;
}
/**
* @param {string} loaderId
* @param {string} name
*/
_onLifecycleEvent(loaderId, name) {
if (name === 'init') {
this._loaderId = loaderId;
this._lifecycleEvents.clear();
}
this._lifecycleEvents.add(name);
}
_detach() {