Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/playwright-core/src/server/bidi/bidiConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import type * as bidi from './third_party/bidiProtocol';

// BidiPlaywright uses this special id to issue Browser.close command which we
// should ignore.
export const kBrowserCloseMessageId = 0;
export const kBrowserCloseMessageId = Number.MAX_SAFE_INTEGER - 1;
export const kShutdownSessionNewMessageId = kBrowserCloseMessageId - 1;

export class BidiConnection {
private readonly _transport: ConnectionTransport;
Expand Down Expand Up @@ -235,7 +236,7 @@ export class BidiSession extends EventEmitter {

dispatchMessage(message: any) {
const object = message as bidi.Message;
if (object.id === kBrowserCloseMessageId)
if (object.id === kBrowserCloseMessageId || object.id === kShutdownSessionNewMessageId)
return;
if (object.id && this._callbacks.has(object.id)) {
const callback = this._callbacks.get(object.id)!;
Expand Down
19 changes: 17 additions & 2 deletions packages/playwright-core/src/server/bidi/bidiFirefox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import path from 'path';
import { wrapInASCIIBox } from '../utils/ascii';
import { BrowserType, kNoXServerRunningError } from '../browserType';
import { BidiBrowser } from './bidiBrowser';
import { kBrowserCloseMessageId } from './bidiConnection';
import { kBrowserCloseMessageId, kShutdownSessionNewMessageId } from './bidiConnection';
import { createProfile } from './third_party/firefoxPrefs';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';

Expand Down Expand Up @@ -76,8 +76,23 @@ export class BidiFirefox extends BrowserType {
return env;
}

override attemptToGracefullyCloseBrowser(transport: ConnectionTransport): void {
override attemptToGracefullyCloseBrowser(transport: ConnectionTransport) {
this._attemptToGracefullyCloseBrowser(transport).catch(() => {});
}

private async _attemptToGracefullyCloseBrowser(transport: ConnectionTransport): Promise<void> {
// Note that it's fine to reuse the transport, since our connection ignores kBrowserCloseMessageId.
if (!transport.onmessage) {
// browser.close does not work without an active session. If there is no connection
// created with the transport, make sure to create a new session first.
transport.send({ method: 'session.new', params: { capabilities: {} }, id: kShutdownSessionNewMessageId });
await new Promise(resolve => {
transport.onmessage = message => {
if (message.id === kShutdownSessionNewMessageId)
resolve(true);
};
});
}
transport.send({ method: 'browser.close', params: {}, id: kBrowserCloseMessageId });
}

Expand Down
Loading