fix(webServer): do not set baseURL equal to webServer.url (#11951)

This commit is contained in:
Dmitry Gozman 2022-02-08 15:57:36 -08:00 committed by GitHub
parent 8dff2e35c8
commit e92caf01b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 56 deletions

View File

@ -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

View File

@ -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');
});
```

View File

@ -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<boolean>, delay: number, cancellati
}
function getIsAvailableFunction({ url, port }: Pick<WebServerConfig, 'port' | 'url'>) {
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.`);

View File

@ -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<TestArgs = {}, WorkerArgs = {}> {
* 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<TestArgs = {}, WorkerArgs = {}> {
* 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');
* });
* ```

View File

@ -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');
});
`,