From 24d4fb1e5cb0745f8d5d7ead46f3f3db82db448f Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 13 Mar 2020 08:09:48 -0700 Subject: [PATCH] api(click): remove tripleclick, respect clickCount (#1373) --- docs/api.md | 105 ---------------------------------------- src/dom.ts | 4 -- src/frames.ts | 6 --- src/input.ts | 78 +++++++---------------------- src/page.ts | 4 -- test/click.spec.js | 2 +- test/navigation.spec.js | 2 +- 7 files changed, 20 insertions(+), 181 deletions(-) diff --git a/docs/api.md b/docs/api.md index 26dc8cb438..626b40006c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -681,7 +681,6 @@ page.removeListener('request', logRequest); - [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders) - [page.setViewportSize(viewportSize)](#pagesetviewportsizeviewportsize) - [page.title()](#pagetitle) -- [page.tripleclick(selector[, options])](#pagetripleclickselector-options) - [page.type(selector, text[, options])](#pagetypeselector-text-options) - [page.uncheck(selector, [options])](#pageuncheckselector-options) - [page.url()](#pageurl) @@ -1571,38 +1570,6 @@ await page.goto('https://example.com'); Shortcut for [page.mainFrame().title()](#frametitle). -#### page.tripleclick(selector[, options]) -- `selector` <[string]> A selector to search for element to triple click. If there are multiple elements satisfying the selector, the first will be triple clicked. -- `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. - - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - - `offset` <[Object]> A point to triple click relative to the top-left corner of element padding box. If not specified, triple clicks to some visible point of the element. - - x <[number]> - - y <[number]> - - `modifiers` <[Array]<"Alt"|"Control"|"Meta"|"Shift">> Modifier keys to press. Ensures that only these modifiers are pressed during the triple click, and then restores current modifiers back. If not specified, currently pressed modifiers are used. - - `force` <[boolean]> Whether to bypass the actionability checks. By default actions wait until the element is: - - displayed (for example, no `display:none`), - - is not moving (for example, waits until css transition finishes), - - receives pointer events at the action point (for example, waits until element becomes non-obscured by other elements). - Even if the action is forced, it will wait for the element matching selector to be in DOM. Defaults to `false`. - - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|"nowait"> Actions that cause navigations are waiting for those navigations to fire `domcontentloaded` by default. This behavior can be changed to either wait for another load phase or to omit the waiting altogether using `nowait`: - - `'domcontentloaded'` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - - `'load'` - consider navigation to be finished when the `load` event is fired. - - `'networkidle0'` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. - - `'networkidle2'` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms. - - `'nowait'` - do not wait. - - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. -- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully triple clicked. The Promise will be rejected if there is no element matching `selector`. - -This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to triple click in the center of the element. -If there's no element matching `selector`, the method throws an error. - -Bear in mind that if the first or second click of the `tripleclick()` triggers a navigation event, there will be an exception. - -> **NOTE** `page.tripleclick()` dispatches three `click` events and a single `dblclick` event. - -Shortcut for [page.mainFrame().tripleclick(selector[, options])](#frametripleclickselector-options). - #### page.type(selector, text[, options]) - `selector` <[string]> A selector of an element to type into. If there are multiple elements satisfying the selector, the first will be used. - `text` <[string]> A text to type into a focused element. @@ -1917,7 +1884,6 @@ An example of getting text from an iframe element: - [frame.selectOption(selector, values[, options])](#frameselectoptionselector-values-options) - [frame.setContent(html[, options])](#framesetcontenthtml-options) - [frame.title()](#frametitle) -- [frame.tripleclick(selector[, options])](#frametripleclickselector-options) - [frame.type(selector, text[, options])](#frametypeselector-text-options) - [frame.uncheck(selector, [options])](#frameuncheckselector-options) - [frame.url()](#frameurl) @@ -2298,36 +2264,6 @@ frame.selectOption('select#colors', { value: 'blue' }, { index: 2 }, 'red'); #### frame.title() - returns: <[Promise]<[string]>> The page's title. -#### frame.tripleclick(selector[, options]) -- `selector` <[string]> A selector to search for element to triple click. If there are multiple elements satisfying the selector, the first will be triple clicked. -- `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. - - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - - `offset` <[Object]> A point to triple click relative to the top-left corner of element padding box. If not specified, triple clicks to some visible point of the element. - - x <[number]> - - y <[number]> - - `modifiers` <[Array]<"Alt"|"Control"|"Meta"|"Shift">> Modifier keys to press. Ensures that only these modifiers are pressed during the triple click, and then restores current modifiers back. If not specified, currently pressed modifiers are used. - - `force` <[boolean]> Whether to bypass the actionability checks. By default actions wait until the element is: - - displayed (for example, no `display:none`), - - is not moving (for example, waits until css transition finishes), - - receives pointer events at the action point (for example, waits until element becomes non-obscured by other elements). - Even if the action is forced, it will wait for the element matching selector to be in DOM. Defaults to `false`. - - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|"nowait"> Actions that cause navigations are waiting for those navigations to fire `domcontentloaded` by default. This behavior can be changed to either wait for another load phase or to omit the waiting altogether using `nowait`: - - `'domcontentloaded'` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - - `'load'` - consider navigation to be finished when the `load` event is fired. - - `'networkidle0'` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. - - `'networkidle2'` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms. - - `'nowait'` - do not wait. - - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. -- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully triple clicked. The Promise will be rejected if there is no element matching `selector`. - -This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to triple click in the center of the element. -If there's no element matching `selector`, the method throws an error. - -Bear in mind that if the first or second click of the `tripleclick()` triggers a navigation event, there will be an exception. - -> **NOTE** `frame.tripleclick()` dispatches three `click` events and a single `dblclick` event. - #### frame.type(selector, text[, options]) - `selector` <[string]> A selector of an element to type into. If there are multiple elements satisfying the selector, the first will be used. - `text` <[string]> A text to type into a focused element. @@ -2532,7 +2468,6 @@ ElementHandle instances can be used as arguments in [`page.$eval()`](#pageevalse - [elementHandle.selectOption(values[, options])](#elementhandleselectoptionvalues-options) - [elementHandle.setInputFiles(files)](#elementhandlesetinputfilesfiles) - [elementHandle.toString()](#elementhandletostring) -- [elementHandle.tripleclick([options])](#elementhandletripleclickoptions) - [elementHandle.type(text[, options])](#elementhandletypetext-options) - [elementHandle.uncheck([options])](#elementhandleuncheckoptions) @@ -2806,35 +2741,6 @@ Sets the value of the file input to these file paths or files. If some of the ` #### elementHandle.toString() - returns: <[string]> -#### elementHandle.tripleclick([options]) -- `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. - - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - - `offset` <[Object]> A point to triple click relative to the top-left corner of element padding box. If not specified, triple clicks to some visible point of the element. - - x <[number]> - - y <[number]> - - `modifiers` <[Array]<"Alt"|"Control"|"Meta"|"Shift">> Modifier keys to press. Ensures that only these modifiers are pressed during the triple click, and then restores current modifiers back. If not specified, currently pressed modifiers are used. - - `force` <[boolean]> Whether to bypass the actionability checks. By default actions wait until the element is: - - displayed (for example, no `display:none`), - - is not moving (for example, waits until css transition finishes), - - receives pointer events at the action point (for example, waits until element becomes non-obscured by other elements). - Even if the action is forced, it will wait for the element matching selector to be in DOM. Defaults to `false`. - - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|"nowait"> Actions that cause navigations are waiting for those navigations to fire `domcontentloaded` by default. This behavior can be changed to either wait for another load phase or to omit the waiting altogether using `nowait`: - - `'domcontentloaded'` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - - `'load'` - consider navigation to be finished when the `load` event is fired. - - `'networkidle0'` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. - - `'networkidle2'` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms. - - `'nowait'` - do not wait. - - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. -- returns: <[Promise]> Promise which resolves when the element is successfully triple clicked. Promise gets rejected if the element is detached from DOM. - -This method scrolls element into view if needed, and then uses [page.mouse](#pagemouse) to click in the center of the element. -If the element is detached from DOM, the method throws an error. - -Bear in mind that if the first or second click of the `tripleclick()` triggers a navigation event, there will be an exception. - -> **NOTE** `elementHandle.tripleclick()` dispatches three `click` events and a single `dblclick` event. - #### elementHandle.type(text[, options]) - `text` <[string]> A text to type into a focused element. - `options` <[Object]> @@ -3164,7 +3070,6 @@ await page.mouse.up(); - [mouse.dblclick(x, y[, options])](#mousedblclickx-y-options) - [mouse.down([options])](#mousedownoptions) - [mouse.move(x, y[, options])](#mousemovex-y-options) -- [mouse.tripleclick(x, y[, options])](#mousetripleclickx-y-options) - [mouse.up([options])](#mouseupoptions) @@ -3206,16 +3111,6 @@ Dispatches a `mousedown` event. Dispatches a `mousemove` event. -#### mouse.tripleclick(x, y[, options]) -- `x` <[number]> -- `y` <[number]> -- `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. - - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. -- returns: <[Promise]> - -Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions) and [`mouse.up`](#mouseupoptions). - #### mouse.up([options]) - `options` <[Object]> - `button` <"left"|"right"|"middle"> Defaults to `left`. diff --git a/src/dom.ts b/src/dom.ts index de09d3916b..c5d9bec08e 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -273,10 +273,6 @@ export class ElementHandle extends js.JSHandle { return this._performPointerAction(point => this._page.mouse.dblclick(point.x, point.y, options), options); } - tripleclick(options?: MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise { - return this._performPointerAction(point => this._page.mouse.tripleclick(point.x, point.y, options), options); - } - async selectOption(values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[], options?: types.NavigatingActionWaitOptions): Promise { let vals: string[] | ElementHandle[] | types.SelectOption[]; if (!Array.isArray(values)) diff --git a/src/frames.ts b/src/frames.ts index c82d3b90b8..9d5aae1a90 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -817,12 +817,6 @@ export class Frame { handle.dispose(); } - async tripleclick(selector: string, options?: dom.MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { - const handle = await this._waitForSelectorInUtilityContext(selector, options); - await handle.tripleclick(options); - handle.dispose(); - } - async fill(selector: string, value: string, options?: types.NavigatingActionWaitOptions) { const handle = await this._waitForSelectorInUtilityContext(selector, options); await handle.fill(value, options); diff --git a/src/input.ts b/src/input.ts index 99cbf09834..4024354b9c 100644 --- a/src/input.ts +++ b/src/input.ts @@ -221,70 +221,28 @@ export class Mouse { } async click(x: number, y: number, options: MouseClickOptions = {}) { - const {delay = null} = options; - if (delay !== null) { - await Promise.all([ - this.move(x, y), - this.down(options), - ]); - await new Promise(f => setTimeout(f, delay)); - await this.up(options); + const { delay = null, clickCount = 1 } = options; + if (delay) { + this.move(x, y); + for (let cc = 1; cc <= clickCount; ++cc) { + await this.down({ ...options, clickCount: cc }); + await new Promise(f => setTimeout(f, delay)); + await this.up({ ...options, clickCount: cc }); + if (cc < clickCount) + await new Promise(f => setTimeout(f, delay)); + } } else { - await Promise.all([ - this.move(x, y), - this.down(options), - this.up(options), - ]); + const promises = []; + promises.push(this.move(x, y)); + for (let cc = 1; cc <= clickCount; ++cc) { + promises.push(this.down({ ...options, clickCount: cc })); + promises.push(this.up({ ...options, clickCount: cc })); + } + await Promise.all(promises); } } async dblclick(x: number, y: number, options: MouseMultiClickOptions = {}) { - const { delay = null } = options; - if (delay !== null) { - await this.move(x, y); - await this.down({ ...options, clickCount: 1 }); - await new Promise(f => setTimeout(f, delay)); - await this.up({ ...options, clickCount: 1 }); - await new Promise(f => setTimeout(f, delay)); - await this.down({ ...options, clickCount: 2 }); - await new Promise(f => setTimeout(f, delay)); - await this.up({ ...options, clickCount: 2 }); - } else { - await Promise.all([ - this.move(x, y), - this.down({ ...options, clickCount: 1 }), - this.up({ ...options, clickCount: 1 }), - this.down({ ...options, clickCount: 2 }), - this.up({ ...options, clickCount: 2 }), - ]); - } - } - - async tripleclick(x: number, y: number, options: MouseMultiClickOptions = {}) { - const { delay = null } = options; - if (delay !== null) { - await this.move(x, y); - await this.down({ ...options, clickCount: 1 }); - await new Promise(f => setTimeout(f, delay)); - await this.up({ ...options, clickCount: 1 }); - await new Promise(f => setTimeout(f, delay)); - await this.down({ ...options, clickCount: 2 }); - await new Promise(f => setTimeout(f, delay)); - await this.up({ ...options, clickCount: 2 }); - await new Promise(f => setTimeout(f, delay)); - await this.down({ ...options, clickCount: 3 }); - await new Promise(f => setTimeout(f, delay)); - await this.up({ ...options, clickCount: 3 }); - } else { - await Promise.all([ - this.move(x, y), - this.down({ ...options, clickCount: 1 }), - this.up({ ...options, clickCount: 1 }), - this.down({ ...options, clickCount: 2 }), - this.up({ ...options, clickCount: 2 }), - this.down({ ...options, clickCount: 3 }), - this.up({ ...options, clickCount: 3 }), - ]); - } + await this.click(x, y, { ...options, clickCount: 2 }); } } diff --git a/src/page.ts b/src/page.ts index fb72d4ba35..47f7767e6a 100644 --- a/src/page.ts +++ b/src/page.ts @@ -468,10 +468,6 @@ export class Page extends platform.EventEmitter { return this.mainFrame().dblclick(selector, options); } - async tripleclick(selector: string, options?: dom.MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { - return this.mainFrame().tripleclick(selector, options); - } - async fill(selector: string, value: string, options?: types.NavigatingActionWaitOptions) { return this.mainFrame().fill(selector, value, options); } diff --git a/test/click.spec.js b/test/click.spec.js index e1ec17cff0..23aafedb4c 100644 --- a/test/click.spec.js +++ b/test/click.spec.js @@ -110,7 +110,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI await page.goto(server.PREFIX + '/input/textarea.html'); const text = 'This is the text that we are going to try to select. Let\'s see how it goes.'; await page.fill('textarea', text); - await page.tripleclick('textarea'); + await page.click('textarea', { clickCount: 3 }); expect(await page.evaluate(() => { const textarea = document.querySelector('textarea'); return textarea.value.substring(textarea.selectionStart, textarea.selectionEnd); diff --git a/test/navigation.spec.js b/test/navigation.spec.js index 049c2f0920..350a445bb6 100644 --- a/test/navigation.spec.js +++ b/test/navigation.spec.js @@ -982,7 +982,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF await page.setContent(`foobar`); await page.click('a'); }); - it('clicking on download link', async({page, server, httpsServer}) => { + it.fail(FFOX)('clicking on download link', async({page, server, httpsServer}) => { await page.setContent(`table2.wasm`); await page.click('a'); });