@cronn/element-snapshot 0.10.0 → 0.11.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/dist/browser-lib.iife.js +707 -0
- package/dist/{index.d.ts → index.d.mts} +105 -100
- package/dist/index.mjs +166 -0
- package/package.json +16 -8
- package/dist/browser-lib.d.ts +0 -131
- package/dist/browser-lib.global.js +0 -784
- package/dist/index.js +0 -169
|
@@ -1,143 +1,148 @@
|
|
|
1
|
-
import { Locator } from
|
|
1
|
+
import { Locator } from "@playwright/test";
|
|
2
2
|
|
|
3
|
+
//#region src/browser/state.d.ts
|
|
3
4
|
interface DisableableAttributes {
|
|
4
|
-
|
|
5
|
+
disabled?: boolean;
|
|
5
6
|
}
|
|
6
7
|
interface SelectableAttributes {
|
|
7
|
-
|
|
8
|
+
selected?: boolean;
|
|
8
9
|
}
|
|
9
10
|
interface InputStateAttributes extends DisableableAttributes {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface ButtonSnapshot extends GenericElementSnapshot<"button", ButtonAttributes> {
|
|
11
|
+
readonly?: boolean;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
invalid?: boolean;
|
|
16
14
|
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/browser/button.d.ts
|
|
17
|
+
interface ButtonSnapshot extends GenericElementSnapshot<"button", ButtonAttributes> {}
|
|
17
18
|
interface ButtonAttributes extends DisableableAttributes {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
expanded?: boolean;
|
|
20
|
+
pressed?: PressedValue;
|
|
20
21
|
}
|
|
21
22
|
type PressedValue = true | "mixed";
|
|
22
|
-
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/browser/description.d.ts
|
|
23
25
|
interface DiscribableAttributes {
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface InputSnapshot extends GenericElementSnapshot<CommonInputRole, InputAttributes> {
|
|
26
|
+
description?: string;
|
|
28
27
|
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/browser/input.d.ts
|
|
30
|
+
interface InputSnapshot extends GenericElementSnapshot<CommonInputRole, InputAttributes> {}
|
|
29
31
|
type InputRole = "button" | "combobox" | CommonInputRole;
|
|
30
32
|
type CommonInputRole = "checkbox" | "radio" | "searchbox" | "slider" | "spinbutton" | "textbox";
|
|
31
33
|
interface InputAttributes extends CommonInputAttributes {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
value?: string;
|
|
35
|
+
checked?: boolean;
|
|
34
36
|
}
|
|
35
37
|
interface CommonInputAttributes extends InputStateAttributes, DiscribableAttributes {
|
|
36
|
-
|
|
38
|
+
placeholder?: string;
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/browser/combobox.d.ts
|
|
39
42
|
interface ComboboxSnapshot extends GenericElementSnapshot<"combobox", ComboboxAttributes> {
|
|
40
|
-
|
|
43
|
+
options?: Array<OptionSnapshot>;
|
|
41
44
|
}
|
|
42
45
|
interface ComboboxAttributes extends CommonInputAttributes {
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
interface OptionSnapshot extends GenericElementSnapshot<"option", OptionAttributes> {
|
|
46
|
+
value?: string | Array<string>;
|
|
46
47
|
}
|
|
48
|
+
interface OptionSnapshot extends GenericElementSnapshot<"option", OptionAttributes> {}
|
|
47
49
|
interface OptionAttributes {
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
declare const CONTAINER_ROLES: Set<"paragraph" | "list" | "listitem" | "listbox" | "article" | "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "region" | "search" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "rowheader" | "cell" | "gridcell" | "alert" | "menu" | "tablist" | "tabpanel" | "separator">;
|
|
52
|
-
interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {
|
|
50
|
+
selected?: boolean;
|
|
53
51
|
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/browser/container.d.ts
|
|
54
|
+
declare const CONTAINER_ROLES: Set<"paragraph" | "list" | "listitem" | "listbox" | "article" | "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "region" | "search" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "rowheader" | "cell" | "gridcell" | "alert" | "menu" | "tablist" | "tabpanel">;
|
|
55
|
+
interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {}
|
|
54
56
|
type ContainerRole = SetValues<typeof CONTAINER_ROLES>;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/browser/dialog.d.ts
|
|
59
|
+
interface DialogSnapshot extends GenericElementSnapshot<DialogRole, DialogAttributes> {}
|
|
58
60
|
type DialogRole = "dialog" | "alertdialog";
|
|
59
61
|
interface DialogAttributes extends DiscribableAttributes {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
interface RadiogroupSnapshot extends GenericElementSnapshot<"radiogroup", RadiogroupAttributes> {
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
interface HeadingSnapshot extends GenericElementSnapshot<"heading", HeadingAttributes> {
|
|
71
|
-
}
|
|
62
|
+
modal?: boolean;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/browser/group.d.ts
|
|
66
|
+
interface GroupSnapshot extends GenericElementSnapshot<"group"> {}
|
|
67
|
+
interface RadiogroupSnapshot extends GenericElementSnapshot<"radiogroup", RadiogroupAttributes> {}
|
|
68
|
+
interface RadiogroupAttributes extends DiscribableAttributes {}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/browser/heading.d.ts
|
|
71
|
+
interface HeadingSnapshot extends GenericElementSnapshot<"heading", HeadingAttributes> {}
|
|
72
72
|
interface HeadingAttributes {
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
73
|
+
level?: number;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/browser/image.d.ts
|
|
77
|
+
interface ImageSnapshot extends GenericElementSnapshot<"img"> {}
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/browser/link.d.ts
|
|
80
|
+
interface LinkSnapshot extends GenericElementSnapshot<"link", LinkAttributes> {}
|
|
81
81
|
interface LinkAttributes {
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
interface MenuitemAttributes extends LinkAttributes, DisableableAttributes {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
interface ProgressbarSnapshot extends GenericElementSnapshot<"progressbar", ProgressbarAttributes> {
|
|
91
|
-
}
|
|
82
|
+
url?: string;
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/browser/list.d.ts
|
|
86
|
+
interface MenuitemSnapshot extends GenericElementSnapshot<"menuitem", MenuitemAttributes> {}
|
|
87
|
+
interface MenuitemAttributes extends LinkAttributes, DisableableAttributes {}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/browser/progressbar.d.ts
|
|
90
|
+
interface ProgressbarSnapshot extends GenericElementSnapshot<"progressbar", ProgressbarAttributes> {}
|
|
92
91
|
interface ProgressbarAttributes {
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
interface
|
|
102
|
-
|
|
92
|
+
value?: number;
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/browser/separator.d.ts
|
|
96
|
+
interface SeparatorSnapshot extends GenericElementSnapshot<"separator"> {}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/browser/tab.d.ts
|
|
99
|
+
interface TabSnapshot extends GenericElementSnapshot<"tab", TabAttributes> {}
|
|
100
|
+
interface TabAttributes extends DisableableAttributes, SelectableAttributes {}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/browser/table.d.ts
|
|
103
|
+
interface ColumnheaderSnapshot extends GenericElementSnapshot<"columnheader", ColumnheaderAttributes> {}
|
|
103
104
|
interface ColumnheaderAttributes {
|
|
104
|
-
|
|
105
|
+
sort?: SortAttribute;
|
|
105
106
|
}
|
|
106
107
|
declare const SORT_ATTRIBUTES: Set<"ascending" | "descending" | "other">;
|
|
107
108
|
type SortAttribute = SetValues<typeof SORT_ATTRIBUTES>;
|
|
108
|
-
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/browser/text.d.ts
|
|
109
111
|
interface TextSnapshot {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
role: "text";
|
|
113
|
+
name: string;
|
|
112
114
|
}
|
|
113
|
-
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/browser/types.d.ts
|
|
114
117
|
type NodeRole = ElementRole | "text";
|
|
115
|
-
type ElementRole = "heading" | "link" | "button" | "option" | "tab" | "menuitem" | "columnheader" | "group" | "radiogroup" | "progressbar" | "img" | ContainerRole | InputRole | DialogRole;
|
|
118
|
+
type ElementRole = "heading" | "link" | "button" | "option" | "tab" | "menuitem" | "columnheader" | "group" | "radiogroup" | "progressbar" | "img" | "separator" | ContainerRole | InputRole | DialogRole;
|
|
116
119
|
type NodeSnapshot = ElementSnapshot | TextSnapshot;
|
|
117
|
-
type ElementSnapshot = ContainerSnapshot | HeadingSnapshot | LinkSnapshot | ButtonSnapshot | InputSnapshot | ComboboxSnapshot | OptionSnapshot | DialogSnapshot | TabSnapshot | MenuitemSnapshot | ColumnheaderSnapshot | GroupSnapshot | RadiogroupSnapshot | ProgressbarSnapshot | ImageSnapshot;
|
|
120
|
+
type ElementSnapshot = ContainerSnapshot | HeadingSnapshot | LinkSnapshot | ButtonSnapshot | InputSnapshot | ComboboxSnapshot | OptionSnapshot | DialogSnapshot | TabSnapshot | MenuitemSnapshot | ColumnheaderSnapshot | GroupSnapshot | RadiogroupSnapshot | ProgressbarSnapshot | ImageSnapshot | SeparatorSnapshot;
|
|
118
121
|
interface GenericElementSnapshot<TRole extends NodeRole = NodeRole, TAttributes = unknown> {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
role: TRole;
|
|
123
|
+
name?: string;
|
|
124
|
+
attributes?: TAttributes;
|
|
125
|
+
children?: Array<NodeSnapshot>;
|
|
123
126
|
}
|
|
124
127
|
type SetValues<TSet> = TSet extends Set<infer TValue> ? TValue : never;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/utils/snapshot.d.ts
|
|
130
|
+
type SnapshotFilter = (snapshot: NodeSnapshot) => boolean;
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/playwright/snapshot.d.ts
|
|
128
133
|
interface ElementSnapshotOptions {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Include only elements in the snapshot for which the specified filter returns `true`
|
|
136
|
+
*
|
|
137
|
+
* @default () => true
|
|
138
|
+
*/
|
|
139
|
+
filter?: SnapshotFilter;
|
|
140
|
+
/**
|
|
141
|
+
* Include combobox options in the snapshot
|
|
142
|
+
*
|
|
143
|
+
* @default false
|
|
144
|
+
*/
|
|
145
|
+
includeComboboxOptions?: boolean;
|
|
141
146
|
}
|
|
142
147
|
/**
|
|
143
148
|
* Creates an Element Snapshot of the specified element
|
|
@@ -157,5 +162,5 @@ declare function snapshotElement(locator: Locator, options?: ElementSnapshotOpti
|
|
|
157
162
|
* @experimental
|
|
158
163
|
*/
|
|
159
164
|
declare function snapshotElementRaw(locator: Locator): Promise<Array<NodeSnapshot>>;
|
|
160
|
-
|
|
161
|
-
export { type ButtonSnapshot, type ColumnheaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type GroupSnapshot, type HeadingSnapshot, type InputSnapshot, type LinkSnapshot, type MenuitemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadiogroupSnapshot, type TabSnapshot, type TextSnapshot, snapshotElement, snapshotElementRaw };
|
|
165
|
+
//#endregion
|
|
166
|
+
export { type ButtonSnapshot, type ColumnheaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type GroupSnapshot, type HeadingSnapshot, type InputSnapshot, type LinkSnapshot, type MenuitemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadiogroupSnapshot, type TabSnapshot, type TextSnapshot, snapshotElement, snapshotElementRaw };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { packageDirectory } from "package-directory";
|
|
3
|
+
|
|
4
|
+
//#region src/playwright/proxy.ts
|
|
5
|
+
var ElementSnapshotProxy = class {
|
|
6
|
+
page;
|
|
7
|
+
constructor(page) {
|
|
8
|
+
this.page = page;
|
|
9
|
+
}
|
|
10
|
+
async snapshotElement(locator) {
|
|
11
|
+
if (!await this.isLibraryLoaded()) await this.loadLibrary();
|
|
12
|
+
return await locator.evaluate((element) => {
|
|
13
|
+
return window.snapshotElement(element);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async isLibraryLoaded() {
|
|
17
|
+
return await this.page.evaluate(() => typeof window.snapshotElement === "function");
|
|
18
|
+
}
|
|
19
|
+
async loadLibrary() {
|
|
20
|
+
const packageRootDir = await this.resolvePackageRootDir();
|
|
21
|
+
const libPath = path.resolve(packageRootDir, "dist", "browser-lib.iife.js");
|
|
22
|
+
await this.page.addScriptTag({ path: libPath });
|
|
23
|
+
}
|
|
24
|
+
async resolvePackageRootDir() {
|
|
25
|
+
const packageDir = await packageDirectory({ cwd: import.meta.dirname });
|
|
26
|
+
if (packageDir === void 0) throw new Error("Unable to resolve root directory of package");
|
|
27
|
+
return packageDir;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/utils/snapshot.ts
|
|
33
|
+
function filterSnapshots(snapshots, filter) {
|
|
34
|
+
return snapshots.flatMap((snapshot) => {
|
|
35
|
+
const filteredChildren = hasChildren(snapshot) ? filterSnapshots(snapshot.children ?? [], filter) : [];
|
|
36
|
+
if (filter(snapshot)) return {
|
|
37
|
+
...snapshot,
|
|
38
|
+
children: filteredChildren.length > 0 ? filteredChildren : void 0
|
|
39
|
+
};
|
|
40
|
+
return filteredChildren;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function hasChildren(snapshot) {
|
|
44
|
+
return "children" in snapshot && snapshot.children !== void 0 && snapshot.children.length > 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/playwright/transformer.ts
|
|
49
|
+
var ElementSnapshotTransformer = class {
|
|
50
|
+
filter;
|
|
51
|
+
includeComboboxOptions;
|
|
52
|
+
constructor(options = {}) {
|
|
53
|
+
this.filter = options.filter;
|
|
54
|
+
this.includeComboboxOptions = options.includeComboboxOptions ?? false;
|
|
55
|
+
}
|
|
56
|
+
transform(snapshots) {
|
|
57
|
+
const filteredSnapshots = this.filterSnapshots(snapshots);
|
|
58
|
+
const transformedSnapshots = this.transformSnapshots(filteredSnapshots);
|
|
59
|
+
if (transformedSnapshots.length === 1) return transformedSnapshots.at(0);
|
|
60
|
+
return transformedSnapshots;
|
|
61
|
+
}
|
|
62
|
+
filterSnapshots(snapshots) {
|
|
63
|
+
if (this.filter === void 0) return snapshots;
|
|
64
|
+
return filterSnapshots(snapshots, this.filter);
|
|
65
|
+
}
|
|
66
|
+
transformSnapshots(snapshots) {
|
|
67
|
+
return snapshots.map((snapshot) => this.transformSnapshotRecursive(snapshot));
|
|
68
|
+
}
|
|
69
|
+
transformSnapshotRecursive(snapshot) {
|
|
70
|
+
if (snapshot.role === "text") return this.simplifyTextSnapshot(snapshot);
|
|
71
|
+
return this.simplifyElementSnapshot(snapshot);
|
|
72
|
+
}
|
|
73
|
+
simplifyTextSnapshot(snapshot) {
|
|
74
|
+
return snapshot.name;
|
|
75
|
+
}
|
|
76
|
+
simplifyElementSnapshot(snapshot) {
|
|
77
|
+
const normalizedSnapshot = this.normalizeElementSnapshot(snapshot);
|
|
78
|
+
if (this.isEmpty(normalizedSnapshot)) {
|
|
79
|
+
const { role } = normalizedSnapshot;
|
|
80
|
+
return this.transformedSnapshot(role, "");
|
|
81
|
+
}
|
|
82
|
+
if (this.hasOnlyName(normalizedSnapshot)) {
|
|
83
|
+
const { role, name } = normalizedSnapshot;
|
|
84
|
+
return this.transformedSnapshot(role, name);
|
|
85
|
+
}
|
|
86
|
+
if (this.hasOnlyChildren(normalizedSnapshot)) {
|
|
87
|
+
const { role, children } = normalizedSnapshot;
|
|
88
|
+
return this.transformedSnapshot(role, children.length === 1 ? children.at(0) : children);
|
|
89
|
+
}
|
|
90
|
+
if (snapshot.role === "combobox") return this.simplifyComboboxSnapshot(snapshot);
|
|
91
|
+
const { role, name, attributes, children } = normalizedSnapshot;
|
|
92
|
+
return this.transformedSnapshot(role, {
|
|
93
|
+
name,
|
|
94
|
+
...attributes,
|
|
95
|
+
children
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
normalizeElementSnapshot(snapshot) {
|
|
99
|
+
const sparseAttributes = this.removeUndefinedProperties(snapshot.attributes ?? {});
|
|
100
|
+
const transformedChildren = this.transformSnapshots(snapshot?.children ?? []);
|
|
101
|
+
const nameEqualsChildren = transformedChildren.length === 1 && snapshot.name === transformedChildren.at(0);
|
|
102
|
+
return {
|
|
103
|
+
role: snapshot.role,
|
|
104
|
+
name: snapshot.name,
|
|
105
|
+
attributes: sparseAttributes,
|
|
106
|
+
children: nameEqualsChildren ? void 0 : transformedChildren.length === 0 ? void 0 : transformedChildren
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
simplifyComboboxSnapshot(snapshot) {
|
|
110
|
+
const { role, name, attributes } = this.normalizeElementSnapshot(snapshot);
|
|
111
|
+
const transformedOptions = (snapshot.options ?? []).map((optionSnapshot) => this.simplifyElementSnapshot(optionSnapshot));
|
|
112
|
+
return this.transformedSnapshot(role, {
|
|
113
|
+
name,
|
|
114
|
+
...attributes,
|
|
115
|
+
options: this.includeComboboxOptions && transformedOptions.length > 0 ? transformedOptions : void 0
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
isEmpty(snapshot) {
|
|
119
|
+
return snapshot.name === void 0 && (snapshot.attributes === void 0 || Object.keys(snapshot.attributes).length === 0) && (snapshot.children === void 0 || snapshot.children.length === 0);
|
|
120
|
+
}
|
|
121
|
+
hasOnlyName(snapshot) {
|
|
122
|
+
return snapshot.name !== void 0 && snapshot.attributes === void 0 && snapshot.children === void 0;
|
|
123
|
+
}
|
|
124
|
+
hasOnlyChildren(snapshot) {
|
|
125
|
+
return snapshot.name === void 0 && snapshot.attributes === void 0 && snapshot.children !== void 0;
|
|
126
|
+
}
|
|
127
|
+
removeUndefinedProperties(attributes) {
|
|
128
|
+
const sparseAttributes = {};
|
|
129
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
130
|
+
if (value !== void 0) sparseAttributes[key] = value;
|
|
131
|
+
});
|
|
132
|
+
return Object.keys(sparseAttributes).length > 0 ? sparseAttributes : void 0;
|
|
133
|
+
}
|
|
134
|
+
transformedSnapshot(role, content) {
|
|
135
|
+
return { [role]: content };
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/playwright/snapshot.ts
|
|
141
|
+
/**
|
|
142
|
+
* Creates an Element Snapshot of the specified element
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* await expect(snapshotElement(page.getByRole("main"))).toMatchJsonSnapshot();
|
|
147
|
+
* ```
|
|
148
|
+
* @param locator Locator for the element to snapshot
|
|
149
|
+
* @experimental
|
|
150
|
+
*/
|
|
151
|
+
async function snapshotElement(locator, options) {
|
|
152
|
+
const snapshot = await snapshotElementRaw(locator);
|
|
153
|
+
return new ElementSnapshotTransformer(options).transform(snapshot);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Creates an Element Snapshot of the specified element, returning the raw snapshot data for custom transformations
|
|
157
|
+
*
|
|
158
|
+
* @param locator Locator for the element to snapshot
|
|
159
|
+
* @experimental
|
|
160
|
+
*/
|
|
161
|
+
async function snapshotElementRaw(locator) {
|
|
162
|
+
return await new ElementSnapshotProxy(locator.page()).snapshotElement(locator);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
export { snapshotElement, snapshotElementRaw };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cronn/element-snapshot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Element snapshots for Playwright",
|
|
5
5
|
"author": "cronn",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,27 +29,31 @@
|
|
|
29
29
|
"exports": {
|
|
30
30
|
"./package.json": "./package.json",
|
|
31
31
|
".": {
|
|
32
|
-
"types": "./dist/index.d.
|
|
33
|
-
"default": "./dist/index.
|
|
32
|
+
"types": "./dist/index.d.mts",
|
|
33
|
+
"default": "./dist/index.mjs"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"dist"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"package-directory": "8.
|
|
40
|
+
"package-directory": "8.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
+
"@playwright/test": "1.58.2",
|
|
43
44
|
"@trivago/prettier-plugin-sort-imports": "6.0.2",
|
|
44
|
-
"@types/node": "24.10.
|
|
45
|
+
"@types/node": "24.10.12",
|
|
46
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
45
47
|
"eslint": "9.39.2",
|
|
46
48
|
"eslint-config-prettier": "10.1.8",
|
|
47
49
|
"eslint-plugin-unused-imports": "4.3.0",
|
|
48
|
-
"@playwright/test": "1.58.0",
|
|
49
50
|
"prettier": "3.8.1",
|
|
50
|
-
"
|
|
51
|
+
"tsdown": "0.20.3",
|
|
51
52
|
"typescript": "5.9.3",
|
|
52
53
|
"typescript-eslint": "8.54.0",
|
|
54
|
+
"vitest": "4.0.18",
|
|
55
|
+
"@cronn/playwright-file-snapshots": "0.38.1",
|
|
56
|
+
"@cronn/test-utils": "0.0.0",
|
|
53
57
|
"@cronn/shared-configs": "0.0.0"
|
|
54
58
|
},
|
|
55
59
|
"peerDependencies": {
|
|
@@ -58,7 +62,11 @@
|
|
|
58
62
|
"scripts": {
|
|
59
63
|
"lint:check": "eslint src/ --max-warnings=0",
|
|
60
64
|
"lint:fix": "eslint src/ --max-warnings=0 --fix",
|
|
65
|
+
"test:unit": "vitest run",
|
|
66
|
+
"test:unit:coverage": "vitest run --coverage",
|
|
67
|
+
"test:integration": "playwright test",
|
|
68
|
+
"playwright:install": "playwright install chromium",
|
|
61
69
|
"compile": "tsc",
|
|
62
|
-
"build": "
|
|
70
|
+
"build": "tsdown"
|
|
63
71
|
}
|
|
64
72
|
}
|
package/dist/browser-lib.d.ts
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
interface DisableableAttributes {
|
|
2
|
-
disabled?: boolean;
|
|
3
|
-
}
|
|
4
|
-
interface SelectableAttributes {
|
|
5
|
-
selected?: boolean;
|
|
6
|
-
}
|
|
7
|
-
interface InputStateAttributes extends DisableableAttributes {
|
|
8
|
-
readonly?: boolean;
|
|
9
|
-
required?: boolean;
|
|
10
|
-
invalid?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface ButtonSnapshot extends GenericElementSnapshot<"button", ButtonAttributes> {
|
|
14
|
-
}
|
|
15
|
-
interface ButtonAttributes extends DisableableAttributes {
|
|
16
|
-
expanded?: boolean;
|
|
17
|
-
pressed?: PressedValue;
|
|
18
|
-
}
|
|
19
|
-
type PressedValue = true | "mixed";
|
|
20
|
-
|
|
21
|
-
interface DiscribableAttributes {
|
|
22
|
-
description?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface InputSnapshot extends GenericElementSnapshot<CommonInputRole, InputAttributes> {
|
|
26
|
-
}
|
|
27
|
-
type InputRole = "button" | "combobox" | CommonInputRole;
|
|
28
|
-
type CommonInputRole = "checkbox" | "radio" | "searchbox" | "slider" | "spinbutton" | "textbox";
|
|
29
|
-
interface InputAttributes extends CommonInputAttributes {
|
|
30
|
-
value?: string;
|
|
31
|
-
checked?: boolean;
|
|
32
|
-
}
|
|
33
|
-
interface CommonInputAttributes extends InputStateAttributes, DiscribableAttributes {
|
|
34
|
-
placeholder?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface ComboboxSnapshot extends GenericElementSnapshot<"combobox", ComboboxAttributes> {
|
|
38
|
-
options?: Array<OptionSnapshot>;
|
|
39
|
-
}
|
|
40
|
-
interface ComboboxAttributes extends CommonInputAttributes {
|
|
41
|
-
value?: string | Array<string>;
|
|
42
|
-
}
|
|
43
|
-
interface OptionSnapshot extends GenericElementSnapshot<"option", OptionAttributes> {
|
|
44
|
-
}
|
|
45
|
-
interface OptionAttributes {
|
|
46
|
-
selected?: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface DialogSnapshot extends GenericElementSnapshot<DialogRole, DialogAttributes> {
|
|
50
|
-
}
|
|
51
|
-
type DialogRole = "dialog" | "alertdialog";
|
|
52
|
-
interface DialogAttributes extends DiscribableAttributes {
|
|
53
|
-
modal?: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface GroupSnapshot extends GenericElementSnapshot<"group"> {
|
|
57
|
-
}
|
|
58
|
-
interface RadiogroupSnapshot extends GenericElementSnapshot<"radiogroup", RadiogroupAttributes> {
|
|
59
|
-
}
|
|
60
|
-
interface RadiogroupAttributes extends DiscribableAttributes {
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface HeadingSnapshot extends GenericElementSnapshot<"heading", HeadingAttributes> {
|
|
64
|
-
}
|
|
65
|
-
interface HeadingAttributes {
|
|
66
|
-
level?: number;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface ImageSnapshot extends GenericElementSnapshot<"img"> {
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
interface LinkSnapshot extends GenericElementSnapshot<"link", LinkAttributes> {
|
|
73
|
-
}
|
|
74
|
-
interface LinkAttributes {
|
|
75
|
-
url?: string;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface MenuitemSnapshot extends GenericElementSnapshot<"menuitem", MenuitemAttributes> {
|
|
79
|
-
}
|
|
80
|
-
interface MenuitemAttributes extends LinkAttributes, DisableableAttributes {
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
interface ProgressbarSnapshot extends GenericElementSnapshot<"progressbar", ProgressbarAttributes> {
|
|
84
|
-
}
|
|
85
|
-
interface ProgressbarAttributes {
|
|
86
|
-
value?: number;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface TabSnapshot extends GenericElementSnapshot<"tab", TabAttributes> {
|
|
90
|
-
}
|
|
91
|
-
interface TabAttributes extends DisableableAttributes, SelectableAttributes {
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
interface ColumnheaderSnapshot extends GenericElementSnapshot<"columnheader", ColumnheaderAttributes> {
|
|
95
|
-
}
|
|
96
|
-
interface ColumnheaderAttributes {
|
|
97
|
-
sort?: SortAttribute;
|
|
98
|
-
}
|
|
99
|
-
declare const SORT_ATTRIBUTES: Set<"ascending" | "descending" | "other">;
|
|
100
|
-
type SortAttribute = SetValues<typeof SORT_ATTRIBUTES>;
|
|
101
|
-
|
|
102
|
-
interface TextSnapshot {
|
|
103
|
-
role: "text";
|
|
104
|
-
name: string;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
type SnapshotTargetElement = HTMLElement | SVGElement;
|
|
108
|
-
type NodeRole = ElementRole | "text";
|
|
109
|
-
type ElementRole = "heading" | "link" | "button" | "option" | "tab" | "menuitem" | "columnheader" | "group" | "radiogroup" | "progressbar" | "img" | ContainerRole | InputRole | DialogRole;
|
|
110
|
-
type NodeSnapshot = ElementSnapshot | TextSnapshot;
|
|
111
|
-
type ElementSnapshot = ContainerSnapshot | HeadingSnapshot | LinkSnapshot | ButtonSnapshot | InputSnapshot | ComboboxSnapshot | OptionSnapshot | DialogSnapshot | TabSnapshot | MenuitemSnapshot | ColumnheaderSnapshot | GroupSnapshot | RadiogroupSnapshot | ProgressbarSnapshot | ImageSnapshot;
|
|
112
|
-
interface GenericElementSnapshot<TRole extends NodeRole = NodeRole, TAttributes = unknown> {
|
|
113
|
-
role: TRole;
|
|
114
|
-
name?: string;
|
|
115
|
-
attributes?: TAttributes;
|
|
116
|
-
children?: Array<NodeSnapshot>;
|
|
117
|
-
}
|
|
118
|
-
type SetValues<TSet> = TSet extends Set<infer TValue> ? TValue : never;
|
|
119
|
-
|
|
120
|
-
declare const CONTAINER_ROLES: Set<"paragraph" | "list" | "listitem" | "listbox" | "article" | "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "region" | "search" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "rowheader" | "cell" | "gridcell" | "alert" | "menu" | "tablist" | "tabpanel" | "separator">;
|
|
121
|
-
interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {
|
|
122
|
-
}
|
|
123
|
-
type ContainerRole = SetValues<typeof CONTAINER_ROLES>;
|
|
124
|
-
|
|
125
|
-
declare function snapshotElement(element: SnapshotTargetElement): Array<NodeSnapshot>;
|
|
126
|
-
|
|
127
|
-
declare global {
|
|
128
|
-
interface Window {
|
|
129
|
-
snapshotElement: typeof snapshotElement;
|
|
130
|
-
}
|
|
131
|
-
}
|