From 43304e980d1164c55cca8b871fd76546a133013e Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Thu, 15 Sep 2022 17:04:41 -0700 Subject: [PATCH] feat: show browser.close() stack in "Browser has been closed" error (#17376) Often times we see "Browser has been closed" error, but it's not entirely clear why. Showing the close stack might help. ```js page.goto: Connection closed ==== Closed by ==== at /Users/dgozman/code/playwright/tests/library/browsertype-connect.spec.ts:477:32 ``` --- packages/playwright-core/src/client/connection.ts | 5 ++++- tests/library/browsertype-connect.spec.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/client/connection.ts b/packages/playwright-core/src/client/connection.ts index 4090db4f05..51e49b4b2f 100644 --- a/packages/playwright-core/src/client/connection.ts +++ b/packages/playwright-core/src/client/connection.ts @@ -36,7 +36,7 @@ import { WritableStream } from './writableStream'; import { debugLogger } from '../common/debugLogger'; import { SelectorsOwner } from './selectors'; import { Android, AndroidSocket, AndroidDevice } from './android'; -import type { ParsedStackTrace } from '../utils/stackTrace'; +import { captureStackTrace, type ParsedStackTrace } from '../utils/stackTrace'; import { Artifact } from './artifact'; import { EventEmitter } from 'events'; import { JsonPipe } from './jsonPipe'; @@ -166,6 +166,9 @@ export class Connection extends EventEmitter { } close(errorMessage: string = 'Connection closed') { + const stack = captureStackTrace().frameTexts.join('\n'); + if (stack) + errorMessage += '\n ==== Closed by ====\n' + stack + '\n'; this._closedErrorMessage = errorMessage; for (const callback of this._callbacks.values()) callback.reject(new Error(errorMessage)); diff --git a/tests/library/browsertype-connect.spec.ts b/tests/library/browsertype-connect.spec.ts index dcc0edb673..c819747a69 100644 --- a/tests/library/browsertype-connect.spec.ts +++ b/tests/library/browsertype-connect.spec.ts @@ -478,7 +478,10 @@ test('should properly disconnect when connection closes from the client side', a await disconnectedPromise; expect(browser.isConnected()).toBe(false); - expect((await navigationPromise).message).toContain('Connection closed'); + const navMessage = (await navigationPromise).message; + expect(navMessage).toContain('Connection closed'); + expect(navMessage).toContain('Closed by'); + expect(navMessage).toContain(__filename); expect((await waitForNavigationPromise).message).toContain('Navigation failed because page was closed'); expect((await page.goto(server.EMPTY_PAGE).catch(e => e)).message).toContain('has been closed'); expect((await page.waitForNavigation().catch(e => e)).message).toContain('Navigation failed because page was closed');