feat: allow options in automatic screenshots (#19143)
Closes #9983 Allowing Automatic Screenshots in `PlaywrightTestConfig` to have `fullPage` & `omitBackground` as optional parameters.
This commit is contained in:
		
							parent
							
								
									cac67fb94f
								
							
						
					
					
						commit
						cd4ccdfa29
					
				|  | @ -190,7 +190,10 @@ Learn more about [various timeouts](../test-timeouts.md). | |||
| 
 | ||||
| ## property: TestOptions.screenshot | ||||
| * since: v1.10 | ||||
| - type: <[Screenshot]<"off"|"on"|"only-on-failure">> | ||||
| - type: <[Object]|[ScreenshotMode]<"off"|"on"||"only-on-failure">> | ||||
|   - `mode` <[ScreenshotMode]<"off"|"on"|"only-on-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`. | ||||
| 
 | ||||
| Whether to automatically capture a screenshot after each test. Defaults to `'off'`. | ||||
| * `'off'`: Do not capture screenshots. | ||||
|  |  | |||
|  | @ -255,6 +255,8 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
|     if (debugMode()) | ||||
|       testInfo.setTimeout(0); | ||||
| 
 | ||||
|     const screenshotOptions = typeof screenshot !== 'string' ? { fullPage: screenshot.fullPage, omitBackground: screenshot.omitBackground } : undefined; | ||||
|     const screenshotMode = typeof screenshot === 'string' ? screenshot : screenshot.mode; | ||||
|     const traceMode = normalizeTraceMode(trace); | ||||
|     const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true }; | ||||
|     const traceOptions = typeof trace === 'string' ? defaultTraceOptions : { ...defaultTraceOptions, ...trace, mode: undefined }; | ||||
|  | @ -342,7 +344,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
|       temporaryScreenshots.push(screenshotPath); | ||||
|       // Pass caret=initial to avoid any evaluations that might slow down the screenshot
 | ||||
|       // and let the page modify itself from the problematic state it had at the moment of failure.
 | ||||
|       await page.screenshot({ timeout: 5000, path: screenshotPath, caret: 'initial' }).catch(() => {}); | ||||
|       await page.screenshot({ ...screenshotOptions, timeout: 5000, path: screenshotPath, caret: 'initial' }).catch(() => {}); | ||||
|     }; | ||||
| 
 | ||||
|     const screenshotOnTestFailure = async () => { | ||||
|  | @ -354,7 +356,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
| 
 | ||||
|     const onWillCloseContext = async (context: BrowserContext) => { | ||||
|       await stopTracing(context.tracing); | ||||
|       if (screenshot === 'on' || screenshot === 'only-on-failure') { | ||||
|       if (screenshotMode === 'on' || screenshotMode === 'only-on-failure') { | ||||
|         // Capture screenshot for now. We'll know whether we have to preserve them
 | ||||
|         // after the test finishes.
 | ||||
|         await Promise.all(context.pages().map(screenshotPage)); | ||||
|  | @ -380,7 +382,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
|       const existingApiRequests: APIRequestContext[] =  Array.from((playwright.request as any)._contexts as Set<APIRequestContext>); | ||||
|       await Promise.all(existingApiRequests.map(onDidCreateRequestContext)); | ||||
|     } | ||||
|     if (screenshot === 'on' || screenshot === 'only-on-failure') | ||||
|     if (screenshotMode === 'on' || screenshotMode === 'only-on-failure') | ||||
|       testInfoImpl._onTestFailureImmediateCallbacks.set(screenshotOnTestFailure, 'Screenshot on failure'); | ||||
| 
 | ||||
|     // 2. Run the test.
 | ||||
|  | @ -389,7 +391,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
|     // 3. Determine whether we need the artifacts.
 | ||||
|     const testFailed = testInfo.status !== testInfo.expectedStatus; | ||||
|     const preserveTrace = captureTrace && (traceMode === 'on' || (testFailed && traceMode === 'retain-on-failure') || (traceMode === 'on-first-retry' && testInfo.retry === 1)); | ||||
|     const captureScreenshots = (screenshot === 'on' || (screenshot === 'only-on-failure' && testFailed)); | ||||
|     const captureScreenshots = screenshotMode === 'on' || (screenshotMode === 'only-on-failure' && testFailed); | ||||
| 
 | ||||
|     const traceAttachments: string[] = []; | ||||
|     const addTraceAttachment = () => { | ||||
|  | @ -446,7 +448,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({ | |||
|             return; | ||||
|           // Pass caret=initial to avoid any evaluations that might slow down the screenshot
 | ||||
|           // and let the page modify itself from the problematic state it had at the moment of failure.
 | ||||
|           await page.screenshot({ timeout: 5000, path: addScreenshotAttachment(), caret: 'initial' }).catch(() => {}); | ||||
|           await page.screenshot({ ...screenshotOptions, timeout: 5000, path: addScreenshotAttachment(), caret: 'initial' }).catch(() => {}); | ||||
|         })); | ||||
|       } | ||||
|     }).concat(leftoverApiRequests.map(async context => { | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse } from 'playwright-core'; | ||||
| import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; | ||||
| export * from 'playwright-core'; | ||||
| 
 | ||||
| export type ReporterDescription = | ||||
|  | @ -2965,7 +2965,7 @@ export interface PlaywrightWorkerOptions { | |||
|    * | ||||
|    * Learn more about [automatic screenshots](https://playwright.dev/docs/test-configuration#automatic-screenshots).
 | ||||
|    */ | ||||
|   screenshot: 'off' | 'on' | 'only-on-failure'; | ||||
|   screenshot: ScreenshotMode | { mode: ScreenshotMode } & Pick<PageScreenshotOptions, 'fullPage' | 'omitBackground'>; | ||||
|   /** | ||||
|    * Whether to record trace for each test. Defaults to `'off'`. | ||||
|    * - `'off'`: Do not record trace. | ||||
|  | @ -2995,6 +2995,7 @@ export interface PlaywrightWorkerOptions { | |||
|   video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize }; | ||||
| } | ||||
| 
 | ||||
| export type ScreenshotMode = 'off' | 'on' | 'only-on-failure'; | ||||
| export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; | ||||
| export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
|  */ | ||||
| 
 | ||||
| import type { Page, ViewportSize } from 'playwright-core'; | ||||
| import type { VideoMode } from '@playwright/test'; | ||||
| import type { PageScreenshotOptions, ScreenshotMode, VideoMode } from '@playwright/test'; | ||||
| export { expect } from '@playwright/test'; | ||||
| 
 | ||||
| // Page test does not guarantee an isolated context, just a new page (because Android).
 | ||||
|  | @ -26,6 +26,7 @@ export type PageTestFixtures = { | |||
| export type PageWorkerFixtures = { | ||||
|   headless: boolean; | ||||
|   channel: string; | ||||
|   screenshot: ScreenshotMode | { mode: ScreenshotMode } & Pick<PageScreenshotOptions, 'fullPage' | 'omitBackground'>; | ||||
|   trace: 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | /** deprecated */ 'retry-with-trace'; | ||||
|   video: VideoMode | { mode: VideoMode, size: ViewportSize }; | ||||
|   browserName: 'chromium' | 'firefox' | 'webkit'; | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 73 KiB | 
|  | @ -189,6 +189,35 @@ test('should work with screenshot: only-on-failure', async ({ runInlineTest }, t | |||
|   ]); | ||||
| }); | ||||
| 
 | ||||
| test('should work with screenshot: only-on-failure & fullPage', async ({ runInlineTest, server }, testInfo) => { | ||||
|   const result = await runInlineTest({ | ||||
|     'artifacts.spec.ts': ` | ||||
|     const { test } = pwt; | ||||
| 
 | ||||
|     test('should fail and take fullPage screenshots', async ({ page }) => { | ||||
|       await page.setViewportSize({ width: 500, height: 500 }); | ||||
|       await page.goto('${server.PREFIX}/grid.html'); | ||||
|       expect(1).toBe(2); | ||||
|     }); | ||||
|     `,
 | ||||
|     'playwright.config.ts': ` | ||||
|       module.exports = { use: { screenshot: { mode: 'only-on-failure', fullPage: true } } }; | ||||
|     `,
 | ||||
|   }, { workers: 1 }); | ||||
|   expect(result.exitCode).toBe(1); | ||||
|   expect(result.passed).toBe(0); | ||||
|   expect(result.failed).toBe(1); | ||||
|   expect(listFiles(testInfo.outputPath('test-results'))).toEqual([ | ||||
|     'artifacts-should-fail-and-take-fullPage-screenshots', | ||||
|     '  test-failed-1.png', | ||||
|     'report.json', | ||||
|   ]); | ||||
|   const screenshotFailure = fs.readFileSync( | ||||
|       testInfo.outputPath('test-results', 'artifacts-should-fail-and-take-fullPage-screenshots', 'test-failed-1.png') | ||||
|   ); | ||||
|   expect.soft(screenshotFailure).toMatchSnapshot('screenshot-grid-fullpage.png'); | ||||
| }); | ||||
| 
 | ||||
| test('should work with trace: on', async ({ runInlineTest }, testInfo) => { | ||||
|   const result = await runInlineTest({ | ||||
|     ...testFiles, | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse } from 'playwright-core'; | ||||
| import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core'; | ||||
| export * from 'playwright-core'; | ||||
| 
 | ||||
| export type ReporterDescription = | ||||
|  | @ -208,11 +208,12 @@ export interface PlaywrightWorkerOptions { | |||
|   channel: BrowserChannel | undefined; | ||||
|   launchOptions: LaunchOptions; | ||||
|   connectOptions: ConnectOptions | undefined; | ||||
|   screenshot: 'off' | 'on' | 'only-on-failure'; | ||||
|   screenshot: ScreenshotMode | { mode: ScreenshotMode } & Pick<PageScreenshotOptions, 'fullPage' | 'omitBackground'>; | ||||
|   trace: TraceMode | /** deprecated */ 'retry-with-trace' | { mode: TraceMode, snapshots?: boolean, screenshots?: boolean, sources?: boolean }; | ||||
|   video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize }; | ||||
| } | ||||
| 
 | ||||
| export type ScreenshotMode = 'off' | 'on' | 'only-on-failure'; | ||||
| export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; | ||||
| export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry'; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue