chore: throw on context.close() if it was closed externally (#21347)
This commit is contained in:
parent
57624bc01b
commit
09ff7eaaf2
|
|
@ -30,7 +30,6 @@ import { Waiter } from './waiter';
|
||||||
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions } from './types';
|
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions } from './types';
|
||||||
import { headersObjectToArray, isRegExp, isString } from '../utils';
|
import { headersObjectToArray, isRegExp, isString } from '../utils';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { isSafeCloseError } from '../common/errors';
|
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
import type * as structs from '../../types/structs';
|
import type * as structs from '../../types/structs';
|
||||||
import { CDPSession } from './cdpSession';
|
import { CDPSession } from './cdpSession';
|
||||||
|
|
@ -59,6 +58,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||||
readonly _serviceWorkers = new Set<Worker>();
|
readonly _serviceWorkers = new Set<Worker>();
|
||||||
readonly _isChromium: boolean;
|
readonly _isChromium: boolean;
|
||||||
private _harRecorders = new Map<string, { path: string, content: 'embed' | 'attach' | 'omit' | undefined }>();
|
private _harRecorders = new Map<string, { path: string, content: 'embed' | 'attach' | 'omit' | undefined }>();
|
||||||
|
private _closeWasCalled = false;
|
||||||
|
|
||||||
static from(context: channels.BrowserContextChannel): BrowserContext {
|
static from(context: channels.BrowserContextChannel): BrowserContext {
|
||||||
return (context as any)._object;
|
return (context as any)._object;
|
||||||
|
|
@ -344,31 +344,28 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(): Promise<void> {
|
async close(): Promise<void> {
|
||||||
try {
|
if (this._closeWasCalled)
|
||||||
await this._wrapApiCall(async () => {
|
return;
|
||||||
await this._browserType?._onWillCloseContext?.(this);
|
this._closeWasCalled = true;
|
||||||
for (const [harId, harParams] of this._harRecorders) {
|
await this._wrapApiCall(async () => {
|
||||||
const har = await this._channel.harExport({ harId });
|
await this._browserType?._onWillCloseContext?.(this);
|
||||||
const artifact = Artifact.from(har.artifact);
|
for (const [harId, harParams] of this._harRecorders) {
|
||||||
// Server side will compress artifact if content is attach or if file is .zip.
|
const har = await this._channel.harExport({ harId });
|
||||||
const isCompressed = harParams.content === 'attach' || harParams.path.endsWith('.zip');
|
const artifact = Artifact.from(har.artifact);
|
||||||
const needCompressed = harParams.path.endsWith('.zip');
|
// Server side will compress artifact if content is attach or if file is .zip.
|
||||||
if (isCompressed && !needCompressed) {
|
const isCompressed = harParams.content === 'attach' || harParams.path.endsWith('.zip');
|
||||||
await artifact.saveAs(harParams.path + '.tmp');
|
const needCompressed = harParams.path.endsWith('.zip');
|
||||||
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
|
if (isCompressed && !needCompressed) {
|
||||||
} else {
|
await artifact.saveAs(harParams.path + '.tmp');
|
||||||
await artifact.saveAs(harParams.path);
|
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
|
||||||
}
|
} else {
|
||||||
await artifact.delete();
|
await artifact.saveAs(harParams.path);
|
||||||
}
|
}
|
||||||
}, true);
|
await artifact.delete();
|
||||||
await this._channel.close();
|
}
|
||||||
await this._closedPromise;
|
}, true);
|
||||||
} catch (e) {
|
await this._channel.close();
|
||||||
if (isSafeCloseError(e))
|
await this._closedPromise;
|
||||||
return;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _enableRecorder(params: {
|
async _enableRecorder(params: {
|
||||||
|
|
|
||||||
|
|
@ -532,7 +532,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||||
else
|
else
|
||||||
await this._channel.close(options);
|
await this._channel.close(options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isSafeCloseError(e))
|
if (isSafeCloseError(e) && !options.runBeforeUnload)
|
||||||
return;
|
return;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -426,29 +426,6 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not throw on context.close after disconnect', async ({ connect, startRemoteServer }) => {
|
|
||||||
const remoteServer = await startRemoteServer(kind);
|
|
||||||
const browser = await connect(remoteServer.wsEndpoint());
|
|
||||||
const context = await browser.newContext();
|
|
||||||
await context.newPage();
|
|
||||||
await Promise.all([
|
|
||||||
new Promise(f => browser.on('disconnected', f)),
|
|
||||||
remoteServer.close()
|
|
||||||
]);
|
|
||||||
await context.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should not throw on page.close after disconnect', async ({ connect, startRemoteServer }) => {
|
|
||||||
const remoteServer = await startRemoteServer(kind);
|
|
||||||
const browser = await connect(remoteServer.wsEndpoint());
|
|
||||||
const page = await browser.newPage();
|
|
||||||
await Promise.all([
|
|
||||||
new Promise(f => browser.on('disconnected', f)),
|
|
||||||
remoteServer.close()
|
|
||||||
]);
|
|
||||||
await page.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should saveAs videos from remote browser', async ({ connect, startRemoteServer }, testInfo) => {
|
test('should saveAs videos from remote browser', async ({ connect, startRemoteServer }, testInfo) => {
|
||||||
const remoteServer = await startRemoteServer(kind);
|
const remoteServer = await startRemoteServer(kind);
|
||||||
const browser = await connect(remoteServer.wsEndpoint());
|
const browser = await connect(remoteServer.wsEndpoint());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue