feat: screenshot:on-first-failure (#33266)

This commit is contained in:
Dmitry Gozman 2024-10-24 04:41:35 -07:00 committed by GitHub
parent 1950bbdc6e
commit 2e01154bb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 8 deletions

View File

@ -479,8 +479,8 @@ export default defineConfig({
## property: TestOptions.screenshot
* since: v1.10
- type: <[Object]|[ScreenshotMode]<"off"|"on"|"only-on-failure">>
- `mode` <[ScreenshotMode]<"off"|"on"|"only-on-failure">> Automatic screenshot mode.
- type: <[Object]|[ScreenshotMode]<"off"|"on"|"only-on-failure"|"on-first-failure">>
- `mode` <[ScreenshotMode]<"off"|"on"|"only-on-failure"|"on-first-failure">> Automatic screenshot mode.
- `fullPage` ?<[boolean]> When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to `false`.
- `omitBackground` ?<[boolean]> Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. Defaults to `false`.
@ -488,6 +488,7 @@ Whether to automatically capture a screenshot after each test. Defaults to `'off
* `'off'`: Do not capture screenshots.
* `'on'`: Capture screenshot after each test.
* `'only-on-failure'`: Capture screenshot after each test failure.
* `'on-first-failure'`: Capture screenshot after each test's first failure.
**Usage**

View File

@ -571,7 +571,7 @@ class ArtifactsRecorder {
if (this._reusedContexts.has(context))
return;
await this._stopTracing(context.tracing);
if (this._screenshotMode === 'on' || this._screenshotMode === 'only-on-failure') {
if (this._screenshotMode === 'on' || this._screenshotMode === 'only-on-failure' || (this._screenshotMode === 'on-first-failure' && this._testInfo.retry === 0)) {
// Capture screenshot for now. We'll know whether we have to preserve them
// after the test finishes.
await Promise.all(context.pages().map(page => this._screenshotPage(page, true)));
@ -588,14 +588,19 @@ class ArtifactsRecorder {
await this._stopTracing(tracing);
}
private _shouldCaptureScreenshotUponFinish() {
return this._screenshotMode === 'on' ||
(this._screenshotMode === 'only-on-failure' && this._testInfo._isFailure()) ||
(this._screenshotMode === 'on-first-failure' && this._testInfo._isFailure() && this._testInfo.retry === 0);
}
async didFinishTestFunction() {
const captureScreenshots = this._screenshotMode === 'on' || (this._screenshotMode === 'only-on-failure' && this._testInfo._isFailure());
if (captureScreenshots)
if (this._shouldCaptureScreenshotUponFinish())
await this._screenshotOnTestFailure();
}
async didFinishTest() {
const captureScreenshots = this._screenshotMode === 'on' || (this._screenshotMode === 'only-on-failure' && this._testInfo._isFailure());
const captureScreenshots = this._shouldCaptureScreenshotUponFinish();
if (captureScreenshots)
await this._screenshotOnTestFailure();

View File

@ -5863,6 +5863,7 @@ export interface PlaywrightWorkerOptions {
* - `'off'`: Do not capture screenshots.
* - `'on'`: Capture screenshot after each test.
* - `'only-on-failure'`: Capture screenshot after each test failure.
* - `'on-first-failure'`: Capture screenshot after each test's first failure.
*
* **Usage**
*
@ -5938,7 +5939,7 @@ export interface PlaywrightWorkerOptions {
video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize };
}
export type ScreenshotMode = 'off' | 'on' | 'only-on-failure';
export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure';
export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';

View File

@ -192,6 +192,33 @@ test('should work with screenshot: only-on-failure', async ({ runInlineTest }, t
]);
});
test('should work with screenshot: on-first-failure', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('fails', async ({ page }) => {
await page.setContent('I am the page');
expect(1).toBe(2);
});
`,
'playwright.config.ts': `
module.exports = {
retries: 1,
use: { screenshot: 'on-first-failure' }
};
`,
}, { workers: 1 });
expect(result.exitCode).toBe(1);
expect(result.passed).toBe(0);
expect(result.failed).toBe(1);
expect(listFiles(testInfo.outputPath('test-results'))).toEqual([
'.last-run.json',
'a-fails',
' test-failed-1.png',
]);
});
test('should work with screenshot: only-on-failure & fullPage', async ({ runInlineTest, server }, testInfo) => {
const result = await runInlineTest({
'artifacts.spec.ts': `

View File

@ -236,7 +236,7 @@ export interface PlaywrightWorkerOptions {
video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize };
}
export type ScreenshotMode = 'off' | 'on' | 'only-on-failure';
export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure';
export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';