chore(test-runner): support self signed certificate in webServer (#13032)

This commit is contained in:
Max Schmitt 2022-03-24 17:30:52 +01:00 committed by GitHub
parent 434a729396
commit 1797c5c249
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 7 deletions

View File

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

View File

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

View File

@ -35,7 +35,7 @@ export class WebServer {
private _processExitedPromise!: Promise<any>;
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> {
@ -122,13 +122,21 @@ async function isPortUsed(port: number): Promise<boolean> {
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 => {
(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<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) {
const urlObject = new URL(url);
return () => isURLAvailable(urlObject);
return () => isURLAvailable(urlObject, ignoreHTTPSErrors, onStdErr);
} else if (port !== undefined && url === undefined) {
return () => isPortUsed(port);
} else {

View File

@ -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.
*/

View File

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

View File

@ -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.
*/