@cronn/element-snapshot 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -79
- package/dist/index.d.mts +17 -14
- package/dist/index.mjs +21 -18
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
# Element Snapshots
|
|
1
|
+
# Playwright Element Snapshots
|
|
2
2
|
|
|
3
|
-
Element
|
|
3
|
+
Element snapshots for Playwright.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Read the full documentation](https://cronn.github.io/file-snapshots/playwright/element-snapshots/)
|
|
6
6
|
|
|
7
7
|
> [!NOTE]
|
|
8
8
|
> Element Snapshots are currently experimental. Not all HTML elements, ARIA roles and attributes are covered. Breaking changes to the snapshot format are possible.
|
|
9
9
|
|
|
10
10
|
## Getting Started
|
|
11
11
|
|
|
12
|
-
###
|
|
12
|
+
### Installation
|
|
13
13
|
|
|
14
14
|
```shell
|
|
15
|
-
|
|
15
|
+
pnpm add -D @cronn/element-snapshot
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
```shell
|
|
19
|
-
|
|
19
|
+
npm install -D @cronn/element-snapshot
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
```shell
|
|
23
|
-
|
|
23
|
+
yarn add -D @cronn/element-snapshot
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Writing Tests
|
|
27
27
|
|
|
28
|
-
This package provides multiple snapshot formats for different use cases:
|
|
29
|
-
|
|
30
|
-
- **General-Purpose Snapshots**: Human-readable JSON format for all element types
|
|
31
|
-
- **Markdown Table Snapshots**: Specialized format for tables and grids ([documentation](docs/markdown-table-snapshot.md))
|
|
32
|
-
- **Custom Snapshots**: Build your own snapshot formats using raw element data and utility functions
|
|
33
|
-
|
|
34
|
-
### General-Purpose Snapshots
|
|
35
|
-
|
|
36
|
-
The function `snapshotElement` provides a general-purpose snapshot including all supported roles and attributes. It can be used to achieve a high test coverage, but can become hard to read for complex HTML structures.
|
|
37
|
-
|
|
38
28
|
```ts
|
|
39
|
-
import {
|
|
29
|
+
import { semanticSnapshot } from "@cronn/element-snapshot";
|
|
40
30
|
import { defineValidationFileExpect } from "@cronn/playwright-file-snapshots";
|
|
41
31
|
|
|
42
32
|
const expect = defineValidationFileExpect();
|
|
43
33
|
|
|
44
34
|
test("matches element snapshot", async ({ page }) => {
|
|
45
|
-
await
|
|
35
|
+
await page.setContent(`
|
|
36
|
+
<main>
|
|
37
|
+
<h1>List</h1>
|
|
38
|
+
<ul>
|
|
39
|
+
<li>Apple</li>
|
|
40
|
+
<li>Peach</li>
|
|
41
|
+
</ul>
|
|
42
|
+
</main>
|
|
43
|
+
`);
|
|
44
|
+
|
|
45
|
+
await expect(semanticSnapshot(page.getByRole("main"))).toMatchJsonFile();
|
|
46
46
|
});
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
**Output (`matches_element_snapshot.json`):**
|
|
50
50
|
|
|
51
51
|
```json
|
|
52
52
|
{
|
|
@@ -70,62 +70,3 @@ Element Snapshot Example:
|
|
|
70
70
|
]
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
|
-
|
|
74
|
-
To improve the specificity of certain tests, `snapshotElement` can be called on certain areas of the page only:
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
test("matches navigation snapshot", async ({ page }) => {
|
|
78
|
-
await expect(snapshotElement(page.getByRole("navigation"))).toMatchJsonFile({
|
|
79
|
-
name: "navigation",
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### Snapshot Options
|
|
85
|
-
|
|
86
|
-
Snapshot options can be passed when calling the snapshot function:
|
|
87
|
-
|
|
88
|
-
```ts
|
|
89
|
-
await expect(
|
|
90
|
-
snapshotElement(page.getByLabel("My select"), {
|
|
91
|
-
filter: (element) => element.role === "heading",
|
|
92
|
-
}),
|
|
93
|
-
).toMatchJsonFile({
|
|
94
|
-
name: "headings",
|
|
95
|
-
});
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
| Option | Default Value | Description |
|
|
99
|
-
| ------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
-
| `filter` | `() => true` | Include only elements in the snapshot for which the specified filter returns `true`. |
|
|
101
|
-
| `recurseFilter` | `false` | Recursively apply specified filter to children of filtered elements. By default, recursion ends when the filter returns `true` for an element. Should be `true` for filters intended to remove specific elements recursively. |
|
|
102
|
-
| `includeComboboxOptions` | `false` | Include combobox options in the snapshot. |
|
|
103
|
-
|
|
104
|
-
### Custom Snapshots
|
|
105
|
-
|
|
106
|
-
The function `snapshotElementRaw` provides the raw element snapshot in a strictly typed structure. This format is not well suited to be read by humans, but can be utilized to derive custom snapshot formats, e.g. for HTML tables.
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
import { snapshotElementRaw } from "@cronn/element-snapshot";
|
|
110
|
-
|
|
111
|
-
test("matches custom snapshot", async ({ page }) => {
|
|
112
|
-
const tableSnapshot = await snapshotElementRaw(page.getByRole("table"));
|
|
113
|
-
const markdownTable = transformToMarkdownTable(tableSnapshot);
|
|
114
|
-
|
|
115
|
-
await expect(markdownTable).toMatchTextFile({ fileExtension: "md" });
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
function transformToMarkdownTable(snapshot: Array<NodeSnapshot>): string {
|
|
119
|
-
// transform table snapshot to markdown table
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
#### Utility Functions for Custom Snapshots
|
|
124
|
-
|
|
125
|
-
| Function | Description |
|
|
126
|
-
| ---------------- | --------------------------------------------------------------------- |
|
|
127
|
-
| `filter` | Filters node snapshots based on the provided predicate function. |
|
|
128
|
-
| `filterByRole` | Filters node snapshots by the specified role. |
|
|
129
|
-
| `includeRole` | Includes only elements with the specified role. |
|
|
130
|
-
| `excludeRole` | Excludes elements with the specified role. |
|
|
131
|
-
| `getTextContent` | Aggregates and normalizes the text content of all provided snapshots. |
|
package/dist/index.d.mts
CHANGED
|
@@ -186,7 +186,7 @@ declare function filter(options: FilterOptions): Array<NodeSnapshot>;
|
|
|
186
186
|
declare function filterByRole<TRole extends NodeRole>(role: TRole, snapshots: Array<NodeSnapshot>): Array<SnapshotByRole<TRole>>;
|
|
187
187
|
//#endregion
|
|
188
188
|
//#region src/playwright/snapshot.d.ts
|
|
189
|
-
interface
|
|
189
|
+
interface SemanticSnapshotOptions {
|
|
190
190
|
/**
|
|
191
191
|
* Include only elements in the snapshot for which the specified filter returns `true`
|
|
192
192
|
*
|
|
@@ -210,23 +210,26 @@ interface ElementSnapshotOptions {
|
|
|
210
210
|
includeComboboxOptions?: boolean;
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
213
|
-
*
|
|
213
|
+
* Captures a semantic snapshot of the specified locator's DOM structure.
|
|
214
214
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* @param
|
|
220
|
-
* @
|
|
215
|
+
* This function creates a raw snapshot of the DOM element identified by the locator
|
|
216
|
+
* and transforms it into a semantic representation using the provided options.
|
|
217
|
+
*
|
|
218
|
+
* @param locator - The Locator instance that identifies the DOM element to snapshot
|
|
219
|
+
* @param options - Optional configuration settings for controlling the snapshot behavior
|
|
220
|
+
* @return A promise that resolves to the semantic snapshot
|
|
221
221
|
*/
|
|
222
|
-
declare function
|
|
222
|
+
declare function semanticSnapshot(locator: Locator, options?: SemanticSnapshotOptions): Promise<unknown>;
|
|
223
223
|
/**
|
|
224
|
-
*
|
|
224
|
+
* Captures a raw snapshot of the element matched by the provided locator.
|
|
225
|
+
*
|
|
226
|
+
* Returns an array of node snapshots representing the current state of the matched elements
|
|
227
|
+
* in the DOM, including their properties, attributes, and structure.
|
|
225
228
|
*
|
|
226
|
-
* @param locator Locator
|
|
227
|
-
* @
|
|
229
|
+
* @param locator - The Locator instance used to identify the target element to snapshot
|
|
230
|
+
* @return A promise that resolves to an array of NodeSnapshot objects representing the captured element
|
|
228
231
|
*/
|
|
229
|
-
declare function
|
|
232
|
+
declare function rawSnapshot(locator: Locator): Promise<Array<NodeSnapshot>>;
|
|
230
233
|
//#endregion
|
|
231
234
|
//#region src/utils/predicates.d.ts
|
|
232
235
|
/**
|
|
@@ -244,4 +247,4 @@ declare function excludeRole<TRole extends NodeRole>(role: TRole | Array<TRole>)
|
|
|
244
247
|
*/
|
|
245
248
|
declare function getTextContent(snapshots: Array<NodeSnapshot>): string;
|
|
246
249
|
//#endregion
|
|
247
|
-
export { type ButtonSnapshot, type ColumnheaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type GroupSnapshot, type HeadingSnapshot, type ImageSnapshot, type InputSnapshot, type LinkSnapshot, type MarkdownTableSnapshotOptions, type MenuitemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadiogroupSnapshot, type SeparatorSnapshot, type SnapshotByRole, type TabSnapshot, type TextSnapshot, excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot,
|
|
250
|
+
export { type ButtonSnapshot, type ColumnheaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type GroupSnapshot, type HeadingSnapshot, type ImageSnapshot, type InputSnapshot, type LinkSnapshot, type MarkdownTableSnapshotOptions, type MenuitemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadiogroupSnapshot, type SeparatorSnapshot, type SnapshotByRole, type TabSnapshot, type TextSnapshot, excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot, rawSnapshot, semanticSnapshot };
|
package/dist/index.mjs
CHANGED
|
@@ -106,8 +106,8 @@ var ElementSnapshotProxy = class {
|
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
//#endregion
|
|
109
|
-
//#region src/playwright/transformer.ts
|
|
110
|
-
var
|
|
109
|
+
//#region src/playwright/semantic-snapshot-transformer.ts
|
|
110
|
+
var SemanticSnapshotTransformer = class {
|
|
111
111
|
filter;
|
|
112
112
|
recurseFilter;
|
|
113
113
|
includeComboboxOptions;
|
|
@@ -206,26 +206,29 @@ var ElementSnapshotTransformer = class {
|
|
|
206
206
|
//#endregion
|
|
207
207
|
//#region src/playwright/snapshot.ts
|
|
208
208
|
/**
|
|
209
|
-
*
|
|
209
|
+
* Captures a semantic snapshot of the specified locator's DOM structure.
|
|
210
210
|
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
* @param
|
|
216
|
-
* @
|
|
211
|
+
* This function creates a raw snapshot of the DOM element identified by the locator
|
|
212
|
+
* and transforms it into a semantic representation using the provided options.
|
|
213
|
+
*
|
|
214
|
+
* @param locator - The Locator instance that identifies the DOM element to snapshot
|
|
215
|
+
* @param options - Optional configuration settings for controlling the snapshot behavior
|
|
216
|
+
* @return A promise that resolves to the semantic snapshot
|
|
217
217
|
*/
|
|
218
|
-
async function
|
|
219
|
-
const snapshot = await
|
|
220
|
-
return new
|
|
218
|
+
async function semanticSnapshot(locator, options) {
|
|
219
|
+
const snapshot = await rawSnapshot(locator);
|
|
220
|
+
return new SemanticSnapshotTransformer(options).transform(snapshot);
|
|
221
221
|
}
|
|
222
222
|
/**
|
|
223
|
-
*
|
|
223
|
+
* Captures a raw snapshot of the element matched by the provided locator.
|
|
224
|
+
*
|
|
225
|
+
* Returns an array of node snapshots representing the current state of the matched elements
|
|
226
|
+
* in the DOM, including their properties, attributes, and structure.
|
|
224
227
|
*
|
|
225
|
-
* @param locator Locator
|
|
226
|
-
* @
|
|
228
|
+
* @param locator - The Locator instance used to identify the target element to snapshot
|
|
229
|
+
* @return A promise that resolves to an array of NodeSnapshot objects representing the captured element
|
|
227
230
|
*/
|
|
228
|
-
async function
|
|
231
|
+
async function rawSnapshot(locator) {
|
|
229
232
|
return await new ElementSnapshotProxy(locator.page()).snapshotElement(locator);
|
|
230
233
|
}
|
|
231
234
|
//#endregion
|
|
@@ -245,7 +248,7 @@ const sortIndicators = {
|
|
|
245
248
|
* Creates a Markdown table snapshot from a table or grid element
|
|
246
249
|
*/
|
|
247
250
|
async function markdownTableSnapshot(locator, options = {}) {
|
|
248
|
-
const { columnHeaders, rows } = parseTable(await
|
|
251
|
+
const { columnHeaders, rows } = parseTable(await rawSnapshot(locator), options);
|
|
249
252
|
return markdownTable([columnHeaders, ...rows]);
|
|
250
253
|
}
|
|
251
254
|
function parseTable(snapshot, options) {
|
|
@@ -279,4 +282,4 @@ function getCellTexts(row) {
|
|
|
279
282
|
}).map((cell) => getTextContent(cell.children));
|
|
280
283
|
}
|
|
281
284
|
//#endregion
|
|
282
|
-
export { excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot,
|
|
285
|
+
export { excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot, rawSnapshot, semanticSnapshot };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cronn/element-snapshot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Element snapshots for Playwright",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/cronn/file-snapshots/issues"
|
|
@@ -12,19 +12,19 @@
|
|
|
12
12
|
"url": "git+https://github.com/cronn/file-snapshots.git",
|
|
13
13
|
"directory": "packages/element-snapshot"
|
|
14
14
|
},
|
|
15
|
-
"homepage": "https://github.
|
|
15
|
+
"homepage": "https://cronn.github.io/file-snapshots/playwright/element-snapshots/",
|
|
16
16
|
"engines": {
|
|
17
17
|
"node": "^20 || ^22 || >=24"
|
|
18
18
|
},
|
|
19
19
|
"devEngines": {
|
|
20
20
|
"runtime": {
|
|
21
21
|
"name": "node",
|
|
22
|
-
"version": ">=24.
|
|
22
|
+
"version": ">=24.14.1 <25",
|
|
23
23
|
"onFail": "error"
|
|
24
24
|
},
|
|
25
25
|
"packageManager": {
|
|
26
26
|
"name": "pnpm",
|
|
27
|
-
"version": ">=10.
|
|
27
|
+
"version": ">=10.33.0 <11",
|
|
28
28
|
"onFail": "error"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
@@ -48,21 +48,21 @@
|
|
|
48
48
|
"@playwright/test": "1.58.2",
|
|
49
49
|
"@trivago/prettier-plugin-sort-imports": "6.0.2",
|
|
50
50
|
"@types/node": "24.12.0",
|
|
51
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
52
|
-
"@vitest/coverage-v8": "4.0
|
|
53
|
-
"eslint": "10.0
|
|
51
|
+
"@typescript/native-preview": "7.0.0-dev.20260323.1",
|
|
52
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
53
|
+
"eslint": "10.1.0",
|
|
54
54
|
"eslint-config-prettier": "10.1.8",
|
|
55
55
|
"eslint-plugin-check-file": "3.3.1",
|
|
56
56
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
57
57
|
"prettier": "3.8.1",
|
|
58
58
|
"publint": "0.3.18",
|
|
59
|
-
"tsdown": "0.21.
|
|
60
|
-
"typescript-eslint": "8.
|
|
61
|
-
"vitest": "4.0
|
|
62
|
-
"@cronn/playwright-file-snapshots": "1.0.
|
|
59
|
+
"tsdown": "0.21.4",
|
|
60
|
+
"typescript-eslint": "8.57.1",
|
|
61
|
+
"vitest": "4.1.0",
|
|
62
|
+
"@cronn/playwright-file-snapshots": "1.0.2",
|
|
63
63
|
"@cronn/shared-configs": "0.0.0",
|
|
64
64
|
"@cronn/test-utils": "0.0.0",
|
|
65
|
-
"@cronn/vitest-file-snapshots": "1.0.
|
|
65
|
+
"@cronn/vitest-file-snapshots": "1.0.2"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"@playwright/test": "^1.55"
|