diff --git a/docs/src/api/class-screenshotassertions.md b/docs/src/api/class-screenshotassertions.md new file mode 100644 index 0000000000..ba7ef1af03 --- /dev/null +++ b/docs/src/api/class-screenshotassertions.md @@ -0,0 +1,41 @@ +# class: ScreenshotAssertions +* 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`]. + +```js +expect(screenshot).toMatchSnapshot('landing-page.png'); +``` + + + +## method: ScreenshotAssertions.toMatchSnapshot + +Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory. + +```js +// Basic usage. +expect(await page.screenshot()).toMatchSnapshot('landing-page.png'); + +// Configure image matching threshold. +expect(await page.screenshot()).toMatchSnapshot('landing-page.png', { threshold: 0.3 }); + +// Bring some structure to your snapshot files by passing file path segments. +expect(await page.screenshot()).toMatchSnapshot(['landing', 'step2.png']); +expect(await page.screenshot()).toMatchSnapshot(['landing', 'step3.png']); +``` + +Learn more about [visual comparisons](./test-snapshots.md). + +### param: ScreenshotAssertions.toMatchSnapshot.name +- `name` <[string]|[Array]<[string]>> + +Snapshot name. + +### option: ScreenshotAssertions.toMatchSnapshot.pixelCount = %%-assertions-pixel-count-%% + +### option: ScreenshotAssertions.toMatchSnapshot.pixelRatio = %%-assertions-pixel-ratio-%% + +### option: ScreenshotAssertions.toMatchSnapshot.threshold = %%-assertions-threshold-%% diff --git a/docs/src/test-assertions-js.md b/docs/src/test-assertions-js.md index 530d890594..169f74e248 100644 --- a/docs/src/test-assertions-js.md +++ b/docs/src/test-assertions-js.md @@ -96,307 +96,9 @@ The same works with soft assertions: expect.soft(value, 'my soft assertion').toBe(56); ``` -## expect(locator).toBeChecked([options]) -- `options` - - `checked` <[boolean]> - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to the checked input. - -```js -const locator = page.locator('.subscribe'); -await expect(locator).toBeChecked(); -``` - -## expect(locator).toBeDisabled([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to a disabled element. - -```js -const locator = page.locator('button.submit'); -await expect(locator).toBeDisabled(); -``` - -## expect(locator).toBeEditable([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an editable element. - -```js -const locator = page.locator('input'); -await expect(locator).toBeEditable(); -``` - -## expect(locator).toBeEmpty([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an empty editable element or to a DOM node that has no text. - -```js -const locator = page.locator('div.warning'); -await expect(locator).toBeEmpty(); -``` - -## expect(locator).toBeEnabled([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an enabled element. - -```js -const locator = page.locator('button.submit'); -await expect(locator).toBeEnabled(); -``` - -## expect(locator).toBeFocused([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to a focused DOM node. - -```js -const locator = page.locator('input'); -await expect(locator).toBeFocused(); -``` - -## expect(locator).toBeHidden([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to a hidden DOM node, which is the opposite of [visible](./actionability.md#visible). - -```js -const locator = page.locator('.my-element'); -await expect(locator).toBeHidden(); -``` - -## expect(locator).toBeVisible([options]) -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to a [visible](./actionability.md#visible) DOM node. - -```js -const locator = page.locator('.my-element'); -await expect(locator).toBeVisible(); -``` - -## expect(locator).toContainText(expected[, options]) -- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - - `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text. - -Ensures [Locator] points to an element that contains the given text. You can use regular expressions for the value as well. - -```js -const locator = page.locator('.title'); -await expect(locator).toContainText('substring'); -await expect(locator).toContainText(/\d messages/); -``` - -Note that if array is passed as an expected value, entire lists can be asserted: - -```js -const locator = page.locator('list > .list-item'); -await expect(locator).toContainText(['Text 1', 'Text 4', 'Text 5']); -``` - -## expect(locator).toHaveAttribute(name, value[, options]) -- `name` <[string]> Attribute name -- `value` <[string]|[RegExp]> Attribute value -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an element with given attribute. - -```js -const locator = page.locator('input'); -await expect(locator).toHaveAttribute('type', 'text'); -``` - -## expect(locator).toHaveClass(expected[, options]) -- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an element with given CSS class. - -```js -const locator = page.locator('#component'); -await expect(locator).toHaveClass(/selected/); -``` - -Note that if array is passed as an expected value, entire lists can be asserted: - -```js -const locator = page.locator('list > .component'); -await expect(locator).toHaveClass(['component', 'component selected', 'component']); -``` - -## expect(locator).toHaveCount(count[, options]) -- `count` <[number]> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] resolves to an exact number of DOM nodes. - -```js -const list = page.locator('list > .component'); -await expect(list).toHaveCount(3); -``` - -## expect(locator).toHaveCSS(name, value[, options]) -- `name` <[string]> CSS property name -- `value` <[string]|[RegExp]> CSS property value -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] resolves to an element with the given computed CSS style. - -```js -const locator = page.locator('button'); -await expect(locator).toHaveCSS('display', 'flex'); -``` - -## expect(locator).toHaveId(id[, options]) -- `id` <[string]> Element id -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an element with the given DOM Node ID. - -```js -const locator = page.locator('input'); -await expect(locator).toHaveId('lastname'); -``` - -## expect(locator).toHaveJSProperty(name, value[, options]) -- `name` <[string]> Property name -- `value` <[any]> Property value -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an element with given JavaScript property. Note that this property can be -of a primitive type as well as a plain serializable JavaScript object. - -```js -const locator = page.locator('.component'); -await expect(locator).toHaveJSProperty('loaded', true); -``` - -## expect(locator).toHaveText(expected[, options]) -- `expected` <[string] | [RegExp] | [Array]<[string]|[RegExp]>> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - - `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text. - -Ensures [Locator] points to an element with the given text. You can use regular expressions for the value as well. - -```js -const locator = page.locator('.title'); -await expect(locator).toHaveText(/Welcome, Test User/); -await expect(locator).toHaveText(/Welcome, .*/); -``` - -Note that if array is passed as an expected value, entire lists can be asserted: - -```js -const locator = page.locator('list > .component'); -await expect(locator).toHaveText(['Text 1', 'Text 2', 'Text 3']); -``` - -## expect(locator).toHaveValue(value[, options]) -- `value` <[string] | [RegExp]> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures [Locator] points to an element with the given input value. You can use regular expressions for the value as well. - -```js -const locator = page.locator('input[type=number]'); -await expect(locator).toHaveValue(/[0-9]/); -``` - -## expect(page).toHaveTitle(title[, options]) -- `title` <[string] | [RegExp]> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures page has a given title. - -```js -await expect(page).toHaveTitle(/.*checkout/); -``` - -## expect(page).toHaveURL(url[, options]) -- `url` <[string] | [RegExp]> -- `options` - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures page is navigated to a given URL. - -```js -await expect(page).toHaveURL(/.*checkout/); -``` - -## expect(value).toMatchSnapshot(name[, options]) -- `name` <[string] | [Array]<[string]>> Snapshot name. -- `options` - - `threshold` <[float]> an acceptable percieved color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax), default is configurable with [`property: TestConfig.expect`]. Defaults to `0.2`. - - `pixelCount` <[int]> an acceptable amount of pixels that could be different, unset by default. - - `pixelRatio` <[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`, unset by default. - -Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory. - -```js -// Basic usage. -expect(await page.screenshot()).toMatchSnapshot('landing-page.png'); - -// Configure image matching threshold. -expect(await page.screenshot()).toMatchSnapshot('landing-page.png', { threshold: 0.3 }); - -// Bring some structure to your snapshot files by passing file path segments. -expect(await page.screenshot()).toMatchSnapshot(['landing', 'step2.png']); -expect(await page.screenshot()).toMatchSnapshot(['landing', 'step3.png']); -``` - -Learn more about [visual comparisons](./test-snapshots.md). - -## expect(pageOrLocator).toHaveScreenshot([options]) -- `options` - - `name` <[string] | [Array]<[string]>> Optional snapshot name. - - `disableAnimations` <[boolean]> When true, 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. - - `omitBackground` <[boolean]> Hides default white background and allows capturing screenshots with transparency. Defaults to `false`. - - `fullPage` <[boolean]> When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to `false`. - - `mask` <[Array]<[Locator]>> Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with -a pink box `#FF00FF` that completely covers its bounding box. - - `clip` <[Object]> An object which specifies clipping of the resulting image. - - `x` <[float]> x-coordinate of top-left corner of clip area - - `y` <[float]> y-coordinate of top-left corner of clip area - - `width` <[float]> width of clipping area - - `height` <[float]> height of clipping area - - `threshold` <[float]> an acceptable percieved color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between pixels in compared images, between zero (strict) and one (lax), default is configurable with [`property: TestConfig.expect`]. Defaults to `0.2`. - - `pixelCount` <[int]> an acceptable amount of pixels that could be different, unset by default. - - `pixelRatio` <[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`, unset by default. - - `timeout` <[number]> Time to retry assertion for, defaults to `timeout` in [`property: TestConfig.expect`]. - -Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory. - -```js -// Basic usage. -await expect(page).toHaveScreenshot({ name: 'landing-page.png' }); -await expect(page.locator('text=Submit')).toHaveScreenshot(); - -// Take a full page screenshot and auto-generate screenshot name -await expect(page).toHaveScreenshot({ fullPage: true }); - -// Configure image matching properties. -await expect(page.locator('text=Submit').toHaveScreenshot({ pixelRatio: 0.01 }); -``` +## API reference +See the following pages for Playwright-specific assertions: +- [APIResponseAssertions] assertions for [APIResponse] +- [LocatorAssertions] assertions for [Locator] +- [PageAssertions] assertions for [Page] +- [ScreenshotAssertions] for comparing screenshot with stored value diff --git a/utils/doclint/missingDocs.js b/utils/doclint/missingDocs.js index c4e1cd0930..d014a8888a 100644 --- a/utils/doclint/missingDocs.js +++ b/utils/doclint/missingDocs.js @@ -22,7 +22,7 @@ const path = require('path'); /** @typedef {import('../../markdown').MarkdownNode} MarkdownNode */ -const IGNORE_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions']; +const IGNORE_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'ScreenshotAssertions']; module.exports = function lint(documentation, jsSources, apiFileName) { const errors = []; diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index 23eb9c36ae..16234e10c9 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -109,7 +109,7 @@ class TypesGenerator { return (!docsOnlyClassMapping && docClass) ? this.classBody(docClass) : ''; }); - const IGNORED_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions']; + const IGNORED_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'ScreenshotAssertions']; const classes = this.documentation.classesArray.filter(cls => !IGNORED_CLASSES.includes(cls.name)).filter(cls => !handledClasses.has(cls.name)); { const playwright = this.documentation.classesArray.find(c => c.name === 'Playwright');