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);
+ });
});