From 8f74cc8a9010aefc64118dd0822b94c0169f0aa4 Mon Sep 17 00:00:00 2001 From: JoelEinbinder Date: Tue, 29 Aug 2017 14:13:38 -0700 Subject: [PATCH] [api] Add "step" option to mouse.move method (#601) This patch adds "step" option to the mouse.move method, that optionally tweens mouse movement over multiple steps. References #423. --- docs/api.md | 6 ++++-- lib/Input.js | 20 +++++++++++++------- test/test.js | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/api.md b/docs/api.md index 7b84407e..edd1c3a3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -79,7 +79,7 @@ * [class: Mouse](#class-mouse) + [mouse.click(x, y, [options])](#mouseclickx-y-options) + [mouse.down([options])](#mousedownoptions) - + [mouse.move(x, y)](#mousemovex-y) + + [mouse.move(x, y, [options])](#mousemovex-y-options) + [mouse.up([options])](#mouseupoptions) * [class: Tracing](#class-tracing) + [tracing.start(options)](#tracingstartoptions) @@ -933,9 +933,11 @@ Shortcut for [`mouse.move`](#mousemovex-y), [`mouse.down`](#mousedownoptions) an Dispatches a `mousedown` event. -#### mouse.move(x, y) +#### mouse.move(x, y, [options]) - `x` <[number]> - `y` <[number]> +- `options` <[Object]> + - `steps` <[number]> defaults to 1. Sends intermediate `mousemove` events. - returns: <[Promise]> Dispatches a `mousemove` event. diff --git a/lib/Input.js b/lib/Input.js index 3a571fdb..623eed38 100644 --- a/lib/Input.js +++ b/lib/Input.js @@ -109,17 +109,23 @@ class Mouse { /** * @param {number} x * @param {number} y + * @param {Object=} options * @return {!Promise} */ - async move(x, y) { + async move(x, y, options = {}) { + const fromX = this._x, fromY = this._y; this._x = x; this._y = y; - await this._client.send('Input.dispatchMouseEvent', { - type: 'mouseMoved', - button: this._button, - x, y, - modifiers: this._keyboard._modifiers - }); + const steps = options.steps || 1; + for (let i = 1; i <= steps; i++) { + await this._client.send('Input.dispatchMouseEvent', { + type: 'mouseMoved', + button: this._button, + x: fromX + (this._x - fromX) * (i / steps), + y: fromY + (this._y - fromY) * (i / steps), + modifiers: this._keyboard._modifiers + }); + } } /** diff --git a/test/test.js b/test/test.js index 868175c5..05ac21ce 100644 --- a/test/test.js +++ b/test/test.js @@ -1472,6 +1472,24 @@ describe('Page', function() { // This await should not hang. await page.click('a'); })); + it('should tween mouse movement', SX(async function() { + await page.evaluate(() => { + window.result = []; + document.addEventListener('mousemove', event => { + window.result.push([event.clientX, event.clientY]); + }); + }); + await page.mouse.move(100, 100); + await page.mouse.move(200, 300, {steps: 5}); + expect(await page.evaluate('result')).toEqual([ + [100, 100], + [120, 140], + [140, 180], + [160, 220], + [180, 260], + [200, 300] + ]); + })); function dimensions() { const rect = document.querySelector('textarea').getBoundingClientRect(); return {