From e92caf01b30b3c541e9084addbd1e2928a7d6952 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Tue, 8 Feb 2022 15:57:36 -0800 Subject: [PATCH] fix(webServer): do not set baseURL equal to webServer.url (#11951) --- docs/src/test-advanced-js.md | 11 +++- docs/src/test-api/class-testconfig.md | 39 +++++++------- packages/playwright-test/src/webServer.ts | 8 +-- packages/playwright-test/types/test.d.ts | 64 ++++++++++++----------- tests/playwright-test/web-server.spec.ts | 4 +- 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/docs/src/test-advanced-js.md b/docs/src/test-advanced-js.md index 13244146a4..1192712aa6 100644 --- a/docs/src/test-advanced-js.md +++ b/docs/src/test-advanced-js.md @@ -139,9 +139,16 @@ export const test = base.extend<{ saveLogs: void }>({ To launch a server during the tests, use the `webServer` option in the [configuration file](#configuration-object). -You can specify a port via `port` or additional environment variables, see [here](#configuration-object). The server will wait for it to be available (on `127.0.0.1` or `::1`) before running the tests. For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. +If `port` is specified in the config, test runner will wait for `127.0.0.1:port` or `::1:port` to be available before running the tests. +If `url` is specified in the config, test runner will wait for that `url` to return 2xx response before running the tests. -The port gets then passed over to Playwright as a [`param: baseURL`] when creating the context [`method: Browser.newContext`]. +For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. + +The `port` (but not the `url`) gets passed over to Playwright as a [`property: TestOptions.baseURL`]. For example port `8080` produces `baseURL` equal `http://localhost:8080`. + +:::note +It is also recommended to specify [`property: TestOptions.baseURL`] in the config, so that tests could use relative urls. +::: ```js js-flavor=ts // playwright.config.ts diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index 37e04c1543..a169d21673 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -568,10 +568,15 @@ export default config; Launch a development web server during the tests. -If the port is specified, the server will wait for it to be available on `127.0.0.1` or `::1`, before running the tests. If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. +If the port is specified, the server will wait for it to be available on `127.0.0.1` or `::1`, before running the tests. If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. -The port or url gets then passed over to Playwright as a `baseURL` when creating the context [`method: Browser.newContext`]. -For example port `8080` ends up in `baseURL` to be `http://localhost:8080`. If you want to instead use `https://` you need to manually specify the `baseURL` inside `use` or use a url instead of a port in the `webServer` configuration. The url ends up in `baseURL` without any change. +For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. + +The `port` (but not the `url`) gets passed over to Playwright as a [`property: TestOptions.baseURL`]. For example port `8080` produces `baseURL` equal `http://localhost:8080`. + +:::note +It is also recommended to specify [`property: TestOptions.baseURL`] in the config, so that tests could use relative urls. +::: ```js js-flavor=ts // playwright.config.ts @@ -583,6 +588,9 @@ const config: PlaywrightTestConfig = { timeout: 120 * 1000, reuseExistingServer: !process.env.CI, }, + use: { + baseURL: 'http://localhost:3000/', + }, }; export default config; ``` @@ -598,22 +606,21 @@ const config = { timeout: 120 * 1000, reuseExistingServer: !process.env.CI, }, + use: { + baseURL: 'http://localhost:3000/', + }, }; module.exports = config; ``` -Now you can use a relative path when navigating the page, or use `baseURL` fixture: +Now you can use a relative path when navigating the page: ```js js-flavor=ts // test.spec.ts import { test } from '@playwright/test'; -test('test', async ({ page, baseURL }) => { - // baseURL is taken directly from your web server, - // e.g. http://localhost:3000 - await page.goto(baseURL + '/bar'); - // Alternatively, just use relative path, because baseURL is already - // set for the default context and page. - // For example, this will result in http://localhost:3000/foo + +test('test', async ({ page }) => { + // This will result in http://localhost:3000/foo await page.goto('/foo'); }); ``` @@ -621,13 +628,9 @@ test('test', async ({ page, baseURL }) => { ```js js-flavor=js // test.spec.js const { test } = require('@playwright/test'); -test('test', async ({ page, baseURL }) => { - // baseURL is taken directly from your web server, - // e.g. http://localhost:3000 - await page.goto(baseURL + '/bar'); - // Alternatively, just use relative path, because baseURL is already - // set for the default context and page. - // For example, this will result in http://localhost:3000/foo + +test('test', async ({ page }) => { + // This will result in http://localhost:3000/foo await page.goto('/foo'); }); ``` diff --git a/packages/playwright-test/src/webServer.ts b/packages/playwright-test/src/webServer.ts index 3e99aa134d..74d1d66108 100644 --- a/packages/playwright-test/src/webServer.ts +++ b/packages/playwright-test/src/webServer.ts @@ -91,8 +91,8 @@ export class WebServer { private async _waitForProcess() { await this._waitForAvailability(); - const baseURL = this.config.url ?? `http://localhost:${this.config.port}`; - process.env.PLAYWRIGHT_TEST_BASE_URL = baseURL; + if (this.config.port !== undefined) + process.env.PLAYWRIGHT_TEST_BASE_URL = `http://localhost:${this.config.port}`; } private async _waitForAvailability() { @@ -148,10 +148,10 @@ async function waitFor(waitFn: () => Promise, delay: number, cancellati } function getIsAvailableFunction({ url, port }: Pick) { - if (url && typeof port === 'undefined') { + if (url !== undefined && port === undefined) { const urlObject = new URL(url); return () => isURLAvailable(urlObject); - } else if (port && typeof url === 'undefined') { + } else if (port !== undefined && url === undefined) { return () => isPortUsed(port); } else { throw new Error(`Exactly one of 'port' or 'url' is required in config.webServer.`); diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index 365bc7ad5e..e2da6cb791 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -577,15 +577,18 @@ interface TestConfig { * Launch a development web server during the tests. * * If the port is specified, the server will wait for it to be available on `127.0.0.1` or `::1`, before running the tests. - * If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. For - * continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an + * If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. + * + * For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an * existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. * - * The port or url gets then passed over to Playwright as a `baseURL` when creating the context - * [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). For example port - * `8080` ends up in `baseURL` to be `http://localhost:8080`. If you want to instead use `https://` you need to manually - * specify the `baseURL` inside `use` or use a url instead of a port in the `webServer` configuration. The url ends up in - * `baseURL` without any change. + * The `port` (but not the `url`) gets passed over to Playwright as a + * [testOptions.baseURL](https://playwright.dev/docs/api/class-testoptions#test-options-base-url). For example port `8080` + * produces `baseURL` equal `http://localhost:8080`. + * + * > NOTE: It is also recommended to specify + * [testOptions.baseURL](https://playwright.dev/docs/api/class-testoptions#test-options-base-url) in the config, so that + * tests could use relative urls. * * ```ts * // playwright.config.ts @@ -597,22 +600,21 @@ interface TestConfig { * timeout: 120 * 1000, * reuseExistingServer: !process.env.CI, * }, + * use: { + * baseURL: 'http://localhost:3000/', + * }, * }; * export default config; * ``` * - * Now you can use a relative path when navigating the page, or use `baseURL` fixture: + * Now you can use a relative path when navigating the page: * * ```ts * // test.spec.ts * import { test } from '@playwright/test'; - * test('test', async ({ page, baseURL }) => { - * // baseURL is taken directly from your web server, - * // e.g. http://localhost:3000 - * await page.goto(baseURL + '/bar'); - * // Alternatively, just use relative path, because baseURL is already - * // set for the default context and page. - * // For example, this will result in http://localhost:3000/foo + * + * test('test', async ({ page }) => { + * // This will result in http://localhost:3000/foo * await page.goto('/foo'); * }); * ``` @@ -1068,15 +1070,18 @@ export interface FullConfig { * Launch a development web server during the tests. * * If the port is specified, the server will wait for it to be available on `127.0.0.1` or `::1`, before running the tests. - * If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. For - * continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an + * If the url is specified, the server will wait for the URL to return a 2xx status code before running the tests. + * + * For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an * existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable. * - * The port or url gets then passed over to Playwright as a `baseURL` when creating the context - * [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). For example port - * `8080` ends up in `baseURL` to be `http://localhost:8080`. If you want to instead use `https://` you need to manually - * specify the `baseURL` inside `use` or use a url instead of a port in the `webServer` configuration. The url ends up in - * `baseURL` without any change. + * The `port` (but not the `url`) gets passed over to Playwright as a + * [testOptions.baseURL](https://playwright.dev/docs/api/class-testoptions#test-options-base-url). For example port `8080` + * produces `baseURL` equal `http://localhost:8080`. + * + * > NOTE: It is also recommended to specify + * [testOptions.baseURL](https://playwright.dev/docs/api/class-testoptions#test-options-base-url) in the config, so that + * tests could use relative urls. * * ```ts * // playwright.config.ts @@ -1088,22 +1093,21 @@ export interface FullConfig { * timeout: 120 * 1000, * reuseExistingServer: !process.env.CI, * }, + * use: { + * baseURL: 'http://localhost:3000/', + * }, * }; * export default config; * ``` * - * Now you can use a relative path when navigating the page, or use `baseURL` fixture: + * Now you can use a relative path when navigating the page: * * ```ts * // test.spec.ts * import { test } from '@playwright/test'; - * test('test', async ({ page, baseURL }) => { - * // baseURL is taken directly from your web server, - * // e.g. http://localhost:3000 - * await page.goto(baseURL + '/bar'); - * // Alternatively, just use relative path, because baseURL is already - * // set for the default context and page. - * // For example, this will result in http://localhost:3000/foo + * + * test('test', async ({ page }) => { + * // This will result in http://localhost:3000/foo * await page.goto('/foo'); * }); * ``` diff --git a/tests/playwright-test/web-server.spec.ts b/tests/playwright-test/web-server.spec.ts index c43e5ea6ed..c17c7fae03 100644 --- a/tests/playwright-test/web-server.spec.ts +++ b/tests/playwright-test/web-server.spec.ts @@ -114,8 +114,8 @@ test('should create a server with url', async ({ runInlineTest }, { workerIndex 'test.spec.ts': ` const { test } = pwt; test('connect to the server', async ({baseURL, page}) => { - expect(baseURL).toBe('http://localhost:${port}/ready'); - await page.goto(baseURL); + expect(baseURL).toBe(undefined); + await page.goto('http://localhost:${port}/ready'); expect(await page.textContent('body')).toBe('hello'); }); `,