Skip to content

Commit 0499a31

Browse files
authored
feat(browser): support --inspect (#6433)
1 parent c3b2757 commit 0499a31

File tree

4 files changed

+140
-16
lines changed

4 files changed

+140
-16
lines changed

docs/guide/debugging.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,66 @@ You can also add a dedicated launch configuration to debug a test file in VS Cod
3838

3939
Then in the debug tab, ensure 'Debug Current Test File' is selected. You can then open the test file you want to debug and press F5 to start debugging.
4040

41+
### Browser mode
42+
43+
To debug [Vitest Browser Mode](/guide/browser/index.md), pass `--inspect` in CLI or define it in your Vitest configuration:
44+
45+
::: code-group
46+
```bash [CLI]
47+
vitest --inspect --browser
48+
```
49+
```ts [vitest.config.js]
50+
import { defineConfig } from 'vitest/config'
51+
52+
export default defineConfig({
53+
test: {
54+
inspect: true,
55+
browser: {
56+
name: 'chromium',
57+
provider: 'playwright',
58+
},
59+
},
60+
})
61+
```
62+
:::
63+
64+
By default Vitest will use port `9229` as debugging port. You can overwrite it with by passing value in `inspect`:
65+
66+
```bash
67+
vitest --inspect=127.0.0.1:3000 --browser
68+
```
69+
70+
Use following [VSCode Compound configuration](https://code.visualstudio.com/docs/editor/debugging#_compound-launch-configurations) for launching Vitest and attaching debugger in the browser:
71+
72+
```json
73+
{
74+
"version": "0.2.0",
75+
"configurations": [
76+
{
77+
"type": "node",
78+
"request": "launch",
79+
"name": "Run Vitest Browser",
80+
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
81+
"console": "integratedTerminal",
82+
"args": ["--inspect", "--browser"]
83+
},
84+
{
85+
"type": "chrome",
86+
"request": "attach",
87+
"name": "Attach to Vitest Browser",
88+
"port": 9229
89+
}
90+
],
91+
"compounds": [
92+
{
93+
"name": "Debug Vitest Browser",
94+
"configurations": ["Attach to Vitest Browser", "Run Vitest Browser"],
95+
"stopAll": true
96+
}
97+
]
98+
}
99+
```
100+
41101
## IntelliJ IDEA
42102

43103
Create a 'Node.js' run configuration. Use the following settings to run all tests in debug mode:

packages/browser/src/node/providers/playwright.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ export class PlaywrightBrowserProvider implements BrowserProvider {
7171
headless: options.headless,
7272
} satisfies LaunchOptions
7373

74+
if (this.ctx.config.inspector.enabled) {
75+
// NodeJS equivalent defaults: https://nodejs.org/en/learn/getting-started/debugging#enable-inspector
76+
const port = this.ctx.config.inspector.port || 9229
77+
const host = this.ctx.config.inspector.host || '127.0.0.1'
78+
79+
launchOptions.args ||= []
80+
launchOptions.args.push(`--remote-debugging-port=${port}`)
81+
launchOptions.args.push(`--remote-debugging-address=${host}`)
82+
83+
this.ctx.logger.log(`Debugger listening on ws://${host}:${port}`)
84+
}
85+
7486
// start Vitest UI maximized only on supported browsers
7587
if (this.ctx.config.browser.ui && this.browserName === 'chromium') {
7688
if (!launchOptions.args) {

packages/vitest/src/node/config/resolveConfig.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,26 +213,37 @@ export function resolveConfig(
213213
&& resolved.poolOptions?.threads?.singleThread
214214
const isSingleFork
215215
= resolved.pool === 'forks' && resolved.poolOptions?.forks?.singleFork
216+
const isBrowser = resolved.browser.enabled
216217

217-
if (resolved.fileParallelism && !isSingleThread && !isSingleFork) {
218+
if (resolved.fileParallelism && !isSingleThread && !isSingleFork && !isBrowser) {
218219
const inspectOption = `--inspect${resolved.inspectBrk ? '-brk' : ''}`
219220
throw new Error(
220221
`You cannot use ${inspectOption} without "--no-file-parallelism", "poolOptions.threads.singleThread" or "poolOptions.forks.singleFork"`,
221222
)
222223
}
223224
}
224225

225-
// In browser-mode v8-coverage works only with playwright + chromium
226-
if (resolved.browser.enabled && resolved.coverage.enabled && resolved.coverage.provider === 'v8') {
227-
if (!(resolved.browser.provider === 'playwright' && resolved.browser.name === 'chromium')) {
228-
const browserConfig = { browser: { provider: resolved.browser.provider, name: resolved.browser.name } }
226+
// Browser-mode "Playwright + Chromium" only features:
227+
if (resolved.browser.enabled && !(resolved.browser.provider === 'playwright' && resolved.browser.name === 'chromium')) {
228+
const browserConfig = { browser: { provider: resolved.browser.provider, name: resolved.browser.name } }
229229

230+
if (resolved.coverage.enabled && resolved.coverage.provider === 'v8') {
230231
throw new Error(
231232
`@vitest/coverage-v8 does not work with\n${JSON.stringify(browserConfig, null, 2)}\n`
232233
+ `\nUse either:\n${JSON.stringify({ browser: { provider: 'playwright', name: 'chromium' } }, null, 2)}`
233234
+ `\n\n...or change your coverage provider to:\n${JSON.stringify({ coverage: { provider: 'istanbul' } }, null, 2)}\n`,
234235
)
235236
}
237+
238+
if (resolved.inspect || resolved.inspectBrk) {
239+
const inspectOption = `--inspect${resolved.inspectBrk ? '-brk' : ''}`
240+
241+
throw new Error(
242+
`${inspectOption} does not work with\n${JSON.stringify(browserConfig, null, 2)}\n`
243+
+ `\nUse either:\n${JSON.stringify({ browser: { provider: 'playwright', name: 'chromium' } }, null, 2)}`
244+
+ `\n\n...or disable ${inspectOption}\n`,
245+
)
246+
}
236247
}
237248

238249
resolved.coverage.reporter = resolveCoverageReporters(resolved.coverage.reporter)

test/config/test/failures.test.ts

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { version } from 'vitest/package.json'
55
import { normalize, resolve } from 'pathe'
66
import * as testUtils from '../../test-utils'
77

8+
const providers = ['playwright', 'webdriverio', 'preview'] as const
9+
const names = ['edge', 'chromium', 'webkit', 'chrome', 'firefox', 'safari'] as const
10+
const browsers = providers.map(provider => names.map(name => ({ name, provider }))).flat()
11+
812
function runVitest(config: NonNullable<UserConfig> & { shard?: any }) {
913
return testUtils.runVitest({ root: './fixtures/test', ...config }, [])
1014
}
@@ -63,20 +67,17 @@ test('inspect-brk cannot be used with multi processing', async () => {
6367
expect(stderr).toMatch('Error: You cannot use --inspect without "--no-file-parallelism", "poolOptions.threads.singleThread" or "poolOptions.forks.singleFork"')
6468
})
6569

66-
test('v8 coverage provider throws when not playwright + chromium', async () => {
67-
const providers = ['playwright', 'webdriverio', 'preview']
68-
const names = ['edge', 'chromium', 'webkit', 'chrome', 'firefox', 'safari']
70+
test('inspect and --inspect-brk cannot be used when not playwright + chromium', async () => {
71+
for (const option of ['inspect', 'inspectBrk']) {
72+
const cli = `--inspect${option === 'inspectBrk' ? '-brk' : ''}`
6973

70-
for (const provider of providers) {
71-
for (const name of names) {
74+
for (const { provider, name } of browsers) {
7275
if (provider === 'playwright' && name === 'chromium') {
7376
continue
7477
}
7578

7679
const { stderr } = await runVitest({
77-
coverage: {
78-
enabled: true,
79-
},
80+
[option]: true,
8081
browser: {
8182
enabled: true,
8283
provider,
@@ -85,7 +86,48 @@ test('v8 coverage provider throws when not playwright + chromium', async () => {
8586
})
8687

8788
expect(stderr).toMatch(
88-
`Error: @vitest/coverage-v8 does not work with
89+
`Error: ${cli} does not work with
90+
{
91+
"browser": {
92+
"provider": "${provider}",
93+
"name": "${name}"
94+
}
95+
}
96+
97+
Use either:
98+
{
99+
"browser": {
100+
"provider": "playwright",
101+
"name": "chromium"
102+
}
103+
}
104+
105+
...or disable ${cli}
106+
`,
107+
)
108+
}
109+
}
110+
})
111+
112+
test('v8 coverage provider throws when not playwright + chromium', async () => {
113+
for (const { provider, name } of browsers) {
114+
if (provider === 'playwright' && name === 'chromium') {
115+
continue
116+
}
117+
118+
const { stderr } = await runVitest({
119+
coverage: {
120+
enabled: true,
121+
},
122+
browser: {
123+
enabled: true,
124+
provider,
125+
name,
126+
},
127+
})
128+
129+
expect(stderr).toMatch(
130+
`Error: @vitest/coverage-v8 does not work with
89131
{
90132
"browser": {
91133
"provider": "${provider}",
@@ -108,8 +150,7 @@ Use either:
108150
}
109151
}
110152
`,
111-
)
112-
}
153+
)
113154
}
114155
})
115156

0 commit comments

Comments
 (0)