chore(test-runner): support self signed certificate in webServer (#13032)
This commit is contained in:
parent
434a729396
commit
1797c5c249
|
|
@ -615,6 +615,7 @@ export default config;
|
||||||
- `command` <[string]> Command which gets executed
|
- `command` <[string]> Command which gets executed
|
||||||
- `port` <[int]> Port to wait on for the web server (exactly one of `port` or `url` is required)
|
- `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)
|
- `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
|
- `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
|
- `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
|
- `cwd` <[string]> Working directory to run the command in
|
||||||
|
|
|
||||||
|
|
@ -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'`.
|
- `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.
|
- `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).
|
- `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.
|
- `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.
|
You can specify these options in the configuration file. Note that testing options are **top-level**, do not put them into the `use` section.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export class WebServer {
|
||||||
private _processExitedPromise!: Promise<any>;
|
private _processExitedPromise!: Promise<any>;
|
||||||
|
|
||||||
constructor(private readonly config: WebServerConfig, private readonly reporter: Reporter) {
|
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<WebServer> {
|
public static async create(config: WebServerConfig, reporter: Reporter): Promise<WebServer> {
|
||||||
|
|
@ -122,13 +122,21 @@ async function isPortUsed(port: number): Promise<boolean> {
|
||||||
return await innerIsPortUsed('127.0.0.1') || await innerIsPortUsed('::1');
|
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<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
(url.protocol === 'https:' ? https : http).get(url, res => {
|
(isHttps ? https : http).get(url, requestOptions, res => {
|
||||||
res.resume();
|
res.resume();
|
||||||
const statusCode = res.statusCode ?? 0;
|
const statusCode = res.statusCode ?? 0;
|
||||||
resolve(statusCode >= 200 && statusCode < 300);
|
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);
|
resolve(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -143,10 +151,10 @@ async function waitFor(waitFn: () => Promise<boolean>, delay: number, cancellati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIsAvailableFunction({ url, port }: Pick<WebServerConfig, 'port' | 'url'>) {
|
function getIsAvailableFunction({ url, port, ignoreHTTPSErrors }: Pick<WebServerConfig, 'port' | 'url' | 'ignoreHTTPSErrors'>, onStdErr: Reporter['onStdErr']) {
|
||||||
if (url !== undefined && port === undefined) {
|
if (url !== undefined && port === undefined) {
|
||||||
const urlObject = new URL(url);
|
const urlObject = new URL(url);
|
||||||
return () => isURLAvailable(urlObject);
|
return () => isURLAvailable(urlObject, ignoreHTTPSErrors, onStdErr);
|
||||||
} else if (port !== undefined && url === undefined) {
|
} else if (port !== undefined && url === undefined) {
|
||||||
return () => isPortUsed(port);
|
return () => isPortUsed(port);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
4
packages/playwright-test/types/test.d.ts
vendored
4
packages/playwright-test/types/test.d.ts
vendored
|
|
@ -466,6 +466,10 @@ export type WebServerConfig = {
|
||||||
* Exactly one of `port` or `url` is required.
|
* Exactly one of `port` or `url` is required.
|
||||||
*/
|
*/
|
||||||
url?: string,
|
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.
|
* How long to wait for the process to start up and be available in milliseconds. Defaults to 60000.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
});
|
||||||
|
|
|
||||||
4
utils/generate_types/overrides-test.d.ts
vendored
4
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -130,6 +130,10 @@ export type WebServerConfig = {
|
||||||
* Exactly one of `port` or `url` is required.
|
* Exactly one of `port` or `url` is required.
|
||||||
*/
|
*/
|
||||||
url?: string,
|
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.
|
* How long to wait for the process to start up and be available in milliseconds. Defaults to 60000.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue