diff --git a/docs/api.md b/docs/api.md index 6e04af656c6cd..513f05d6244b8 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1466,7 +1466,7 @@ Get the browser context that the page belongs to. - `selector` <[string]> A [selector] to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked. - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully clicked. The Promise will be rejected if there is no element matching `selector`. @@ -3508,7 +3508,7 @@ await browser - `x` <[number]> - `y` <[number]> - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - returns: <[Promise]> @@ -3518,7 +3518,7 @@ Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownopt #### mouse.down([options]) - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - returns: <[Promise]> @@ -3593,7 +3593,7 @@ Dispatches a `mousemove` event. #### mouse.up([options]) - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - returns: <[Promise]> @@ -3891,7 +3891,7 @@ Adds a `` tag into the page with the desired URL or a ` A [selector] to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked. - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully clicked. The Promise will be rejected if there is no element matching `selector`. @@ -4654,7 +4654,7 @@ This method returns boxes of the element, or `null` if the element is not visibl #### elementHandle.click([options]) - `options` <[Object]> - - `button` <"left"|"right"|"middle"> Defaults to `left`. + - `button` <"left"|"right"|"middle"|"back"|"forward"> Defaults to `left`. - `clickCount` <[number]> defaults to 1. See [UIEvent.detail]. - `delay` <[number]> Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. - `offset` <[Object]> Offset in pixels relative to the top-left corner of the border box of the element. diff --git a/src/common/Input.ts b/src/common/Input.ts index e3506cf3e5406..03d02a5768e68 100644 --- a/src/common/Input.ts +++ b/src/common/Input.ts @@ -280,7 +280,7 @@ export class Keyboard { /** * @public */ -export type MouseButton = 'left' | 'right' | 'middle'; +export type MouseButton = 'left' | 'right' | 'middle' | 'back' | 'forward'; /** * @public diff --git a/src/common/JSHandle.ts b/src/common/JSHandle.ts index 9faf863fca0df..9e7ec6d56693f 100644 --- a/src/common/JSHandle.ts +++ b/src/common/JSHandle.ts @@ -32,6 +32,8 @@ import { UnwrapPromiseLike, } from './EvalTypes.js'; import { isNode } from '../environment.js'; +import { MouseButton } from './Input.js'; + /** * @public */ @@ -1177,7 +1179,7 @@ export interface ClickOptions { /** * @defaultValue 'left' */ - button?: 'left' | 'right' | 'middle'; + button?: MouseButton; /** * @defaultValue 1 */ diff --git a/test/assets/input/scrollable.html b/test/assets/input/scrollable.html index 885d3739d5f01..75757824a4a1a 100644 --- a/test/assets/input/scrollable.html +++ b/test/assets/input/scrollable.html @@ -12,12 +12,26 @@ button.id = 'button-' + i; button.onclick = () => button.textContent = 'clicked'; button.oncontextmenu = event => { + if (![2].includes(event.button)) { + return; + } event.preventDefault(); button.textContent = 'context menu'; } + button.onmouseup = event => { + if (![1,3,4].includes(event.button)) { + return; + } + event.preventDefault(); + button.textContent = { + 3: 'back click', + 4: 'forward click', + 1: 'aux click', + }[event.button]; + } document.body.appendChild(button); document.body.appendChild(document.createElement('br')); } - \ No newline at end of file + diff --git a/test/click.spec.ts b/test/click.spec.ts index e680bacb43e61..947d8344451d8 100644 --- a/test/click.spec.ts +++ b/test/click.spec.ts @@ -283,6 +283,33 @@ describe('Page.click', function () { await page.evaluate(() => document.querySelector('#button-8').textContent) ).toBe('context menu'); }); + it('should fire aux event on middle click', async () => { + const { page, server } = getTestState(); + + await page.goto(server.PREFIX + '/input/scrollable.html'); + await page.click('#button-8', { button: 'middle' }); + expect( + await page.evaluate(() => document.querySelector('#button-8').textContent) + ).toBe('aux click'); + }); + it('should fire back click', async () => { + const { page, server } = getTestState(); + + await page.goto(server.PREFIX + '/input/scrollable.html'); + await page.click('#button-8', { button: 'back' }); + expect( + await page.evaluate(() => document.querySelector('#button-8').textContent) + ).toBe('back click'); + }); + it('should fire forward click', async () => { + const { page, server } = getTestState(); + + await page.goto(server.PREFIX + '/input/scrollable.html'); + await page.click('#button-8', { button: 'forward' }); + expect( + await page.evaluate(() => document.querySelector('#button-8').textContent) + ).toBe('forward click'); + }); // @see https://github.com/puppeteer/puppeteer/issues/206 it('should click links which cause navigation', async () => { const { page, server } = getTestState(); diff --git a/utils/doclint/check_public_api/index.js b/utils/doclint/check_public_api/index.js index 6ff6df38c5fca..741f8319c2dba 100644 --- a/utils/doclint/check_public_api/index.js +++ b/utils/doclint/check_public_api/index.js @@ -926,21 +926,21 @@ function compareDocumentations(actual, expected) { [ 'Method Mouse.click() options.button', { - actualName: '"left"|"right"|"middle"', + actualName: '"left"|"right"|"middle"|"back"|"forward"', expectedName: 'MouseButton', }, ], [ 'Method Frame.click() options.button', { - actualName: '"left"|"right"|"middle"', + actualName: '"left"|"right"|"middle"|"back"|"forward"', expectedName: 'MouseButton', }, ], [ 'Method Page.click() options.button', { - actualName: '"left"|"right"|"middle"', + actualName: '"left"|"right"|"middle"|"back"|"forward"', expectedName: 'MouseButton', }, ],