fix: dispatch touch events in webkit (#34250)
This commit is contained in:
parent
7ee7e018fa
commit
edfbab2a79
|
|
@ -13,10 +13,6 @@ If your web application relies on [pointer events](https://developer.mozilla.org
|
|||
|
||||
You can dispatch touch events to the page using [`method: Locator.dispatchEvent`]. [Touch](https://developer.mozilla.org/en-US/docs/Web/API/Touch) points can be passed as arguments, see examples below.
|
||||
|
||||
:::note
|
||||
The examples work only in Chromium and Firefox, as the [`Touch()`](https://developer.mozilla.org/en-US/docs/Web/API/Touch/Touch) constructor is not supported in WebKit.
|
||||
:::
|
||||
|
||||
#### Emulating pan gesture
|
||||
|
||||
In the example below, we emulate pan gesture that is expected to move the map. The app under test only uses `clientX/clientY` coordinates of the touch point, so we initialize just that. In a more complex scenario you may need to also set `pageX/pageY/screenX/screenY`, if your app needs them.
|
||||
|
|
|
|||
|
|
@ -1016,11 +1016,37 @@ export class InjectedScript {
|
|||
case 'mouse': event = new MouseEvent(type, eventInit); break;
|
||||
case 'keyboard': event = new KeyboardEvent(type, eventInit); break;
|
||||
case 'touch': {
|
||||
// WebKit does not support Touch constructor, but has deprecated createTouch and createTouchList methods.
|
||||
if (this._browserName === 'webkit') {
|
||||
const createTouch = (t: any) => {
|
||||
if (t instanceof Touch)
|
||||
return t;
|
||||
// createTouch does not accept clientX/clientY, so we have to use pageX/pageY.
|
||||
let pageX = t.pageX;
|
||||
if (pageX === undefined && t.clientX !== undefined)
|
||||
pageX = t.clientX + (this.document.scrollingElement?.scrollLeft || 0);
|
||||
let pageY = t.pageY;
|
||||
if (pageY === undefined && t.clientY !== undefined)
|
||||
pageY = t.clientY + (this.document.scrollingElement?.scrollTop || 0);
|
||||
return (this.document as any).createTouch(this.window, t.target ?? node, t.identifier, pageX, pageY, t.screenX, t.screenY, t.radiusX, t.radiusY, t.rotationAngle, t.force);
|
||||
};
|
||||
const createTouchList = (touches: any) => {
|
||||
if (touches instanceof TouchList || !touches)
|
||||
return touches;
|
||||
return (this.document as any).createTouchList(...touches.map(createTouch));
|
||||
};
|
||||
eventInit.target ??= node;
|
||||
eventInit.touches = createTouchList(eventInit.touches);
|
||||
eventInit.targetTouches = createTouchList(eventInit.targetTouches);
|
||||
eventInit.changedTouches = createTouchList(eventInit.changedTouches);
|
||||
event = new TouchEvent(type, eventInit);
|
||||
} else {
|
||||
eventInit.target ??= node;
|
||||
eventInit.touches = eventInit.touches?.map((t: any) => t instanceof Touch ? t : new Touch({ ...t, target: t.target ?? node }));
|
||||
eventInit.targetTouches = eventInit.targetTouches?.map((t: any) => t instanceof Touch ? t : new Touch({ ...t, target: t.target ?? node }));
|
||||
eventInit.changedTouches = eventInit.changedTouches?.map((t: any) => t instanceof Touch ? t : new Touch({ ...t, target: t.target ?? node }));
|
||||
event = new TouchEvent(type, eventInit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'pointer': event = new PointerEvent(type, eventInit); break;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import { contextTest as it, expect } from '../config/browserTest';
|
|||
it.use({ hasTouch: true });
|
||||
|
||||
it('should support touch points in touch event arguments', async ({ page, server, browserName }) => {
|
||||
it.fixme(browserName === 'webkit', 'WebKit does not have Touch constructor');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`
|
||||
<div data-testid='outer' style="position: absolute; width: 120px; height: 120px; background-color: red;">
|
||||
|
|
|
|||
Loading…
Reference in a new issue