feat: add touchstart, touchmove and touchend methods (#9622)
This commit is contained in:
parent
6e226bcc22
commit
c8bb11adfc
@ -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 <code>change</code> and <code>input</code> event once all the provided options have been selected. If there's no <code><select></code> element matching <code>selector</code>, the method throws an error. |
|
| [select(values)](./puppeteer.elementhandle.select.md) | | Triggers a <code>change</code> and <code>input</code> event once all the provided options have been selected. If there's no <code><select></code> element matching <code>selector</code>, 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. |
|
| [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. |
|
| [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) | | <p>Focuses the element, and then sends a <code>keydown</code>, <code>keypress</code>/<code>input</code>, and <code>keyup</code> event for each character in the text.</p><p>To press a special key, like <code>Control</code> or <code>ArrowDown</code>, use [ElementHandle.press()](./puppeteer.elementhandle.press.md).</p> |
|
| [type(text, options)](./puppeteer.elementhandle.type.md) | | <p>Focuses the element, and then sends a <code>keydown</code>, <code>keypress</code>/<code>input</code>, and <code>keyup</code> event for each character in the text.</p><p>To press a special key, like <code>Control</code> or <code>ArrowDown</code>, use [ElementHandle.press()](./puppeteer.elementhandle.press.md).</p> |
|
||||||
| [uploadFile(this, filePaths)](./puppeteer.elementhandle.uploadfile.md) | | This method expects <code>elementHandle</code> to point to an [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). |
|
| [uploadFile(this, filePaths)](./puppeteer.elementhandle.uploadfile.md) | | This method expects <code>elementHandle</code> to point to an [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). |
|
||||||
| [waitForSelector(selector, options)](./puppeteer.elementhandle.waitforselector.md) | | <p>Wait for an element matching the given selector to appear in the current element.</p><p>Unlike [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), this method does not work across navigations or if the element is detached from DOM.</p> |
|
| [waitForSelector(selector, options)](./puppeteer.elementhandle.waitforselector.md) | | <p>Wait for an element matching the given selector to appear in the current element.</p><p>Unlike [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), this method does not work across navigations or if the element is detached from DOM.</p> |
|
||||||
|
23
docs/api/puppeteer.elementhandle.touchend.md
Normal file
23
docs/api/puppeteer.elementhandle.touchend.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
sidebar_label: ElementHandle.touchEnd
|
||||||
|
---
|
||||||
|
|
||||||
|
# ElementHandle.touchEnd() method
|
||||||
|
|
||||||
|
#### Signature:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class ElementHandle {
|
||||||
|
touchEnd(this: ElementHandle<Element>): Promise<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------------------------------------------------------------ | ----------- |
|
||||||
|
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
23
docs/api/puppeteer.elementhandle.touchmove.md
Normal file
23
docs/api/puppeteer.elementhandle.touchmove.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
sidebar_label: ElementHandle.touchMove
|
||||||
|
---
|
||||||
|
|
||||||
|
# ElementHandle.touchMove() method
|
||||||
|
|
||||||
|
#### Signature:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class ElementHandle {
|
||||||
|
touchMove(this: ElementHandle<Element>): Promise<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------------------------------------------------------------ | ----------- |
|
||||||
|
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
23
docs/api/puppeteer.elementhandle.touchstart.md
Normal file
23
docs/api/puppeteer.elementhandle.touchstart.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
sidebar_label: ElementHandle.touchStart
|
||||||
|
---
|
||||||
|
|
||||||
|
# ElementHandle.touchStart() method
|
||||||
|
|
||||||
|
#### Signature:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class ElementHandle {
|
||||||
|
touchStart(this: ElementHandle<Element>): Promise<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------------------------------------------------------------ | ----------- |
|
||||||
|
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
@ -18,6 +18,9 @@ The constructor for this class is marked as internal. Third-party code should no
|
|||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
| Method | Modifiers | Description |
|
| Method | Modifiers | Description |
|
||||||
| ------------------------------------------- | --------- | --------------------------------------------------------------------- |
|
| --------------------------------------------------------- | --------- | --------------------------------------------------------------------- |
|
||||||
| [tap(x, y)](./puppeteer.touchscreen.tap.md) | | Dispatches a <code>touchstart</code> and <code>touchend</code> event. |
|
| [tap(x, y)](./puppeteer.touchscreen.tap.md) | | Dispatches a <code>touchstart</code> and <code>touchend</code> event. |
|
||||||
|
| [touchEnd()](./puppeteer.touchscreen.touchend.md) | | Dispatches a <code>touchend</code> event. |
|
||||||
|
| [touchMove(x, y)](./puppeteer.touchscreen.touchmove.md) | | Dispatches a <code>touchMove</code> event. |
|
||||||
|
| [touchStart(x, y)](./puppeteer.touchscreen.touchstart.md) | | Dispatches a <code>touchstart</code> event. |
|
||||||
|
19
docs/api/puppeteer.touchscreen.touchend.md
Normal file
19
docs/api/puppeteer.touchscreen.touchend.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
sidebar_label: Touchscreen.touchEnd
|
||||||
|
---
|
||||||
|
|
||||||
|
# Touchscreen.touchEnd() method
|
||||||
|
|
||||||
|
Dispatches a `touchend` event.
|
||||||
|
|
||||||
|
#### Signature:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class Touchscreen {
|
||||||
|
touchEnd(): Promise<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
26
docs/api/puppeteer.touchscreen.touchmove.md
Normal file
26
docs/api/puppeteer.touchscreen.touchmove.md
Normal file
@ -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<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------ | -------------------------------- |
|
||||||
|
| x | number | Horizontal position of the move. |
|
||||||
|
| y | number | Vertical position of the move. |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
26
docs/api/puppeteer.touchscreen.touchstart.md
Normal file
26
docs/api/puppeteer.touchscreen.touchstart.md
Normal file
@ -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<void>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------ | ------------------------------- |
|
||||||
|
| x | number | Horizontal position of the tap. |
|
||||||
|
| y | number | Vertical position of the tap. |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
|
||||||
|
Promise<void>
|
@ -869,7 +869,25 @@ export class ElementHandle<
|
|||||||
async tap(this: ElementHandle<Element>): Promise<void> {
|
async tap(this: ElementHandle<Element>): Promise<void> {
|
||||||
await this.#scrollIntoViewIfNeeded();
|
await this.#scrollIntoViewIfNeeded();
|
||||||
const {x, y} = await this.clickablePoint();
|
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<Element>): Promise<void> {
|
||||||
|
await this.#scrollIntoViewIfNeeded();
|
||||||
|
const {x, y} = await this.clickablePoint();
|
||||||
|
await this.#page.touchscreen.touchStart(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
async touchMove(this: ElementHandle<Element>): Promise<void> {
|
||||||
|
await this.#scrollIntoViewIfNeeded();
|
||||||
|
const {x, y} = await this.clickablePoint();
|
||||||
|
await this.#page.touchscreen.touchMove(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
async touchEnd(this: ElementHandle<Element>): Promise<void> {
|
||||||
|
await this.#scrollIntoViewIfNeeded();
|
||||||
|
await this.#page.touchscreen.touchEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -670,12 +670,40 @@ export class Touchscreen {
|
|||||||
* @param y - Vertical position of the tap.
|
* @param y - Vertical position of the tap.
|
||||||
*/
|
*/
|
||||||
async tap(x: number, y: number): Promise<void> {
|
async tap(x: number, y: number): Promise<void> {
|
||||||
|
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<void> {
|
||||||
const touchPoints = [{x: Math.round(x), y: Math.round(y)}];
|
const touchPoints = [{x: Math.round(x), y: Math.round(y)}];
|
||||||
await this.#client.send('Input.dispatchTouchEvent', {
|
await this.#client.send('Input.dispatchTouchEvent', {
|
||||||
type: 'touchStart',
|
type: 'touchStart',
|
||||||
touchPoints,
|
touchPoints,
|
||||||
modifiers: this.#keyboard._modifiers,
|
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<void> {
|
||||||
|
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<void> {
|
||||||
await this.#client.send('Input.dispatchTouchEvent', {
|
await this.#client.send('Input.dispatchTouchEvent', {
|
||||||
type: 'touchEnd',
|
type: 'touchEnd',
|
||||||
touchPoints: [],
|
touchPoints: [],
|
||||||
|
@ -2975,6 +2975,12 @@
|
|||||||
"parameters": ["firefox"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[touchscreen.spec] Touchscreen should report touchMove",
|
||||||
|
"platforms": ["linux"],
|
||||||
|
"parameters": ["firefox"],
|
||||||
|
"expectations": ["FAIL"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[tracing.spec]",
|
"testIdPattern": "[tracing.spec]",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
65
test/assets/input/touches-move.html
Normal file
65
test/assets/input/touches-move.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Drag-and-drop test</title>
|
||||||
|
<style>
|
||||||
|
#drop {
|
||||||
|
width: 5em;
|
||||||
|
height: 5em;
|
||||||
|
border: 1px solid black;
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#drag {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="touch" draggable="true">touch me</div>
|
||||||
|
<script>
|
||||||
|
window.result = [];
|
||||||
|
function log(...args) {
|
||||||
|
console.log.apply(console, args);
|
||||||
|
result.push(args.join(' '));
|
||||||
|
}
|
||||||
|
window.didTouchStart = false;
|
||||||
|
window.didDragEnter = false;
|
||||||
|
window.didTouchMove = false;
|
||||||
|
window.didTouchEnd = false;
|
||||||
|
const drag = document.getElementById('touch');
|
||||||
|
drag.addEventListener('touchstart', function (event) {
|
||||||
|
console.log("touchstart")
|
||||||
|
window.didTouchStart = true;
|
||||||
|
});
|
||||||
|
drag.addEventListener('touchmove', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
log('Touchmove:', ...Array.from(event.changedTouches).map(touch => "x: "+ Math.round(touch.clientX) +" y: "+ Math.round(touch.clientY)));
|
||||||
|
window.didTouchMove = true;
|
||||||
|
var touchLocation = event.targetTouches[0];
|
||||||
|
var moveLoction = event.changedTouches[0];
|
||||||
|
drag.style.left = touchLocation.pageX + 'px';
|
||||||
|
drag.style.top = touchLocation.pageY + 'px';
|
||||||
|
});
|
||||||
|
drag.addEventListener('touchend', function (event) {
|
||||||
|
console.log("touch end")
|
||||||
|
log('Touchend:', ...Array.from(event.changedTouches).map(touch => touch.identifier));
|
||||||
|
if(Array.from(event.changedTouches).map((touch) => {
|
||||||
|
console.log("x: "+ Math.round(touch.clientX) +" y: "+ Math.round(touch.clientY))
|
||||||
|
window.touchX = touch.clientX;
|
||||||
|
window.touchY = touch.clientY;
|
||||||
|
}))
|
||||||
|
event.preventDefault();
|
||||||
|
window.didTouchEnd = true;
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
import {KnownDevices} from 'puppeteer';
|
import {KnownDevices, BoundingBox} from 'puppeteer';
|
||||||
import {
|
import {
|
||||||
getTestState,
|
getTestState,
|
||||||
setupTestBrowserHooks,
|
setupTestBrowserHooks,
|
||||||
@ -38,6 +38,7 @@ describe('Touchscreen', function () {
|
|||||||
})
|
})
|
||||||
).toBe('Clicked');
|
).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should report touches', async () => {
|
it('should report touches', async () => {
|
||||||
const {page, server} = getTestState();
|
const {page, server} = getTestState();
|
||||||
const iPhone = KnownDevices['iPhone 6']!;
|
const iPhone = KnownDevices['iPhone 6']!;
|
||||||
@ -51,4 +52,28 @@ describe('Touchscreen', function () {
|
|||||||
})
|
})
|
||||||
).toEqual(['Touchstart: 0', 'Touchend: 0']);
|
).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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user