@cronn/element-snapshot 0.10.0 → 0.12.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.
@@ -0,0 +1,191 @@
1
+ import { Locator } from "@playwright/test";
2
+
3
+ //#region src/browser/state.d.ts
4
+ interface DisableableAttributes {
5
+ disabled?: boolean;
6
+ }
7
+ interface SelectableAttributes {
8
+ selected?: boolean;
9
+ }
10
+ interface InputStateAttributes extends DisableableAttributes {
11
+ readonly?: boolean;
12
+ required?: boolean;
13
+ invalid?: boolean;
14
+ }
15
+ //#endregion
16
+ //#region src/browser/button.d.ts
17
+ interface ButtonSnapshot extends GenericElementSnapshot<"button", ButtonAttributes> {}
18
+ interface ButtonAttributes extends DisableableAttributes {
19
+ expanded?: boolean;
20
+ pressed?: PressedValue;
21
+ }
22
+ type PressedValue = true | "mixed";
23
+ //#endregion
24
+ //#region src/browser/description.d.ts
25
+ interface DiscribableAttributes {
26
+ description?: string;
27
+ }
28
+ //#endregion
29
+ //#region src/browser/input.d.ts
30
+ interface InputSnapshot extends GenericElementSnapshot<CommonInputRole, InputAttributes> {}
31
+ type InputRole = "button" | "combobox" | CommonInputRole;
32
+ type CommonInputRole = "checkbox" | "radio" | "searchbox" | "slider" | "spinbutton" | "textbox";
33
+ interface InputAttributes extends CommonInputAttributes {
34
+ value?: string;
35
+ checked?: boolean;
36
+ }
37
+ interface CommonInputAttributes extends InputStateAttributes, DiscribableAttributes {
38
+ placeholder?: string;
39
+ }
40
+ //#endregion
41
+ //#region src/browser/combobox.d.ts
42
+ interface ComboboxSnapshot extends GenericElementSnapshot<"combobox", ComboboxAttributes> {
43
+ options?: Array<OptionSnapshot>;
44
+ }
45
+ interface ComboboxAttributes extends CommonInputAttributes {
46
+ value?: string | Array<string>;
47
+ }
48
+ interface OptionSnapshot extends GenericElementSnapshot<"option", OptionAttributes> {}
49
+ interface OptionAttributes {
50
+ selected?: boolean;
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" | "descriptionlist" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "rowheader" | "cell" | "gridcell" | "alert" | "menu" | "tablist" | "tabpanel">;
55
+ interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {}
56
+ type ContainerRole = SetValues<typeof CONTAINER_ROLES>;
57
+ //#endregion
58
+ //#region src/browser/dialog.d.ts
59
+ interface DialogSnapshot extends GenericElementSnapshot<DialogRole, DialogAttributes> {}
60
+ type DialogRole = "dialog" | "alertdialog";
61
+ interface DialogAttributes extends DiscribableAttributes {
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
+ interface HeadingAttributes {
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
+ interface LinkAttributes {
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> {}
91
+ interface ProgressbarAttributes {
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> {}
104
+ interface ColumnheaderAttributes {
105
+ sort?: SortAttribute;
106
+ }
107
+ declare const SORT_ATTRIBUTES: Set<"ascending" | "descending" | "other">;
108
+ type SortAttribute = SetValues<typeof SORT_ATTRIBUTES>;
109
+ //#endregion
110
+ //#region src/browser/text.d.ts
111
+ interface TextSnapshot {
112
+ role: "text";
113
+ name: string;
114
+ }
115
+ //#endregion
116
+ //#region src/browser/types.d.ts
117
+ type NodeRole = ElementRole | "text";
118
+ type ElementRole = "heading" | "link" | "button" | "option" | "tab" | "menuitem" | "columnheader" | "group" | "radiogroup" | "progressbar" | "img" | "separator" | ContainerRole | InputRole | DialogRole;
119
+ type NodeSnapshot = ElementSnapshot | TextSnapshot;
120
+ type ElementSnapshot = ContainerSnapshot | HeadingSnapshot | LinkSnapshot | ButtonSnapshot | InputSnapshot | ComboboxSnapshot | OptionSnapshot | DialogSnapshot | TabSnapshot | MenuitemSnapshot | ColumnheaderSnapshot | GroupSnapshot | RadiogroupSnapshot | ProgressbarSnapshot | ImageSnapshot | SeparatorSnapshot;
121
+ interface GenericElementSnapshot<TRole extends NodeRole = NodeRole, TAttributes = unknown> {
122
+ role: TRole;
123
+ name?: string;
124
+ attributes?: TAttributes;
125
+ children?: Array<NodeSnapshot>;
126
+ }
127
+ type SetValues<TSet> = TSet extends Set<infer TValue> ? TValue : never;
128
+ //#endregion
129
+ //#region src/utils/snapshot.d.ts
130
+ type SnapshotFilter = (snapshot: NodeSnapshot) => boolean;
131
+ type GuardedSnapshotFilter<TSnapshot extends NodeSnapshot> = (snapshot: NodeSnapshot) => snapshot is TSnapshot;
132
+ type FilteredSnapshot<TSnapshot extends NodeSnapshot> = TSnapshot extends GenericElementSnapshot ? TSnapshot & {
133
+ children?: Array<TSnapshot>;
134
+ } : TSnapshot;
135
+ interface SnapshotFilterOptions {
136
+ filter: SnapshotFilter;
137
+ snapshots: Array<NodeSnapshot>;
138
+ recurse: boolean;
139
+ }
140
+ interface GuardedSnapshotFilterOptions<TSnapshot extends NodeSnapshot> {
141
+ filter: GuardedSnapshotFilter<TSnapshot>;
142
+ snapshots: Array<NodeSnapshot>;
143
+ recurse?: boolean;
144
+ }
145
+ declare function filterSnapshots<TSnapshot extends NodeSnapshot = NodeSnapshot>(options: GuardedSnapshotFilterOptions<TSnapshot>): Array<FilteredSnapshot<TSnapshot>>;
146
+ declare function filterSnapshots(options: SnapshotFilterOptions): Array<NodeSnapshot>;
147
+ //#endregion
148
+ //#region src/playwright/snapshot.d.ts
149
+ interface ElementSnapshotOptions {
150
+ /**
151
+ * Include only elements in the snapshot for which the specified filter returns `true`
152
+ *
153
+ * @default () => true
154
+ */
155
+ filter?: SnapshotFilter;
156
+ /**
157
+ * Recursively apply specified filter to children of filtered elements
158
+ *
159
+ * By default, recursion ends when the filter returns `true` for an element.
160
+ * Should be `true` for filters intended to remove specific elements recursively.
161
+ *
162
+ * @default false
163
+ */
164
+ recurseFilter?: boolean;
165
+ /**
166
+ * Include combobox options in the snapshot
167
+ *
168
+ * @default false
169
+ */
170
+ includeComboboxOptions?: boolean;
171
+ }
172
+ /**
173
+ * Creates an Element Snapshot of the specified element
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * await expect(snapshotElement(page.getByRole("main"))).toMatchJsonSnapshot();
178
+ * ```
179
+ * @param locator Locator for the element to snapshot
180
+ * @experimental
181
+ */
182
+ declare function snapshotElement(locator: Locator, options?: ElementSnapshotOptions): Promise<unknown>;
183
+ /**
184
+ * Creates an Element Snapshot of the specified element, returning the raw snapshot data for custom transformations
185
+ *
186
+ * @param locator Locator for the element to snapshot
187
+ * @experimental
188
+ */
189
+ declare function snapshotElementRaw(locator: Locator): Promise<Array<NodeSnapshot>>;
190
+ //#endregion
191
+ 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 MenuitemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadiogroupSnapshot, type SeparatorSnapshot, type TabSnapshot, type TextSnapshot, filterSnapshots, snapshotElement, snapshotElementRaw };
package/dist/index.mjs ADDED
@@ -0,0 +1,180 @@
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(options) {
34
+ const { filter, snapshots, recurse = false } = options;
35
+ return snapshots.flatMap((snapshot) => {
36
+ const isFilteredIn = filter(snapshot);
37
+ if (isFilteredIn && !recurse) return snapshot;
38
+ if (!isFilteredIn && recurse) return [];
39
+ const filteredChildren = hasChildren(snapshot) ? filterSnapshots({
40
+ filter,
41
+ snapshots: snapshot.children ?? [],
42
+ recurse
43
+ }) : [];
44
+ if (!isFilteredIn) return filteredChildren;
45
+ return {
46
+ ...snapshot,
47
+ children: filteredChildren.length > 0 ? filteredChildren : void 0
48
+ };
49
+ });
50
+ }
51
+ function hasChildren(snapshot) {
52
+ return "children" in snapshot && snapshot.children !== void 0 && snapshot.children.length > 0;
53
+ }
54
+
55
+ //#endregion
56
+ //#region src/playwright/transformer.ts
57
+ var ElementSnapshotTransformer = class {
58
+ filter;
59
+ recurseFilter;
60
+ includeComboboxOptions;
61
+ constructor(options = {}) {
62
+ this.filter = options.filter;
63
+ this.recurseFilter = options.recurseFilter ?? false;
64
+ this.includeComboboxOptions = options.includeComboboxOptions ?? false;
65
+ }
66
+ transform(snapshots) {
67
+ const filteredSnapshots = this.filterSnapshots(snapshots);
68
+ const transformedSnapshots = this.transformSnapshots(filteredSnapshots);
69
+ if (transformedSnapshots.length === 1) return transformedSnapshots.at(0);
70
+ return transformedSnapshots;
71
+ }
72
+ filterSnapshots(snapshots) {
73
+ if (this.filter === void 0) return snapshots;
74
+ return filterSnapshots({
75
+ filter: this.filter,
76
+ snapshots,
77
+ recurse: this.recurseFilter
78
+ });
79
+ }
80
+ transformSnapshots(snapshots) {
81
+ return snapshots.map((snapshot) => this.transformSnapshotRecursive(snapshot));
82
+ }
83
+ transformSnapshotRecursive(snapshot) {
84
+ if (snapshot.role === "text") return this.simplifyTextSnapshot(snapshot);
85
+ return this.simplifyElementSnapshot(snapshot);
86
+ }
87
+ simplifyTextSnapshot(snapshot) {
88
+ return snapshot.name;
89
+ }
90
+ simplifyElementSnapshot(snapshot) {
91
+ const normalizedSnapshot = this.normalizeElementSnapshot(snapshot);
92
+ if (this.isEmpty(normalizedSnapshot)) {
93
+ const { role } = normalizedSnapshot;
94
+ return this.transformedSnapshot(role, "");
95
+ }
96
+ if (this.hasOnlyName(normalizedSnapshot)) {
97
+ const { role, name } = normalizedSnapshot;
98
+ return this.transformedSnapshot(role, name);
99
+ }
100
+ if (this.hasOnlyChildren(normalizedSnapshot)) {
101
+ const { role, children } = normalizedSnapshot;
102
+ return this.transformedSnapshot(role, children.length === 1 ? children.at(0) : children);
103
+ }
104
+ if (snapshot.role === "combobox") return this.simplifyComboboxSnapshot(snapshot);
105
+ const { role, name, attributes, children } = normalizedSnapshot;
106
+ return this.transformedSnapshot(role, {
107
+ name,
108
+ ...attributes,
109
+ children
110
+ });
111
+ }
112
+ normalizeElementSnapshot(snapshot) {
113
+ const sparseAttributes = this.removeUndefinedProperties(snapshot.attributes ?? {});
114
+ const transformedChildren = this.transformSnapshots(snapshot?.children ?? []);
115
+ const nameEqualsChildren = transformedChildren.length === 1 && snapshot.name === transformedChildren.at(0);
116
+ return {
117
+ role: snapshot.role,
118
+ name: snapshot.name,
119
+ attributes: sparseAttributes,
120
+ children: nameEqualsChildren ? void 0 : transformedChildren.length === 0 ? void 0 : transformedChildren
121
+ };
122
+ }
123
+ simplifyComboboxSnapshot(snapshot) {
124
+ const { role, name, attributes } = this.normalizeElementSnapshot(snapshot);
125
+ const transformedOptions = (snapshot.options ?? []).map((optionSnapshot) => this.simplifyElementSnapshot(optionSnapshot));
126
+ return this.transformedSnapshot(role, {
127
+ name,
128
+ ...attributes,
129
+ options: this.includeComboboxOptions && transformedOptions.length > 0 ? transformedOptions : void 0
130
+ });
131
+ }
132
+ isEmpty(snapshot) {
133
+ return snapshot.name === void 0 && (snapshot.attributes === void 0 || Object.keys(snapshot.attributes).length === 0) && (snapshot.children === void 0 || snapshot.children.length === 0);
134
+ }
135
+ hasOnlyName(snapshot) {
136
+ return snapshot.name !== void 0 && snapshot.attributes === void 0 && snapshot.children === void 0;
137
+ }
138
+ hasOnlyChildren(snapshot) {
139
+ return snapshot.name === void 0 && snapshot.attributes === void 0 && snapshot.children !== void 0;
140
+ }
141
+ removeUndefinedProperties(attributes) {
142
+ const sparseAttributes = {};
143
+ Object.entries(attributes).forEach(([key, value]) => {
144
+ if (value !== void 0) sparseAttributes[key] = value;
145
+ });
146
+ return Object.keys(sparseAttributes).length > 0 ? sparseAttributes : void 0;
147
+ }
148
+ transformedSnapshot(role, content) {
149
+ return { [role]: content };
150
+ }
151
+ };
152
+
153
+ //#endregion
154
+ //#region src/playwright/snapshot.ts
155
+ /**
156
+ * Creates an Element Snapshot of the specified element
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * await expect(snapshotElement(page.getByRole("main"))).toMatchJsonSnapshot();
161
+ * ```
162
+ * @param locator Locator for the element to snapshot
163
+ * @experimental
164
+ */
165
+ async function snapshotElement(locator, options) {
166
+ const snapshot = await snapshotElementRaw(locator);
167
+ return new ElementSnapshotTransformer(options).transform(snapshot);
168
+ }
169
+ /**
170
+ * Creates an Element Snapshot of the specified element, returning the raw snapshot data for custom transformations
171
+ *
172
+ * @param locator Locator for the element to snapshot
173
+ * @experimental
174
+ */
175
+ async function snapshotElementRaw(locator) {
176
+ return await new ElementSnapshotProxy(locator.page()).snapshotElement(locator);
177
+ }
178
+
179
+ //#endregion
180
+ export { filterSnapshots, snapshotElement, snapshotElementRaw };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cronn/element-snapshot",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Element snapshots for Playwright",
5
5
  "author": "cronn",
6
6
  "license": "Apache-2.0",
@@ -29,28 +29,32 @@
29
29
  "exports": {
30
30
  "./package.json": "./package.json",
31
31
  ".": {
32
- "types": "./dist/index.d.ts",
33
- "default": "./dist/index.js"
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.1.0"
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.9",
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
- "tsup": "8.5.1",
51
+ "tsdown": "0.20.3",
51
52
  "typescript": "5.9.3",
52
53
  "typescript-eslint": "8.54.0",
53
- "@cronn/shared-configs": "0.0.0"
54
+ "vitest": "4.0.18",
55
+ "@cronn/playwright-file-snapshots": "0.38.1",
56
+ "@cronn/shared-configs": "0.0.0",
57
+ "@cronn/test-utils": "0.0.0"
54
58
  },
55
59
  "peerDependencies": {
56
60
  "@playwright/test": "^1.55"
@@ -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": "tsup"
70
+ "build": "tsdown"
63
71
  }
64
72
  }
@@ -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
- }