[Bug]: VS Code Debugging closes browser after stopping
Version
1.54.0, 1.55.0, 1.56.0
Steps to reproduce
- In VS code, add a breakpoint inside a test
- Right-click the test and select
Debug Test - When the breakpoint is reached, click the Stop button
- 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 cursoroption 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
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?
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 cursoroption 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?
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.
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.
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.
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:
and the browser closes.
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?
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.
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.
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.
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.
That's so weird. I'm assuming this is just a plain new Playwright project?
Yes, I started it like this:
npm init playwright@latest new-project
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
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?
I'm also able to reproduce it and would really appreciate if it could be prioritized, many thanks in advance.
Hi. I've seen this issue as well. It makes it more difficult to create and adjust tests. Hopefully it can be fixed soon.
I can reproduce it now, thank you. https://github.com/microsoft/playwright/commit/71088f6e9dce156ceecb3e381368942f9b6b0a8e is the first failing commit.
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.
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:
- Run the test in headed mode for debugging using the VSCode Playwright Extension
- Have the Show browser option selected
- Comment out any global/local page.close() and/or context.close()
- 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:
- Have the extension working and navigate to a test step
- Right-click the Green Play Symbol and select "Run Tests."
- The behavior/bug is repeated.
Is there another workaround?
We also experience this problem via debug and non-debug. Any ideas on a workaround?
@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided context / page fixtures?
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.
@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided
context/pagefixtures?
using the provided context / page fixtures
for a workaround, what is the suggested way to stop on a page for recording purposes?
@AndreNguyen124 @seanLiberty are you creating the browser contexts / pages yourself, or are you using the provided
context/pagefixtures?
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.
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.
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
contextandpagefixtures 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--headedmode.
adding an await page.pause() will work when running via CLI - can record again. Thanks @Skn0tt
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