refactor: use Deferred for session close (#10258)

This commit is contained in:
Nikolay Vitkov 2023-05-30 09:03:42 +02:00 committed by GitHub
parent f342c26d95
commit 39935c8a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -152,9 +152,8 @@ export class CDPPage extends Page {
#viewport: Viewport | null; #viewport: Viewport | null;
#screenshotTaskQueue: TaskQueue; #screenshotTaskQueue: TaskQueue;
#workers = new Map<string, WebWorker>(); #workers = new Map<string, WebWorker>();
#fileChooserPromises = new Set<Deferred<FileChooser>>(); #fileChooserDeferreds = new Set<Deferred<FileChooser>>();
#sessionCloseDeferred = createDeferred<Error>();
#disconnectPromise?: Promise<Error>;
#serviceWorkerBypassed = false; #serviceWorkerBypassed = false;
#userDragInterceptionEnabled = false; #userDragInterceptionEnabled = false;
@ -224,6 +223,12 @@ export class CDPPage extends Page {
return this.emit(PageEmittedEvents.RequestFinished, event); return this.emit(PageEmittedEvents.RequestFinished, event);
}); });
client.once(CDPSessionEmittedEvents.Disconnected, () => {
return this.#sessionCloseDeferred.resolve(
new TargetCloseError('Target closed')
);
});
client.on('Page.domContentEventFired', () => { client.on('Page.domContentEventFired', () => {
return this.emit(PageEmittedEvents.DOMContentLoaded); return this.emit(PageEmittedEvents.DOMContentLoaded);
}); });
@ -326,7 +331,7 @@ export class CDPPage extends Page {
async #onFileChooser( async #onFileChooser(
event: Protocol.Page.FileChooserOpenedEvent event: Protocol.Page.FileChooserOpenedEvent
): Promise<void> { ): Promise<void> {
if (!this.#fileChooserPromises.size) { if (!this.#fileChooserDeferreds.size) {
return; return;
} }
@ -339,10 +344,10 @@ export class CDPPage extends Page {
)) as ElementHandle<HTMLInputElement>; )) as ElementHandle<HTMLInputElement>;
const fileChooser = new FileChooser(handle, event); const fileChooser = new FileChooser(handle, event);
for (const promise of this.#fileChooserPromises) { for (const promise of this.#fileChooserDeferreds) {
promise.resolve(fileChooser); promise.resolve(fileChooser);
} }
this.#fileChooserPromises.clear(); this.#fileChooserDeferreds.clear();
} }
/** /**
@ -367,13 +372,13 @@ export class CDPPage extends Page {
override waitForFileChooser( override waitForFileChooser(
options: WaitTimeoutOptions = {} options: WaitTimeoutOptions = {}
): Promise<FileChooser> { ): Promise<FileChooser> {
const needsEnable = this.#fileChooserPromises.size === 0; const needsEnable = this.#fileChooserDeferreds.size === 0;
const {timeout = this.#timeoutSettings.timeout()} = options; const {timeout = this.#timeoutSettings.timeout()} = options;
const deferred = createDeferred<FileChooser>({ const deferred = createDeferred<FileChooser>({
message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`, message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`,
timeout, timeout,
}); });
this.#fileChooserPromises.add(deferred); this.#fileChooserDeferreds.add(deferred);
let enablePromise: Promise<void> | undefined; let enablePromise: Promise<void> | undefined;
if (needsEnable) { if (needsEnable) {
enablePromise = this.#client.send('Page.setInterceptFileChooserDialog', { enablePromise = this.#client.send('Page.setInterceptFileChooserDialog', {
@ -385,7 +390,7 @@ export class CDPPage extends Page {
return result; return result;
}) })
.catch(error => { .catch(error => {
this.#fileChooserPromises.delete(deferred); this.#fileChooserDeferreds.delete(deferred);
throw error; throw error;
}); });
} }
@ -944,17 +949,6 @@ export class CDPPage extends Page {
return await this.mainFrame().waitForNavigation(options); return await this.mainFrame().waitForNavigation(options);
} }
#sessionClosePromise(): Promise<Error> {
if (!this.#disconnectPromise) {
this.#disconnectPromise = new Promise(fulfill => {
return this.#client.once(CDPSessionEmittedEvents.Disconnected, () => {
return fulfill(new TargetCloseError('Target closed'));
});
});
}
return this.#disconnectPromise;
}
override async waitForRequest( override async waitForRequest(
urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise<boolean>), urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise<boolean>),
options: {timeout?: number} = {} options: {timeout?: number} = {}
@ -973,7 +967,7 @@ export class CDPPage extends Page {
return false; return false;
}, },
timeout, timeout,
this.#sessionClosePromise() this.#sessionCloseDeferred.valueOrThrow()
); );
} }
@ -997,7 +991,7 @@ export class CDPPage extends Page {
return false; return false;
}, },
timeout, timeout,
this.#sessionClosePromise() this.#sessionCloseDeferred.valueOrThrow()
); );
} }
@ -1054,7 +1048,7 @@ export class CDPPage extends Page {
await Promise.race([ await Promise.race([
idleDeferred.valueOrThrow(), idleDeferred.valueOrThrow(),
...eventPromises, ...eventPromises,
this.#sessionClosePromise(), this.#sessionCloseDeferred.valueOrThrow(),
]).then( ]).then(
r => { r => {
cleanup(); cleanup();
@ -1094,14 +1088,14 @@ export class CDPPage extends Page {
FrameManagerEmittedEvents.FrameAttached, FrameManagerEmittedEvents.FrameAttached,
predicate, predicate,
timeout, timeout,
this.#sessionClosePromise() this.#sessionCloseDeferred.valueOrThrow()
), ),
waitForEvent( waitForEvent(
this.#frameManager, this.#frameManager,
FrameManagerEmittedEvents.FrameNavigated, FrameManagerEmittedEvents.FrameNavigated,
predicate, predicate,
timeout, timeout,
this.#sessionClosePromise() this.#sessionCloseDeferred.valueOrThrow()
), ),
...this.frames().map(async frame => { ...this.frames().map(async frame => {
if (await predicate(frame)) { if (await predicate(frame)) {