Skip to content

Commit 6157282

Browse files
authoredApr 8, 2024··
feat: allow custom host for --inspect and --inspect-brk (#5509)
1 parent 672a1ed commit 6157282

File tree

8 files changed

+129
-15
lines changed

8 files changed

+129
-15
lines changed
 

‎docs/guide/cli.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ Run only [benchmark](https://vitest.dev/guide/features.html#benchmarking-experim
9696
| `--shard <shard>` | Execute tests in a specified shard |
9797
| `--sequence` | Define in what order to run tests. Use [cac's dot notation] to specify options (for example, use `--sequence.shuffle` to run tests in random order or `--sequence.shuffle --sequence.seed SEED_ID` to run a specific order) |
9898
| `--no-color` | Removes colors from the console output |
99-
| `--inspect` | Enables Node.js inspector |
100-
| `--inspect-brk` | Enables Node.js inspector with break |
99+
| `--inspect [[host:]port]` | Enable Node.js inspector (default: 127.0.0.1:9229) |
100+
| `--inspect-brk [[host:]port]` | Enables Node.js inspector and break before the test starts |
101101
| `--bail <number>` | Stop test execution when given number of tests have failed |
102102
| `--retry <times>` | Retry the test specific number of times if it fails |
103103
| `--exclude <glob>` | Additional file globs to be excluded from test |

‎packages/vitest/src/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// if changed, update also jsdocs and docs
22
export const defaultPort = 51204
33
export const defaultBrowserPort = 63315
4+
export const defaultInspectPort = 9229
45

56
export const EXIT_CODE_RESTART = 43
67

‎packages/vitest/src/node/cli/cli-config.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,9 @@ export const cliOptionsConfig: VitestCLIOptions = {
308308
if (typeof browser === 'boolean')
309309
return { enabled: browser }
310310
if (browser === 'true' || browser === 'false')
311-
return { enabled: browser !== 'false' }
311+
return { enabled: browser === 'true' }
312+
if (browser === 'yes' || browser === 'no')
313+
return { enabled: browser === 'yes' }
312314
if (typeof browser === 'string')
313315
return { enabled: true, name: browser }
314316
return browser
@@ -465,11 +467,28 @@ export const cliOptionsConfig: VitestCLIOptions = {
465467
},
466468
},
467469
inspect: {
468-
description: 'Enable Node.js inspector',
470+
description: 'Enable Node.js inspector (default: 127.0.0.1:9229)',
471+
argument: '[[host:]port]',
472+
transform(portOrEnabled) {
473+
if (portOrEnabled === 0 || portOrEnabled === 'true' || portOrEnabled === 'yes')
474+
return true
475+
if (portOrEnabled === 'false' || portOrEnabled === 'no')
476+
return false
477+
return portOrEnabled
478+
},
469479
},
470480
inspectBrk: {
471-
description: 'Enable Node.js inspector with break',
481+
description: 'Enable Node.js inspector and break before the test starts',
482+
argument: '[[host:]port]',
483+
transform(portOrEnabled) {
484+
if (portOrEnabled === 0 || portOrEnabled === 'true' || portOrEnabled === 'yes')
485+
return true
486+
if (portOrEnabled === 'false' || portOrEnabled === 'no')
487+
return false
488+
return portOrEnabled
489+
},
472490
},
491+
inspector: null,
473492
testTimeout: {
474493
description: 'Default timeout of a test in milliseconds (default: 5000)',
475494
argument: '<timeout>',

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

+24-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { normalize, relative, resolve } from 'pathe'
33
import c from 'picocolors'
44
import type { ResolvedConfig as ResolvedViteConfig } from 'vite'
55
import type { ApiConfig, ResolvedConfig, UserConfig, VitestRunMode } from '../types'
6-
import { defaultBrowserPort, defaultPort, extraInlineDeps } from '../constants'
6+
import { defaultBrowserPort, defaultInspectPort, defaultPort, extraInlineDeps } from '../constants'
77
import { benchmarkConfigDefaults, configDefaults } from '../defaults'
88
import { isCI, stdProvider, toArray } from '../utils'
99
import type { BuiltinPool } from '../types/pool-options'
@@ -20,6 +20,21 @@ function resolvePath(path: string, root: string) {
2020
)
2121
}
2222

23+
function parseInspector(inspect: string | undefined | boolean | number) {
24+
if (typeof inspect === 'boolean' || inspect === undefined)
25+
return {}
26+
if (typeof inspect === 'number')
27+
return { port: inspect }
28+
29+
if (inspect.match(/https?:\//))
30+
throw new Error(`Inspector host cannot be a URL. Use "host:port" instead of "${inspect}"`)
31+
32+
const [host, port] = inspect.split(':')
33+
if (!port)
34+
return { host }
35+
return { host, port: Number(port) || defaultInspectPort }
36+
}
37+
2338
export function resolveApiServerConfig<Options extends ApiConfig & UserConfig>(
2439
options: Options,
2540
): ApiConfig | undefined {
@@ -88,8 +103,14 @@ export function resolveConfig(
88103
mode,
89104
} as any as ResolvedConfig
90105

91-
resolved.inspect = Boolean(resolved.inspect)
92-
resolved.inspectBrk = Boolean(resolved.inspectBrk)
106+
const inspector = resolved.inspect || resolved.inspectBrk
107+
108+
resolved.inspector = {
109+
...resolved.inspector,
110+
...parseInspector(inspector),
111+
enabled: !!inspector,
112+
waitForDebugger: options.inspector?.waitForDebugger ?? !!resolved.inspectBrk,
113+
}
93114

94115
if (viteConfig.base !== '/')
95116
resolved.base = viteConfig.base

‎packages/vitest/src/node/workspace.ts

+1
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ export class WorkspaceProject {
410410
},
411411
inspect: this.ctx.config.inspect,
412412
inspectBrk: this.ctx.config.inspectBrk,
413+
inspector: this.ctx.config.inspector,
413414
alias: [],
414415
includeTaskLocation: this.config.includeTaskLocation ?? this.ctx.config.includeTaskLocation,
415416
env: {

‎packages/vitest/src/runtime/inspector.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,21 @@ let session: InstanceType<typeof inspector.Session>
1212
*/
1313
export function setupInspect(ctx: ContextRPC) {
1414
const config = ctx.config
15-
const isEnabled = config.inspect || config.inspectBrk
15+
const isEnabled = config.inspector.enabled
1616

1717
if (isEnabled) {
1818
inspector = __require('node:inspector')
1919
// Inspector may be open already if "isolate: false" is used
2020
const isOpen = inspector.url() !== undefined
2121

2222
if (!isOpen) {
23-
inspector.open()
23+
inspector.open(
24+
config.inspector.port,
25+
config.inspector.host,
26+
config.inspector.waitForDebugger,
27+
)
2428

2529
if (config.inspectBrk) {
26-
inspector.waitForDebugger()
2730
const firstTestFile = ctx.files[0]
2831

2932
// Stop at first test file

‎packages/vitest/src/types/config.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -675,15 +675,37 @@ export interface InlineConfig {
675675
*
676676
* Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`.
677677
*/
678-
inspect?: boolean
678+
inspect?: boolean | string
679679

680680
/**
681681
* Debug tests by opening `node:inspector` in worker / child process and wait for debugger to connect.
682682
* Provides similar experience as `--inspect-brk` Node CLI argument.
683683
*
684684
* Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`.
685685
*/
686-
inspectBrk?: boolean
686+
inspectBrk?: boolean | string
687+
688+
/**
689+
* Inspector options. If `--inspect` or `--inspect-brk` is enabled, these options will be passed to the inspector.
690+
*/
691+
inspector?: {
692+
/**
693+
* Enable inspector
694+
*/
695+
enabled?: boolean
696+
/**
697+
* Port to run inspector on
698+
*/
699+
port?: number
700+
/**
701+
* Host to run inspector on
702+
*/
703+
host?: string
704+
/**
705+
* Wait for debugger to connect before running tests
706+
*/
707+
waitForDebugger?: boolean
708+
}
687709

688710
/**
689711
* Modify default Chai config. Vitest uses Chai for `expect` and `assert` matches.

‎test/config/test/resolution.test.ts

+49-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { UserConfig } from 'vitest'
22
import type { UserConfig as ViteUserConfig } from 'vite'
3-
import { describe, expect, it } from 'vitest'
4-
import { createVitest } from 'vitest/node'
3+
import { describe, expect, it, onTestFinished, vi } from 'vitest'
4+
import { createVitest, parseCLI } from 'vitest/node'
55
import { extraInlineDeps } from 'vitest/config'
66

77
async function vitest(cliOptions: UserConfig, configValue: UserConfig = {}, viteConfig: ViteUserConfig = {}) {
@@ -263,3 +263,50 @@ describe('correctly defines api flag', () => {
263263
})
264264
})
265265
})
266+
267+
describe.each([
268+
'--inspect',
269+
'--inspect-brk',
270+
])('correctly parses %s flags', (inspectFlagName) => {
271+
it.each([
272+
['', { enabled: true }],
273+
['true', { enabled: true }],
274+
['yes', { enabled: true }],
275+
['false', { enabled: false }],
276+
['no', { enabled: false }],
277+
278+
['1002', { enabled: true, port: 1002 }],
279+
['www.remote.com:1002', { enabled: true, port: 1002, host: 'www.remote.com' }],
280+
['www.remote.com', { enabled: true, host: 'www.remote.com' }],
281+
])(`parses "vitest ${inspectFlagName} %s" value`, async (cliValue, inspect) => {
282+
const rawConfig = parseCLI(
283+
`vitest --no-file-parallelism ${inspectFlagName} ${cliValue}`,
284+
)
285+
const c = await config(rawConfig.options)
286+
expect(c.inspector).toEqual({
287+
...inspect,
288+
waitForDebugger: inspectFlagName === '--inspect-brk' && inspect.enabled,
289+
})
290+
})
291+
it('cannot use a URL', async () => {
292+
const url = 'https://www.remote.com:1002'
293+
const rawConfig = parseCLI([
294+
'vitest',
295+
'--no-file-parallelism',
296+
inspectFlagName,
297+
url,
298+
])
299+
const error = vi.fn()
300+
const originalError = console.error
301+
console.error = error
302+
onTestFinished(() => {
303+
console.error = originalError
304+
})
305+
await expect(async () => {
306+
await config(rawConfig.options)
307+
}).rejects.toThrowError()
308+
expect(error.mock.lastCall[0]).toEqual(
309+
expect.stringContaining(`Inspector host cannot be a URL. Use "host:port" instead of "${url}"`),
310+
)
311+
})
312+
})

0 commit comments

Comments
 (0)
Please sign in to comment.