feat: expose configuration for HTML report serving. (#17560)
Fixes #16667
This commit is contained in:
parent
10d7c60abf
commit
ec40e49978
|
|
@ -238,13 +238,19 @@ By default, HTML report is opened automatically if some of the tests failed. You
|
||||||
`open` property in the Playwright config. The possible values for that property are `always`, `never` and `on-failure`
|
`open` property in the Playwright config. The possible values for that property are `always`, `never` and `on-failure`
|
||||||
(default).
|
(default).
|
||||||
|
|
||||||
|
You can also configure `host` and `port` that are used to serve the HTML report.
|
||||||
|
|
||||||
```js tab=js-js
|
```js tab=js-js
|
||||||
// playwright.config.js
|
// playwright.config.js
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||||
const config = {
|
const config = {
|
||||||
reporter: [ ['html', { open: 'never' }] ],
|
reporter: [ ['html', {
|
||||||
|
open: 'never',
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 9223,
|
||||||
|
}] ],
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|
@ -647,4 +653,4 @@ export default config;
|
||||||
|
|
||||||
* [Allure](https://www.npmjs.com/package/allure-playwright)
|
* [Allure](https://www.npmjs.com/package/allure-playwright)
|
||||||
* [Monocart](https://github.com/cenfun/monocart-reporter)
|
* [Monocart](https://github.com/cenfun/monocart-reporter)
|
||||||
* [Tesults](https://www.tesults.com/docs/playwright)
|
* [Tesults](https://www.tesults.com/docs/playwright)
|
||||||
|
|
|
||||||
|
|
@ -51,14 +51,14 @@ export class HttpServer {
|
||||||
return this._port;
|
return this._port;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(port?: number): Promise<string> {
|
async start(port?: number, host = 'localhost'): Promise<string> {
|
||||||
assert(!this._started, 'server already started');
|
assert(!this._started, 'server already started');
|
||||||
this._started = true;
|
this._started = true;
|
||||||
this._server.on('connection', socket => {
|
this._server.on('connection', socket => {
|
||||||
this._activeSockets.add(socket);
|
this._activeSockets.add(socket);
|
||||||
socket.once('close', () => this._activeSockets.delete(socket));
|
socket.once('close', () => this._activeSockets.delete(socket));
|
||||||
});
|
});
|
||||||
this._server.listen(port, 'localhost');
|
this._server.listen(port, host);
|
||||||
await new Promise(cb => this._server!.once('listening', cb));
|
await new Promise(cb => this._server!.once('listening', cb));
|
||||||
const address = this._server.address();
|
const address = this._server.address();
|
||||||
assert(address, 'Could not bind server socket');
|
assert(address, 'Could not bind server socket');
|
||||||
|
|
@ -67,7 +67,7 @@ export class HttpServer {
|
||||||
this._urlPrefix = address;
|
this._urlPrefix = address;
|
||||||
} else {
|
} else {
|
||||||
this._port = address.port;
|
this._port = address.port;
|
||||||
this._urlPrefix = `http://localhost:${address.port}`;
|
this._urlPrefix = `http://${host}:${address.port}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this._urlPrefix;
|
return this._urlPrefix;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ type HtmlReportOpenOption = 'always' | 'never' | 'on-failure';
|
||||||
type HtmlReporterOptions = {
|
type HtmlReporterOptions = {
|
||||||
outputFolder?: string,
|
outputFolder?: string,
|
||||||
open?: HtmlReportOpenOption,
|
open?: HtmlReportOpenOption,
|
||||||
|
host?: string,
|
||||||
|
port?: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
class HtmlReporter implements ReporterInternal {
|
class HtmlReporter implements ReporterInternal {
|
||||||
|
|
@ -116,7 +118,7 @@ class HtmlReporter implements ReporterInternal {
|
||||||
const { ok, singleTestId } = this._buildResult!;
|
const { ok, singleTestId } = this._buildResult!;
|
||||||
const shouldOpen = this._open === 'always' || (!ok && this._open === 'on-failure');
|
const shouldOpen = this._open === 'always' || (!ok && this._open === 'on-failure');
|
||||||
if (shouldOpen) {
|
if (shouldOpen) {
|
||||||
await showHTMLReport(this._outputFolder, singleTestId);
|
await showHTMLReport(this._outputFolder, this._options.host, this._options.port, singleTestId);
|
||||||
} else {
|
} else {
|
||||||
const relativeReportPath = this._outputFolder === standaloneDefaultFolder() ? '' : ' ' + path.relative(process.cwd(), this._outputFolder);
|
const relativeReportPath = this._outputFolder === standaloneDefaultFolder() ? '' : ' ' + path.relative(process.cwd(), this._outputFolder);
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -147,7 +149,7 @@ function standaloneDefaultFolder(): string {
|
||||||
return reportFolderFromEnv() ?? defaultReportFolder(process.cwd());
|
return reportFolderFromEnv() ?? defaultReportFolder(process.cwd());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function showHTMLReport(reportFolder: string | undefined, testId?: string) {
|
export async function showHTMLReport(reportFolder: string | undefined, host: string = 'localhost', port: number = 9223, testId?: string) {
|
||||||
const folder = reportFolder ?? standaloneDefaultFolder();
|
const folder = reportFolder ?? standaloneDefaultFolder();
|
||||||
try {
|
try {
|
||||||
assert(fs.statSync(folder).isDirectory());
|
assert(fs.statSync(folder).isDirectory());
|
||||||
|
|
@ -157,7 +159,7 @@ export async function showHTMLReport(reportFolder: string | undefined, testId?:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const server = startHtmlReportServer(folder);
|
const server = startHtmlReportServer(folder);
|
||||||
let url = await server.start(9323);
|
let url = await server.start(port, host);
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log(colors.cyan(` Serving HTML report at ${url}. Press Ctrl+C to quit.`));
|
console.log(colors.cyan(` Serving HTML report at ${url}. Press Ctrl+C to quit.`));
|
||||||
if (testId)
|
if (testId)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue