chore: use custom disposable stack (#10943)
This commit is contained in:
parent
cfed7b93ec
commit
164bdd29b0
@ -148,7 +148,6 @@
|
|||||||
"ws": "8.14.1"
|
"ws": "8.14.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"disposablestack": "1.1.1",
|
|
||||||
"mitt": "3.0.1",
|
"mitt": "3.0.1",
|
||||||
"parsel-js": "1.1.2",
|
"parsel-js": "1.1.2",
|
||||||
"rxjs": "7.8.1"
|
"rxjs": "7.8.1"
|
||||||
|
@ -18,10 +18,10 @@ import {type ChildProcess} from 'child_process';
|
|||||||
|
|
||||||
import {type Protocol} from 'devtools-protocol';
|
import {type Protocol} from 'devtools-protocol';
|
||||||
|
|
||||||
import {Symbol} from '../../third_party/disposablestack/disposablestack.js';
|
|
||||||
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
||||||
import {debugError, waitWithTimeout} from '../common/util.js';
|
import {debugError, waitWithTimeout} from '../common/util.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {asyncDisposeSymbol, disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import type {BrowserContext} from './BrowserContext.js';
|
import type {BrowserContext} from './BrowserContext.js';
|
||||||
import type {Page} from './Page.js';
|
import type {Page} from './Page.js';
|
||||||
@ -488,12 +488,12 @@ export abstract class Browser extends EventEmitter<BrowserEvents> {
|
|||||||
abstract get connected(): boolean;
|
abstract get connected(): boolean;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
return void this.close().catch(debugError);
|
return void this.close().catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.asyncDispose](): Promise<void> {
|
[asyncDisposeSymbol](): Promise<void> {
|
||||||
return this.close();
|
return this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
||||||
import {debugError} from '../common/util.js';
|
import {debugError} from '../common/util.js';
|
||||||
|
import {asyncDisposeSymbol, disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import type {Browser, Permission} from './Browser.js';
|
import type {Browser, Permission} from './Browser.js';
|
||||||
import {type Page} from './Page.js';
|
import {type Page} from './Page.js';
|
||||||
@ -226,12 +227,12 @@ export abstract class BrowserContext extends EventEmitter<BrowserContextEvents>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
return void this.close().catch(debugError);
|
return void this.close().catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.asyncDispose](): Promise<void> {
|
[asyncDisposeSymbol](): Promise<void> {
|
||||||
return this.close();
|
return this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
import type Protocol from 'devtools-protocol';
|
import type Protocol from 'devtools-protocol';
|
||||||
|
|
||||||
import {Symbol} from '../../third_party/disposablestack/disposablestack.js';
|
|
||||||
import {
|
import {
|
||||||
type EvaluateFuncWith,
|
type EvaluateFuncWith,
|
||||||
type HandleFor,
|
type HandleFor,
|
||||||
@ -24,6 +23,7 @@ import {
|
|||||||
} from '../common/types.js';
|
} from '../common/types.js';
|
||||||
import {debugError, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
import {debugError, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
||||||
import {moveable, throwIfDisposed} from '../util/decorators.js';
|
import {moveable, throwIfDisposed} from '../util/decorators.js';
|
||||||
|
import {disposeSymbol, asyncDisposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type ElementHandle} from './ElementHandle.js';
|
import {type ElementHandle} from './ElementHandle.js';
|
||||||
import {type Realm} from './Realm.js';
|
import {type Realm} from './Realm.js';
|
||||||
@ -217,12 +217,12 @@ export abstract class JSHandle<T = unknown> {
|
|||||||
abstract remoteObject(): Protocol.Runtime.RemoteObject;
|
abstract remoteObject(): Protocol.Runtime.RemoteObject;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
return void this.dispose().catch(debugError);
|
return void this.dispose().catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.asyncDispose](): Promise<void> {
|
[asyncDisposeSymbol](): Promise<void> {
|
||||||
return this.dispose();
|
return this.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ import {
|
|||||||
import type {Viewport} from '../common/Viewport.js';
|
import type {Viewport} from '../common/Viewport.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {type Deferred} from '../util/Deferred.js';
|
import {type Deferred} from '../util/Deferred.js';
|
||||||
|
import {asyncDisposeSymbol, disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import type {Browser} from './Browser.js';
|
import type {Browser} from './Browser.js';
|
||||||
import type {BrowserContext} from './BrowserContext.js';
|
import type {BrowserContext} from './BrowserContext.js';
|
||||||
@ -2853,12 +2854,12 @@ export abstract class Page extends EventEmitter<PageEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
return void this.close().catch(debugError);
|
return void this.close().catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.asyncDispose](): Promise<void> {
|
[asyncDisposeSymbol](): Promise<void> {
|
||||||
return this.close();
|
return this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
type InnerLazyParams,
|
type InnerLazyParams,
|
||||||
} from '../common/types.js';
|
} from '../common/types.js';
|
||||||
import {TaskManager, WaitTask} from '../common/WaitTask.js';
|
import {TaskManager, WaitTask} from '../common/WaitTask.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type ElementHandle} from './ElementHandle.js';
|
import {type ElementHandle} from './ElementHandle.js';
|
||||||
import {type Environment} from './Environment.js';
|
import {type Environment} from './Environment.js';
|
||||||
@ -102,7 +103,7 @@ export abstract class Realm implements Disposable {
|
|||||||
|
|
||||||
#disposed = false;
|
#disposed = false;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
this.#disposed = true;
|
this.#disposed = true;
|
||||||
this.taskManager.terminateAll(
|
this.taskManager.terminateAll(
|
||||||
new Error('waitForFunction failed: frame got detached.')
|
new Error('waitForFunction failed: frame got detached.')
|
||||||
|
@ -34,6 +34,7 @@ import {
|
|||||||
waitWithTimeout,
|
waitWithTimeout,
|
||||||
} from '../common/util.js';
|
} from '../common/util.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getWaitUntilSingle,
|
getWaitUntilSingle,
|
||||||
@ -250,15 +251,15 @@ export class BidiFrame extends Frame {
|
|||||||
return this.#disposed;
|
return this.#disposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
if (this.#disposed) {
|
if (this.#disposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#disposed = true;
|
this.#disposed = true;
|
||||||
this.#abortDeferred.reject(new Error('Frame detached'));
|
this.#abortDeferred.reject(new Error('Frame detached'));
|
||||||
this.#context.dispose();
|
this.#context.dispose();
|
||||||
this.sandboxes[MAIN_SANDBOX][Symbol.dispose]();
|
this.sandboxes[MAIN_SANDBOX][disposeSymbol]();
|
||||||
this.sandboxes[PUPPETEER_SANDBOX][Symbol.dispose]();
|
this.sandboxes[PUPPETEER_SANDBOX][disposeSymbol]();
|
||||||
}
|
}
|
||||||
|
|
||||||
#exposedFunctions = new Map<string, ExposeableFunction<never[], unknown>>();
|
#exposedFunctions = new Map<string, ExposeableFunction<never[], unknown>>();
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
EventSubscription,
|
EventSubscription,
|
||||||
type EventType,
|
type EventType,
|
||||||
} from '../common/EventEmitter.js';
|
} from '../common/EventEmitter.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type BidiConnection} from './Connection.js';
|
import {type BidiConnection} from './Connection.js';
|
||||||
import {type BidiFrame} from './Frame.js';
|
import {type BidiFrame} from './Frame.js';
|
||||||
|
@ -59,6 +59,7 @@ import {
|
|||||||
import {type Viewport} from '../common/Viewport.js';
|
import {type Viewport} from '../common/Viewport.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type BidiBrowser} from './Browser.js';
|
import {type BidiBrowser} from './Browser.js';
|
||||||
import {type BidiBrowserContext} from './BrowserContext.js';
|
import {type BidiBrowserContext} from './BrowserContext.js';
|
||||||
@ -314,7 +315,7 @@ export class BidiPage extends Page {
|
|||||||
for (const child of frame.childFrames()) {
|
for (const child of frame.childFrames()) {
|
||||||
this.#removeFramesRecursively(child);
|
this.#removeFramesRecursively(child);
|
||||||
}
|
}
|
||||||
frame[Symbol.dispose]();
|
frame[disposeSymbol]();
|
||||||
this.#networkManager.clearMapAfterFrameDispose(frame);
|
this.#networkManager.clearMapAfterFrameDispose(frame);
|
||||||
this.#frameTree.removeFrame(frame);
|
this.#frameTree.removeFrame(frame);
|
||||||
this.emit(PageEvent.FrameDetached, frame);
|
this.emit(PageEvent.FrameDetached, frame);
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
isString,
|
isString,
|
||||||
} from '../common/util.js';
|
} from '../common/util.js';
|
||||||
import type PuppeteerUtil from '../injected/injected.js';
|
import type PuppeteerUtil from '../injected/injected.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
import {stringifyFunction} from '../util/Function.js';
|
import {stringifyFunction} from '../util/Function.js';
|
||||||
|
|
||||||
import {type BidiConnection} from './Connection.js';
|
import {type BidiConnection} from './Connection.js';
|
||||||
@ -198,7 +199,7 @@ export class BidiRealm extends EventEmitter<Record<EventType, any>> {
|
|||||||
: createBidiHandle(sandbox, result.result);
|
: createBidiHandle(sandbox, result.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
this.connection.off(
|
this.connection.off(
|
||||||
Bidi.ChromiumBidi.Script.EventNames.RealmCreated,
|
Bidi.ChromiumBidi.Script.EventNames.RealmCreated,
|
||||||
this.handleRealmCreated
|
this.handleRealmCreated
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {JSHandle} from '../api/JSHandle.js';
|
import {JSHandle} from '../api/JSHandle.js';
|
||||||
import {debugError} from '../common/util.js';
|
import {debugError} from '../common/util.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
import {isErrorLike} from '../util/ErrorLike.js';
|
import {isErrorLike} from '../util/ErrorLike.js';
|
||||||
|
|
||||||
import {type ExecutionContext} from './ExecutionContext.js';
|
import {type ExecutionContext} from './ExecutionContext.js';
|
||||||
|
@ -20,6 +20,7 @@ import {type CDPSession} from '../api/CDPSession.js';
|
|||||||
import {EventSubscription} from '../common/EventEmitter.js';
|
import {EventSubscription} from '../common/EventEmitter.js';
|
||||||
import {debugError, PuppeteerURL} from '../common/util.js';
|
import {debugError, PuppeteerURL} from '../common/util.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CoverageEntry class represents one entry of the coverage report.
|
* The CoverageEntry class represents one entry of the coverage report.
|
||||||
|
@ -23,6 +23,7 @@ import {type Page, type WaitTimeoutOptions} from '../api/Page.js';
|
|||||||
import {setPageContent} from '../common/util.js';
|
import {setPageContent} from '../common/util.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
import {isErrorLike} from '../util/ErrorLike.js';
|
import {isErrorLike} from '../util/ErrorLike.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -338,12 +339,12 @@ export class CdpFrame extends Frame {
|
|||||||
return this.#detached;
|
return this.#detached;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
if (this.#detached) {
|
if (this.#detached) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#detached = true;
|
this.#detached = true;
|
||||||
this.worlds[MAIN_WORLD][Symbol.dispose]();
|
this.worlds[MAIN_WORLD][disposeSymbol]();
|
||||||
this.worlds[PUPPETEER_WORLD][Symbol.dispose]();
|
this.worlds[PUPPETEER_WORLD][disposeSymbol]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import {type TimeoutSettings} from '../common/TimeoutSettings.js';
|
|||||||
import {debugError, PuppeteerURL, UTILITY_WORLD_NAME} from '../common/util.js';
|
import {debugError, PuppeteerURL, UTILITY_WORLD_NAME} from '../common/util.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
import {isErrorLike} from '../util/ErrorLike.js';
|
import {isErrorLike} from '../util/ErrorLike.js';
|
||||||
|
|
||||||
import {CdpCDPSession} from './CDPSession.js';
|
import {CdpCDPSession} from './CDPSession.js';
|
||||||
@ -561,7 +562,7 @@ export class FrameManager extends EventEmitter<FrameManagerEvents> {
|
|||||||
for (const child of frame.childFrames()) {
|
for (const child of frame.childFrames()) {
|
||||||
this.#removeFramesRecursively(child);
|
this.#removeFramesRecursively(child);
|
||||||
}
|
}
|
||||||
frame[Symbol.dispose]();
|
frame[disposeSymbol]();
|
||||||
this._frameTree.removeFrame(frame);
|
this._frameTree.removeFrame(frame);
|
||||||
this.emit(FrameManagerEvent.FrameDetached, frame);
|
this.emit(FrameManagerEvent.FrameDetached, frame);
|
||||||
frame.emit(FrameEvent.FrameDetached, frame);
|
frame.emit(FrameEvent.FrameDetached, frame);
|
||||||
|
@ -32,6 +32,7 @@ import {
|
|||||||
withSourcePuppeteerURLIfNone,
|
withSourcePuppeteerURLIfNone,
|
||||||
} from '../common/util.js';
|
} from '../common/util.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type Binding} from './Binding.js';
|
import {type Binding} from './Binding.js';
|
||||||
import {type ExecutionContext, createCdpHandle} from './ExecutionContext.js';
|
import {type ExecutionContext, createCdpHandle} from './ExecutionContext.js';
|
||||||
@ -278,8 +279,8 @@ export class IsolatedWorld extends Realm {
|
|||||||
return newHandle;
|
return newHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
super[Symbol.dispose]();
|
super[disposeSymbol]();
|
||||||
this.client.off('Runtime.bindingCalled', this.#onBindingCalled);
|
this.client.off('Runtime.bindingCalled', this.#onBindingCalled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import {type TimeoutError} from '../common/Errors.js';
|
|||||||
import {EventSubscription} from '../common/EventEmitter.js';
|
import {EventSubscription} from '../common/EventEmitter.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type CdpFrame} from './Frame.js';
|
import {type CdpFrame} from './Frame.js';
|
||||||
import {FrameManagerEvent} from './FrameManager.js';
|
import {FrameManagerEvent} from './FrameManager.js';
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import type {Protocol} from 'devtools-protocol';
|
import type {Protocol} from 'devtools-protocol';
|
||||||
|
|
||||||
import {type CDPSession, CDPSessionEvent} from '../api/CDPSession.js';
|
import {CDPSessionEvent, type CDPSession} from '../api/CDPSession.js';
|
||||||
import type {Frame} from '../api/Frame.js';
|
import type {Frame} from '../api/Frame.js';
|
||||||
import {
|
import {
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@ -25,12 +25,13 @@ import {
|
|||||||
} from '../common/EventEmitter.js';
|
} from '../common/EventEmitter.js';
|
||||||
import {debugError, isString} from '../common/util.js';
|
import {debugError, isString} from '../common/util.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
|
|
||||||
import {CdpHTTPRequest} from './HTTPRequest.js';
|
import {CdpHTTPRequest} from './HTTPRequest.js';
|
||||||
import {CdpHTTPResponse} from './HTTPResponse.js';
|
import {CdpHTTPResponse} from './HTTPResponse.js';
|
||||||
import {
|
import {
|
||||||
type FetchRequestId,
|
|
||||||
NetworkEventManager,
|
NetworkEventManager,
|
||||||
|
type FetchRequestId,
|
||||||
} from './NetworkEventManager.js';
|
} from './NetworkEventManager.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Symbol} from '../../third_party/disposablestack/disposablestack.js';
|
|
||||||
import mitt, {
|
import mitt, {
|
||||||
type Emitter,
|
type Emitter,
|
||||||
type EventHandlerMap,
|
type EventHandlerMap,
|
||||||
type EventType,
|
type EventType,
|
||||||
} from '../../third_party/mitt/index.js';
|
} from '../../third_party/mitt/index.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
/**
|
/**
|
||||||
@ -230,7 +230,7 @@ export class EventSubscription<
|
|||||||
this.#target.on(this.#type, this.#handler);
|
this.#target.on(this.#type, this.#handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
this.#target.off(this.#type, this.#handler);
|
this.#target.off(this.#type, this.#handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {type JSHandle} from '../api/JSHandle.js';
|
import {type JSHandle} from '../api/JSHandle.js';
|
||||||
|
import {DisposableStack, disposeSymbol} from '../util/disposable.js';
|
||||||
|
|
||||||
import {type AwaitableIterable, type HandleFor} from './types.js';
|
import {type AwaitableIterable, type HandleFor} from './types.js';
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ async function* fastTransposeIteratorHandle<T>(
|
|||||||
using stack = new DisposableStack();
|
using stack = new DisposableStack();
|
||||||
stack.defer(() => {
|
stack.defer(() => {
|
||||||
for (using handle of handles) {
|
for (using handle of handles) {
|
||||||
handle[Symbol.dispose]();
|
handle[disposeSymbol]();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
yield* handles;
|
yield* handles;
|
||||||
|
@ -29,6 +29,7 @@ import {type Page} from '../api/Page.js';
|
|||||||
import {isNode} from '../environment.js';
|
import {isNode} from '../environment.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
|
import {disposeSymbol} from '../util/disposable.js';
|
||||||
import {isErrorLike} from '../util/ErrorLike.js';
|
import {isErrorLike} from '../util/ErrorLike.js';
|
||||||
|
|
||||||
import {debug} from './Debug.js';
|
import {debug} from './Debug.js';
|
||||||
@ -614,7 +615,7 @@ export class Mutex {
|
|||||||
constructor(mutex: Mutex) {
|
constructor(mutex: Mutex) {
|
||||||
this.#mutex = mutex;
|
this.#mutex = mutex;
|
||||||
}
|
}
|
||||||
[Symbol.dispose](): void {
|
[disposeSymbol](): void {
|
||||||
return this.#mutex.release();
|
return this.#mutex.release();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ import {type ConnectionTransport} from '../common/ConnectionTransport.js';
|
|||||||
import {EventSubscription} from '../common/EventEmitter.js';
|
import {EventSubscription} from '../common/EventEmitter.js';
|
||||||
import {debugError} from '../common/util.js';
|
import {debugError} from '../common/util.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
|
import {DisposableStack} from '../util/disposable.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
|
@ -14,18 +14,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Symbol} from '../../third_party/disposablestack/disposablestack.js';
|
|
||||||
import {type Disposed, type Moveable} from '../common/types.js';
|
import {type Disposed, type Moveable} from '../common/types.js';
|
||||||
|
|
||||||
|
import {asyncDisposeSymbol, disposeSymbol} from './disposable.js';
|
||||||
|
|
||||||
const instances = new WeakSet<object>();
|
const instances = new WeakSet<object>();
|
||||||
|
|
||||||
export function moveable<
|
export function moveable<
|
||||||
Class extends abstract new (...args: never[]) => Moveable,
|
Class extends abstract new (...args: never[]) => Moveable,
|
||||||
>(Class: Class, _: ClassDecoratorContext<Class>): Class {
|
>(Class: Class, _: ClassDecoratorContext<Class>): Class {
|
||||||
let hasDispose = false;
|
let hasDispose = false;
|
||||||
if (Class.prototype[Symbol.dispose]) {
|
if (Class.prototype[disposeSymbol]) {
|
||||||
const dispose = Class.prototype[Symbol.dispose];
|
const dispose = Class.prototype[disposeSymbol];
|
||||||
Class.prototype[Symbol.dispose] = function (this: InstanceType<Class>) {
|
Class.prototype[disposeSymbol] = function (this: InstanceType<Class>) {
|
||||||
if (instances.has(this)) {
|
if (instances.has(this)) {
|
||||||
instances.delete(this);
|
instances.delete(this);
|
||||||
return;
|
return;
|
||||||
@ -34,11 +35,9 @@ export function moveable<
|
|||||||
};
|
};
|
||||||
hasDispose = true;
|
hasDispose = true;
|
||||||
}
|
}
|
||||||
if (Class.prototype[Symbol.asyncDispose]) {
|
if (Class.prototype[asyncDisposeSymbol]) {
|
||||||
const asyncDispose = Class.prototype[Symbol.asyncDispose];
|
const asyncDispose = Class.prototype[asyncDisposeSymbol];
|
||||||
Class.prototype[Symbol.asyncDispose] = function (
|
Class.prototype[asyncDisposeSymbol] = function (this: InstanceType<Class>) {
|
||||||
this: InstanceType<Class>
|
|
||||||
) {
|
|
||||||
if (instances.has(this)) {
|
if (instances.has(this)) {
|
||||||
instances.delete(this);
|
instances.delete(this);
|
||||||
return;
|
return;
|
||||||
|
169
packages/puppeteer-core/src/util/disposable.ts
Normal file
169
packages/puppeteer-core/src/util/disposable.ts
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface SymbolConstructor {
|
||||||
|
/**
|
||||||
|
* A method that is used to release resources held by an object. Called by
|
||||||
|
* the semantics of the `using` statement.
|
||||||
|
*/
|
||||||
|
readonly dispose: unique symbol;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method that is used to asynchronously release resources held by an
|
||||||
|
* object. Called by the semantics of the `await using` statement.
|
||||||
|
*/
|
||||||
|
readonly asyncDispose: unique symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Disposable {
|
||||||
|
[Symbol.dispose](): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AsyncDisposable {
|
||||||
|
[Symbol.asyncDispose](): PromiseLike<void>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(Symbol as any).dispose ??= Symbol('dispose');
|
||||||
|
(Symbol as any).asyncDispose ??= Symbol('asyncDispose');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const disposeSymbol: typeof Symbol.dispose = Symbol.dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const asyncDisposeSymbol: typeof Symbol.asyncDispose =
|
||||||
|
Symbol.asyncDispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export class DisposableStack {
|
||||||
|
#disposed = false;
|
||||||
|
#stack: Disposable[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value indicating whether this stack has been disposed.
|
||||||
|
*/
|
||||||
|
get disposed(): boolean {
|
||||||
|
return this.#disposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes each resource in the stack in the reverse order that they were added.
|
||||||
|
*/
|
||||||
|
dispose(): void {
|
||||||
|
if (this.#disposed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#disposed = true;
|
||||||
|
for (const resource of this.#stack.reverse()) {
|
||||||
|
resource[disposeSymbol]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a disposable resource to the stack, returning the resource.
|
||||||
|
*
|
||||||
|
* @param value - The resource to add. `null` and `undefined` will not be added,
|
||||||
|
* but will be returned.
|
||||||
|
* @returns The provided {@link value}.
|
||||||
|
*/
|
||||||
|
use<T extends Disposable | null | undefined>(value: T): T {
|
||||||
|
if (value) {
|
||||||
|
this.#stack.push(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a value and associated disposal callback as a resource to the stack.
|
||||||
|
*
|
||||||
|
* @param value - The value to add.
|
||||||
|
* @param onDispose - The callback to use in place of a `[disposeSymbol]()`
|
||||||
|
* method. Will be invoked with `value` as the first parameter.
|
||||||
|
* @returns The provided {@link value}.
|
||||||
|
*/
|
||||||
|
adopt<T>(value: T, onDispose: (value: T) => void): T {
|
||||||
|
this.#stack.push({
|
||||||
|
[disposeSymbol]() {
|
||||||
|
onDispose(value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a callback to be invoked when the stack is disposed.
|
||||||
|
*/
|
||||||
|
defer(onDispose: () => void): void {
|
||||||
|
this.#stack.push({
|
||||||
|
[disposeSymbol]() {
|
||||||
|
onDispose();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move all resources out of this stack and into a new `DisposableStack`, and
|
||||||
|
* marks this stack as disposed.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* class C {
|
||||||
|
* #res1: Disposable;
|
||||||
|
* #res2: Disposable;
|
||||||
|
* #disposables: DisposableStack;
|
||||||
|
* constructor() {
|
||||||
|
* // stack will be disposed when exiting constructor for any reason
|
||||||
|
* using stack = new DisposableStack();
|
||||||
|
*
|
||||||
|
* // get first resource
|
||||||
|
* this.#res1 = stack.use(getResource1());
|
||||||
|
*
|
||||||
|
* // get second resource. If this fails, both `stack` and `#res1` will be disposed.
|
||||||
|
* this.#res2 = stack.use(getResource2());
|
||||||
|
*
|
||||||
|
* // all operations succeeded, move resources out of `stack` so that
|
||||||
|
* // they aren't disposed when constructor exits
|
||||||
|
* this.#disposables = stack.move();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* [disposeSymbol]() {
|
||||||
|
* this.#disposables.dispose();
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
move(): DisposableStack {
|
||||||
|
if (this.#disposed) {
|
||||||
|
throw new ReferenceError('a disposed stack can not use anything new'); // step 3
|
||||||
|
}
|
||||||
|
const stack = new DisposableStack(); // step 4-5
|
||||||
|
stack.#stack = this.#stack;
|
||||||
|
this.#disposed = true;
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
[disposeSymbol] = this.dispose;
|
||||||
|
|
||||||
|
readonly [Symbol.toStringTag] = 'DisposableStack';
|
||||||
|
}
|
@ -1,191 +0,0 @@
|
|||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
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
|
|
||||||
|
|
||||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
||||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
||||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
||||||
|
|
||||||
See the Apache Version 2.0 License for specific language governing permissions
|
|
||||||
and limitations under the License.
|
|
||||||
***************************************************************************** */
|
|
||||||
|
|
||||||
import 'disposablestack/auto';
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface SymbolConstructor {
|
|
||||||
/**
|
|
||||||
* A method that is used to release resources held by an object. Called by the semantics of the `using` statement.
|
|
||||||
*/
|
|
||||||
readonly dispose: unique symbol;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A method that is used to asynchronously release resources held by an object. Called by the semantics of the `await using` statement.
|
|
||||||
*/
|
|
||||||
readonly asyncDispose: unique symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Disposable {
|
|
||||||
[Symbol.dispose](): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AsyncDisposable {
|
|
||||||
[Symbol.asyncDispose](): PromiseLike<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SuppressedError extends Error {
|
|
||||||
error: any;
|
|
||||||
suppressed: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SuppressedErrorConstructor extends ErrorConstructor {
|
|
||||||
new (error: any, suppressed: any, message?: string): SuppressedError;
|
|
||||||
(error: any, suppressed: any, message?: string): SuppressedError;
|
|
||||||
readonly prototype: SuppressedError;
|
|
||||||
}
|
|
||||||
var SuppressedError: SuppressedErrorConstructor;
|
|
||||||
|
|
||||||
interface DisposableStack {
|
|
||||||
/**
|
|
||||||
* Returns a value indicating whether this stack has been disposed.
|
|
||||||
*/
|
|
||||||
readonly disposed: boolean;
|
|
||||||
/**
|
|
||||||
* Disposes each resource in the stack in the reverse order that they were added.
|
|
||||||
*/
|
|
||||||
dispose(): void;
|
|
||||||
/**
|
|
||||||
* Adds a disposable resource to the stack, returning the resource.
|
|
||||||
* @param value The resource to add. `null` and `undefined` will not be added, but will be returned.
|
|
||||||
* @returns The provided {@link value}.
|
|
||||||
*/
|
|
||||||
use<T extends Disposable | null | undefined>(value: T): T;
|
|
||||||
/**
|
|
||||||
* Adds a value and associated disposal callback as a resource to the stack.
|
|
||||||
* @param value The value to add.
|
|
||||||
* @param onDispose The callback to use in place of a `[Symbol.dispose]()` method. Will be invoked with `value`
|
|
||||||
* as the first parameter.
|
|
||||||
* @returns The provided {@link value}.
|
|
||||||
*/
|
|
||||||
adopt<T>(value: T, onDispose: (value: T) => void): T;
|
|
||||||
/**
|
|
||||||
* Adds a callback to be invoked when the stack is disposed.
|
|
||||||
*/
|
|
||||||
defer(onDispose: () => void): void;
|
|
||||||
/**
|
|
||||||
* Move all resources out of this stack and into a new `DisposableStack`, and marks this stack as disposed.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* class C {
|
|
||||||
* #res1: Disposable;
|
|
||||||
* #res2: Disposable;
|
|
||||||
* #disposables: DisposableStack;
|
|
||||||
* constructor() {
|
|
||||||
* // stack will be disposed when exiting constructor for any reason
|
|
||||||
* using stack = new DisposableStack();
|
|
||||||
*
|
|
||||||
* // get first resource
|
|
||||||
* this.#res1 = stack.use(getResource1());
|
|
||||||
*
|
|
||||||
* // get second resource. If this fails, both `stack` and `#res1` will be disposed.
|
|
||||||
* this.#res2 = stack.use(getResource2());
|
|
||||||
*
|
|
||||||
* // all operations succeeded, move resources out of `stack` so that they aren't disposed
|
|
||||||
* // when constructor exits
|
|
||||||
* this.#disposables = stack.move();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* [Symbol.dispose]() {
|
|
||||||
* this.#disposables.dispose();
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
move(): DisposableStack;
|
|
||||||
[Symbol.dispose](): void;
|
|
||||||
readonly [Symbol.toStringTag]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DisposableStackConstructor {
|
|
||||||
new (): DisposableStack;
|
|
||||||
readonly prototype: DisposableStack;
|
|
||||||
}
|
|
||||||
var DisposableStack: DisposableStackConstructor;
|
|
||||||
|
|
||||||
interface AsyncDisposableStack {
|
|
||||||
/**
|
|
||||||
* Returns a value indicating whether this stack has been disposed.
|
|
||||||
*/
|
|
||||||
readonly disposed: boolean;
|
|
||||||
/**
|
|
||||||
* Disposes each resource in the stack in the reverse order that they were added.
|
|
||||||
*/
|
|
||||||
disposeAsync(): Promise<void>;
|
|
||||||
/**
|
|
||||||
* Adds a disposable resource to the stack, returning the resource.
|
|
||||||
* @param value The resource to add. `null` and `undefined` will not be added, but will be returned.
|
|
||||||
* @returns The provided {@link value}.
|
|
||||||
*/
|
|
||||||
use<T extends AsyncDisposable | Disposable | null | undefined>(value: T): T;
|
|
||||||
/**
|
|
||||||
* Adds a value and associated disposal callback as a resource to the stack.
|
|
||||||
* @param value The value to add.
|
|
||||||
* @param onDisposeAsync The callback to use in place of a `[Symbol.asyncDispose]()` method. Will be invoked with `value`
|
|
||||||
* as the first parameter.
|
|
||||||
* @returns The provided {@link value}.
|
|
||||||
*/
|
|
||||||
adopt<T>(
|
|
||||||
value: T,
|
|
||||||
onDisposeAsync: (value: T) => PromiseLike<void> | void
|
|
||||||
): T;
|
|
||||||
/**
|
|
||||||
* Adds a callback to be invoked when the stack is disposed.
|
|
||||||
*/
|
|
||||||
defer(onDisposeAsync: () => PromiseLike<void> | void): void;
|
|
||||||
/**
|
|
||||||
* Move all resources out of this stack and into a new `DisposableStack`, and marks this stack as disposed.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* class C {
|
|
||||||
* #res1: Disposable;
|
|
||||||
* #res2: Disposable;
|
|
||||||
* #disposables: DisposableStack;
|
|
||||||
* constructor() {
|
|
||||||
* // stack will be disposed when exiting constructor for any reason
|
|
||||||
* using stack = new DisposableStack();
|
|
||||||
*
|
|
||||||
* // get first resource
|
|
||||||
* this.#res1 = stack.use(getResource1());
|
|
||||||
*
|
|
||||||
* // get second resource. If this fails, both `stack` and `#res1` will be disposed.
|
|
||||||
* this.#res2 = stack.use(getResource2());
|
|
||||||
*
|
|
||||||
* // all operations succeeded, move resources out of `stack` so that they aren't disposed
|
|
||||||
* // when constructor exits
|
|
||||||
* this.#disposables = stack.move();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* [Symbol.dispose]() {
|
|
||||||
* this.#disposables.dispose();
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
move(): AsyncDisposableStack;
|
|
||||||
[Symbol.asyncDispose](): Promise<void>;
|
|
||||||
readonly [Symbol.toStringTag]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AsyncDisposableStackConstructor {
|
|
||||||
new (): AsyncDisposableStack;
|
|
||||||
readonly prototype: AsyncDisposableStack;
|
|
||||||
}
|
|
||||||
var AsyncDisposableStack: AsyncDisposableStackConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Symbol = globalThis.Symbol;
|
|
||||||
export const DisposableStack = globalThis.DisposableStack;
|
|
||||||
export const AsyncDisposableStack = globalThis.AsyncDisposableStack;
|
|
@ -17,6 +17,10 @@
|
|||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
import {Puppeteer} from 'puppeteer';
|
import {Puppeteer} from 'puppeteer';
|
||||||
import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js';
|
import {ElementHandle} from 'puppeteer-core/internal/api/ElementHandle.js';
|
||||||
|
import {
|
||||||
|
asyncDisposeSymbol,
|
||||||
|
disposeSymbol,
|
||||||
|
} from 'puppeteer-core/internal/util/disposable.js';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -918,7 +922,7 @@ describe('ElementHandle specs', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('document');
|
using handle = await page.evaluateHandle('document');
|
||||||
const spy = sinon.spy(handle, Symbol.dispose);
|
const spy = sinon.spy(handle, disposeSymbol);
|
||||||
{
|
{
|
||||||
using _ = handle;
|
using _ = handle;
|
||||||
}
|
}
|
||||||
@ -932,7 +936,7 @@ describe('ElementHandle specs', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('document');
|
using handle = await page.evaluateHandle('document');
|
||||||
const spy = sinon.spy(handle, Symbol.asyncDispose);
|
const spy = sinon.spy(handle, asyncDisposeSymbol);
|
||||||
{
|
{
|
||||||
await using _ = handle;
|
await using _ = handle;
|
||||||
}
|
}
|
||||||
@ -946,7 +950,7 @@ describe('ElementHandle specs', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('document');
|
using handle = await page.evaluateHandle('document');
|
||||||
const spy = sinon.spy(handle, Symbol.dispose);
|
const spy = sinon.spy(handle, disposeSymbol);
|
||||||
{
|
{
|
||||||
using _ = handle;
|
using _ = handle;
|
||||||
handle.move();
|
handle.move();
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
import {JSHandle} from 'puppeteer-core/internal/api/JSHandle.js';
|
import {JSHandle} from 'puppeteer-core/internal/api/JSHandle.js';
|
||||||
|
import {
|
||||||
|
asyncDisposeSymbol,
|
||||||
|
disposeSymbol,
|
||||||
|
} from 'puppeteer-core/internal/util/disposable.js';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
||||||
@ -338,7 +342,7 @@ describe('JSHandle', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('new Set()');
|
using handle = await page.evaluateHandle('new Set()');
|
||||||
const spy = sinon.spy(handle, Symbol.dispose);
|
const spy = sinon.spy(handle, disposeSymbol);
|
||||||
{
|
{
|
||||||
using _ = handle;
|
using _ = handle;
|
||||||
}
|
}
|
||||||
@ -352,7 +356,7 @@ describe('JSHandle', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('new Set()');
|
using handle = await page.evaluateHandle('new Set()');
|
||||||
const spy = sinon.spy(handle, Symbol.asyncDispose);
|
const spy = sinon.spy(handle, asyncDisposeSymbol);
|
||||||
{
|
{
|
||||||
await using _ = handle;
|
await using _ = handle;
|
||||||
}
|
}
|
||||||
@ -366,7 +370,7 @@ describe('JSHandle', function () {
|
|||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
using handle = await page.evaluateHandle('new Set()');
|
using handle = await page.evaluateHandle('new Set()');
|
||||||
const spy = sinon.spy(handle, Symbol.dispose);
|
const spy = sinon.spy(handle, disposeSymbol);
|
||||||
{
|
{
|
||||||
using _ = handle;
|
using _ = handle;
|
||||||
handle.move();
|
handle.move();
|
||||||
|
Loading…
Reference in New Issue
Block a user