diff --git a/docs/api/puppeteer.elementhandle.md b/docs/api/puppeteer.elementhandle.md index 74e574b1..0fdeb068 100644 --- a/docs/api/puppeteer.elementhandle.md +++ b/docs/api/puppeteer.elementhandle.md @@ -73,6 +73,9 @@ The constructor for this class is marked as internal. Third-party code should no | [select(values)](./puppeteer.elementhandle.select.md) | | Triggers a change and input event once all the provided options have been selected. If there's no <select> element matching selector, the method throws an error. | | [tap(this)](./puppeteer.elementhandle.tap.md) | | This method scrolls element into view if needed, and then uses [Touchscreen.tap()](./puppeteer.touchscreen.tap.md) to tap in the center of the element. If the element is detached from DOM, the method throws an error. | | [toElement(tagName)](./puppeteer.elementhandle.toelement.md) | | Converts the current handle to the given element type. | +| [touchEnd(this)](./puppeteer.elementhandle.touchend.md) | | | +| [touchMove(this)](./puppeteer.elementhandle.touchmove.md) | | | +| [touchStart(this)](./puppeteer.elementhandle.touchstart.md) | | | | [type(text, options)](./puppeteer.elementhandle.type.md) | |

Focuses the element, and then sends a keydown, keypress/input, and keyup event for each character in the text.

To press a special key, like Control or ArrowDown, use [ElementHandle.press()](./puppeteer.elementhandle.press.md).

| | [uploadFile(this, filePaths)](./puppeteer.elementhandle.uploadfile.md) | | This method expects elementHandle to point to an [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). | | [waitForSelector(selector, options)](./puppeteer.elementhandle.waitforselector.md) | |

Wait for an element matching the given selector to appear in the current element.

Unlike [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), this method does not work across navigations or if the element is detached from DOM.

| diff --git a/docs/api/puppeteer.elementhandle.touchend.md b/docs/api/puppeteer.elementhandle.touchend.md new file mode 100644 index 00000000..037605aa --- /dev/null +++ b/docs/api/puppeteer.elementhandle.touchend.md @@ -0,0 +1,23 @@ +--- +sidebar_label: ElementHandle.touchEnd +--- + +# ElementHandle.touchEnd() method + +#### Signature: + +```typescript +class ElementHandle { + touchEnd(this: ElementHandle): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------------------------------------------------------------ | ----------- | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.elementhandle.touchmove.md b/docs/api/puppeteer.elementhandle.touchmove.md new file mode 100644 index 00000000..f2221a7f --- /dev/null +++ b/docs/api/puppeteer.elementhandle.touchmove.md @@ -0,0 +1,23 @@ +--- +sidebar_label: ElementHandle.touchMove +--- + +# ElementHandle.touchMove() method + +#### Signature: + +```typescript +class ElementHandle { + touchMove(this: ElementHandle): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------------------------------------------------------------ | ----------- | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.elementhandle.touchstart.md b/docs/api/puppeteer.elementhandle.touchstart.md new file mode 100644 index 00000000..2fda4fe7 --- /dev/null +++ b/docs/api/puppeteer.elementhandle.touchstart.md @@ -0,0 +1,23 @@ +--- +sidebar_label: ElementHandle.touchStart +--- + +# ElementHandle.touchStart() method + +#### Signature: + +```typescript +class ElementHandle { + touchStart(this: ElementHandle): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------------------------------------------------------------ | ----------- | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.touchscreen.md b/docs/api/puppeteer.touchscreen.md index d2b34258..3275b9bf 100644 --- a/docs/api/puppeteer.touchscreen.md +++ b/docs/api/puppeteer.touchscreen.md @@ -18,6 +18,9 @@ The constructor for this class is marked as internal. Third-party code should no ## Methods -| Method | Modifiers | Description | -| ------------------------------------------- | --------- | --------------------------------------------------------------------- | -| [tap(x, y)](./puppeteer.touchscreen.tap.md) | | Dispatches a touchstart and touchend event. | +| Method | Modifiers | Description | +| --------------------------------------------------------- | --------- | --------------------------------------------------------------------- | +| [tap(x, y)](./puppeteer.touchscreen.tap.md) | | Dispatches a touchstart and touchend event. | +| [touchEnd()](./puppeteer.touchscreen.touchend.md) | | Dispatches a touchend event. | +| [touchMove(x, y)](./puppeteer.touchscreen.touchmove.md) | | Dispatches a touchMove event. | +| [touchStart(x, y)](./puppeteer.touchscreen.touchstart.md) | | Dispatches a touchstart event. | diff --git a/docs/api/puppeteer.touchscreen.touchend.md b/docs/api/puppeteer.touchscreen.touchend.md new file mode 100644 index 00000000..2f94f4b0 --- /dev/null +++ b/docs/api/puppeteer.touchscreen.touchend.md @@ -0,0 +1,19 @@ +--- +sidebar_label: Touchscreen.touchEnd +--- + +# Touchscreen.touchEnd() method + +Dispatches a `touchend` event. + +#### Signature: + +```typescript +class Touchscreen { + touchEnd(): Promise; +} +``` + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.touchscreen.touchmove.md b/docs/api/puppeteer.touchscreen.touchmove.md new file mode 100644 index 00000000..190a533b --- /dev/null +++ b/docs/api/puppeteer.touchscreen.touchmove.md @@ -0,0 +1,26 @@ +--- +sidebar_label: Touchscreen.touchMove +--- + +# Touchscreen.touchMove() method + +Dispatches a `touchMove` event. + +#### Signature: + +```typescript +class Touchscreen { + touchMove(x: number, y: number): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------ | -------------------------------- | +| x | number | Horizontal position of the move. | +| y | number | Vertical position of the move. | + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.touchscreen.touchstart.md b/docs/api/puppeteer.touchscreen.touchstart.md new file mode 100644 index 00000000..ded9789c --- /dev/null +++ b/docs/api/puppeteer.touchscreen.touchstart.md @@ -0,0 +1,26 @@ +--- +sidebar_label: Touchscreen.touchStart +--- + +# Touchscreen.touchStart() method + +Dispatches a `touchstart` event. + +#### Signature: + +```typescript +class Touchscreen { + touchStart(x: number, y: number): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------ | ------------------------------- | +| x | number | Horizontal position of the tap. | +| y | number | Vertical position of the tap. | + +**Returns:** + +Promise<void> diff --git a/packages/puppeteer-core/src/common/ElementHandle.ts b/packages/puppeteer-core/src/common/ElementHandle.ts index 3a49faee..7f259d29 100644 --- a/packages/puppeteer-core/src/common/ElementHandle.ts +++ b/packages/puppeteer-core/src/common/ElementHandle.ts @@ -869,7 +869,25 @@ export class ElementHandle< async tap(this: ElementHandle): Promise { await this.#scrollIntoViewIfNeeded(); const {x, y} = await this.clickablePoint(); - await this.#page.touchscreen.tap(x, y); + await this.#page.touchscreen.touchStart(x, y); + await this.#page.touchscreen.touchEnd(); + } + + async touchStart(this: ElementHandle): Promise { + await this.#scrollIntoViewIfNeeded(); + const {x, y} = await this.clickablePoint(); + await this.#page.touchscreen.touchStart(x, y); + } + + async touchMove(this: ElementHandle): Promise { + await this.#scrollIntoViewIfNeeded(); + const {x, y} = await this.clickablePoint(); + await this.#page.touchscreen.touchMove(x, y); + } + + async touchEnd(this: ElementHandle): Promise { + await this.#scrollIntoViewIfNeeded(); + await this.#page.touchscreen.touchEnd(); } /** diff --git a/packages/puppeteer-core/src/common/Input.ts b/packages/puppeteer-core/src/common/Input.ts index 02ffaddf..f181b6b6 100644 --- a/packages/puppeteer-core/src/common/Input.ts +++ b/packages/puppeteer-core/src/common/Input.ts @@ -670,12 +670,40 @@ export class Touchscreen { * @param y - Vertical position of the tap. */ async tap(x: number, y: number): Promise { + await this.touchStart(x, y); + await this.touchEnd(); + } + + /** + * Dispatches a `touchstart` event. + * @param x - Horizontal position of the tap. + * @param y - Vertical position of the tap. + */ + async touchStart(x: number, y: number): Promise { const touchPoints = [{x: Math.round(x), y: Math.round(y)}]; await this.#client.send('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints, modifiers: this.#keyboard._modifiers, }); + } + /** + * Dispatches a `touchMove` event. + * @param x - Horizontal position of the move. + * @param y - Vertical position of the move. + */ + async touchMove(x: number, y: number): Promise { + const movePoints = [{x: Math.round(x), y: Math.round(y)}]; + await this.#client.send('Input.dispatchTouchEvent', { + type: 'touchMove', + touchPoints: movePoints, + modifiers: this.#keyboard._modifiers, + }); + } + /** + * Dispatches a `touchend` event. + */ + async touchEnd(): Promise { await this.#client.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [], diff --git a/test/TestExpectations.json b/test/TestExpectations.json index 8e102fa3..96c59534 100644 --- a/test/TestExpectations.json +++ b/test/TestExpectations.json @@ -2975,6 +2975,12 @@ "parameters": ["firefox"], "expectations": ["FAIL"] }, + { + "testIdPattern": "[touchscreen.spec] Touchscreen should report touchMove", + "platforms": ["linux"], + "parameters": ["firefox"], + "expectations": ["FAIL"] + }, { "testIdPattern": "[tracing.spec]", "platforms": ["darwin", "linux", "win32"], diff --git a/test/assets/input/touches-move.html b/test/assets/input/touches-move.html new file mode 100644 index 00000000..212330d4 --- /dev/null +++ b/test/assets/input/touches-move.html @@ -0,0 +1,65 @@ + + + + + Drag-and-drop test + + + + +
touch me
+ + + + diff --git a/test/src/touchscreen.spec.ts b/test/src/touchscreen.spec.ts index be7bf3fc..569f74ef 100644 --- a/test/src/touchscreen.spec.ts +++ b/test/src/touchscreen.spec.ts @@ -15,7 +15,7 @@ */ import expect from 'expect'; -import {KnownDevices} from 'puppeteer'; +import {KnownDevices, BoundingBox} from 'puppeteer'; import { getTestState, setupTestBrowserHooks, @@ -38,6 +38,7 @@ describe('Touchscreen', function () { }) ).toBe('Clicked'); }); + it('should report touches', async () => { const {page, server} = getTestState(); const iPhone = KnownDevices['iPhone 6']!; @@ -51,4 +52,28 @@ describe('Touchscreen', function () { }) ).toEqual(['Touchstart: 0', 'Touchend: 0']); }); + + it('should report touchMove', async () => { + const {page, server} = getTestState(); + const iPhone = KnownDevices['iPhone 6']!; + await page.emulate(iPhone); + await page.goto(server.PREFIX + '/input/touches-move.html'); + const touch = (await page.$('#touch'))!; + const touchObj = (await touch.boundingBox()) as BoundingBox; + await page.touchscreen.touchStart(touchObj.x, touchObj.y); + const movePosx = 100; + const movePosy = 100; + await page.touchscreen.touchMove(movePosx, movePosy); + await page.touchscreen.touchEnd(); + expect( + await page.evaluate(() => { + return (globalThis as any).touchX; + }) + ).toBe(movePosx); + expect( + await page.evaluate(() => { + return (globalThis as any).touchY; + }) + ).toBe(movePosy); + }); });