playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Bug]: VS Code Debugging closes browser after stopping

Open pedramg opened this issue 3 months ago • 27 comments

Version

1.54.0, 1.55.0, 1.56.0

Steps to reproduce

  1. In VS code, add a breakpoint inside a test
  2. Right-click the test and select Debug Test
  3. When the breakpoint is reached, click the Stop button
  4. The browser is closed instead of staying open

There are 2 reasons I need to do step 3:

  • The application doesn't load properly unless this is done
  • I want to use the Record at cursor option to extend the test, but this option is disabled unless this is done

Expected behavior

Browser does not close when the Stop button is clicked as is the behavior in playwright 1.53 and earlier

Actual behavior

Browser closes when the Stop button is clicked.

Additional context

I asked about this in the discord channel: https://discord.com/channels/807756831384403968/1054804523652231198/threads/1425851812300329091

Environment

System:
    OS: macOS 15.5
    CPU: (12) arm64 Apple M2 Pro
    Memory: 77.19 MB / 16.00 GB
  Binaries:
    Node: 22.15.0 - /Users/pedram/.nvm/versions/node/v22.15.0/bin/node
    npm: 10.9.2 - /Users/pedram/.nvm/versions/node/v22.15.0/bin/npm
  IDEs:
    VSCode: 1.105.0 - /usr/local/bin/code
  Languages:
    Bash: 3.2.57 - /bin/bash
  npmPackages:
    @playwright/test: 1.54.0 => 1.54.0

pedramg avatar Oct 13 '25 11:10 pedramg

Hi Pedram! I work on our VS Code extension and i'd love to help. I haven't seen this before and I have a suspicion it's related to the page you're testing. Could you provide me with a reproduction repository, as explained in the issue template?

Skn0tt avatar Oct 13 '25 12:10 Skn0tt

Hi Simon! While I was creating a reproduction repo, I noticed that this part of the issue:

The application doesn't load properly unless this is done

only happens in our dev env and not our prod env.

But, what do you think about this part of the issue?

I want to use the Record at cursor option to extend the test, but this option is disabled unless this is done

This also happens in our prod env. You don't need a reproduction repo for that, right?

pedramg avatar Oct 13 '25 13:10 pedramg

That's be design. If you're debugging, and we didn't disable "Record at cursor", it would be surprising that the test still follows the old code when you step through the test. It'd trip up our entire line highlighting and the annotations.

The idea behind "record at cursor" is that you run the test in normal mode (no debugging). When you enable "Show Browser", the browser will remain open even after the test finishes, so you can use that browser window to record. If you want to record in the middle of your test, you can place an early return where you want to record, and follow the same approach.

Skn0tt avatar Oct 13 '25 13:10 Skn0tt

That's be design. If you're debugging, and we didn't disable "Record at cursor", it would be surprising that the test still follows the old code when you step through the test. It'd trip up our entire line highlighting and the annotations.

I understand that "Record at cursor" needs to be disabled while debugging, but why does the browser need to be closed when stopping the debugging?

If you want to record in the middle of your test, you can place an early return where you want to record, and follow the same approach.

How do I place an early return? I could comment out all following lines and the afterEach/afterAll, but this is much slower than the old behavior in 1.53.0 where you can just add a breakpoint (or run it until it fails) and then click Stop and inspect the browser.

pedramg avatar Oct 13 '25 14:10 pedramg

The browser closing is a bug, and it's related to your application as you mentioned. If you provide me with a reproduction case, I'll do my best to fix it.

Skn0tt avatar Oct 13 '25 14:10 Skn0tt

Ok, so the browser closing can be seen with any application, for example add a breakpoint on the second line of this test:

test('close issue', async ({ page }) => {
    await page.goto('https://playwright.dev/');
    await page.getByRole('link', { name: 'Get started' }).click(); // add breakpoint on this line
});

Then run "Debug Test", wait until breakpoint is reached, click Stop:

Image

and the browser closes.

pedramg avatar Oct 13 '25 14:10 pedramg

Oh, you actually stop the debugging! I understand what's going on now, sorry. When you stop the debugger, the entire test process closes. I'm not aware of any changes in 1.53 that would have impacted that.

Could you elaborate why you're clicking the Stop button? Would your workflow work if you clicked it at a later point?

Skn0tt avatar Oct 13 '25 14:10 Skn0tt

Could you elaborate why you're clicking the Stop button?

I click the Stop button so I can use "Record at cursor" and this works fine in 1.53

And sometimes I click the Stop button so I can manually inspect the browser (the application won't load properly in our test env otherwise)

Would your workflow work if you clicked it at a later point?

Not really, because I want the test to stop.

pedramg avatar Oct 13 '25 14:10 pedramg

I've debugged it a bit more and I think I know what's going on now. Could you try going into the Testing Sidebar of VS Code, and under the Playwright section, enable "Show Browser"? That should restore your old behaviour.

Image

You are most likely seeing the effects of https://github.com/microsoft/playwright-vscode/pull/685, which was a bug fix intended to ensure we actually close browsers when "Show Browser" is disabled. Looks like it has the side effect that it closes the browser for you.

Skn0tt avatar Oct 14 '25 13:10 Skn0tt

I already have the "Show Browser" option enabled:

https://github.com/user-attachments/assets/c7098826-a9ff-4368-a1ea-abfb96491ac8

I also tried with "Show Browser" disabled and saw the same behavior.

pedramg avatar Oct 14 '25 14:10 pedramg

That's so weird. I'm assuming this is just a plain new Playwright project?

Skn0tt avatar Oct 14 '25 14:10 Skn0tt

Yes, I started it like this: npm init playwright@latest new-project

Image

Here is the behavior using 1.53.2, the last version where the browser does not close:

https://github.com/user-attachments/assets/d799f108-fbf1-4088-a091-ac5a391a3b9c

pedramg avatar Oct 14 '25 15:10 pedramg

I'm able to reproduce it. This affects flow of fixing tests somewhere in the middle if they are broken. Could you please prioritize it?

maxtheqa avatar Oct 20 '25 23:10 maxtheqa

I'm also able to reproduce it and would really appreciate if it could be prioritized, many thanks in advance.

qarammer avatar Oct 20 '25 23:10 qarammer

Hi. I've seen this issue as well. It makes it more difficult to create and adjust tests. Hopefully it can be fixed soon.

dnlp7 avatar Oct 20 '25 23:10 dnlp7

I can reproduce it now, thank you. https://github.com/microsoft/playwright/commit/71088f6e9dce156ceecb3e381368942f9b6b0a8e is the first failing commit.

Skn0tt avatar Oct 21 '25 08:10 Skn0tt

This was an unwanted regression. Separate from this, we're currently working on something related to debugging the open browser, which should also help your usecase. I'll let y'all know once we have something testable.

In the meantime, you should be able to work around this by running tests in non-Debug mode, and commenting out the parts of the test you don't want to run.

Skn0tt avatar Oct 21 '25 11:10 Skn0tt

Hello, I can also reproduce something similar to this. Although I don't use the debugger to run Playwright tests, our process/repo steps follow something like this:

  1. Run the test in headed mode for debugging using the VSCode Playwright Extension
  2. Have the Show browser option selected
  3. Comment out any global/local page.close() and/or context.close()
  4. Run the test using the extension

Expected Results: The test will execute what test steps there are and stop at the last test step without closing

Actual Results: The test will execute what test steps there are and then close the browser (If running in headed mode)

Note: I can also reproduce this error running the tests in non-debug mode and commenting out the tests I don't want to run.

Repo Steps:

  1. Have the extension working and navigate to a test step
  2. Right-click the Green Play Symbol and select "Run Tests."
  3. The behavior/bug is repeated.

Is there another workaround?

AndreNguyen124 avatar Oct 21 '25 21:10 AndreNguyen124

We also experience this problem via debug and non-debug. Any ideas on a workaround?

seanLiberty avatar Oct 24 '25 16:10 seanLiberty

@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided context / page fixtures?

Skn0tt avatar Oct 27 '25 08:10 Skn0tt

I have this problem too (in non-debug mode), I think it's to do when using the browser context to create a page to be used across multiple tests.

As an example I've altered the example test spec included with playwright with a beforeAll step including the new page setup

With it like this, the browser automatically closes at the end of running the tests (in non-debug mode, and with 'Show Browser' selected in the extension options):

import {test, expect, Page} from "@playwright/test";

let page: Page;

test.beforeAll("goto page", async ({browser}) => {
  page = await browser.newPage();
  await page.goto("https://playwright.dev/");
});

test("get title", async () => {
  // Expect a title "to contain" a substring.
  await expect(page).toHaveTitle(/Playwright/);
});

test("get started link", async () => {
  await page.goto("https://playwright.dev/");

  // Click the get started link.
  await page.getByRole("link", {name: "Get started"}).click();

  // Expects page to have a heading with the name of Installation.
  await expect(page.getByRole("heading", {name: "Installation"})).toBeVisible();
});

Is this intended, or should the browser/page remain open after running the above test file?

If I don't use the browser context (ie. running the example spec unaltered from install), then the browser remains open after running the tests.

sneekypeeks avatar Nov 01 '25 17:11 sneekypeeks

@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided context / page fixtures?

using the provided context / page fixtures

seanLiberty avatar Nov 07 '25 22:11 seanLiberty

for a workaround, what is the suggested way to stop on a page for recording purposes?

seanLiberty avatar Nov 07 '25 22:11 seanLiberty

@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided context / page fixtures?

I'm currently creating browser contexts/pages for my Playwright project. I traced the commit history per your comment above and downgraded our version to 1.53, which seemed to be a fix.

AndreNguyen124 avatar Nov 10 '25 16:11 AndreNguyen124

Is this intended, or should the browser/page remain open after running the above test file? (from @sneekypeeks)

Yes that's per design. Only the context and page fixtures are connected to VS Code's "Show Browser" feature. If you change your code like this, it works again:

 let page: Page;
 
-test.beforeAll("goto page", async ({ browser }) => {
-  page = await browser.newPage();
+test.beforeAll("goto page", async ({ context }) => {
+  page = await context.newPage();
   await page.goto("https://playwright.dev/");
 });

for a workaround, what is the suggested way to stop on a page for recording purposes? (@seanLiberty)

put page.pause() where you want to stop, and use the CLI to run the test in --headed mode.

Skn0tt avatar Nov 11 '25 10:11 Skn0tt

Is this intended, or should the browser/page remain open after running the above test file? (from @sneekypeeks)

Yes that's per design. Only the context and page fixtures are connected to VS Code's "Show Browser" feature. If you change your code like this, it works again:

let page: Page;

-test.beforeAll("goto page", async ({ browser }) => {

  • page = await browser.newPage(); +test.beforeAll("goto page", async ({ context }) => {
  • page = await context.newPage(); await page.goto("https://playwright.dev/"); });

for a workaround, what is the suggested way to stop on a page for recording purposes? (@seanLiberty)

put page.pause() where you want to stop, and use the CLI to run the test in --headed mode.

adding an await page.pause() will work when running via CLI - can record again. Thanks @Skn0tt

seanLiberty avatar Nov 11 '25 14:11 seanLiberty

I am running into the same issue. For me, it began yesterday. I have had two state changes happen (VSCode and the Playwright Plugin - both or either may be causing the behavior)

Loom: https://www.loom.com/share/cb16d43551074868a7c3bb033ddbd8ad

brennx0r avatar Dec 02 '25 21:12 brennx0r