From d5ec1cd27b95e29584897fe681f6801c3cc1371f Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Wed, 30 Aug 2017 17:38:16 -0700 Subject: [PATCH 1/3] Add TouchScreen with tap and swipe --- docs/api.md | 29 +++++++++++++ lib/ElementHandle.js | 9 +++- lib/FrameManager.js | 16 ++++--- lib/Input.js | 56 ++++++++++++++++++++++++- lib/Page.js | 12 +++++- test/assets/input/touches.html | 35 ++++++++++++++++ test/test.js | 18 ++++++++ utils/doclint/check_public_api/index.js | 1 + 8 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 test/assets/input/touches.html diff --git a/docs/api.md b/docs/api.md index de388e2494272..872549574ac1c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -66,6 +66,7 @@ + [page.setUserAgent(userAgent)](#pagesetuseragentuseragent) + [page.setViewport(viewport)](#pagesetviewportviewport) + [page.title()](#pagetitle) + + [page.touchScreen](#pagetouchscreen) + [page.tracing](#pagetracing) + [page.type(text, options)](#pagetypetext-options) + [page.url()](#pageurl) @@ -83,6 +84,9 @@ + [mouse.down([options])](#mousedownoptions) + [mouse.move(x, y, [options])](#mousemovex-y-options) + [mouse.up([options])](#mouseupoptions) + * [class: TouchScreen](#class-touchscreen) + + [touchScreen.swipe(x, y, toX, toY)](#touchscreenswipex-y-tox-toy) + + [touchScreen.tap(x, y)](#touchscreentapx-y) * [class: Tracing](#class-tracing) + [tracing.start(options)](#tracingstartoptions) + [tracing.stop()](#tracingstop) @@ -113,6 +117,7 @@ + [elementHandle.dispose()](#elementhandledispose) + [elementHandle.evaluate(pageFunction, ...args)](#elementhandleevaluatepagefunction-args) + [elementHandle.hover()](#elementhandlehover) + + [elementHandle.tap()](#elementhandletap) + [elementHandle.uploadFile(...filePaths)](#elementhandleuploadfilefilepaths) * [class: Request](#class-request) + [request.abort()](#requestabort) @@ -783,6 +788,9 @@ In the case of multiple pages in a single browser, each page can have its own vi Shortcut for [page.mainFrame().title()](#frametitle). +#### page.touchScreen +- returns: <[TouchScreen]> + #### page.tracing - returns: <[Tracing]> @@ -978,6 +986,20 @@ Dispatches a `mousemove` event. Dispatches a `mouseup` event. +### class: TouchScreen + +#### touchScreen.swipe(x, y, toX, toY) +- `x` <[number]> +- `y` <[number]> +- `toX` <[number]> +- `toY` <[number]> +- returns: <[Promise]> + +#### touchScreen.tap(x, y) +- `x` <[number]> +- `y` <[number]> +- returns: <[Promise]> + ### class: Tracing You can use [`tracing.start`](#tracingstartoptions) and [`tracing.stop`](#tracingstop) to create a trace file which can be opened in Chrome DevTools or [timeline viewer](https://chromedevtools.github.io/timeline-viewer/). @@ -1266,6 +1288,12 @@ The element will be passed as the first argument to `pageFunction`, followed by This method scrolls element into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element. If the element is detached from DOM, the method throws an error. +#### elementHandle.tap() +- returns: <[Promise]> Promise which resolves when the element is successfully tapped. Promise gets rejected if the element is detached from DOM. + +This method scrolls element into view if needed, and then uses [touchScreen.tap](#touchscreentapx-y) to tap in the center of the element. +If the element is detached from DOM, the method throws an error. + #### elementHandle.uploadFile(...filePaths) - `...filePaths` <...[string]> Sets the value of the file input these paths. If some of the `filePaths` are relative paths, then they are resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). - returns: <[Promise]> @@ -1388,3 +1416,4 @@ Contains the URL of the response. [ElementHandle]: #class-elementhandle "ElementHandle" [UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail" [Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable" +[TouchScreen]: #class-touchscreen "TouchScreen" diff --git a/lib/ElementHandle.js b/lib/ElementHandle.js index 697e4a40015aa..7694ea24f6cb4 100644 --- a/lib/ElementHandle.js +++ b/lib/ElementHandle.js @@ -21,11 +21,13 @@ class ElementHandle { * @param {!Connection} client * @param {!Object} remoteObject * @param {!Mouse} mouse + * @param {!TouchScreen} touchScreen; */ - constructor(client, remoteObject, mouse) { + constructor(client, remoteObject, mouse, touchScreen) { this._client = client; this._remoteObject = remoteObject; this._mouse = mouse; + this._touchScreen = touchScreen; this._disposed = false; } @@ -96,6 +98,11 @@ class ElementHandle { const objectId = this._remoteObject.objectId; return this._client.send('DOM.setFileInputFiles', { objectId, files }); } + + async tap() { + const {x, y} = await this._visibleCenter(); + await this._touchScreen.tap(x, y); + } } module.exports = ElementHandle; diff --git a/lib/FrameManager.js b/lib/FrameManager.js index 5e632b038c683..f6bc688100d7a 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -24,11 +24,13 @@ class FrameManager extends EventEmitter { * @param {!Session} client * @param {!Object} frameTree * @param {!Mouse} mouse + * @param {!TouchScreen} touchScreen */ - constructor(client, mouse) { + constructor(client, mouse, touchScreen) { super(); this._client = client; this._mouse = mouse; + this._touchScreen = touchScreen; /** @type {!Map} */ this._frames = new Map(); @@ -62,7 +64,7 @@ class FrameManager extends EventEmitter { return; console.assert(parentFrameId); const parentFrame = this._frames.get(parentFrameId); - const frame = new Frame(this._client, this._mouse, parentFrame, frameId); + const frame = new Frame(this._client, this._mouse, this._touchScreen, parentFrame, frameId); this._frames.set(frame._id, frame); this.emit(FrameManager.Events.FrameAttached, frame); } @@ -89,7 +91,7 @@ class FrameManager extends EventEmitter { frame._id = framePayload.id; } else { // Initial main frame navigation. - frame = new Frame(this._client, this._mouse, null, framePayload.id); + frame = new Frame(this._client, this._mouse, this._touchScreen, null, framePayload.id); } this._frames.set(framePayload.id, frame); this._mainFrame = frame; @@ -154,12 +156,14 @@ class Frame { /** * @param {!Session} client * @param {!Mouse} mouse + * @param {!TouchScreen} touchScreen * @param {?Frame} parentFrame * @param {string} frameId */ - constructor(client, mouse, parentFrame, frameId) { + constructor(client, mouse, touchScreen, parentFrame, frameId) { this._client = client; this._mouse = mouse; + this._touchScreen = touchScreen; this._parentFrame = parentFrame; this._url = ''; this._id = frameId; @@ -190,7 +194,7 @@ class Frame { async $(selector) { const remoteObject = await this._rawEvaluate(selector => document.querySelector(selector), selector); if (remoteObject.subtype === 'node') - return new ElementHandle(this._client, remoteObject, this._mouse); + return new ElementHandle(this._client, remoteObject, this._mouse, this._touchScreen); await helper.releaseObject(this._client, remoteObject); return null; } @@ -225,7 +229,7 @@ class Frame { const releasePromises = [helper.releaseObject(this._client, remoteObject)]; for (const property of properties) { if (property.enumerable && property.value.subtype === 'node') - result.push(new ElementHandle(this._client, property.value, this._mouse)); + result.push(new ElementHandle(this._client, property.value, this._mouse, this._touchScreen)); else releasePromises.push(helper.releaseObject(this._client, property.value)); } diff --git a/lib/Input.js b/lib/Input.js index 8e93e47874cdc..c5c0eb7f8dcb4 100644 --- a/lib/Input.js +++ b/lib/Input.js @@ -169,6 +169,59 @@ class Mouse { } } +class TouchScreen { + /** + * @param {Session} client + * @param {Keyboard} keyboard + */ + constructor(client, keyboard) { + this._client = client; + this._keyboard = keyboard; + } + + /** + * @param {number} x + * @param {number} y + */ + async tap(x, y) { + const touchPoints = [{x: Math.round(x), y: Math.round(y)}]; + await this._client.send('Input.dispatchTouchEvent', { + type: 'touchStart', + touchPoints, + modifiers: this._keyboard._modifiers + }); + await this._client.send('Input.dispatchTouchEvent', { + type: 'touchEnd', + touchPoints: [], + modifiers: this._keyboard._modifiers + }); + } + + /** + * @param {number} x + * @param {number} y + * @param {number} toX + * @param {number} toY + */ + async swipe(x, y, toX, toY) { + await this._client.send('Input.dispatchTouchEvent', { + type: 'touchStart', + touchPoints: [{x: Math.round(x), y: Math.round(y)}], + modifiers: this._keyboard._modifiers + }); + await this._client.send('Input.dispatchTouchEvent', { + type: 'touchMove', + touchPoints: [{x: Math.round(toX), y: Math.round(toY)}], + modifiers: this._keyboard._modifiers + }); + await this._client.send('Input.dispatchTouchEvent', { + type: 'touchEnd', + touchPoints: [], + modifiers: this._keyboard._modifiers + }); + } +} + const keys = { 'Cancel': 3, 'Help': 6, @@ -288,6 +341,7 @@ function codeForKey(key) { return 0; } -module.exports = { Keyboard, Mouse }; +module.exports = { Keyboard, Mouse, TouchScreen}; helper.tracePublicAPI(Keyboard); helper.tracePublicAPI(Mouse); +helper.tracePublicAPI(TouchScreen); diff --git a/lib/Page.js b/lib/Page.js index 90e75373922ff..58144f2433ff7 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -22,7 +22,7 @@ const NavigatorWatcher = require('./NavigatorWatcher'); const Dialog = require('./Dialog'); const EmulationManager = require('./EmulationManager'); const FrameManager = require('./FrameManager'); -const {Keyboard, Mouse} = require('./Input'); +const {Keyboard, Mouse, TouchScreen} = require('./Input'); const Tracing = require('./Tracing'); const helper = require('./helper'); @@ -60,7 +60,8 @@ class Page extends EventEmitter { this._client = client; this._keyboard = new Keyboard(client); this._mouse = new Mouse(client, this._keyboard); - this._frameManager = new FrameManager(client, this._mouse); + this._touchScreen = new TouchScreen(client, this._keyboard); + this._frameManager = new FrameManager(client, this._mouse, this._touchScreen); this._networkManager = new NetworkManager(client); this._emulationManager = new EmulationManager(client); this._tracing = new Tracing(client); @@ -105,6 +106,13 @@ class Page extends EventEmitter { return this._keyboard; } + /** + * @return {!TouchScreen} + */ + get touchScreen() { + return this._touchScreen; + } + /** * @return {!Tracing} */ diff --git a/test/assets/input/touches.html b/test/assets/input/touches.html new file mode 100644 index 0000000000000..4392cfacbd5bb --- /dev/null +++ b/test/assets/input/touches.html @@ -0,0 +1,35 @@ + + + + Touch test + + + + + + + \ No newline at end of file diff --git a/test/test.js b/test/test.js index fb83be8c821d2..f26d99136a6a7 100644 --- a/test/test.js +++ b/test/test.js @@ -1509,6 +1509,24 @@ describe('Page', function() { [200, 300] ]); })); + it('should tap the button', SX(async function() { + await page.goto(PREFIX + '/input/button.html'); + const button = await page.$('button'); + await button.tap(); + expect(await page.evaluate(() => result)).toBe('Clicked'); + })); + it('should report touches', SX(async function() { + await page.goto(PREFIX + '/input/touches.html'); + const button = await page.$('button'); + await button.tap(); + expect(await page.evaluate(() => getResult())).toEqual(['Touchstart: 0', 'Touchend: 0']); + })); + it('should scroll with touch', SX(async function() { + await page.goto(PREFIX + '/input/scrollable.html'); + expect(await page.evaluate('window.scrollY')).toBe(0); + await page.touchScreen.swipe(50, 200, 50, 50); + expect(await page.evaluate('window.scrollY')).toBe(135); + })); function dimensions() { const rect = document.querySelector('textarea').getBoundingClientRect(); return { diff --git a/utils/doclint/check_public_api/index.js b/utils/doclint/check_public_api/index.js index 3d482d44838b6..1d7fcebc2f182 100644 --- a/utils/doclint/check_public_api/index.js +++ b/utils/doclint/check_public_api/index.js @@ -44,6 +44,7 @@ const EXCLUDE_METHODS = new Set([ 'Headers.fromPayload', 'Keyboard.constructor', 'Mouse.constructor', + 'TouchScreen.constructor', 'Tracing.constructor', 'Page.constructor', 'Page.create', From 3f5fee5fb1c08989e7319bfb823dcbe5bafd369a Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Thu, 31 Aug 2017 11:57:40 -0700 Subject: [PATCH 2/3] Remove swipe for now --- docs/api.md | 8 -------- lib/Input.js | 24 ------------------------ test/test.js | 6 ------ 3 files changed, 38 deletions(-) diff --git a/docs/api.md b/docs/api.md index 872549574ac1c..073220163d99f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -85,7 +85,6 @@ + [mouse.move(x, y, [options])](#mousemovex-y-options) + [mouse.up([options])](#mouseupoptions) * [class: TouchScreen](#class-touchscreen) - + [touchScreen.swipe(x, y, toX, toY)](#touchscreenswipex-y-tox-toy) + [touchScreen.tap(x, y)](#touchscreentapx-y) * [class: Tracing](#class-tracing) + [tracing.start(options)](#tracingstartoptions) @@ -988,13 +987,6 @@ Dispatches a `mouseup` event. ### class: TouchScreen -#### touchScreen.swipe(x, y, toX, toY) -- `x` <[number]> -- `y` <[number]> -- `toX` <[number]> -- `toY` <[number]> -- returns: <[Promise]> - #### touchScreen.tap(x, y) - `x` <[number]> - `y` <[number]> diff --git a/lib/Input.js b/lib/Input.js index c5c0eb7f8dcb4..150beb3086d58 100644 --- a/lib/Input.js +++ b/lib/Input.js @@ -196,30 +196,6 @@ class TouchScreen { modifiers: this._keyboard._modifiers }); } - - /** - * @param {number} x - * @param {number} y - * @param {number} toX - * @param {number} toY - */ - async swipe(x, y, toX, toY) { - await this._client.send('Input.dispatchTouchEvent', { - type: 'touchStart', - touchPoints: [{x: Math.round(x), y: Math.round(y)}], - modifiers: this._keyboard._modifiers - }); - await this._client.send('Input.dispatchTouchEvent', { - type: 'touchMove', - touchPoints: [{x: Math.round(toX), y: Math.round(toY)}], - modifiers: this._keyboard._modifiers - }); - await this._client.send('Input.dispatchTouchEvent', { - type: 'touchEnd', - touchPoints: [], - modifiers: this._keyboard._modifiers - }); - } } const keys = { diff --git a/test/test.js b/test/test.js index f26d99136a6a7..1428d82f9157e 100644 --- a/test/test.js +++ b/test/test.js @@ -1521,12 +1521,6 @@ describe('Page', function() { await button.tap(); expect(await page.evaluate(() => getResult())).toEqual(['Touchstart: 0', 'Touchend: 0']); })); - it('should scroll with touch', SX(async function() { - await page.goto(PREFIX + '/input/scrollable.html'); - expect(await page.evaluate('window.scrollY')).toBe(0); - await page.touchScreen.swipe(50, 200, 50, 50); - expect(await page.evaluate('window.scrollY')).toBe(135); - })); function dimensions() { const rect = document.querySelector('textarea').getBoundingClientRect(); return { From e3fbbbee9d70dc353510561d28452370603ac22d Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Fri, 1 Sep 2017 10:08:18 -0700 Subject: [PATCH 3/3] page.tap, touchscreen --- docs/api.md | 28 +++++++++++++++++-------- lib/ElementHandle.js | 8 +++---- lib/FrameManager.js | 20 +++++++++--------- lib/Input.js | 6 +++--- lib/Page.js | 22 +++++++++++++------ test/test.js | 3 +-- utils/doclint/check_public_api/index.js | 2 +- 7 files changed, 54 insertions(+), 35 deletions(-) diff --git a/docs/api.md b/docs/api.md index 073220163d99f..9dd9282e78cb6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -65,8 +65,9 @@ + [page.setRequestInterceptionEnabled(value)](#pagesetrequestinterceptionenabledvalue) + [page.setUserAgent(userAgent)](#pagesetuseragentuseragent) + [page.setViewport(viewport)](#pagesetviewportviewport) + + [page.tap(selector)](#pagetapselector) + [page.title()](#pagetitle) - + [page.touchScreen](#pagetouchscreen) + + [page.touchscreen](#pagetouchscreen) + [page.tracing](#pagetracing) + [page.type(text, options)](#pagetypetext-options) + [page.url()](#pageurl) @@ -84,8 +85,8 @@ + [mouse.down([options])](#mousedownoptions) + [mouse.move(x, y, [options])](#mousemovex-y-options) + [mouse.up([options])](#mouseupoptions) - * [class: TouchScreen](#class-touchscreen) - + [touchScreen.tap(x, y)](#touchscreentapx-y) + * [class: Touchscreen](#class-touchscreen) + + [touchscreen.tap(x, y)](#touchscreentapx-y) * [class: Tracing](#class-tracing) + [tracing.start(options)](#tracingstartoptions) + [tracing.stop()](#tracingstop) @@ -782,13 +783,20 @@ puppeteer.launch().then(async browser => { In the case of multiple pages in a single browser, each page can have its own viewport size. +#### page.tap(selector) +- `selector` <[string]> A [selector] to search for element to tap. If there are multiple elements satisfying the selector, the first will be tapped. +- returns: <[Promise]> + +This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.touchscreen](#pagetouchscreen) to tap in the center of the element. +If there's no element matching `selector`, the method throws an error. + #### page.title() - returns: <[Promise]<[string]>> Returns page's title. Shortcut for [page.mainFrame().title()](#frametitle). -#### page.touchScreen -- returns: <[TouchScreen]> +#### page.touchscreen +- returns: <[Touchscreen]> #### page.tracing - returns: <[Tracing]> @@ -985,13 +993,15 @@ Dispatches a `mousemove` event. Dispatches a `mouseup` event. -### class: TouchScreen +### class: Touchscreen -#### touchScreen.tap(x, y) +#### touchscreen.tap(x, y) - `x` <[number]> - `y` <[number]> - returns: <[Promise]> +Dispatches a `touchstart` and `touchend` event. + ### class: Tracing You can use [`tracing.start`](#tracingstartoptions) and [`tracing.stop`](#tracingstop) to create a trace file which can be opened in Chrome DevTools or [timeline viewer](https://chromedevtools.github.io/timeline-viewer/). @@ -1283,7 +1293,7 @@ If the element is detached from DOM, the method throws an error. #### elementHandle.tap() - returns: <[Promise]> Promise which resolves when the element is successfully tapped. Promise gets rejected if the element is detached from DOM. -This method scrolls element into view if needed, and then uses [touchScreen.tap](#touchscreentapx-y) to tap in the center of the element. +This method scrolls element into view if needed, and then uses [touchscreen.tap](#touchscreentapx-y) to tap in the center of the element. If the element is detached from DOM, the method throws an error. #### elementHandle.uploadFile(...filePaths) @@ -1408,4 +1418,4 @@ Contains the URL of the response. [ElementHandle]: #class-elementhandle "ElementHandle" [UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail" [Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable" -[TouchScreen]: #class-touchscreen "TouchScreen" +[Touchscreen]: #class-touchscreen "Touchscreen" diff --git a/lib/ElementHandle.js b/lib/ElementHandle.js index 7694ea24f6cb4..4c2ba64cbdb60 100644 --- a/lib/ElementHandle.js +++ b/lib/ElementHandle.js @@ -21,13 +21,13 @@ class ElementHandle { * @param {!Connection} client * @param {!Object} remoteObject * @param {!Mouse} mouse - * @param {!TouchScreen} touchScreen; + * @param {!Touchscreen} touchscreen; */ - constructor(client, remoteObject, mouse, touchScreen) { + constructor(client, remoteObject, mouse, touchscreen) { this._client = client; this._remoteObject = remoteObject; this._mouse = mouse; - this._touchScreen = touchScreen; + this._touchscreen = touchscreen; this._disposed = false; } @@ -101,7 +101,7 @@ class ElementHandle { async tap() { const {x, y} = await this._visibleCenter(); - await this._touchScreen.tap(x, y); + await this._touchscreen.tap(x, y); } } diff --git a/lib/FrameManager.js b/lib/FrameManager.js index f6bc688100d7a..14882ec0f56c4 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -24,13 +24,13 @@ class FrameManager extends EventEmitter { * @param {!Session} client * @param {!Object} frameTree * @param {!Mouse} mouse - * @param {!TouchScreen} touchScreen + * @param {!Touchscreen} touchscreen */ - constructor(client, mouse, touchScreen) { + constructor(client, mouse, touchscreen) { super(); this._client = client; this._mouse = mouse; - this._touchScreen = touchScreen; + this._touchscreen = touchscreen; /** @type {!Map} */ this._frames = new Map(); @@ -64,7 +64,7 @@ class FrameManager extends EventEmitter { return; console.assert(parentFrameId); const parentFrame = this._frames.get(parentFrameId); - const frame = new Frame(this._client, this._mouse, this._touchScreen, parentFrame, frameId); + const frame = new Frame(this._client, this._mouse, this._touchscreen, parentFrame, frameId); this._frames.set(frame._id, frame); this.emit(FrameManager.Events.FrameAttached, frame); } @@ -91,7 +91,7 @@ class FrameManager extends EventEmitter { frame._id = framePayload.id; } else { // Initial main frame navigation. - frame = new Frame(this._client, this._mouse, this._touchScreen, null, framePayload.id); + frame = new Frame(this._client, this._mouse, this._touchscreen, null, framePayload.id); } this._frames.set(framePayload.id, frame); this._mainFrame = frame; @@ -156,14 +156,14 @@ class Frame { /** * @param {!Session} client * @param {!Mouse} mouse - * @param {!TouchScreen} touchScreen + * @param {!Touchscreen} touchscreen * @param {?Frame} parentFrame * @param {string} frameId */ - constructor(client, mouse, touchScreen, parentFrame, frameId) { + constructor(client, mouse, touchscreen, parentFrame, frameId) { this._client = client; this._mouse = mouse; - this._touchScreen = touchScreen; + this._touchscreen = touchscreen; this._parentFrame = parentFrame; this._url = ''; this._id = frameId; @@ -194,7 +194,7 @@ class Frame { async $(selector) { const remoteObject = await this._rawEvaluate(selector => document.querySelector(selector), selector); if (remoteObject.subtype === 'node') - return new ElementHandle(this._client, remoteObject, this._mouse, this._touchScreen); + return new ElementHandle(this._client, remoteObject, this._mouse, this._touchscreen); await helper.releaseObject(this._client, remoteObject); return null; } @@ -229,7 +229,7 @@ class Frame { const releasePromises = [helper.releaseObject(this._client, remoteObject)]; for (const property of properties) { if (property.enumerable && property.value.subtype === 'node') - result.push(new ElementHandle(this._client, property.value, this._mouse, this._touchScreen)); + result.push(new ElementHandle(this._client, property.value, this._mouse, this._touchscreen)); else releasePromises.push(helper.releaseObject(this._client, property.value)); } diff --git a/lib/Input.js b/lib/Input.js index 150beb3086d58..ef6a7e4339ab2 100644 --- a/lib/Input.js +++ b/lib/Input.js @@ -169,7 +169,7 @@ class Mouse { } } -class TouchScreen { +class Touchscreen { /** * @param {Session} client * @param {Keyboard} keyboard @@ -317,7 +317,7 @@ function codeForKey(key) { return 0; } -module.exports = { Keyboard, Mouse, TouchScreen}; +module.exports = { Keyboard, Mouse, Touchscreen}; helper.tracePublicAPI(Keyboard); helper.tracePublicAPI(Mouse); -helper.tracePublicAPI(TouchScreen); +helper.tracePublicAPI(Touchscreen); diff --git a/lib/Page.js b/lib/Page.js index 58144f2433ff7..8af47b21618d3 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -22,7 +22,7 @@ const NavigatorWatcher = require('./NavigatorWatcher'); const Dialog = require('./Dialog'); const EmulationManager = require('./EmulationManager'); const FrameManager = require('./FrameManager'); -const {Keyboard, Mouse, TouchScreen} = require('./Input'); +const {Keyboard, Mouse, Touchscreen} = require('./Input'); const Tracing = require('./Tracing'); const helper = require('./helper'); @@ -60,8 +60,8 @@ class Page extends EventEmitter { this._client = client; this._keyboard = new Keyboard(client); this._mouse = new Mouse(client, this._keyboard); - this._touchScreen = new TouchScreen(client, this._keyboard); - this._frameManager = new FrameManager(client, this._mouse, this._touchScreen); + this._touchscreen = new Touchscreen(client, this._keyboard); + this._frameManager = new FrameManager(client, this._mouse, this._touchscreen); this._networkManager = new NetworkManager(client); this._emulationManager = new EmulationManager(client); this._tracing = new Tracing(client); @@ -107,10 +107,20 @@ class Page extends EventEmitter { } /** - * @return {!TouchScreen} + * @return {!Touchscreen} */ - get touchScreen() { - return this._touchScreen; + get touchscreen() { + return this._touchscreen; + } + + /** + * @param {string} selector + */ + async tap(selector) { + const handle = await this.$(selector); + console.assert(handle, 'No node found for selector: ' + selector); + await handle.tap(); + await handle.dispose(); } /** diff --git a/test/test.js b/test/test.js index 1428d82f9157e..c0d56913e2497 100644 --- a/test/test.js +++ b/test/test.js @@ -1511,8 +1511,7 @@ describe('Page', function() { })); it('should tap the button', SX(async function() { await page.goto(PREFIX + '/input/button.html'); - const button = await page.$('button'); - await button.tap(); + await page.tap('button'); expect(await page.evaluate(() => result)).toBe('Clicked'); })); it('should report touches', SX(async function() { diff --git a/utils/doclint/check_public_api/index.js b/utils/doclint/check_public_api/index.js index 1d7fcebc2f182..d7205ce03f7cd 100644 --- a/utils/doclint/check_public_api/index.js +++ b/utils/doclint/check_public_api/index.js @@ -44,7 +44,7 @@ const EXCLUDE_METHODS = new Set([ 'Headers.fromPayload', 'Keyboard.constructor', 'Mouse.constructor', - 'TouchScreen.constructor', + 'Touchscreen.constructor', 'Tracing.constructor', 'Page.constructor', 'Page.create',