mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-27 21:58:52 +03:00
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 { headersObjectToArray, isRegExp, isString } from '../utils';
|
||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||
import { isSafeCloseError } from '../common/errors';
|
||||
import type * as api from '../../types/types';
|
||||
import type * as structs from '../../types/structs';
|
||||
import { CDPSession } from './cdpSession';
|
||||
@ -59,6 +58,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||
readonly _serviceWorkers = new Set<Worker>();
|
||||
readonly _isChromium: boolean;
|
||||
private _harRecorders = new Map<string, { path: string, content: 'embed' | 'attach' | 'omit' | undefined }>();
|
||||
private _closeWasCalled = false;
|
||||
|
||||
static from(context: channels.BrowserContextChannel): BrowserContext {
|
||||
return (context as any)._object;
|
||||
@ -344,31 +344,28 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
try {
|
||||
await this._wrapApiCall(async () => {
|
||||
await this._browserType?._onWillCloseContext?.(this);
|
||||
for (const [harId, harParams] of this._harRecorders) {
|
||||
const har = await this._channel.harExport({ harId });
|
||||
const artifact = Artifact.from(har.artifact);
|
||||
// Server side will compress artifact if content is attach or if file is .zip.
|
||||
const isCompressed = harParams.content === 'attach' || harParams.path.endsWith('.zip');
|
||||
const needCompressed = harParams.path.endsWith('.zip');
|
||||
if (isCompressed && !needCompressed) {
|
||||
await artifact.saveAs(harParams.path + '.tmp');
|
||||
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
|
||||
} else {
|
||||
await artifact.saveAs(harParams.path);
|
||||
}
|
||||
await artifact.delete();
|
||||
if (this._closeWasCalled)
|
||||
return;
|
||||
this._closeWasCalled = true;
|
||||
await this._wrapApiCall(async () => {
|
||||
await this._browserType?._onWillCloseContext?.(this);
|
||||
for (const [harId, harParams] of this._harRecorders) {
|
||||
const har = await this._channel.harExport({ harId });
|
||||
const artifact = Artifact.from(har.artifact);
|
||||
// Server side will compress artifact if content is attach or if file is .zip.
|
||||
const isCompressed = harParams.content === 'attach' || harParams.path.endsWith('.zip');
|
||||
const needCompressed = harParams.path.endsWith('.zip');
|
||||
if (isCompressed && !needCompressed) {
|
||||
await artifact.saveAs(harParams.path + '.tmp');
|
||||
await this._connection.localUtils()._channel.harUnzip({ zipFile: harParams.path + '.tmp', harFile: harParams.path });
|
||||
} else {
|
||||
await artifact.saveAs(harParams.path);
|
||||
}
|
||||
}, true);
|
||||
await this._channel.close();
|
||||
await this._closedPromise;
|
||||
} catch (e) {
|
||||
if (isSafeCloseError(e))
|
||||
return;
|
||||
throw e;
|
||||
}
|
||||
await artifact.delete();
|
||||
}
|
||||
}, true);
|
||||
await this._channel.close();
|
||||
await this._closedPromise;
|
||||
}
|
||||
|
||||
async _enableRecorder(params: {
|
||||
|
@ -532,7 +532,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||
else
|
||||
await this._channel.close(options);
|
||||
} catch (e) {
|
||||
if (isSafeCloseError(e))
|
||||
if (isSafeCloseError(e) && !options.runBeforeUnload)
|
||||
return;
|
||||
throw e;
|
||||
}
|
||||
|
@ -426,29 +426,6 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
||||
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) => {
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
const browser = await connect(remoteServer.wsEndpoint());
|
||||
|
Loading…
Reference in New Issue
Block a user