GeezerVison is showing github.com — fix: support api.port 0 (#11641) · vitest-dev/vitest@3667cf8
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: docs/config/api.md +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -13,6 +13,8 @@ Listen to port and serve API for [the UI](/guide/ui) or [browser server](/guide/ | 13 | 13 |
| 14 | 14 | In Browser Mode the server binds its port on the first browser launch, unless `api` or `ui` is enabled. | 15 | 15 |
| | 16 | +Set `port` to `0` to let the operating system pick a free port. | | 17 | + | 16 | 18 | ## api.allowWrite <Version>4.1.0</Version> {#api-allowwrite} | 17 | 19 |
| 18 | 20 | - **Type:** `boolean` | |
Collapse file Copy file name to clipboardExpand all lines: packages/vitest/src/node/config/resolveConfig.ts +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -120,7 +120,7 @@ export function resolveApiServerConfig( | 120 | 120 | } | 121 | 121 |
| 122 | 122 | if (api) { | 123 | | - if (!api.port && !api.middlewareMode) { | | 123 | + if (api.port == null && !api.middlewareMode) { | 124 | 124 | api.port = defaultPort | 125 | 125 | } | 126 | 126 | } else { | @@ -132,7 +132,7 @@ export function resolveApiServerConfig( | 132 | 132 | api.middlewareMode = false | 133 | 133 | // The browser server is standalone, so it always needs a port even when the | 134 | 134 | // user didn't configure `api`/`ui` (in which case `api` defaulted above) | 135 | | - if (!api.port) { | | 135 | + if (api.port == null) { | 136 | 136 | api.port = defaultPort | 137 | 137 | } | 138 | 138 | } | |
Collapse file Copy file name to clipboardExpand all lines: packages/vitest/src/node/logger.ts +10-16Lines changed: 10 additions & 16 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -237,22 +237,16 @@ export class Logger { | 237 | 237 | this.log(PAD + c.gray(`Running tests with seed "${seed}"`)) | 238 | 238 | } | 239 | 239 |
| 240 | | - if (this.ctx.config.ui) { | 241 | | - const host = this.ctx.config.api?.host || 'localhost' | 242 | | - const port = this.ctx.vite.config.server.port | 243 | | - const url = new URL(this.ctx.config.uiBase, `http://${host}:${port}`) | 244 | | - url.searchParams.set('token', this.ctx.config.api.token) | 245 | | - | 246 | | - this.log(PAD + c.dim(c.green(`UI started at ${url}`))) | 247 | | - } | 248 | | - // browser mode always has `api.port`, but only listens on startup for `api`/`ui` | 249 | | - else if (this.ctx.config.api?.port && this.ctx.config._apiRequested) { | 250 | | - const resolvedUrls = this.ctx.vite.resolvedUrls | 251 | | - // workaround for https://github.com/vitejs/vite/issues/15438, it was fixed in vite 5.1 | 252 | | - const fallbackUrl = `http://${this.ctx.config.api.host || 'localhost'}:${this.ctx.config.api.port}` | 253 | | - const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] ?? fallbackUrl | 254 | | - | 255 | | - this.log(PAD + c.dim(c.green(`API started at ${new URL('/', origin)}`))) | | 240 | + const resolvedUrls = this.ctx.vite.resolvedUrls | | 241 | + const origin = resolvedUrls?.local[0] ?? resolvedUrls?.network[0] | | 242 | + if (origin && this.ctx.config._apiRequested) { | | 243 | + if (this.ctx.config.ui) { | | 244 | + const url = new URL(this.ctx.config.uiBase, origin) | | 245 | + url.searchParams.set('token', this.ctx.config.api.token) | | 246 | + this.log(PAD + c.dim(c.green(`UI started at ${url}`))) | | 247 | + } else { | | 248 | + this.log(PAD + c.dim(c.green(`API started at ${new URL('/', origin)}`))) | | 249 | + } | 256 | 250 | } | 257 | 251 |
| 258 | 252 | if (this.ctx.coverageProvider) { | |
Collapse file Copy file name to clipboardExpand all lines: packages/vitest/src/node/plugins/browserLoader.ts +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -173,7 +173,7 @@ export async function createClusterServer( | 173 | 173 |
| 174 | 174 | if (!contribution) { | 175 | 175 | const server = await createViteServer(viteConfig) | 176 | | - if (config.api.port) { | | 176 | + if (config.api.port != null) { | 177 | 177 | await server.listen(config.api.port) | 178 | 178 | } | 179 | 179 | return { server } | |
Collapse file Copy file name to clipboardExpand all lines: test/browser/specs/server-url.test.ts +14-1Lines changed: 14 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | import { afterEach, expect, test } from 'vitest' | 2 | | -import { instances, runBrowserTests } from './utils' | | 2 | +import { defaultBrowserPort } from 'vitest/config' | | 3 | +import { instances, runBrowserTests, runInlineBrowserTests } from './utils' | 3 | 4 |
| 4 | 5 | afterEach(() => { | 5 | 6 | delete process.env.TEST_HTTPS | @@ -28,3 +29,15 @@ test('server-url https', async () => { | 28 | 29 | expect(new URL(url).port).toBe('31122') | 29 | 30 | expect(stdout).toReportSummaryTestFiles({ passed: instances.length }) | 30 | 31 | }) | | 32 | + | | 33 | +test('server-url port 0', async () => { | | 34 | + const { stderr, ctx } = await runInlineBrowserTests( | | 35 | + { 'basic.test.ts': `test('basic', () => {})` }, | | 36 | + { api: { port: 0 }, globals: true, watch: true }, | | 37 | + ) | | 38 | + expect(stderr).toBe('') | | 39 | + const url = ctx?.projects[0].vite.resolvedUrls?.local[0] | | 40 | + expect.assert(url) | | 41 | + // Vite 8.2.1+ binds an OS-assigned port, older Vite binds 5173 | | 42 | + expect(new URL(url).port).not.toBe(String(defaultBrowserPort)) | | 43 | +}) |
Collapse file Copy file name to clipboardExpand all lines: test/e2e/test/override.test.ts +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -50,6 +50,15 @@ describe('correctly defines api flag', () => { | 50 | 50 | }) | 51 | 51 | }) | 52 | 52 |
| | 53 | + it.for<[string, Parameters<typeof config>[0]]>([ | | 54 | + ['api.port', { api: { port: 0 } }], | | 55 | + ['api', { api: 0 }], | | 56 | + ])('keeps port 0 with %s', async ([, options]) => { | | 57 | + const c = await config(options) | | 58 | + expect(c.api.port).toBe(0) | | 59 | + expect(c.$viteConfig.server.port).toBe(0) | | 60 | + }) | | 61 | + | 53 | 62 | it('allowWrite and allowExec default to true when not exposed to network', async () => { | 54 | 63 | const c = await config({ api: { port: 5555 } }) | 55 | 64 | expect(c.api.allowWrite).toBe(true) | |
|