feat(mouse): page.mouse.wheel (#8690)
This commit is contained in:
parent
351c20be48
commit
afae5bef5d
|
|
@ -120,3 +120,22 @@ Dispatches a `mouseup` event.
|
||||||
### option: Mouse.up.button = %%-input-button-%%
|
### option: Mouse.up.button = %%-input-button-%%
|
||||||
|
|
||||||
### option: Mouse.up.clickCount = %%-input-click-count-%%
|
### option: Mouse.up.clickCount = %%-input-click-count-%%
|
||||||
|
|
||||||
|
## async method: Mouse.wheel
|
||||||
|
|
||||||
|
Dispatches a `wheel` event.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
Wheel events may cause scrolling if they are not handled, and this method does not
|
||||||
|
wait for the scrolling to finish before returning.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### param: Mouse.wheel.deltaX
|
||||||
|
- `deltaX` <[float]>
|
||||||
|
|
||||||
|
Pixels to scroll horizontally.
|
||||||
|
|
||||||
|
### param: Mouse.wheel.deltaY
|
||||||
|
- `deltaY` <[float]>
|
||||||
|
|
||||||
|
Pixels to scroll vertically.
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,12 @@ export class Mouse implements api.Mouse {
|
||||||
async dblclick(x: number, y: number, options: Omit<channels.PageMouseClickOptions, 'clickCount'> = {}) {
|
async dblclick(x: number, y: number, options: Omit<channels.PageMouseClickOptions, 'clickCount'> = {}) {
|
||||||
await this.click(x, y, { ...options, clickCount: 2 });
|
await this.click(x, y, { ...options, clickCount: 2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async wheel(deltaX: number, deltaY: number) {
|
||||||
|
await this._page._wrapApiCall(async channel => {
|
||||||
|
await channel.mouseWheel({ deltaX, deltaY });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Touchscreen implements api.Touchscreen {
|
export class Touchscreen implements api.Touchscreen {
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,10 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageInitializer, c
|
||||||
await this._page.mouse.click(params.x, params.y, params);
|
await this._page.mouse.click(params.x, params.y, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async mouseWheel(params: channels.PageMouseWheelParams, metadata: CallMetadata): Promise<void> {
|
||||||
|
await this._page.mouse.wheel(params.deltaX, params.deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
async touchscreenTap(params: channels.PageTouchscreenTapParams, metadata: CallMetadata): Promise<void> {
|
async touchscreenTap(params: channels.PageTouchscreenTapParams, metadata: CallMetadata): Promise<void> {
|
||||||
await this._page.touchscreen.tap(params.x, params.y);
|
await this._page.touchscreen.tap(params.x, params.y);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1105,6 +1105,7 @@ export interface PageChannel extends EventTargetChannel {
|
||||||
mouseDown(params: PageMouseDownParams, metadata?: Metadata): Promise<PageMouseDownResult>;
|
mouseDown(params: PageMouseDownParams, metadata?: Metadata): Promise<PageMouseDownResult>;
|
||||||
mouseUp(params: PageMouseUpParams, metadata?: Metadata): Promise<PageMouseUpResult>;
|
mouseUp(params: PageMouseUpParams, metadata?: Metadata): Promise<PageMouseUpResult>;
|
||||||
mouseClick(params: PageMouseClickParams, metadata?: Metadata): Promise<PageMouseClickResult>;
|
mouseClick(params: PageMouseClickParams, metadata?: Metadata): Promise<PageMouseClickResult>;
|
||||||
|
mouseWheel(params: PageMouseWheelParams, metadata?: Metadata): Promise<PageMouseWheelResult>;
|
||||||
touchscreenTap(params: PageTouchscreenTapParams, metadata?: Metadata): Promise<PageTouchscreenTapResult>;
|
touchscreenTap(params: PageTouchscreenTapParams, metadata?: Metadata): Promise<PageTouchscreenTapResult>;
|
||||||
accessibilitySnapshot(params: PageAccessibilitySnapshotParams, metadata?: Metadata): Promise<PageAccessibilitySnapshotResult>;
|
accessibilitySnapshot(params: PageAccessibilitySnapshotParams, metadata?: Metadata): Promise<PageAccessibilitySnapshotResult>;
|
||||||
pdf(params: PagePdfParams, metadata?: Metadata): Promise<PagePdfResult>;
|
pdf(params: PagePdfParams, metadata?: Metadata): Promise<PagePdfResult>;
|
||||||
|
|
@ -1367,6 +1368,14 @@ export type PageMouseClickOptions = {
|
||||||
clickCount?: number,
|
clickCount?: number,
|
||||||
};
|
};
|
||||||
export type PageMouseClickResult = void;
|
export type PageMouseClickResult = void;
|
||||||
|
export type PageMouseWheelParams = {
|
||||||
|
deltaX: number,
|
||||||
|
deltaY: number,
|
||||||
|
};
|
||||||
|
export type PageMouseWheelOptions = {
|
||||||
|
|
||||||
|
};
|
||||||
|
export type PageMouseWheelResult = void;
|
||||||
export type PageTouchscreenTapParams = {
|
export type PageTouchscreenTapParams = {
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
|
|
@ -3626,6 +3635,7 @@ export const commandsWithTracingSnapshots = new Set([
|
||||||
'Page.mouseDown',
|
'Page.mouseDown',
|
||||||
'Page.mouseUp',
|
'Page.mouseUp',
|
||||||
'Page.mouseClick',
|
'Page.mouseClick',
|
||||||
|
'Page.mouseWheel',
|
||||||
'Page.touchscreenTap',
|
'Page.touchscreenTap',
|
||||||
'Frame.evalOnSelector',
|
'Frame.evalOnSelector',
|
||||||
'Frame.evalOnSelectorAll',
|
'Frame.evalOnSelectorAll',
|
||||||
|
|
|
||||||
|
|
@ -1024,6 +1024,13 @@ Page:
|
||||||
tracing:
|
tracing:
|
||||||
snapshot: true
|
snapshot: true
|
||||||
|
|
||||||
|
mouseWheel:
|
||||||
|
parameters:
|
||||||
|
deltaX: number
|
||||||
|
deltaY: number
|
||||||
|
tracing:
|
||||||
|
snapshot: true
|
||||||
|
|
||||||
touchscreenTap:
|
touchscreenTap:
|
||||||
parameters:
|
parameters:
|
||||||
x: number
|
x: number
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,10 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
button: tOptional(tEnum(['left', 'right', 'middle'])),
|
button: tOptional(tEnum(['left', 'right', 'middle'])),
|
||||||
clickCount: tOptional(tNumber),
|
clickCount: tOptional(tNumber),
|
||||||
});
|
});
|
||||||
|
scheme.PageMouseWheelParams = tObject({
|
||||||
|
deltaX: tNumber,
|
||||||
|
deltaY: tNumber,
|
||||||
|
});
|
||||||
scheme.PageTouchscreenTapParams = tObject({
|
scheme.PageTouchscreenTapParams = tObject({
|
||||||
x: tNumber,
|
x: tNumber,
|
||||||
y: tNumber,
|
y: tNumber,
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,17 @@ export class RawMouseImpl implements input.RawMouse {
|
||||||
clickCount
|
clickCount
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
||||||
|
await this._client.send('Input.dispatchMouseEvent', {
|
||||||
|
type: 'mouseWheel',
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
modifiers: toModifiersMask(modifiers),
|
||||||
|
deltaX,
|
||||||
|
deltaY,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as input from '../input';
|
import * as input from '../input';
|
||||||
|
import { Page } from '../page';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { FFSession } from './ffConnection';
|
import { FFSession } from './ffConnection';
|
||||||
|
|
||||||
|
|
@ -101,6 +102,7 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
|
|
||||||
export class RawMouseImpl implements input.RawMouse {
|
export class RawMouseImpl implements input.RawMouse {
|
||||||
private _client: FFSession;
|
private _client: FFSession;
|
||||||
|
private _page?: Page;
|
||||||
|
|
||||||
constructor(client: FFSession) {
|
constructor(client: FFSession) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
|
|
@ -140,6 +142,23 @@ export class RawMouseImpl implements input.RawMouse {
|
||||||
clickCount
|
clickCount
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
||||||
|
// Wheel events hit the compositor first, so wait one frame for it to be synced.
|
||||||
|
await this._page!.mainFrame().evaluateExpression(`new Promise(requestAnimationFrame)`, false, false, 'utility');
|
||||||
|
await this._client.send('Page.dispatchWheelEvent', {
|
||||||
|
deltaX,
|
||||||
|
deltaY,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
deltaZ: 0,
|
||||||
|
modifiers: toModifiersMask(modifiers)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setPage(page: Page) {
|
||||||
|
this._page = page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ export class FFPage implements PageDelegate {
|
||||||
this._contextIdToContext = new Map();
|
this._contextIdToContext = new Map();
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
this._page = new Page(this, browserContext);
|
this._page = new Page(this, browserContext);
|
||||||
|
this.rawMouse.setPage(this._page);
|
||||||
this._networkManager = new FFNetworkManager(session, this._page);
|
this._networkManager = new FFNetworkManager(session, this._page);
|
||||||
this._page.on(Page.Events.FrameDetached, frame => this._removeContextsForFrame(frame));
|
this._page.on(Page.Events.FrameDetached, frame => this._removeContextsForFrame(frame));
|
||||||
// TODO: remove Page.willOpenNewWindowAsynchronously from the protocol.
|
// TODO: remove Page.willOpenNewWindowAsynchronously from the protocol.
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ export interface RawMouse {
|
||||||
move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>): Promise<void>;
|
move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>): Promise<void>;
|
||||||
down(x: number, y: number, button: types.MouseButton, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, clickCount: number): Promise<void>;
|
down(x: number, y: number, button: types.MouseButton, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, clickCount: number): Promise<void>;
|
||||||
up(x: number, y: number, button: types.MouseButton, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, clickCount: number): Promise<void>;
|
up(x: number, y: number, button: types.MouseButton, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, clickCount: number): Promise<void>;
|
||||||
|
wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Mouse {
|
export class Mouse {
|
||||||
|
|
@ -232,6 +233,11 @@ export class Mouse {
|
||||||
async dblclick(x: number, y: number, options: { delay?: number, button?: types.MouseButton } = {}) {
|
async dblclick(x: number, y: number, options: { delay?: number, button?: types.MouseButton } = {}) {
|
||||||
await this.click(x, y, { ...options, clickCount: 2 });
|
await this.click(x, y, { ...options, clickCount: 2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async wheel(deltaX: number, deltaY: number) {
|
||||||
|
await this._raw.wheel(this._x, this._y, this._buttons, this._keyboard._modifiers(), deltaX, deltaY);
|
||||||
|
await this._page._doSlowMo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const aliases = new Map<string, string[]>([
|
const aliases = new Map<string, string[]>([
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import * as types from '../types';
|
||||||
import { macEditingCommands } from '../macEditingCommands';
|
import { macEditingCommands } from '../macEditingCommands';
|
||||||
import { WKSession } from './wkConnection';
|
import { WKSession } from './wkConnection';
|
||||||
import { isString } from '../../utils/utils';
|
import { isString } from '../../utils/utils';
|
||||||
|
import type { Page } from '../page';
|
||||||
|
|
||||||
function toModifiersMask(modifiers: Set<types.KeyboardModifier>): number {
|
function toModifiersMask(modifiers: Set<types.KeyboardModifier>): number {
|
||||||
// From Source/WebKit/Shared/WebEvent.h
|
// From Source/WebKit/Shared/WebEvent.h
|
||||||
|
|
@ -101,11 +102,17 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
|
|
||||||
export class RawMouseImpl implements input.RawMouse {
|
export class RawMouseImpl implements input.RawMouse {
|
||||||
private readonly _pageProxySession: WKSession;
|
private readonly _pageProxySession: WKSession;
|
||||||
|
private _session?: WKSession;
|
||||||
|
private _page?: Page;
|
||||||
|
|
||||||
constructor(session: WKSession) {
|
constructor(session: WKSession) {
|
||||||
this._pageProxySession = session;
|
this._pageProxySession = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSession(session: WKSession) {
|
||||||
|
this._session = session;
|
||||||
|
}
|
||||||
|
|
||||||
async move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>): Promise<void> {
|
async move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>): Promise<void> {
|
||||||
await this._pageProxySession.send('Input.dispatchMouseEvent', {
|
await this._pageProxySession.send('Input.dispatchMouseEvent', {
|
||||||
type: 'move',
|
type: 'move',
|
||||||
|
|
@ -140,6 +147,23 @@ export class RawMouseImpl implements input.RawMouse {
|
||||||
clickCount
|
clickCount
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
||||||
|
await this._session!.send('Page.updateScrollingState');
|
||||||
|
// Wheel events hit the compositor first, so wait one frame for it to be synced.
|
||||||
|
await this._page!.mainFrame().evaluateExpression(`new Promise(requestAnimationFrame)`, false, false, 'utility');
|
||||||
|
await this._pageProxySession.send('Input.dispatchWheelEvent', {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
deltaX,
|
||||||
|
deltaY,
|
||||||
|
modifiers: toModifiersMask(modifiers),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setPage(page: Page) {
|
||||||
|
this._page = page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
export class RawTouchscreenImpl implements input.RawTouchscreen {
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ export class WKPage implements PageDelegate {
|
||||||
this.rawTouchscreen = new RawTouchscreenImpl(pageProxySession);
|
this.rawTouchscreen = new RawTouchscreenImpl(pageProxySession);
|
||||||
this._contextIdToContext = new Map();
|
this._contextIdToContext = new Map();
|
||||||
this._page = new Page(this, browserContext);
|
this._page = new Page(this, browserContext);
|
||||||
|
this.rawMouse.setPage(this._page);
|
||||||
this._workers = new WKWorkers(this._page);
|
this._workers = new WKWorkers(this._page);
|
||||||
this._session = undefined as any as WKSession;
|
this._session = undefined as any as WKSession;
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
|
|
@ -139,6 +140,7 @@ export class WKPage implements PageDelegate {
|
||||||
eventsHelper.removeEventListeners(this._sessionListeners);
|
eventsHelper.removeEventListeners(this._sessionListeners);
|
||||||
this._session = session;
|
this._session = session;
|
||||||
this.rawKeyboard.setSession(session);
|
this.rawKeyboard.setSession(session);
|
||||||
|
this.rawMouse.setSession(session);
|
||||||
this._addSessionListeners();
|
this._addSessionListeners();
|
||||||
this._workers.setSession(session);
|
this._workers.setSession(session);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
127
tests/page/wheel.spec.ts
Normal file
127
tests/page/wheel.spec.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import type { Page } from '../../';
|
||||||
|
import { test as it, expect } from './pageTest';
|
||||||
|
it.skip(({isElectron, browserMajorVersion}) => {
|
||||||
|
// Old Electron has flaky wheel events.
|
||||||
|
return isElectron && browserMajorVersion <= 11;
|
||||||
|
});
|
||||||
|
it('should dispatch wheel events', async ({page, server}) => {
|
||||||
|
await page.setContent(`<div style="width: 5000px; height: 5000px;"></div>`);
|
||||||
|
await page.mouse.move(50, 60);
|
||||||
|
await listenForWheelEvents(page, 'div');
|
||||||
|
await page.mouse.wheel(0, 100);
|
||||||
|
expect(await page.evaluate('window.lastEvent')).toEqual({
|
||||||
|
deltaX: 0,
|
||||||
|
deltaY: 100,
|
||||||
|
clientX: 50,
|
||||||
|
clientY: 60,
|
||||||
|
deltaMode: 0,
|
||||||
|
ctrlKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
altKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
});
|
||||||
|
await page.waitForFunction('window.scrollY === 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll when nobody is listening', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||||
|
await page.mouse.move(50, 60);
|
||||||
|
await page.mouse.wheel(0, 100);
|
||||||
|
await page.waitForFunction('window.scrollY === 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the modifiers', async ({page}) => {
|
||||||
|
await page.setContent(`<div style="width: 5000px; height: 5000px;"></div>`);
|
||||||
|
await page.mouse.move(50, 60);
|
||||||
|
await listenForWheelEvents(page, 'div');
|
||||||
|
await page.keyboard.down('Shift');
|
||||||
|
await page.mouse.wheel(0, 100);
|
||||||
|
expect(await page.evaluate('window.lastEvent')).toEqual({
|
||||||
|
deltaX: 0,
|
||||||
|
deltaY: 100,
|
||||||
|
clientX: 50,
|
||||||
|
clientY: 60,
|
||||||
|
deltaMode: 0,
|
||||||
|
ctrlKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll horizontally', async ({page}) => {
|
||||||
|
await page.setContent(`<div style="width: 5000px; height: 5000px;"></div>`);
|
||||||
|
await page.mouse.move(50, 60);
|
||||||
|
await listenForWheelEvents(page, 'div');
|
||||||
|
await page.mouse.wheel(100, 0);
|
||||||
|
expect(await page.evaluate('window.lastEvent')).toEqual({
|
||||||
|
deltaX: 100,
|
||||||
|
deltaY: 0,
|
||||||
|
clientX: 50,
|
||||||
|
clientY: 60,
|
||||||
|
deltaMode: 0,
|
||||||
|
ctrlKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
altKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
});
|
||||||
|
await page.waitForFunction('window.scrollX === 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work when the event is canceled', async ({page}) => {
|
||||||
|
await page.setContent(`<div style="width: 5000px; height: 5000px;"></div>`);
|
||||||
|
await page.mouse.move(50, 60);
|
||||||
|
await listenForWheelEvents(page, 'div');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
document.querySelector('div').addEventListener('wheel', e => e.preventDefault());
|
||||||
|
});
|
||||||
|
await page.mouse.wheel(0, 100);
|
||||||
|
expect(await page.evaluate('window.lastEvent')).toEqual({
|
||||||
|
deltaX: 0,
|
||||||
|
deltaY: 100,
|
||||||
|
clientX: 50,
|
||||||
|
clientY: 60,
|
||||||
|
deltaMode: 0,
|
||||||
|
ctrlKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
altKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
});
|
||||||
|
// give the page a chacne to scroll
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
// ensure that it did not.
|
||||||
|
expect(await page.evaluate('window.scrollY')).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function listenForWheelEvents(page: Page, selector: string) {
|
||||||
|
await page.evaluate(selector => {
|
||||||
|
document.querySelector(selector).addEventListener('wheel', (e: WheelEvent) => {
|
||||||
|
window['lastEvent'] = {
|
||||||
|
deltaX: e.deltaX,
|
||||||
|
deltaY: e.deltaY,
|
||||||
|
clientX: e.clientX,
|
||||||
|
clientY: e.clientY,
|
||||||
|
deltaMode: e.deltaMode,
|
||||||
|
ctrlKey: e.ctrlKey,
|
||||||
|
shiftKey: e.shiftKey,
|
||||||
|
altKey: e.altKey,
|
||||||
|
metaKey: e.metaKey,
|
||||||
|
};
|
||||||
|
}, { passive: false });
|
||||||
|
}, selector);
|
||||||
|
}
|
||||||
10
types/types.d.ts
vendored
10
types/types.d.ts
vendored
|
|
@ -13185,6 +13185,16 @@ export interface Mouse {
|
||||||
*/
|
*/
|
||||||
clickCount?: number;
|
clickCount?: number;
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches a `wheel` event.
|
||||||
|
*
|
||||||
|
* > NOTE: Wheel events may cause scrolling if they are not handled, and this method does not wait for the scrolling to
|
||||||
|
* finish before returning.
|
||||||
|
* @param deltaX Pixels to scroll horizontally.
|
||||||
|
* @param deltaY Pixels to scroll vertically.
|
||||||
|
*/
|
||||||
|
wheel(deltaX: number, deltaY: number): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue