chore: unrelease toHaveScreenshot and screenshotsDir (#13304)

This commit is contained in:
Dmitry Gozman 2022-04-05 08:34:51 -07:00 committed by GitHub
parent 825e4631f6
commit e31a5b690a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 133 additions and 451 deletions

View file

@ -998,36 +998,6 @@ Property value.
### option: LocatorAssertions.toHaveJSProperty.timeout = %%-js-assertions-timeout-%%
### option: LocatorAssertions.toHaveJSProperty.timeout = %%-csharp-java-python-assertions-timeout-%%
## async method: LocatorAssertions.toHaveScreenshot
* langs: js
Ensures that [Locator] resolves to a given screenshot. This function will re-take
screenshots until it matches with the saved expectation.
If there's no expectation yet, it will wait until two consecutive screenshots
yield the same result, and save the last one as an expectation.
```js
const locator = page.locator('button');
await expect(locator).toHaveScreenshot();
```
### option: LocatorAssertions.toHaveScreenshot.timeout = %%-js-assertions-timeout-%%
### option: LocatorAssertions.toHaveScreenshot.timeout = %%-csharp-java-python-assertions-timeout-%%
### option: LocatorAssertions.toHaveScreenshot.animations = %%-screenshot-option-animations-%%
### option: LocatorAssertions.toHaveScreenshot.omitBackground = %%-screenshot-option-omit-background-%%
### option: LocatorAssertions.toHaveScreenshot.mask = %%-screenshot-option-mask-%%
### option: LocatorAssertions.toHaveScreenshot.maxDiffPixels = %%-assertions-max-diff-pixels-%%
### option: LocatorAssertions.toHaveScreenshot.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
### option: LocatorAssertions.toHaveScreenshot.threshold = %%-assertions-threshold-%%
## async method: LocatorAssertions.toHaveText
* langs:
- alias-java: hasText

View file

@ -114,40 +114,6 @@ Expected substring or RegExp.
### option: PageAssertions.NotToHaveURL.timeout = %%-js-assertions-timeout-%%
### option: PageAssertions.NotToHaveURL.timeout = %%-csharp-java-python-assertions-timeout-%%
## async method: PageAssertions.toHaveScreenshot
* langs: js
Ensures that the page resolves to a given screenshot. This function will re-take
screenshots until it matches with the saved expectation.
If there's no expectation yet, it will wait until two consecutive screenshots
yield the same result, and save the last one as an expectation.
```js
await expect(page).toHaveScreenshot();
```
### option: PageAssertions.toHaveScreenshot.timeout = %%-js-assertions-timeout-%%
### option: PageAssertions.toHaveScreenshot.timeout = %%-csharp-java-python-assertions-timeout-%%
### option: PageAssertions.toHaveScreenshot.animations = %%-screenshot-option-animations-%%
### option: PageAssertions.toHaveScreenshot.omitBackground = %%-screenshot-option-omit-background-%%
### option: PageAssertions.toHaveScreenshot.fullPage = %%-screenshot-option-full-page-%%
### option: PageAssertions.toHaveScreenshot.clip = %%-screenshot-option-clip-%%
### option: PageAssertions.toHaveScreenshot.mask = %%-screenshot-option-mask-%%
### option: PageAssertions.toHaveScreenshot.caret = %%-screenshot-option-caret-%%
### option: PageAssertions.toHaveScreenshot.maxDiffPixels = %%-assertions-max-diff-pixels-%%
### option: PageAssertions.toHaveScreenshot.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
### option: PageAssertions.toHaveScreenshot.threshold = %%-assertions-threshold-%%
## async method: PageAssertions.toHaveTitle
* langs:
- alias-java: hasTitle

View file

@ -2,8 +2,7 @@
* langs: js
Playwright provides methods for comparing page and element screenshots with
expected values stored in files. See also [`method: PageAssertions.toHaveScreenshot`] and
[`LocatorAssertions.toHaveScreenshot`].
expected values stored in files.
```js
expect(screenshot).toMatchSnapshot('landing-page.png');

View file

@ -36,14 +36,6 @@ export default config;
## property: TestConfig.expect
- type: <[Object]>
- `timeout` <[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
- `toHaveScreenshot` <[Object]>
- `threshold` <[float]> an acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same pixel in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
- `maxDiffPixels` <[int]> an acceptable amount of pixels that could be different, unset by default.
- `maxDiffPixelRatio` <[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
- `animations` <[ScreenshotAnimations]<"allow"|"disable">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disable"`.
- `fonts` <[ScreenshotFonts]<"ready"|"nowait">> See [`option: fonts`] in [`method: Page.screenshot`]. Defaults to `"ready"`.
- `size` <[ScreenshotSize]<"css"|"device">> See [`option: size`] in [`method: Page.screenshot`]. Defaults to `"css"`.
- `toMatchSnapshot` <[Object]>
- `threshold` <[float]> an acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same pixel in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
- `maxDiffPixels` <[int]> an acceptable amount of pixels that could be different, unset by default.
@ -59,7 +51,7 @@ Configuration for the `expect` assertion library. Learn more about [various time
const config = {
expect: {
timeout: 10000,
toHaveScreenshot: {
toMatchSnapshot: {
maxDiffPixels: 10,
},
},
@ -75,7 +67,7 @@ import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
expect: {
timeout: 10000,
toHaveScreenshot: {
toMatchSnapshot: {
maxDiffPixels: 10,
},
},
@ -304,41 +296,6 @@ test('example test', async ({}, testInfo) => {
});
```
## property: TestConfig.screenshotsDir
- type: <[string]>
The base directory, relative to the config file, for screenshot files created with `toHaveScreenshot`. Defaults to
```
<directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
```
This path will serve as the base directory for each test file screenshot directory. For example, the following test structure:
```
smoke-tests/
└── basic.spec.ts
```
will result in the following screenshots folder structure:
```
__screenshots__/
└── darwin/
├── Mobile Safari/
│ └── smoke-tests/
│ └── basic.spec.ts/
│ └── screenshot-expectation.png
└── Desktop Chrome/
└── smoke-tests/
└── basic.spec.ts/
└── screenshot-expectation.png
```
where:
* `darwin/` - a platform name folder
* `Mobile Safari` and `Desktop Chrome` - project names
## property: TestConfig.snapshotDir
- type: <[string]>

View file

@ -107,13 +107,6 @@ export default config;
## property: TestProject.expect
- type: <[Object]>
- `timeout` <[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
- `toHaveScreenshot` <[Object]>
- `threshold` <[float]> an acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same pixel in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
- `maxDiffPixels` <[int]> an acceptable amount of pixels that could be different, unset by default.
- `maxDiffPixelRatio` <[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
- `animations` <[ScreenshotAnimations]<"allow"|"disable">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disable"`.
- `fonts` <[ScreenshotFonts]<"ready"|"nowait">> See [`option: fonts`] in [`method: Page.screenshot`]. Defaults to `"ready"`.
- `size` <[ScreenshotSize]<"css"|"device">> See [`option: size`] in [`method: Page.screenshot`]. Defaults to `"css"`.
- `toMatchSnapshot` <[Object]>
- `threshold` <[float]> an acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same pixel in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
- `maxDiffPixels` <[int]> an acceptable amount of pixels that could be different, unset by default.
@ -155,40 +148,6 @@ Any JSON-serializable metadata that will be put directly to the test report.
Project name is visible in the report and during test execution.
## property: TestProject.screenshotsDir
- type: <[string]>
The base directory, relative to the config file, for screenshot files created with `toHaveScreenshot`. Defaults to
```
<directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
```
This path will serve as the base directory for each test file screenshot directory. For example, the following test structure:
```
smoke-tests/
└── basic.spec.ts
```
will result in the following screenshots folder structure:
```
__screenshots__/
└── darwin/
├── Mobile Safari/
│ └── smoke-tests/
│ └── basic.spec.ts/
│ └── screenshot-expectation.png
└── Desktop Chrome/
└── smoke-tests/
└── basic.spec.ts/
└── screenshot-expectation.png
```
where:
* `darwin/` - a platform name folder
* `Mobile Safari` and `Desktop Chrome` - project names
## property: TestProject.snapshotDir
- type: <[string]>

View file

@ -3,7 +3,7 @@ id: test-snapshots
title: "Visual comparisons"
---
Playwright Test includes the ability to produce and visually compare screenshots using `await expect(pageOrLocator).toHaveScreenshot()`. On first execution, Playwright test will generate reference screenshots. Subsequent runs will compare against the reference.
Playwright Test includes the ability to produce and visually compare screenshots using `expect(await page.screenshot()).toMatchSnapshot()`. On first execution, Playwright test will generate reference screenshots. Subsequent runs will compare against the reference.
```js js-flavor=js
// example.spec.js
@ -11,7 +11,7 @@ const { test, expect } = require('@playwright/test');
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot();
expect(await page.screenshot()).toMatchSnapshot();
});
```
@ -21,7 +21,7 @@ import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot();
expect(await page.screenshot()).toMatchSnapshot();
});
```
@ -45,10 +45,10 @@ drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots
The snapshot name `example-test-1-chromium-darwin.png` consists of a few parts:
- `example-test-1.png` - an auto-generated name of the snapshot. Alternatively you can specify snapshot name as the first argument of the `toMatchSnapshot()` method:
```js js-flavor=js
await expect(page).toHaveScreenshot('landing.png');
expect(await page.screenshot()).toMatchSnapshot('landing.png');
```
```js js-flavor=ts
await expect(page).toHaveScreenshot('landing.png');
expect(await page.screenshot()).toMatchSnapshot('landing.png');
```
- `chromium-darwin` - the browser name and the platform. Screenshots differ between browsers and platforms due to different rendering, fonts and more, so you will need different snapshots for them. If you use multiple projects in your [configuration file](./test-configuration.md), project name will be used instead of `chromium`.
@ -67,10 +67,10 @@ Sometimes you need to update the reference screenshot, for example when the page
npx playwright test --update-snapshots
```
> Note that `snapshotName` also accepts an array of path segments to the snapshot file such as `await expect(page).toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])`.
> Note that `snapshotName` also accepts an array of path segments to the snapshot file such as `expect().toMatchSnapshot(['relative', 'path', 'to', 'snapshot.png'])`.
> However, this path must stay within the snapshots directory for each test file (i.e. `a.spec.js-snapshots`), otherwise it will throw.
Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./test-assertions#expectpageorlocatortohavescreenshot-options) to modify its behavior:
Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./test-assertions#expectpageorlocatortomatchsnapshot-options) to modify its behavior:
```js js-flavor=js
// example.spec.js
@ -78,7 +78,7 @@ const { test, expect } = require('@playwright/test');
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
expect(await page.screenshot()).toMatchSnapshot({ maxDiffPixels: 100 });
});
```
@ -88,7 +88,7 @@ import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
expect(await page.screenshot()).toMatchSnapshot({ maxDiffPixels: 100 });
});
```
@ -97,7 +97,7 @@ If you'd like to share the default value among all the tests in the project, you
```js js-flavor=js
module.exports = {
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
toMatchSnapshot: { maxDiffPixels: 100 },
},
};
```
@ -106,7 +106,7 @@ module.exports = {
import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
toMatchSnapshot: { maxDiffPixels: 100 },
},
};
export default config;

View file

@ -44,7 +44,7 @@ import {
toHaveURL,
toHaveValue
} from './matchers/matchers';
import { toMatchSnapshot, toHaveScreenshot } from './matchers/toMatchSnapshot';
import { toMatchSnapshot, toHaveScreenshot as _toHaveScreenshot } from './matchers/toMatchSnapshot';
import type { Expect, TestError } from './types';
import matchers from 'expect/build/matchers';
import { currentTestInfo } from './globals';
@ -141,7 +141,7 @@ const customMatchers = {
toHaveURL,
toHaveValue,
toMatchSnapshot,
toHaveScreenshot,
_toHaveScreenshot,
};
type ExpectMetaInfo = {

View file

@ -91,8 +91,8 @@ export class Loader {
config.testDir = path.resolve(configDir, config.testDir);
if (config.outputDir !== undefined)
config.outputDir = path.resolve(configDir, config.outputDir);
if (config.screenshotsDir !== undefined)
config.screenshotsDir = path.resolve(configDir, config.screenshotsDir);
if ((config as any)._screenshotsDir !== undefined)
(config as any)._screenshotsDir = path.resolve(configDir, (config as any)._screenshotsDir);
if (config.snapshotDir !== undefined)
config.snapshotDir = path.resolve(configDir, config.snapshotDir);
@ -208,8 +208,8 @@ export class Loader {
projectConfig.testDir = path.resolve(this._configDir, projectConfig.testDir);
if (projectConfig.outputDir !== undefined)
projectConfig.outputDir = path.resolve(this._configDir, projectConfig.outputDir);
if (projectConfig.screenshotsDir !== undefined)
projectConfig.screenshotsDir = path.resolve(this._configDir, projectConfig.screenshotsDir);
if ((projectConfig as any)._screenshotsDir !== undefined)
(projectConfig as any)._screenshotsDir = path.resolve(this._configDir, (projectConfig as any)._screenshotsDir);
if (projectConfig.snapshotDir !== undefined)
projectConfig.snapshotDir = path.resolve(this._configDir, projectConfig.snapshotDir);
@ -218,7 +218,7 @@ export class Loader {
const outputDir = takeFirst(this._configOverrides.outputDir, projectConfig.outputDir, config.outputDir, path.join(throwawayArtifactsPath, 'test-results'));
const snapshotDir = takeFirst(this._configOverrides.snapshotDir, projectConfig.snapshotDir, config.snapshotDir, testDir);
const name = takeFirst(this._configOverrides.name, projectConfig.name, config.name, '');
const screenshotsDir = takeFirst(this._configOverrides.screenshotsDir, projectConfig.screenshotsDir, config.screenshotsDir, path.join(testDir, '__screenshots__', process.platform, name));
const screenshotsDir = takeFirst((this._configOverrides as any)._screenshotsDir, (projectConfig as any)._screenshotsDir, (config as any)._screenshotsDir, path.join(testDir, '__screenshots__', process.platform, name));
const fullProject: FullProjectInternal = {
fullyParallel: takeFirst(this._configOverrides.fullyParallel, projectConfig.fullyParallel, config.fullyParallel, undefined),
expect: takeFirst(this._configOverrides.expect, projectConfig.expect, config.expect, undefined),
@ -231,7 +231,7 @@ export class Loader {
name,
testDir,
snapshotDir,
screenshotsDir,
_screenshotsDir: screenshotsDir,
testIgnore: takeFirst(this._configOverrides.testIgnore, projectConfig.testIgnore, config.testIgnore, []),
testMatch: takeFirst(this._configOverrides.testMatch, projectConfig.testMatch, config.testMatch, '**/?(*.)@(spec|test).*'),
timeout: takeFirst(this._configOverrides.timeout, projectConfig.timeout, config.timeout, 10000),
@ -476,6 +476,7 @@ const baseFullConfig: FullConfigInternal = {
_attachments: [],
_configDir: '',
_testGroupsCount: 0,
_screenshotsDir: '',
};
function resolveReporters(reporters: Config['reporter'], rootDir: string): ReporterDescription[]|undefined {

View file

@ -295,7 +295,7 @@ export async function toHaveScreenshot(
const testInfo = currentTestInfo();
if (!testInfo)
throw new Error(`toHaveScreenshot() must be called during the test`);
const config = testInfo.project.expect?.toHaveScreenshot;
const config = (testInfo.project.expect as any)?._toHaveScreenshot;
const helper = new SnapshotHelper(
testInfo, testInfo._screenshotPath.bind(testInfo), 'png',
{

View file

@ -18,8 +18,8 @@ import fs from 'fs';
import * as mime from 'mime';
import path from 'path';
import { calculateSha1 } from 'playwright-core/lib/utils/utils';
import type { FullProject, TestError, TestInfo, TestStatus } from '../types/test';
import type { FullConfigInternal } from './types';
import type { TestError, TestInfo, TestStatus } from '../types/test';
import type { FullConfigInternal, FullProjectInternal } from './types';
import { WorkerInitParams } from './ipc';
import { Loader } from './loader';
import { ProjectImpl } from './project';
@ -43,7 +43,7 @@ export class TestInfoImpl implements TestInfo {
readonly retry: number;
readonly workerIndex: number;
readonly parallelIndex: number;
readonly project: FullProject;
readonly project: FullProjectInternal;
config: FullConfigInternal;
readonly title: string;
readonly titlePath: string[];
@ -141,7 +141,7 @@ export class TestInfoImpl implements TestInfo {
})();
this._screenshotsDir = (() => {
const relativeTestFilePath = path.relative(this.project.testDir, test._requireFile);
return path.join(this.project.screenshotsDir, relativeTestFilePath);
return path.join(this.project._screenshotsDir, relativeTestFilePath);
})();
}

View file

@ -43,6 +43,7 @@ export interface FullConfigInternal extends FullConfigPublic {
_configDir: string;
_testGroupsCount: number;
_attachments: { name: string, path?: string, body?: Buffer, contentType: string }[];
_screenshotsDir: string;
// Overrides the public field.
projects: FullProjectInternal[];
@ -53,4 +54,5 @@ export interface FullConfigInternal extends FullConfigPublic {
* increasing the surface area of the public API type called FullProject.
*/
export interface FullProjectInternal extends FullProjectPublic {
_screenshotsDir: string;
}

View file

@ -43,45 +43,6 @@ type ExpectSettings = {
* Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
*/
timeout?: number;
toHaveScreenshot?: {
/** An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
*/
threshold?: number,
/**
* An acceptable amount of pixels that could be different, unset by default.
*/
maxDiffPixels?: number,
/**
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
*/
maxDiffPixelRatio?: number,
/**
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
* depending on their duration:
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
* - infinite animations are canceled to initial state, and then played over after the screenshot.
*
* Defaults to `"disabled"` that leaves animations untouched.
*/
animations?: 'allow'|'disabled',
/**
* When set to `"ready"`, screenshot will wait for
* [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) promise to resolve in all
* frames. Defaults to `"ready"`.
*/
fonts?: 'ready'|'nowait',
/**
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
* high-dpi devices will be twice as large or even larger. Defaults to `"css"`.
*/
scale?: 'css'|'device',
/**
* When set to `"hide"`, screenshot will hide text caret.
* When set to `"initial"`, text caret behavior will not be changed. Defaults to `"hide"`.
*/
caret?: 'hide'|'initial',
}
toMatchSnapshot?: {
/** An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
*/
@ -208,41 +169,6 @@ interface TestProject {
* resolve to `snapshots/a.spec.js-snapshots`.
*/
snapshotDir?: string;
/**
* The base directory, relative to the config file, for screenshot files created with `toHaveScreenshot`. Defaults to
*
* ```
* <directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
* ```
*
* This path will serve as the base directory for each test file screenshot directory. For example, the following test
* structure:
*
* ```
* smoke-tests/
* basic.spec.ts
* ```
*
* will result in the following screenshots folder structure:
*
* ```
* __screenshots__/
* darwin/
* Mobile Safari/
* smoke-tests/
* basic.spec.ts/
* screenshot-expectation.png
* Desktop Chrome/
* smoke-tests/
* basic.spec.ts/
* screenshot-expectation.png
* ```
*
* where:
* - `darwin/` - a platform name folder
* - `Mobile Safari` and `Desktop Chrome` - project names
*/
screenshotsDir?: string;
/**
* The output directory for files created during test execution. Defaults to `<package.json-directory>/test-results`.
*
@ -773,7 +699,7 @@ interface TestConfig {
* const config: PlaywrightTestConfig = {
* expect: {
* timeout: 10000,
* toHaveScreenshot: {
* toMatchSnapshot: {
* maxDiffPixels: 10,
* },
* },
@ -801,41 +727,6 @@ interface TestConfig {
* resolve to `snapshots/a.spec.js-snapshots`.
*/
snapshotDir?: string;
/**
* The base directory, relative to the config file, for screenshot files created with `toHaveScreenshot`. Defaults to
*
* ```
* <directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
* ```
*
* This path will serve as the base directory for each test file screenshot directory. For example, the following test
* structure:
*
* ```
* smoke-tests/
* basic.spec.ts
* ```
*
* will result in the following screenshots folder structure:
*
* ```
* __screenshots__/
* darwin/
* Mobile Safari/
* smoke-tests/
* basic.spec.ts/
* screenshot-expectation.png
* Desktop Chrome/
* smoke-tests/
* basic.spec.ts/
* screenshot-expectation.png
* ```
*
* where:
* - `darwin/` - a platform name folder
* - `Mobile Safari` and `Desktop Chrome` - project names
*/
screenshotsDir?: string;
/**
* The output directory for files created during test execution. Defaults to `<package.json-directory>/test-results`.
*

View file

@ -223,18 +223,6 @@ interface LocatorMatchers {
* Asserts given DOM node visible on the screen.
*/
toBeVisible(options?: { timeout?: number }): Promise<Locator>;
/**
* Asserts element's screenshot is matching to the snapshot.
*/
toHaveScreenshot(options?: Omit<LocatorScreenshotOptions, 'path' | 'type' | 'quality'> & ImageComparatorOptions & {
name?: string | string[],
}): Promise<Locator>;
/**
* Asserts element's screenshot is matching to the snapshot.
*/
toHaveScreenshot(name: string | string[], options?: Omit<LocatorScreenshotOptions, 'path' | 'type' | 'quality'> & ImageComparatorOptions): Promise<Locator>;
}
interface PageMatchers {
/**
@ -246,18 +234,6 @@ interface PageMatchers {
* Asserts page's URL.
*/
toHaveURL(expected: string | RegExp, options?: { timeout?: number }): Promise<Page>;
/**
* Asserts page screenshot is matching to the snapshot.
*/
toHaveScreenshot(options?: Omit<PageScreenshotOptions, 'path' | 'quality' | 'type'> & ImageComparatorOptions & {
name?: string | string[],
}): Promise<Page>;
/**
* Asserts page screenshot is matching to the snapshot.
*/
toHaveScreenshot(name: string | string[], options?: Omit<PageScreenshotOptions, 'path' | 'quality' | 'type'> & ImageComparatorOptions): Promise<Page>;
}
interface APIResponseMatchers {

View file

@ -181,7 +181,7 @@ test('should include multiple image diffs', async ({ runInlineTest, page, showRe
const result = await runInlineTest({
'playwright.config.ts': `
module.exports = {
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
use: { viewport: { width: ${IMG_WIDTH}, height: ${IMG_HEIGHT} }}
};
`,
@ -192,9 +192,9 @@ test('should include multiple image diffs', async ({ runInlineTest, page, showRe
const { test } = pwt;
test('fails', async ({ page }, testInfo) => {
testInfo.snapshotSuffix = '';
await expect.soft(page).toHaveScreenshot({ timeout: 1000 });
await expect.soft(page).toHaveScreenshot({ timeout: 1000 });
await expect.soft(page).toHaveScreenshot({ timeout: 1000 });
await expect.soft(page)._toHaveScreenshot({ timeout: 1000 });
await expect.soft(page)._toHaveScreenshot({ timeout: 1000 });
await expect.soft(page)._toHaveScreenshot({ timeout: 1000 });
});
`,
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
@ -260,7 +260,7 @@ test('should include image diff when screenshot failed to generate due to animat
document.body.textContent = Date.now();
}, 50);
});
await expect.soft(page).toHaveScreenshot({ timeout: 1000 });
await expect.soft(page)._toHaveScreenshot({ timeout: 1000 });
});
`,
}, { 'reporter': 'dot,html', 'update-snapshots': true }, { PW_TEST_HTML_REPORT_OPEN: 'never' });

View file

@ -37,7 +37,7 @@ test('should fail to screenshot a page with infinite animation', async ({ runInl
const result = await runInlineTest({
...playwrightConfig({
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
animations: 'allow',
},
},
@ -45,7 +45,7 @@ test('should fail to screenshot a page with infinite animation', async ({ runInl
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 });
await expect(page)._toHaveScreenshot({ timeout: 2000 });
});
`
});
@ -66,7 +66,7 @@ test('should disable animations by default', async ({ runInlineTest }, testInfo)
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.goto('${cssTransitionURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 });
await expect(page)._toHaveScreenshot({ timeout: 2000 });
});
`
}, { 'update-snapshots': true });
@ -75,7 +75,7 @@ test('should disable animations by default', async ({ runInlineTest }, testInfo)
test('should have scale:css by default', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ browser }) => {
const context = await browser.newContext({
@ -83,7 +83,7 @@ test('should have scale:css by default', async ({ runInlineTest }, testInfo) =>
deviceScaleFactor: 2,
});
const page = await context.newPage();
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
await context.close();
});
`
@ -94,19 +94,19 @@ test('should have scale:css by default', async ({ runInlineTest }, testInfo) =>
expect(pngComparator(fs.readFileSync(snapshotOutputPath), whiteImage)).toBe(null);
});
test('should ignore non-documented options in toHaveScreenshot config', async ({ runInlineTest }, testInfo) => {
test('should ignore non-documented options in _toHaveScreenshot config', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
clip: { x: 0, y: 0, width: 10, height: 10 },
},
},
}),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });
@ -126,17 +126,17 @@ test('screenshotPath should include platform and project name by default', async
}),
'a.spec.js': `
pwt.test('is a test', async ({ page }, testInfo) => {
await pwt.expect(page).toHaveScreenshot('snapshot.png');
await pwt.expect(page)._toHaveScreenshot('snapshot.png');
});
`,
'foo/b.spec.js': `
pwt.test('is a test', async ({ page }, testInfo) => {
await pwt.expect(page).toHaveScreenshot('snapshot.png');
await pwt.expect(page)._toHaveScreenshot('snapshot.png');
});
`,
'foo/bar/baz/c.spec.js': `
pwt.test('is a test', async ({ page }, testInfo) => {
await pwt.expect(page).toHaveScreenshot('snapshot.png');
await pwt.expect(page)._toHaveScreenshot('snapshot.png');
});
`,
}, { 'update-snapshots': true });
@ -146,7 +146,7 @@ test('screenshotPath should include platform and project name by default', async
expect(fs.existsSync(testInfo.outputPath('__screenshots__', process.platform, PROJECT_NAME, 'foo', 'bar', 'baz', 'c.spec.js', 'snapshot.png'))).toBeTruthy();
});
test('should report toHaveScreenshot step with expectation name in title', async ({ runInlineTest }) => {
test('should report _toHaveScreenshot step with expectation name in title', async ({ runInlineTest }) => {
const result = await runInlineTest({
'reporter.ts': `
class Reporter {
@ -164,9 +164,9 @@ test('should report toHaveScreenshot step with expectation name in title', async
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
// Named expectation.
await expect(page).toHaveScreenshot('foo.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('foo.png', { timeout: 2000 });
// Anonymous expectation.
await expect(page).toHaveScreenshot({ timeout: 2000 });
await expect(page)._toHaveScreenshot({ timeout: 2000 });
});
`
}, { 'reporter': '', 'workers': 1, 'update-snapshots': true });
@ -175,8 +175,8 @@ test('should report toHaveScreenshot step with expectation name in title', async
expect(result.output.split('\n').filter(line => line.startsWith('%%'))).toEqual([
`%% end browserContext.newPage`,
`%% end Before Hooks`,
`%% end expect.toHaveScreenshot(foo.png)`,
`%% end expect.toHaveScreenshot(is-a-test-1.png)`,
`%% end expect._toHaveScreenshot(foo.png)`,
`%% end expect._toHaveScreenshot(is-a-test-1.png)`,
`%% end browserContext.close`,
`%% end After Hooks`,
]);
@ -186,14 +186,14 @@ test('should not fail when racing with navigation', async ({ runInlineTest }, te
const infiniteAnimationURL = pathToFileURL(path.join(__dirname, '../assets/rotate-z.html'));
const result = await runInlineTest({
...playwrightConfig({
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
}),
'__screenshots__/a.spec.js/snapshot.png': createImage(10, 10, 255, 0, 0),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await Promise.all([
page.goto('${infiniteAnimationURL}'),
expect(page).toHaveScreenshot({
expect(page)._toHaveScreenshot({
name: 'snapshot.png',
animations: "disabled",
clip: { x: 0, y: 0, width: 10, height: 10 },
@ -208,11 +208,11 @@ test('should not fail when racing with navigation', async ({ runInlineTest }, te
test('should successfully screenshot a page with infinite animation with disableAnimation: true', async ({ runInlineTest }, testInfo) => {
const infiniteAnimationURL = pathToFileURL(path.join(__dirname, '../assets/rotate-z.html'));
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}');
await expect(page).toHaveScreenshot({
await expect(page)._toHaveScreenshot({
animations: "disabled",
});
});
@ -224,11 +224,11 @@ test('should successfully screenshot a page with infinite animation with disable
test('should support clip option for page', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': createImage(50, 50, 255, 255, 255),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({
await expect(page)._toHaveScreenshot({
name: 'snapshot.png',
clip: { x: 0, y: 0, width: 50, height: 50, },
});
@ -240,14 +240,14 @@ test('should support clip option for page', async ({ runInlineTest }, testInfo)
test('should support omitBackground option for locator', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.evaluate(() => {
document.body.style.setProperty('width', '100px');
document.body.style.setProperty('height', '100px');
});
await expect(page.locator('body')).toHaveScreenshot({
await expect(page.locator('body'))._toHaveScreenshot({
name: 'snapshot.png',
omitBackground: true,
});
@ -270,10 +270,10 @@ test('should fail to screenshot an element with infinite animation', async ({ ru
const infiniteAnimationURL = pathToFileURL(path.join(__dirname, '../assets/rotate-z.html'));
const result = await runInlineTest({
...playwrightConfig({
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
projects: [{
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
animations: 'allow',
},
},
@ -282,7 +282,7 @@ test('should fail to screenshot an element with infinite animation', async ({ ru
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}');
await expect(page.locator('body')).toHaveScreenshot({ timeout: 2000 });
await expect(page.locator('body'))._toHaveScreenshot({ timeout: 2000 });
});
`
});
@ -300,9 +300,9 @@ test('should fail to screenshot an element that keeps moving', async ({ runInlin
const infiniteAnimationURL = pathToFileURL(path.join(__dirname, '../assets/rotate-z.html'));
const result = await runInlineTest({
...playwrightConfig({
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
animations: 'allow',
},
},
@ -310,7 +310,7 @@ test('should fail to screenshot an element that keeps moving', async ({ runInlin
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}');
await expect(page.locator('div')).toHaveScreenshot({ timeout: 2000 });
await expect(page.locator('div'))._toHaveScreenshot({ timeout: 2000 });
});
`
});
@ -325,10 +325,10 @@ test('should fail to screenshot an element that keeps moving', async ({ runInlin
test('should generate default name', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot();
await expect(page)._toHaveScreenshot();
});
`
});
@ -338,6 +338,8 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => {
});
test('should compile with different option combinations', async ({ runTSC }) => {
test.skip(true, 'Enable when enabling _toHaveScreenshot');
const result = await runTSC({
'playwright.config.ts': `
import type { PlaywrightTestConfig } from '@playwright/test';
@ -361,7 +363,7 @@ test('should compile with different option combinations', async ({ runTSC }) =>
const { test } = pwt;
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot();
await expect(page.locator('body')).toHaveScreenshot({ threshold: 0.2 });
await expect(page.locator('body'))._toHaveScreenshot({ threshold: 0.2 });
await expect(page).toHaveScreenshot({ maxDiffPixelRatio: 0.2 });
await expect(page).toHaveScreenshot({
threshold: 0.2,
@ -383,11 +385,11 @@ test('should compile with different option combinations', async ({ runTSC }) =>
test('should fail when screenshot is different size', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': createImage(22, 33),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
});
@ -401,7 +403,7 @@ test('should fail when given non-png snapshot name', async ({ runInlineTest }) =
const result = await runInlineTest({
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.jpeg');
await expect(page)._toHaveScreenshot('snapshot.jpeg');
});
`
});
@ -413,7 +415,7 @@ test('should fail when given buffer', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(Buffer.from([1])).toHaveScreenshot();
await expect(Buffer.from([1]))._toHaveScreenshot();
});
`
});
@ -423,11 +425,11 @@ test('should fail when given buffer', async ({ runInlineTest }) => {
test('should fail when screenshot is different pixels', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': paintBlackPixels(whiteImage, 12345),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
});
@ -442,11 +444,11 @@ test('should fail when screenshot is different pixels', async ({ runInlineTest }
test('doesn\'t create comparison artifacts in an output folder for passed negated snapshot matcher', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': blueImage,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png');
await expect(page).not._toHaveScreenshot('snapshot.png');
});
`
});
@ -463,11 +465,11 @@ test('doesn\'t create comparison artifacts in an output folder for passed negate
test('should fail on same snapshots with negate matcher', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': whiteImage,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page).not._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
});
@ -479,11 +481,11 @@ test('should fail on same snapshots with negate matcher', async ({ runInlineTest
test('should write missing expectations locally twice and continue', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page).toHaveScreenshot('snapshot2.png');
await expect(page)._toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot2.png');
console.log('Here we are!');
});
`
@ -509,10 +511,10 @@ test('should write missing expectations locally twice and continue', async ({ ru
test('shouldn\'t write missing expectations locally for negated matcher', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png');
await expect(page).not._toHaveScreenshot('snapshot.png');
});
`
});
@ -525,11 +527,11 @@ test('shouldn\'t write missing expectations locally for negated matcher', async
test('should update snapshot with the update-snapshots flag', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': blueImage,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });
@ -543,11 +545,11 @@ test('should update snapshot with the update-snapshots flag', async ({ runInline
test('shouldn\'t update snapshot with the update-snapshots flag for negated matcher', async ({ runInlineTest }, testInfo) => {
const EXPECTED_SNAPSHOT = blueImage;
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png');
await expect(page).not._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });
@ -559,10 +561,10 @@ test('shouldn\'t update snapshot with the update-snapshots flag for negated matc
test('should silently write missing expectations locally with the update-snapshots flag', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });
@ -576,10 +578,10 @@ test('should silently write missing expectations locally with the update-snapsho
test('should not write missing expectations locally with the update-snapshots flag for negated matcher', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png');
await expect(page).not._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });
@ -592,7 +594,7 @@ test('should not write missing expectations locally with the update-snapshots fl
test('should match multiple snapshots', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/red.png': redImage,
'__screenshots__/a.spec.js/green.png': greenImage,
'__screenshots__/a.spec.js/blue.png': blueImage,
@ -600,15 +602,15 @@ test('should match multiple snapshots', async ({ runInlineTest }) => {
pwt.test('is a test', async ({ page }) => {
await Promise.all([
page.evaluate(() => document.documentElement.style.setProperty('background', '#f00')),
expect(page).toHaveScreenshot('red.png'),
expect(page)._toHaveScreenshot('red.png'),
]);
await Promise.all([
page.evaluate(() => document.documentElement.style.setProperty('background', '#0f0')),
expect(page).toHaveScreenshot('green.png'),
expect(page)._toHaveScreenshot('green.png'),
]);
await Promise.all([
page.evaluate(() => document.documentElement.style.setProperty('background', '#00f')),
expect(page).toHaveScreenshot('blue.png'),
expect(page)._toHaveScreenshot('blue.png'),
]);
});
`
@ -618,11 +620,11 @@ test('should match multiple snapshots', async ({ runInlineTest }) => {
test('should use provided name', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/provided.png': whiteImage,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('provided.png');
await expect(page)._toHaveScreenshot('provided.png');
});
`
});
@ -631,11 +633,11 @@ test('should use provided name', async ({ runInlineTest }) => {
test('should use provided name via options', async ({ runInlineTest }) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/provided.png': whiteImage,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({ name: 'provided.png' });
await expect(page)._toHaveScreenshot({ name: 'provided.png' });
});
`
});
@ -647,21 +649,21 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
const EXPECTED_SNAPSHOT = paintBlackPixels(whiteImage, BAD_PIXELS);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
})).exitCode, 'make sure default comparison fails').toBe(1);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', {
await expect(page)._toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_PIXELS}
});
});
@ -672,9 +674,9 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
...playwrightConfig({
projects: [
{
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
maxDiffPixels: BAD_PIXELS
}
},
@ -684,7 +686,7 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
})).exitCode, 'make sure maxDiffPixels option in project config is respected').toBe(0);
@ -696,21 +698,21 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
const EXPECTED_SNAPSHOT = paintBlackPixels(whiteImage, BAD_COUNT);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
})).exitCode, 'make sure default comparison fails').toBe(1);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', {
await expect(page)._toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${Math.floor(BAD_COUNT / 2)},
maxDiffPixelRatio: ${BAD_RATIO},
timeout: 2000,
@ -720,11 +722,11 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
})).exitCode, 'make sure it fails when maxDiffPixels < actualBadPixels < maxDiffPixelRatio').toBe(1);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', {
await expect(page)._toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_COUNT},
maxDiffPixelRatio: ${BAD_RATIO / 2},
timeout: 2000,
@ -734,11 +736,11 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
})).exitCode, 'make sure it fails when maxDiffPixelRatio < actualBadPixels < maxDiffPixels').toBe(1);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', {
await expect(page)._toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_COUNT},
maxDiffPixelRatio: ${BAD_RATIO},
});
@ -753,21 +755,21 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
const EXPECTED_SNAPSHOT = paintBlackPixels(whiteImage, BAD_PIXELS);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
})).exitCode, 'make sure default comparison fails').toBe(1);
expect((await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', {
await expect(page)._toHaveScreenshot('snapshot.png', {
maxDiffPixelRatio: ${BAD_RATIO}
});
});
@ -777,9 +779,9 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
expect((await runInlineTest({
...playwrightConfig({
projects: [{
screenshotsDir: '__screenshots__',
_screenshotsDir: '__screenshots__',
expect: {
toHaveScreenshot: {
_toHaveScreenshot: {
maxDiffPixelRatio: BAD_RATIO,
},
},
@ -788,7 +790,7 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
})).exitCode, 'make sure maxDiffPixels option in project config is respected').toBe(0);
@ -798,7 +800,7 @@ test('should throw for invalid maxDiffPixels values', async ({ runInlineTest })
expect((await runInlineTest({
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({
await expect(page)._toHaveScreenshot({
maxDiffPixels: -1,
});
});
@ -810,7 +812,7 @@ test('should throw for invalid maxDiffPixelRatio values', async ({ runInlineTest
expect((await runInlineTest({
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({
await expect(page)._toHaveScreenshot({
maxDiffPixelRatio: 12,
});
});
@ -821,14 +823,14 @@ test('should throw for invalid maxDiffPixelRatio values', async ({ runInlineTest
test('should attach expected/actual and no diff when sizes are different', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
...playwrightConfig({ screenshotsDir: '__screenshots__' }),
...playwrightConfig({ _screenshotsDir: '__screenshots__' }),
'__screenshots__/a.spec.js/snapshot.png': createImage(2, 2),
'a.spec.js': `
pwt.test.afterEach(async ({}, testInfo) => {
console.log('## ' + JSON.stringify(testInfo.attachments));
});
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
await expect(page)._toHaveScreenshot('snapshot.png', { timeout: 2000 });
});
`
});
@ -857,11 +859,11 @@ test('should fail with missing expectations and retries', async ({ runInlineTest
const result = await runInlineTest({
...playwrightConfig({
retries: 1,
screenshotsDir: '__screenshots__'
_screenshotsDir: '__screenshots__'
}),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
});
@ -878,11 +880,11 @@ test('should update expectations with retries', async ({ runInlineTest }, testIn
const result = await runInlineTest({
...playwrightConfig({
retries: 1,
screenshotsDir: '__screenshots__'
_screenshotsDir: '__screenshots__'
}),
'a.spec.js': `
pwt.test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png');
await expect(page)._toHaveScreenshot('snapshot.png');
});
`
}, { 'update-snapshots': true });

View file

@ -42,45 +42,6 @@ type ExpectSettings = {
* Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
*/
timeout?: number;
toHaveScreenshot?: {
/** An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
*/
threshold?: number,
/**
* An acceptable amount of pixels that could be different, unset by default.
*/
maxDiffPixels?: number,
/**
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
*/
maxDiffPixelRatio?: number,
/**
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
* depending on their duration:
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
* - infinite animations are canceled to initial state, and then played over after the screenshot.
*
* Defaults to `"disabled"` that leaves animations untouched.
*/
animations?: 'allow'|'disabled',
/**
* When set to `"ready"`, screenshot will wait for
* [`document.fonts.ready`](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready) promise to resolve in all
* frames. Defaults to `"ready"`.
*/
fonts?: 'ready'|'nowait',
/**
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
* high-dpi devices will be twice as large or even larger. Defaults to `"css"`.
*/
scale?: 'css'|'device',
/**
* When set to `"hide"`, screenshot will hide text caret.
* When set to `"initial"`, text caret behavior will not be changed. Defaults to `"hide"`.
*/
caret?: 'hide'|'initial',
}
toMatchSnapshot?: {
/** An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax). Defaults to `0.2`.
*/
@ -104,7 +65,6 @@ interface TestProject {
metadata?: any;
name?: string;
snapshotDir?: string;
screenshotsDir?: string;
outputDir?: string;
repeatEach?: number;
retries?: number;
@ -185,7 +145,6 @@ interface TestConfig {
metadata?: any;
name?: string;
snapshotDir?: string;
screenshotsDir?: string;
outputDir?: string;
repeatEach?: number;
retries?: number;