diff --git a/src/client/channelOwner.ts b/src/client/channelOwner.ts index eaaee561f2..8b2d603739 100644 --- a/src/client/channelOwner.ts +++ b/src/client/channelOwner.ts @@ -89,7 +89,7 @@ export abstract class ChannelOwner(func: (channel: C, stackTrace: ParsedStackTrace) => Promise, logger?: Logger): Promise { + async _wrapApiCall(func: (channel: C, stackTrace: ParsedStackTrace) => Promise, logger?: Logger): Promise { logger = logger || this._logger; const stackTrace = captureStackTrace(); const { apiName, frameTexts } = stackTrace; diff --git a/src/client/input.ts b/src/client/input.ts index 11ad5ba776..54c14c3f9d 100644 --- a/src/client/input.ts +++ b/src/client/input.ts @@ -17,56 +17,75 @@ import * as channels from '../protocol/channels'; import * as api from '../../types/types'; +import type { Page } from './page'; export class Keyboard implements api.Keyboard { - private _channel: channels.PageChannel; + private _page: Page; - constructor(channel: channels.PageChannel) { - this._channel = channel; + constructor(page: Page) { + this._page = page; } async down(key: string) { - await this._channel.keyboardDown({ key }); + await this._page._wrapApiCall(async channel => { + await channel.keyboardDown({ key }); + }); } async up(key: string) { - await this._channel.keyboardUp({ key }); + await this._page._wrapApiCall(async channel => { + await channel.keyboardUp({ key }); + }); } async insertText(text: string) { - await this._channel.keyboardInsertText({ text }); + await this._page._wrapApiCall(async channel => { + await channel.keyboardInsertText({ text }); + }); } async type(text: string, options: channels.PageKeyboardTypeOptions = {}) { - await this._channel.keyboardType({ text, ...options }); + await this._page._wrapApiCall(async channel => { + await channel.keyboardType({ text, ...options }); + }); } async press(key: string, options: channels.PageKeyboardPressOptions = {}) { - await this._channel.keyboardPress({ key, ...options }); + await this._page._wrapApiCall(async channel => { + await channel.keyboardPress({ key, ...options }); + }); } } export class Mouse implements api.Mouse { - private _channel: channels.PageChannel; + private _page: Page; - constructor(channel: channels.PageChannel) { - this._channel = channel; + constructor(page: Page) { + this._page = page; } async move(x: number, y: number, options: { steps?: number } = {}) { - await this._channel.mouseMove({ x, y, ...options }); + await this._page._wrapApiCall(async channel => { + await channel.mouseMove({ x, y, ...options }); + }); } async down(options: channels.PageMouseDownOptions = {}) { - await this._channel.mouseDown({ ...options }); + await this._page._wrapApiCall(async channel => { + await channel.mouseDown({ ...options }); + }); } async up(options: channels.PageMouseUpOptions = {}) { - await this._channel.mouseUp(options); + await this._page._wrapApiCall(async channel => { + await channel.mouseUp(options); + }); } async click(x: number, y: number, options: channels.PageMouseClickOptions = {}) { - await this._channel.mouseClick({ x, y, ...options }); + await this._page._wrapApiCall(async channel => { + await channel.mouseClick({ x, y, ...options }); + }); } async dblclick(x: number, y: number, options: Omit = {}) { @@ -75,13 +94,15 @@ export class Mouse implements api.Mouse { } export class Touchscreen implements api.Touchscreen { - private _channel: channels.PageChannel; + private _page: Page; - constructor(channel: channels.PageChannel) { - this._channel = channel; + constructor(page: Page) { + this._page = page; } async tap(x: number, y: number) { - await this._channel.touchscreenTap({x, y}); + await this._page._wrapApiCall(async channel => { + await channel.touchscreenTap({x, y}); + }); } } diff --git a/src/client/page.ts b/src/client/page.ts index 441670200d..c91e0ab2ea 100644 --- a/src/client/page.ts +++ b/src/client/page.ts @@ -98,9 +98,9 @@ export class Page extends ChannelOwner { expect(error.message).toContain('Unknown key: "NotARealKey"'); error = await page.keyboard.press('ё').catch(e => e); - expect(error && error.message).toBe('Unknown key: "ё"'); + expect(error && error.message).toContain('Unknown key: "ё"'); error = await page.keyboard.press('😊').catch(e => e); - expect(error && error.message).toBe('Unknown key: "😊"'); + expect(error && error.message).toContain('Unknown key: "😊"'); }); it('should type emoji', async ({page, server}) => { diff --git a/tests/tracing.spec.ts b/tests/tracing.spec.ts index bbacba9197..716c6fd175 100644 --- a/tests/tracing.spec.ts +++ b/tests/tracing.spec.ts @@ -25,6 +25,9 @@ test('should collect trace with resources, but no js', async ({ context, page, s await page.goto(server.PREFIX + '/frames/frame.html'); await page.setContent(''); await page.click('"Click"'); + await page.mouse.move(20, 20); + await page.mouse.dblclick(30, 30); + await page.keyboard.insertText('abc'); await page.waitForTimeout(2000); // Give it some time to produce screenshots. await page.close(); await context.tracing.stop({ path: testInfo.outputPath('trace.zip') }); @@ -34,6 +37,9 @@ test('should collect trace with resources, but no js', async ({ context, page, s expect(events.find(e => e.metadata?.apiName === 'page.goto')).toBeTruthy(); expect(events.find(e => e.metadata?.apiName === 'page.setContent')).toBeTruthy(); expect(events.find(e => e.metadata?.apiName === 'page.click')).toBeTruthy(); + expect(events.find(e => e.metadata?.apiName === 'mouse.move')).toBeTruthy(); + expect(events.find(e => e.metadata?.apiName === 'mouse.dblclick')).toBeTruthy(); + expect(events.find(e => e.metadata?.apiName === 'keyboard.insertText')).toBeTruthy(); expect(events.find(e => e.metadata?.apiName === 'page.close')).toBeTruthy(); expect(events.some(e => e.type === 'frame-snapshot')).toBeTruthy();