This patch:
- adds Mouse class which holds mouse state and implements mouse primitives,
such as moving, button down and button up.
- implements high-level mouse api, such as `page.click` and `page.hover`.

References #40, References #89
This commit is contained in:
JoelEinbinder
2017-07-21 20:29:31 -07:00
committed by Andrey Lushnikov
parent eb2cb67b0e
commit 98ee35655f
17 changed files with 458 additions and 55 deletions

View File

@@ -20,20 +20,23 @@ let helper = require('./helper');
class FrameManager extends EventEmitter {
/**
* @param {!Connection} client
* @param {!Mouse} mouse
* @return {!Promise<!FrameManager>}
*/
static async create(client) {
static async create(client, mouse) {
let mainFramePayload = await client.send('Page.getResourceTree');
return new FrameManager(client, mainFramePayload.frameTree);
return new FrameManager(client, mainFramePayload.frameTree, mouse);
}
/**
* @param {!Connection} client
* @param {!Object} frameTree
* @param {!Mouse} mouse
*/
constructor(client, frameTree) {
constructor(client, frameTree, mouse) {
super();
this._client = client;
this._mouse = mouse;
/** @type {!Map<string, !Frame>} */
this._frames = new Map();
this._mainFrame = this._addFramesRecursively(null, frameTree);
@@ -405,6 +408,39 @@ class Frame {
return this._frameManager._evaluateOnFrame(this, expression);
}
/**
* @param {string} selector
* @return {!Promise}
*/
async hover(selector) {
let center = await this.evaluate(selector => {
let element = document.querySelector(selector);
if (!element)
return null;
element.scrollIntoViewIfNeeded();
let rect = element.getBoundingClientRect();
return {
x: (rect.left + rect.right) / 2,
y: (rect.top + rect.bottom) / 2
};
}, selector);
if (!center)
throw new Error('No node found for selector: ' + selector);
await this._frameManager._mouse.move(center.x, center.y);
}
/**
* @param {string} selector
* @param {!Object=} options
* @return {!Promise}
*/
async click(selector, options) {
await this.hover(selector);
await this._frameManager._mouse.press(options);
// This is a hack for now, to make clicking less race-prone
await this.evaluate(() => new Promise(f => requestAnimationFrame(f)));
}
/**
* @param {?Object} framePayload
*/