feat: Add support for dispatching device motion events (#28067)

References #27887.
This commit is contained in:
Mattias Wallander 2023-11-13 17:58:46 +01:00 committed by GitHub
parent 0ade89c121
commit c6d154f9c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 1 deletions

View File

@ -71,6 +71,10 @@ interface WebKitLegacyDeviceOrientationEvent extends DeviceOrientationEvent {
readonly initDeviceOrientationEvent: (type: string, bubbles: boolean, cancelable: boolean, alpha: number, beta: number, gamma: number, absolute: boolean) => void;
}
interface WebKitLegacyDeviceMotionEvent extends DeviceMotionEvent {
readonly initDeviceMotionEvent: (type: string, bubbles: boolean, cancelable: boolean, acceleration: DeviceMotionEventAcceleration, accelerationIncludingGravity: DeviceMotionEventAcceleration, rotationRate: DeviceMotionEventRotationRate, interval: number) => void;
}
export class InjectedScript {
private _engines: Map<string, SelectorEngine>;
_evaluator: SelectorEvaluatorImpl;
@ -1049,6 +1053,15 @@ export class InjectedScript {
event.initDeviceOrientationEvent(type, bubbles, cancelable, alpha, beta, gamma, absolute);
}
break;
case 'devicemotion':
try {
event = new DeviceMotionEvent(type, eventInit);
} catch {
const { bubbles, cancelable, acceleration, accelerationIncludingGravity, rotationRate, interval } = eventInit as {bubbles: boolean, cancelable: boolean, acceleration: DeviceMotionEventAcceleration, accelerationIncludingGravity: DeviceMotionEventAcceleration, rotationRate: DeviceMotionEventRotationRate, interval: number};
event = this.document.createEvent('DeviceMotionEvent') as WebKitLegacyDeviceMotionEvent;
event.initDeviceMotionEvent(type, bubbles, cancelable, acceleration, accelerationIncludingGravity, rotationRate, interval);
}
break;
default: event = new Event(type, eventInit); break;
}
node.dispatchEvent(event);
@ -1380,7 +1393,7 @@ function oneLine(s: string): string {
return s.replace(/\n/g, '↵').replace(/\t/g, '⇆');
}
const eventType = new Map<string, 'mouse' | 'keyboard' | 'touch' | 'pointer' | 'focus' | 'drag' | 'wheel' | 'deviceorientation'>([
const eventType = new Map<string, 'mouse' | 'keyboard' | 'touch' | 'pointer' | 'focus' | 'drag' | 'wheel' | 'deviceorientation' | 'devicemotion'>([
['auxclick', 'mouse'],
['click', 'mouse'],
['dblclick', 'mouse'],
@ -1431,6 +1444,8 @@ const eventType = new Map<string, 'mouse' | 'keyboard' | 'touch' | 'pointer' | '
['deviceorientation', 'deviceorientation'],
['deviceorientationabsolute', 'deviceorientation'],
['devicemotion', 'devicemotion'],
]);
const kHoverHitTargetInterceptorEvents = new Set(['mousemove']);

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Device motion test</title>
</head>
<body>
<script>
window.result = 'Was not moved';
window.acceleration = undefined;
window.accelerationIncludingGravity = undefined;
window.rotationRate = undefined;
window.interval = undefined;
document.addEventListener('devicemotion', onMotion, false);
function onMotion(event) {
window.result = 'Moved';
window.acceleration = event.acceleration;
window.accelerationIncludingGravity = event.accelerationIncludingGravity;
window.rotationRate = event.rotationRate;
window.interval = event.interval;
}
</script>
</body>
</html>

View File

@ -193,3 +193,25 @@ it('should dispatch absolute device orientation event', async ({ page, server, i
expect(await page.evaluate('gamma')).toBe(30);
expect(await page.evaluate('absolute')).toBeTruthy();
});
it('should dispatch device motion event', async ({ page, server, isAndroid }) => {
it.skip(isAndroid, 'DeviceOrientationEvent is only available in a secure context. While Androids loopback is not treated as secure.');
await page.goto(server.PREFIX + '/device-motion.html');
await page.locator('html').dispatchEvent('devicemotion', {
acceleration: { x: 10, y: 20, z: 30 },
accelerationIncludingGravity: { x: 15, y: 25, z: 35 },
rotationRate: { alpha: 5, beta: 10, gamma: 15 },
interval: 16,
});
expect(await page.evaluate('result')).toBe('Moved');
expect(await page.evaluate('acceleration.x')).toBe(10);
expect(await page.evaluate('acceleration.y')).toBe(20);
expect(await page.evaluate('acceleration.z')).toBe(30);
expect(await page.evaluate('accelerationIncludingGravity.x')).toBe(15);
expect(await page.evaluate('accelerationIncludingGravity.y')).toBe(25);
expect(await page.evaluate('accelerationIncludingGravity.z')).toBe(35);
expect(await page.evaluate('rotationRate.alpha')).toBe(5);
expect(await page.evaluate('rotationRate.beta')).toBe(10);
expect(await page.evaluate('rotationRate.gamma')).toBe(15);
expect(await page.evaluate('interval')).toBe(16);
});