diff --git a/docs/src/test-api/class-testconfig.md b/docs/src/test-api/class-testconfig.md index 7bf496159a..b7d3aa86b1 100644 --- a/docs/src/test-api/class-testconfig.md +++ b/docs/src/test-api/class-testconfig.md @@ -615,6 +615,7 @@ export default config; - `command` <[string]> Command which gets executed - `port` <[int]> Port to wait on for the web server (exactly one of `port` or `url` is required) - `url` <[string]> URL to wait on for the web server (exactly one of `port` or `url` is required) + - `ignoreHTTPSErrors` <[boolean]> Whether to ignore HTTPS errors when fetching the `url`. Defaults to `false`. - `timeout` <[int]> Maximum duration to wait on until the web server is ready - `reuseExistingServer` <[boolean]> If true, reuse the existing server if it is already running, otherwise it will fail - `cwd` <[string]> Working directory to run the command in diff --git a/docs/src/test-configuration-js.md b/docs/src/test-configuration-js.md index 6e45d00bdd..20cc1ca886 100644 --- a/docs/src/test-configuration-js.md +++ b/docs/src/test-configuration-js.md @@ -557,7 +557,7 @@ In addition to configuring [Browser] or [BrowserContext], videos or screenshots, - `testIgnore`: Glob patterns or regular expressions that should be ignored when looking for the test files. For example, `'**/test-assets'`. - `testMatch`: Glob patterns or regular expressions that match test files. For example, `'**/todo-tests/*.spec.ts'`. By default, Playwright Test runs `.*(test|spec)\.(js|ts|mjs)` files. - `timeout`: Time in milliseconds given to each test. Learn more about [various timeouts](./test-timeouts.md). -- `webServer: { command: string, port: number, timeout?: number, reuseExistingServer?: boolean, cwd?: string, env?: object }` - Launch a process and wait that it's ready before the tests will start. See [launch web server](./test-advanced.md#launching-a-development-web-server-during-the-tests) configuration for examples. +- `webServer: { command: string, port?: number, url?: string, ignoreHTTPSErrors?: boolean, timeout?: number, reuseExistingServer?: boolean, cwd?: string, env?: object }` - Launch a process and wait that it's ready before the tests will start. See [launch web server](./test-advanced.md#launching-a-development-web-server-during-the-tests) configuration for examples. - `workers`: The maximum number of concurrent worker processes to use for parallelizing tests. You can specify these options in the configuration file. Note that testing options are **top-level**, do not put them into the `use` section. diff --git a/packages/playwright-test/src/webServer.ts b/packages/playwright-test/src/webServer.ts index 80ce99b159..717c227dc1 100644 --- a/packages/playwright-test/src/webServer.ts +++ b/packages/playwright-test/src/webServer.ts @@ -35,7 +35,7 @@ export class WebServer { private _processExitedPromise!: Promise; constructor(private readonly config: WebServerConfig, private readonly reporter: Reporter) { - this._isAvailable = getIsAvailableFunction(config); + this._isAvailable = getIsAvailableFunction(config, reporter.onStdErr?.bind(reporter)); } public static async create(config: WebServerConfig, reporter: Reporter): Promise { @@ -122,13 +122,21 @@ async function isPortUsed(port: number): Promise { return await innerIsPortUsed('127.0.0.1') || await innerIsPortUsed('::1'); } -async function isURLAvailable(url: URL) { +async function isURLAvailable(url: URL, ignoreHTTPSErrors: boolean | undefined, onStdErr: Reporter['onStdErr']) { + const isHttps = url.protocol === 'https:'; + const requestOptions = isHttps ? { + rejectUnauthorized: !ignoreHTTPSErrors, + } : {}; return new Promise(resolve => { - (url.protocol === 'https:' ? https : http).get(url, res => { + (isHttps ? https : http).get(url, requestOptions, res => { res.resume(); const statusCode = res.statusCode ?? 0; resolve(statusCode >= 200 && statusCode < 300); - }).on('error', () => { + }).on('error', error => { + if ((error as NodeJS.ErrnoException).code === 'DEPTH_ZERO_SELF_SIGNED_CERT') + onStdErr?.(`[WebServer] Self-signed certificate detected. Try adding ignoreHTTPSErrors: true to config.webServer.`); + else + debugWebServer(`Error while checking if ${url} is available: ${error.message}`); resolve(false); }); }); @@ -143,10 +151,10 @@ async function waitFor(waitFn: () => Promise, delay: number, cancellati } } -function getIsAvailableFunction({ url, port }: Pick) { +function getIsAvailableFunction({ url, port, ignoreHTTPSErrors }: Pick, onStdErr: Reporter['onStdErr']) { if (url !== undefined && port === undefined) { const urlObject = new URL(url); - return () => isURLAvailable(urlObject); + return () => isURLAvailable(urlObject, ignoreHTTPSErrors, onStdErr); } else if (port !== undefined && url === undefined) { return () => isPortUsed(port); } else { diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index e6093ab03e..a930bdd3b9 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -466,6 +466,10 @@ export type WebServerConfig = { * Exactly one of `port` or `url` is required. */ url?: string, + /** + * Whether to ignore HTTPS errors when fetching the `url`. Defaults to `false`. + */ + ignoreHTTPSErrors?: boolean, /** * How long to wait for the process to start up and be available in milliseconds. Defaults to 60000. */ diff --git a/tests/playwright-test/web-server.spec.ts b/tests/playwright-test/web-server.spec.ts index eda277f393..49b1a0e32d 100644 --- a/tests/playwright-test/web-server.spec.ts +++ b/tests/playwright-test/web-server.spec.ts @@ -347,3 +347,22 @@ for (const host of ['localhost', '127.0.0.1', '0.0.0.0']) { } }); } + +test(`should suport self signed certificate`, async ({ runInlineTest, httpsServer }) => { + const result = await runInlineTest({ + 'test.spec.js': ` + const { test } = pwt; + test('pass', async ({}) => { }); + `, + 'playwright.config.js': ` + module.exports = { + webServer: { + url: '${httpsServer.EMPTY_PAGE}', + ignoreHTTPSErrors: true, + reuseExistingServer: true, + }, + }; + `, + }); + expect(result.exitCode).toBe(0); +}); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 7ef6a7c42c..5efff3fff4 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -130,6 +130,10 @@ export type WebServerConfig = { * Exactly one of `port` or `url` is required. */ url?: string, + /** + * Whether to ignore HTTPS errors when fetching the `url`. Defaults to `false`. + */ + ignoreHTTPSErrors?: boolean, /** * How long to wait for the process to start up and be available in milliseconds. Defaults to 60000. */