From 263aa06fa4832d401d983e93b55d247b4e0ee7be Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 11 Sep 2020 13:28:24 -0700 Subject: [PATCH] feat(trace): trace more actions (#3853) --- src/dispatchers/elementHandlerDispatcher.ts | 66 ++++++++++++------- src/dispatchers/frameDispatcher.ts | 70 ++++++++++++++------- src/server/dom.ts | 66 ++++++++----------- src/server/frames.ts | 36 +++++------ src/server/instrumentation.ts | 2 +- 5 files changed, 136 insertions(+), 104 deletions(-) diff --git a/src/dispatchers/elementHandlerDispatcher.ts b/src/dispatchers/elementHandlerDispatcher.ts index 75ae169f7c..376c7b6b51 100644 --- a/src/dispatchers/elementHandlerDispatcher.ts +++ b/src/dispatchers/elementHandlerDispatcher.ts @@ -75,59 +75,83 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann await this._elementHandle.scrollIntoViewIfNeeded(params); } - async hover(params: channels.ElementHandleHoverParams): Promise { - await this._elementHandle.hover(params); + async hover(params: channels.ElementHandleHoverParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'hover', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.hover(progress, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } async click(params: channels.ElementHandleClickParams, metadata?: channels.Metadata): Promise { - const clickMetadata: ActionMetadata = { ...metadata, type: 'click', target: this._elementHandle, page: this._elementHandle._page }; + const actionMetadata: ActionMetadata = { ...metadata, type: 'click', target: this._elementHandle, page: this._elementHandle._page }; return runAbortableTask(async progress => { return await this._elementHandle.click(progress, params); - }, this._elementHandle._page._timeoutSettings.timeout(params), clickMetadata); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } - async dblclick(params: channels.ElementHandleDblclickParams): Promise { - await this._elementHandle.dblclick(params); + async dblclick(params: channels.ElementHandleDblclickParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'dblclick', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.dblclick(progress, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } - async selectOption(params: channels.ElementHandleSelectOptionParams): Promise { - const elements = (params.elements || []).map(e => (e as ElementHandleDispatcher)._elementHandle); - return { values: await this._elementHandle.selectOption(elements, params.options || [], params) }; + async selectOption(params: channels.ElementHandleSelectOptionParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'selectOption', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + const elements = (params.elements || []).map(e => (e as ElementHandleDispatcher)._elementHandle); + return { values: await this._elementHandle.selectOption(progress, elements, params.options || [], params) }; + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } async fill(params: channels.ElementHandleFillParams, metadata?: channels.Metadata): Promise { - const fillMetadata: ActionMetadata = { ...metadata, type: 'fill', value: params.value, target: this._elementHandle, page: this._elementHandle._page }; + const actionMetadata: ActionMetadata = { ...metadata, type: 'fill', value: params.value, target: this._elementHandle, page: this._elementHandle._page }; return runAbortableTask(async progress => { return await this._elementHandle.fill(progress, params.value, params); - }, this._elementHandle._page._timeoutSettings.timeout(params), fillMetadata); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } async selectText(params: channels.ElementHandleSelectTextParams): Promise { await this._elementHandle.selectText(params); } - async setInputFiles(params: channels.ElementHandleSetInputFilesParams): Promise { - await this._elementHandle.setInputFiles(params.files, params); + async setInputFiles(params: channels.ElementHandleSetInputFilesParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'setInputFiles', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.setInputFiles(progress, params.files, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } async focus(): Promise { await this._elementHandle.focus(); } - async type(params: channels.ElementHandleTypeParams): Promise { - await this._elementHandle.type(params.text, params); + async type(params: channels.ElementHandleTypeParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'type', value: params.text, target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.type(progress, params.text, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } - async press(params: channels.ElementHandlePressParams): Promise { - await this._elementHandle.press(params.key, params); + async press(params: channels.ElementHandlePressParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'press', value: params.key, target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.press(progress, params.key, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } - async check(params: channels.ElementHandleCheckParams): Promise { - await this._elementHandle.check(params); + async check(params: channels.ElementHandleCheckParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'check', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.check(progress, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } - async uncheck(params: channels.ElementHandleUncheckParams): Promise { - await this._elementHandle.uncheck(params); + async uncheck(params: channels.ElementHandleUncheckParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'uncheck', target: this._elementHandle, page: this._elementHandle._page }; + return runAbortableTask(async progress => { + return await this._elementHandle.uncheck(progress, params); + }, this._elementHandle._page._timeoutSettings.timeout(params), actionMetadata); } async boundingBox(): Promise { diff --git a/src/dispatchers/frameDispatcher.ts b/src/dispatchers/frameDispatcher.ts index 8c562722f1..43adf40cdc 100644 --- a/src/dispatchers/frameDispatcher.ts +++ b/src/dispatchers/frameDispatcher.ts @@ -111,21 +111,24 @@ export class FrameDispatcher extends Dispatcher { - const clickMetadata: ActionMetadata = { ...metadata, type: 'click', target: params.selector, page: this._frame._page }; - await runAbortableTask(async progress => { + const actionMetadata: ActionMetadata = { ...metadata, type: 'click', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { return await this._frame.click(progress, params.selector, params); - }, this._frame._page._timeoutSettings.timeout(params), clickMetadata); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async dblclick(params: channels.FrameDblclickParams): Promise { - await this._frame.dblclick(params.selector, params); + async dblclick(params: channels.FrameDblclickParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'dblclick', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.dblclick(progress, params.selector, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } async fill(params: channels.FrameFillParams, metadata?: channels.Metadata): Promise { - const fillMetadata: ActionMetadata = { ...metadata, type: 'fill', value: params.value, target: params.selector, page: this._frame._page }; - await runAbortableTask(async progress => { + const actionMetadata: ActionMetadata = { ...metadata, type: 'fill', value: params.value, target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { return await this._frame.fill(progress, params.selector, params.value, params); - }, this._frame._page._timeoutSettings.timeout(params), fillMetadata); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } async focus(params: channels.FrameFocusParams): Promise { @@ -150,33 +153,54 @@ export class FrameDispatcher extends Dispatcher { - await this._frame.hover(params.selector, params); + async hover(params: channels.FrameHoverParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'hover', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.hover(progress, params.selector, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async selectOption(params: channels.FrameSelectOptionParams): Promise { - const elements = (params.elements || []).map(e => (e as ElementHandleDispatcher)._elementHandle); - return { values: await this._frame.selectOption(params.selector, elements, params.options || [], params) }; + async selectOption(params: channels.FrameSelectOptionParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'selectOption', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + const elements = (params.elements || []).map(e => (e as ElementHandleDispatcher)._elementHandle); + return { values: await this._frame.selectOption(progress, params.selector, elements, params.options || [], params) }; + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async setInputFiles(params: channels.FrameSetInputFilesParams): Promise { - await this._frame.setInputFiles(params.selector, params.files, params); + async setInputFiles(params: channels.FrameSetInputFilesParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'setInputFiles', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.setInputFiles(progress, params.selector, params.files, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async type(params: channels.FrameTypeParams): Promise { - await this._frame.type(params.selector, params.text, params); + async type(params: channels.FrameTypeParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'type', value: params.text, target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.type(progress, params.selector, params.text, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async press(params: channels.FramePressParams): Promise { - await this._frame.press(params.selector, params.key, params); + async press(params: channels.FramePressParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'press', value: params.key, target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.press(progress, params.selector, params.key, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async check(params: channels.FrameCheckParams): Promise { - await this._frame.check(params.selector, params); + async check(params: channels.FrameCheckParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'check', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.check(progress, params.selector, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } - async uncheck(params: channels.FrameUncheckParams): Promise { - await this._frame.uncheck(params.selector, params); + async uncheck(params: channels.FrameUncheckParams, metadata?: channels.Metadata): Promise { + const actionMetadata: ActionMetadata = { ...metadata, type: 'uncheck', target: params.selector, page: this._frame._page }; + return runAbortableTask(async progress => { + return await this._frame.uncheck(progress, params.selector, params); + }, this._frame._page._timeoutSettings.timeout(params), actionMetadata); } async waitForFunction(params: channels.FrameWaitForFunctionParams): Promise { diff --git a/src/server/dom.ts b/src/server/dom.ts index 6256485f4b..f1f4fd6bcd 100644 --- a/src/server/dom.ts +++ b/src/server/dom.ts @@ -358,11 +358,9 @@ export class ElementHandle extends js.JSHandle { return 'done'; } - hover(options: types.PointerActionOptions & types.PointerActionWaitOptions = {}): Promise { - return this._page._runAbortableTask(async progress => { - const result = await this._hover(progress, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions): Promise { + const result = await this._hover(progress, options); + return assertDone(throwRetargetableDOMError(result)); } _hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> { @@ -378,22 +376,18 @@ export class ElementHandle extends js.JSHandle { return this._retryPointerAction(progress, 'click', true /* waitForEnabled */, point => this._page.mouse.click(point.x, point.y, options), options); } - dblclick(options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise { - return this._page._runAbortableTask(async progress => { - const result = await this._dblclick(progress, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async dblclick(progress: Progress, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise { + const result = await this._dblclick(progress, options); + return assertDone(throwRetargetableDOMError(result)); } _dblclick(progress: Progress, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { return this._retryPointerAction(progress, 'dblclick', true /* waitForEnabled */, point => this._page.mouse.dblclick(point.x, point.y, options), options); } - async selectOption(elements: ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions = {}): Promise { - return this._page._runAbortableTask(async progress => { - const result = await this._selectOption(progress, elements, values, options); - return throwRetargetableDOMError(result); - }, this._page._timeoutSettings.timeout(options)); + async selectOption(progress: Progress, elements: ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions): Promise { + const result = await this._selectOption(progress, elements, values, options); + return throwRetargetableDOMError(result); } async _selectOption(progress: Progress, elements: ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions): Promise { @@ -449,11 +443,9 @@ export class ElementHandle extends js.JSHandle { }, this._page._timeoutSettings.timeout(options)); } - async setInputFiles(files: types.FilePayload[], options: types.NavigatingActionWaitOptions = {}) { - return this._page._runAbortableTask(async progress => { - const result = await this._setInputFiles(progress, files, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async setInputFiles(progress: Progress, files: types.FilePayload[], options: types.NavigatingActionWaitOptions) { + const result = await this._setInputFiles(progress, files, options); + return assertDone(throwRetargetableDOMError(result)); } async _setInputFiles(progress: Progress, files: types.FilePayload[], options: types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { @@ -490,11 +482,9 @@ export class ElementHandle extends js.JSHandle { return throwFatalDOMError(result); } - async type(text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}): Promise { - return this._page._runAbortableTask(async progress => { - const result = await this._type(progress, text, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async type(progress: Progress, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise { + const result = await this._type(progress, text, options); + return assertDone(throwRetargetableDOMError(result)); } async _type(progress: Progress, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { @@ -509,11 +499,9 @@ export class ElementHandle extends js.JSHandle { }, 'input'); } - async press(key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}): Promise { - return this._page._runAbortableTask(async progress => { - const result = await this._press(progress, key, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async press(progress: Progress, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise { + const result = await this._press(progress, key, options); + return assertDone(throwRetargetableDOMError(result)); } async _press(progress: Progress, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { @@ -528,18 +516,14 @@ export class ElementHandle extends js.JSHandle { }, 'input'); } - async check(options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { - return this._page._runAbortableTask(async progress => { - const result = await this._setChecked(progress, true, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async check(progress: Progress, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { + const result = await this._setChecked(progress, true, options); + return assertDone(throwRetargetableDOMError(result)); } - async uncheck(options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { - return this._page._runAbortableTask(async progress => { - const result = await this._setChecked(progress, false, options); - return assertDone(throwRetargetableDOMError(result)); - }, this._page._timeoutSettings.timeout(options)); + async uncheck(progress: Progress, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { + const result = await this._setChecked(progress, false, options); + return assertDone(throwRetargetableDOMError(result)); } async _setChecked(progress: Progress, state: boolean, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> { @@ -789,7 +773,7 @@ function throwRetargetableDOMError(result: T | RetargetableDOMError): T { return result; } -function assertDone(result: 'done'): void { +export function assertDone(result: 'done'): void { // This function converts 'done' to void and ensures typescript catches unhandled errors. } diff --git a/src/server/frames.ts b/src/server/frames.ts index 17683659ab..c158a2628b 100644 --- a/src/server/frames.ts +++ b/src/server/frames.ts @@ -805,15 +805,15 @@ export class Frame extends EventEmitter { } async click(progress: Progress, selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { - return this._retryWithProgressIfNotConnected(progress, selector, handle => handle._click(progress, options)); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._click(progress, options))); } - async dblclick(selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._dblclick(progress, options)); + async dblclick(progress: Progress, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._dblclick(progress, options))); } async fill(progress: Progress, selector: string, value: string, options: types.NavigatingActionWaitOptions) { - return this._retryWithProgressIfNotConnected(progress, selector, handle => handle._fill(progress, value, options)); + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._fill(progress, value, options))); } async focus(selector: string, options: types.TimeoutOptions = {}) { @@ -858,32 +858,32 @@ export class Frame extends EventEmitter { }, this._page._timeoutSettings.timeout(options)); } - async hover(selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._hover(progress, options)); + async hover(progress: Progress, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._hover(progress, options))); } - async selectOption(selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions = {}): Promise { - return this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._selectOption(progress, elements, values, options)); + async selectOption(progress: Progress, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions = {}): Promise { + return await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._selectOption(progress, elements, values, options)); } - async setInputFiles(selector: string, files: types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setInputFiles(progress, files, options)); + async setInputFiles(progress: Progress, selector: string, files: types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._setInputFiles(progress, files, options))); } - async type(selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._type(progress, text, options)); + async type(progress: Progress, selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._type(progress, text, options))); } - async press(selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._press(progress, key, options)); + async press(progress: Progress, selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._press(progress, key, options))); } - async check(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, true, options)); + async check(progress: Progress, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._setChecked(progress, true, options))); } - async uncheck(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { - await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, false, options)); + async uncheck(progress: Progress, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { + return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, handle => handle._setChecked(progress, false, options))); } async _waitForFunctionExpression(expression: string, isFunction: boolean, arg: any, options: types.WaitForFunctionOptions = {}): Promise> { diff --git a/src/server/instrumentation.ts b/src/server/instrumentation.ts index 63636a9275..1b99ea8872 100644 --- a/src/server/instrumentation.ts +++ b/src/server/instrumentation.ts @@ -19,7 +19,7 @@ import type { ElementHandle } from './dom'; import type { Page } from './page'; export type ActionMetadata = { - type: 'click' | 'fill', + type: 'click' | 'fill' | 'dblclick' | 'hover' | 'selectOption' | 'setInputFiles' | 'type' | 'press' | 'check' | 'uncheck', page: Page, target: ElementHandle | string, value?: string,