From d91c3ed6757749da2c8c064b9151b7fad536f325 Mon Sep 17 00:00:00 2001 From: jrandolf <101637635+jrandolf@users.noreply.github.com> Date: Thu, 31 Aug 2023 14:04:40 +0200 Subject: [PATCH] chore: implement `throwIfDisposed` (#10819) --- .../puppeteer-core/src/common/ElementHandle.ts | 14 ++++++++++++++ packages/puppeteer-core/src/common/types.ts | 7 +++++++ packages/puppeteer-core/src/util/decorators.ts | 18 +++++++++++++++++- test/TestExpectations.json | 12 ++++++------ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/puppeteer-core/src/common/ElementHandle.ts b/packages/puppeteer-core/src/common/ElementHandle.ts index 6980f7f9..69f8648c 100644 --- a/packages/puppeteer-core/src/common/ElementHandle.ts +++ b/packages/puppeteer-core/src/common/ElementHandle.ts @@ -19,6 +19,7 @@ import {Protocol} from 'devtools-protocol'; import {AutofillData, ElementHandle, Point} from '../api/ElementHandle.js'; import {Page, ScreenshotOptions} from '../api/Page.js'; import {assert} from '../util/assert.js'; +import {throwIfDisposed} from '../util/decorators.js'; import {CDPSession} from './Connection.js'; import {ExecutionContext} from './ExecutionContext.js'; @@ -81,6 +82,7 @@ export class CDPElementHandle< return this.#frame; } + @throwIfDisposed() override async $( selector: Selector ): Promise> | null> { @@ -89,6 +91,7 @@ export class CDPElementHandle< > | null>; } + @throwIfDisposed() override async $$( selector: Selector ): Promise>>> { @@ -97,6 +100,7 @@ export class CDPElementHandle< >; } + @throwIfDisposed() override async waitForSelector( selector: Selector, options?: WaitForSelectorOptions @@ -109,6 +113,7 @@ export class CDPElementHandle< override async contentFrame( this: ElementHandle ): Promise; + @throwIfDisposed() override async contentFrame(): Promise { const nodeInfo = await this.client.send('DOM.describeNode', { objectId: this.id, @@ -119,6 +124,7 @@ export class CDPElementHandle< return this.#frameManager.frame(nodeInfo.node.frameId); } + @throwIfDisposed() override async scrollIntoView( this: CDPElementHandle ): Promise { @@ -137,6 +143,7 @@ export class CDPElementHandle< /** * This method creates and captures a dragevent from the element. */ + @throwIfDisposed() override async drag( this: CDPElementHandle, target: Point @@ -150,6 +157,7 @@ export class CDPElementHandle< return await this.#page.mouse.drag(start, target); } + @throwIfDisposed() override async dragEnter( this: CDPElementHandle, data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} @@ -159,6 +167,7 @@ export class CDPElementHandle< await this.#page.mouse.dragEnter(target, data); } + @throwIfDisposed() override async dragOver( this: CDPElementHandle, data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} @@ -168,6 +177,7 @@ export class CDPElementHandle< await this.#page.mouse.dragOver(target, data); } + @throwIfDisposed() override async drop( this: CDPElementHandle, data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} @@ -177,6 +187,7 @@ export class CDPElementHandle< await this.#page.mouse.drop(destination, data); } + @throwIfDisposed() override async dragAndDrop( this: CDPElementHandle, target: CDPElementHandle, @@ -192,6 +203,7 @@ export class CDPElementHandle< await this.#page.mouse.dragAndDrop(startPoint, targetPoint, options); } + @throwIfDisposed() override async uploadFile( this: CDPElementHandle, ...filePaths: string[] @@ -249,6 +261,7 @@ export class CDPElementHandle< } } + @throwIfDisposed() override async screenshot( this: CDPElementHandle, options: ScreenshotOptions = {} @@ -307,6 +320,7 @@ export class CDPElementHandle< return imageData; } + @throwIfDisposed() override async autofill(data: AutofillData): Promise { const nodeInfo = await this.client.send('DOM.describeNode', { objectId: this.handle.id, diff --git a/packages/puppeteer-core/src/common/types.ts b/packages/puppeteer-core/src/common/types.ts index cf861cd6..572ff23a 100644 --- a/packages/puppeteer-core/src/common/types.ts +++ b/packages/puppeteer-core/src/common/types.ts @@ -29,6 +29,13 @@ export interface Moveable { move(): this; } +/** + * @internal + */ +export interface Disposed { + get disposed(): boolean; +} + /** * @internal */ diff --git a/packages/puppeteer-core/src/util/decorators.ts b/packages/puppeteer-core/src/util/decorators.ts index f7d201f8..6aa6801d 100644 --- a/packages/puppeteer-core/src/util/decorators.ts +++ b/packages/puppeteer-core/src/util/decorators.ts @@ -15,7 +15,7 @@ */ import {Symbol} from '../../third_party/disposablestack/disposablestack.js'; -import {Moveable} from '../common/types.js'; +import {Disposed, Moveable} from '../common/types.js'; const instances = new WeakSet(); @@ -57,3 +57,19 @@ export function moveable< } return Class; } + +export function throwIfDisposed(message?: string) { + return ( + target: (this: This, ...args: Args) => Ret, + _: unknown + ) => { + return function (this: This, ...args: Args): Ret { + if (this.disposed) { + throw new Error( + message ?? `Attempted to use disposed ${this.constructor.name}.` + ); + } + return target.call(this, ...args); + }; + }; +} diff --git a/test/TestExpectations.json b/test/TestExpectations.json index b4a1029f..e6af1bc3 100644 --- a/test/TestExpectations.json +++ b/test/TestExpectations.json @@ -17,6 +17,12 @@ "parameters": ["firefox"], "expectations": ["FAIL"] }, + { + "testIdPattern": "[bfcache.spec] *", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["webDriverBiDi"], + "expectations": ["SKIP"] + }, { "testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests *", "platforms": ["darwin", "linux", "win32"], @@ -3899,12 +3905,6 @@ "parameters": ["firefox", "headful"], "expectations": ["PASS", "TIMEOUT"] }, - { - "testIdPattern": "[bfcache.spec] *", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["webDriverBiDi"], - "expectations": ["SKIP"] - }, { "testIdPattern": "[prerender.spec] Prerender can navigate to a prerendered page via input", "platforms": ["darwin", "linux", "win32"],