@cronn/element-snapshot 0.25.0 → 0.27.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 +45 -9
- package/dist/index.d.mts +23 -8
- package/dist/index.mjs +10 -4
- package/package.json +10 -10
package/dist/browser-lib.iife.js
CHANGED
|
@@ -160,7 +160,8 @@
|
|
|
160
160
|
"table",
|
|
161
161
|
"tablist",
|
|
162
162
|
"tabpanel",
|
|
163
|
-
"term"
|
|
163
|
+
"term",
|
|
164
|
+
"tree"
|
|
164
165
|
]);
|
|
165
166
|
//#endregion
|
|
166
167
|
//#region src/browser/container.ts
|
|
@@ -261,7 +262,8 @@
|
|
|
261
262
|
rowgroup: isWithinTableOrGrid,
|
|
262
263
|
rowheader: isWithinTableRowOrGridRow,
|
|
263
264
|
tab: isWithinTablist,
|
|
264
|
-
term: isWithinDescriptionList
|
|
265
|
+
term: isWithinDescriptionList,
|
|
266
|
+
treeitem: isWithinTree
|
|
265
267
|
};
|
|
266
268
|
const INPUT_ROLES = {
|
|
267
269
|
button: "button",
|
|
@@ -371,6 +373,9 @@
|
|
|
371
373
|
function isWithinTablist(element) {
|
|
372
374
|
return isWithinElement(element, roleSelector("tablist"));
|
|
373
375
|
}
|
|
376
|
+
function isWithinTree(element) {
|
|
377
|
+
return isWithinElement(element, roleSelector("tree"));
|
|
378
|
+
}
|
|
374
379
|
//#endregion
|
|
375
380
|
//#region src/browser/text.ts
|
|
376
381
|
function snapshotTextNode(textNode) {
|
|
@@ -424,7 +429,11 @@
|
|
|
424
429
|
"rowheader",
|
|
425
430
|
"tab"
|
|
426
431
|
]);
|
|
427
|
-
const contextBasedNameResolvers = [
|
|
432
|
+
const contextBasedNameResolvers = [
|
|
433
|
+
resolveImageName,
|
|
434
|
+
resolveLegendName,
|
|
435
|
+
resolveTreeItemName
|
|
436
|
+
];
|
|
428
437
|
function resolveAccessibleName(element) {
|
|
429
438
|
const role = parseElementRole(element);
|
|
430
439
|
if (role === void 0 || prohibitsNaming.has(role)) return;
|
|
@@ -456,6 +465,10 @@
|
|
|
456
465
|
if (element instanceof HTMLImageElement) return stringAttribute(element.alt);
|
|
457
466
|
if (role === "img") return resolveAccessibleTextContent(element);
|
|
458
467
|
}
|
|
468
|
+
function resolveTreeItemName(element, role) {
|
|
469
|
+
if (role !== "treeitem") return;
|
|
470
|
+
return resolveAccessibleTextContent(element, Array.from(element.querySelectorAll(roleSelector("group"))));
|
|
471
|
+
}
|
|
459
472
|
//#endregion
|
|
460
473
|
//#region src/browser/state.ts
|
|
461
474
|
function disableableAttributes(element) {
|
|
@@ -464,6 +477,13 @@
|
|
|
464
477
|
function selectableAttributes(element) {
|
|
465
478
|
return { selected: booleanAttribute(element instanceof HTMLOptionElement ? element.hasAttribute("selected") : false) ?? booleanAttribute(element.ariaSelected) };
|
|
466
479
|
}
|
|
480
|
+
function expandableAttributes(element) {
|
|
481
|
+
return { expanded: booleanAttribute(element.ariaExpanded) };
|
|
482
|
+
}
|
|
483
|
+
const checkedValues = /* @__PURE__ */ new Set(["mixed"]);
|
|
484
|
+
function checkableAttributes(element) {
|
|
485
|
+
return { checked: booleanOrEnumAttribute(element.ariaChecked, checkedValues) };
|
|
486
|
+
}
|
|
467
487
|
function inputStateAttributes(element) {
|
|
468
488
|
const supportsHtmlAttributes = isNativeInputElement(element);
|
|
469
489
|
const readonly = booleanAttribute(supportsHtmlAttributes ? element.hasAttribute("readonly") : false);
|
|
@@ -487,7 +507,7 @@
|
|
|
487
507
|
name: resolveAccessibleName(element),
|
|
488
508
|
attributes: {
|
|
489
509
|
...disableableAttributes(element),
|
|
490
|
-
|
|
510
|
+
...expandableAttributes(element),
|
|
491
511
|
pressed: booleanOrEnumAttribute(element.ariaPressed, pressedValues)
|
|
492
512
|
},
|
|
493
513
|
children: snapshotChildren(element)
|
|
@@ -550,7 +570,7 @@
|
|
|
550
570
|
return element.checked ? true : void 0;
|
|
551
571
|
}
|
|
552
572
|
function resolvePlaceholder(element) {
|
|
553
|
-
if (element instanceof
|
|
573
|
+
if (!(element instanceof HTMLInputElement) && !(element instanceof HTMLTextAreaElement)) return;
|
|
554
574
|
return stringAttribute(element.placeholder);
|
|
555
575
|
}
|
|
556
576
|
//#endregion
|
|
@@ -564,6 +584,7 @@
|
|
|
564
584
|
attributes: {
|
|
565
585
|
value: resolveValue$1(element),
|
|
566
586
|
...snapshotCommonInputAttributes(element),
|
|
587
|
+
...expandableAttributes(element),
|
|
567
588
|
options
|
|
568
589
|
},
|
|
569
590
|
children: []
|
|
@@ -571,12 +592,11 @@
|
|
|
571
592
|
}
|
|
572
593
|
function isCombobox(element) {
|
|
573
594
|
if (element instanceof HTMLSelectElement) return element.role === null || element.role === "combobox";
|
|
574
|
-
|
|
575
|
-
return false;
|
|
595
|
+
return element.role === "combobox";
|
|
576
596
|
}
|
|
577
597
|
function resolveValue$1(element) {
|
|
578
|
-
if (element instanceof HTMLButtonElement) return resolveAccessibleTextContent(element);
|
|
579
598
|
if (element instanceof HTMLInputElement) return resolveInputValue(element);
|
|
599
|
+
if (!(element instanceof HTMLSelectElement)) return resolveAccessibleTextContent(element);
|
|
580
600
|
const selectedLabels = Array.from(element.selectedOptions).map((option) => option.label);
|
|
581
601
|
if (selectedLabels.length === 0) return;
|
|
582
602
|
if (selectedLabels.length === 1) return selectedLabels.at(0);
|
|
@@ -787,6 +807,21 @@
|
|
|
787
807
|
return value;
|
|
788
808
|
}
|
|
789
809
|
//#endregion
|
|
810
|
+
//#region src/browser/tree.ts
|
|
811
|
+
function snapshotTreeItem(element) {
|
|
812
|
+
return {
|
|
813
|
+
role: "treeitem",
|
|
814
|
+
name: resolveAccessibleName(element),
|
|
815
|
+
attributes: {
|
|
816
|
+
...disableableAttributes(element),
|
|
817
|
+
...checkableAttributes(element),
|
|
818
|
+
...selectableAttributes(element),
|
|
819
|
+
...expandableAttributes(element)
|
|
820
|
+
},
|
|
821
|
+
children: snapshotChildren(element)
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
//#endregion
|
|
790
825
|
//#region src/browser/element.ts
|
|
791
826
|
const ROLE_SNAPSHOTS = {
|
|
792
827
|
alertdialog: snapshotDialogWithRole("alertdialog"),
|
|
@@ -813,7 +848,8 @@
|
|
|
813
848
|
slider: snapshotInput,
|
|
814
849
|
spinbutton: snapshotInput,
|
|
815
850
|
tab: snapshotTab,
|
|
816
|
-
textbox: snapshotInput
|
|
851
|
+
textbox: snapshotInput,
|
|
852
|
+
treeitem: snapshotTreeItem
|
|
817
853
|
};
|
|
818
854
|
function snapshotElement(element) {
|
|
819
855
|
return snapshotNodeRecursive(element);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Expect, Locator, MatcherReturnType } from "@playwright/test";
|
|
2
2
|
import { PlaywrightMatchJsonFileOptions, PlaywrightMatchTextFileOptions, PlaywrightValidationFileMatcherConfig } from "@cronn/playwright-file-snapshots";
|
|
3
|
+
import { MarkdownTableNormalizer } from "@cronn/lib-file-snapshots";
|
|
3
4
|
//#region src/playwright/markdown-table.d.ts
|
|
4
5
|
interface MarkdownTableSnapshotOptions {
|
|
5
6
|
/**
|
|
@@ -8,6 +9,10 @@ interface MarkdownTableSnapshotOptions {
|
|
|
8
9
|
* @default true
|
|
9
10
|
*/
|
|
10
11
|
showSortIndicator?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Custom normalizers to apply before serialization
|
|
14
|
+
*/
|
|
15
|
+
normalizers?: Array<MarkdownTableNormalizer>;
|
|
11
16
|
}
|
|
12
17
|
/**
|
|
13
18
|
* Creates a Markdown table snapshot from a table or grid element
|
|
@@ -21,6 +26,13 @@ interface DisableableAttributes {
|
|
|
21
26
|
interface SelectableAttributes {
|
|
22
27
|
selected?: boolean;
|
|
23
28
|
}
|
|
29
|
+
interface ExpandableAttributes {
|
|
30
|
+
expanded?: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface CheckableAttributes {
|
|
33
|
+
checked?: CheckedValue;
|
|
34
|
+
}
|
|
35
|
+
type CheckedValue = true | "mixed";
|
|
24
36
|
interface DiscribableAttributes {
|
|
25
37
|
description?: string;
|
|
26
38
|
}
|
|
@@ -32,8 +44,7 @@ interface InputStateAttributes extends DisableableAttributes {
|
|
|
32
44
|
//#endregion
|
|
33
45
|
//#region src/types/elements/button.d.ts
|
|
34
46
|
interface ButtonSnapshot extends GenericElementSnapshot<"button", ButtonAttributes> {}
|
|
35
|
-
interface ButtonAttributes extends DisableableAttributes {
|
|
36
|
-
expanded?: boolean;
|
|
47
|
+
interface ButtonAttributes extends DisableableAttributes, ExpandableAttributes {
|
|
37
48
|
pressed?: PressedValue;
|
|
38
49
|
}
|
|
39
50
|
type PressedValue = true | "mixed";
|
|
@@ -42,7 +53,7 @@ type PressedValue = true | "mixed";
|
|
|
42
53
|
type SetValues<TSet> = TSet extends Set<infer TValue> ? TValue : never;
|
|
43
54
|
//#endregion
|
|
44
55
|
//#region src/types/elements/container.d.ts
|
|
45
|
-
declare const CONTAINER_ROLES: Set<"alert" | "article" | "banner" | "blockquote" | "code" | "complementary" | "contentinfo" | "definition" | "deletion" | "descriptionlist" | "emphasis" | "form" | "grid" | "insertion" | "label" | "list" | "listbox" | "listitem" | "log" | "main" | "mark" | "menu" | "navigation" | "note" | "paragraph" | "row" | "rowgroup" | "search" | "status" | "strong" | "subscript" | "superscript" | "table" | "tablist" | "tabpanel" | "term">;
|
|
56
|
+
declare const CONTAINER_ROLES: Set<"alert" | "article" | "banner" | "blockquote" | "code" | "complementary" | "contentinfo" | "definition" | "deletion" | "descriptionlist" | "emphasis" | "form" | "grid" | "insertion" | "label" | "list" | "listbox" | "listitem" | "log" | "main" | "mark" | "menu" | "navigation" | "note" | "paragraph" | "row" | "rowgroup" | "search" | "status" | "strong" | "subscript" | "superscript" | "table" | "tablist" | "tabpanel" | "term" | "tree">;
|
|
46
57
|
interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {}
|
|
47
58
|
type ContainerRole = SetValues<typeof CONTAINER_ROLES>;
|
|
48
59
|
interface RegionSnapshot extends GenericElementSnapshot<"region"> {}
|
|
@@ -80,7 +91,7 @@ interface CommonInputAttributes extends InputStateAttributes, DiscribableAttribu
|
|
|
80
91
|
placeholder?: string;
|
|
81
92
|
}
|
|
82
93
|
interface ComboboxSnapshot extends GenericElementSnapshot<"combobox", ComboboxAttributes> {}
|
|
83
|
-
interface ComboboxAttributes extends CommonInputAttributes {
|
|
94
|
+
interface ComboboxAttributes extends CommonInputAttributes, ExpandableAttributes {
|
|
84
95
|
value?: string | Array<string>;
|
|
85
96
|
options: Array<OptionSnapshot>;
|
|
86
97
|
}
|
|
@@ -132,9 +143,13 @@ interface TextSnapshot {
|
|
|
132
143
|
name: string;
|
|
133
144
|
}
|
|
134
145
|
//#endregion
|
|
146
|
+
//#region src/types/elements/tree.d.ts
|
|
147
|
+
interface TreeItemSnapshot extends GenericElementSnapshot<"treeitem", TreeItemAttributes> {}
|
|
148
|
+
interface TreeItemAttributes extends CheckableAttributes, DisableableAttributes, ExpandableAttributes, SelectableAttributes {}
|
|
149
|
+
//#endregion
|
|
135
150
|
//#region src/types/role.d.ts
|
|
136
151
|
type TextRole = "text";
|
|
137
|
-
type ElementRole = "button" | "group" | "heading" | "img" | "link" | "menuitem" | "option" | "progressbar" | "radiogroup" | "region" | "separator" | "tab" | CellRole | ContainerRole | DialogRole | InputRole;
|
|
152
|
+
type ElementRole = "button" | "group" | "heading" | "img" | "link" | "menuitem" | "option" | "progressbar" | "radiogroup" | "region" | "separator" | "tab" | "treeitem" | CellRole | ContainerRole | DialogRole | InputRole;
|
|
138
153
|
//#endregion
|
|
139
154
|
//#region src/types/snapshot.d.ts
|
|
140
155
|
type NodeRole = ElementRole | TextRole;
|
|
@@ -148,7 +163,7 @@ interface GenericElementSnapshot<TRole extends NodeRole = NodeRole, TAttributes
|
|
|
148
163
|
attributes: TAttributes;
|
|
149
164
|
children: Array<NodeSnapshot>;
|
|
150
165
|
}
|
|
151
|
-
type ElementSnapshot = ButtonSnapshot | CellSnapshot | ColumnHeaderSnapshot | ComboboxSnapshot | ContainerSnapshot | DialogSnapshot | GroupSnapshot | HeadingSnapshot | ImageSnapshot | InputSnapshot | LinkSnapshot | OptionSnapshot | ProgressbarSnapshot | RegionSnapshot | TabSnapshot | MenuItemSnapshot | RadioGroupSnapshot | SeparatorSnapshot;
|
|
166
|
+
type ElementSnapshot = ButtonSnapshot | CellSnapshot | ColumnHeaderSnapshot | ComboboxSnapshot | ContainerSnapshot | DialogSnapshot | GroupSnapshot | HeadingSnapshot | ImageSnapshot | InputSnapshot | LinkSnapshot | OptionSnapshot | ProgressbarSnapshot | RegionSnapshot | TabSnapshot | MenuItemSnapshot | RadioGroupSnapshot | SeparatorSnapshot | TreeItemSnapshot;
|
|
152
167
|
//#endregion
|
|
153
168
|
//#region src/utils/filter.d.ts
|
|
154
169
|
type FilterPredicate = (snapshot: NodeSnapshot) => boolean;
|
|
@@ -242,7 +257,7 @@ interface ElementSnapshotMatchers {
|
|
|
242
257
|
toMatchMarkdownTableSnapshotFile: (actual: Locator, options?: MatchMarkdownTableSnapshotFileOptions) => Promise<MatcherReturnType>;
|
|
243
258
|
}
|
|
244
259
|
interface MatchSemanticSnapshotFileOptions extends PlaywrightMatchJsonFileOptions, SemanticSnapshotOptions {}
|
|
245
|
-
interface MatchMarkdownTableSnapshotFileOptions extends Omit<PlaywrightMatchTextFileOptions, "fileExtension">, MarkdownTableSnapshotOptions {}
|
|
260
|
+
interface MatchMarkdownTableSnapshotFileOptions extends Omit<PlaywrightMatchTextFileOptions, "fileExtension" | "normalizers">, MarkdownTableSnapshotOptions {}
|
|
246
261
|
//#endregion
|
|
247
262
|
//#region src/playwright/matchers.d.ts
|
|
248
263
|
/**
|
|
@@ -269,4 +284,4 @@ declare function excludeRole<TRole extends NodeRole>(role: TRole | Array<TRole>)
|
|
|
269
284
|
*/
|
|
270
285
|
declare function getTextContent(snapshots: Array<NodeSnapshot>): string;
|
|
271
286
|
//#endregion
|
|
272
|
-
export { type ButtonSnapshot, type CellSnapshot, type ColumnHeaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type ElementSnapshotMatchers, type GroupSnapshot, type HeadingSnapshot, type ImageSnapshot, type InputSnapshot, type LinkSnapshot, type MarkdownTableSnapshotOptions, type MatchMarkdownTableSnapshotFileOptions, type MatchSemanticSnapshotFileOptions, type MenuItemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadioGroupSnapshot, type RegionSnapshot, type SemanticSnapshotOptions, type SeparatorSnapshot, type SnapshotByRole, type TabSnapshot, type TextSnapshot, defineElementSnapshotMatchers, excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot, rawSnapshot, semanticSnapshot };
|
|
287
|
+
export { type ButtonSnapshot, type CellSnapshot, type ColumnHeaderSnapshot, type ComboboxSnapshot, type ContainerSnapshot, type DialogSnapshot, type ElementRole, type ElementSnapshot, type ElementSnapshotMatchers, type GroupSnapshot, type HeadingSnapshot, type ImageSnapshot, type InputSnapshot, type LinkSnapshot, type MarkdownTableSnapshotOptions, type MatchMarkdownTableSnapshotFileOptions, type MatchSemanticSnapshotFileOptions, type MenuItemSnapshot, type NodeRole, type NodeSnapshot, type OptionSnapshot, type ProgressbarSnapshot, type RadioGroupSnapshot, type RegionSnapshot, type SemanticSnapshotOptions, type SeparatorSnapshot, type SnapshotByRole, type TabSnapshot, type TextSnapshot, type TreeItemSnapshot, defineElementSnapshotMatchers, excludeRole, filter, filterByRole, getTextContent, includeRole, markdownTableSnapshot, rawSnapshot, semanticSnapshot };
|
package/dist/index.mjs
CHANGED
|
@@ -236,8 +236,9 @@ const sortIndicators = {
|
|
|
236
236
|
* Creates a Markdown table snapshot from a table or grid element
|
|
237
237
|
*/
|
|
238
238
|
async function markdownTableSnapshot(locator, options = {}) {
|
|
239
|
-
const
|
|
240
|
-
|
|
239
|
+
const { showSortIndicator, normalizers } = options;
|
|
240
|
+
const parsedTable = parseTable(await rawSnapshot(locator), { showSortIndicator });
|
|
241
|
+
return new MarkdownTableSerializer({ normalizers }).serialize(parsedTable);
|
|
241
242
|
}
|
|
242
243
|
function parseTable(snapshot, options) {
|
|
243
244
|
const { showSortIndicator = true } = options;
|
|
@@ -285,8 +286,13 @@ function defineElementSnapshotMatchers(config = {}) {
|
|
|
285
286
|
return await defineJsonFileMatcher("toMatchSemanticSnapshotFile", config).bind(this)(() => semanticSnapshot(actual, options), options);
|
|
286
287
|
}
|
|
287
288
|
async function toMatchMarkdownTableSnapshotFile(actual, options = {}) {
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
const toMatchTextFile = defineTextFileMatcher("toMatchMarkdownTableSnapshotFile", config).bind(this);
|
|
290
|
+
const { showSortIndicator, normalizers, ...matchFileOptions } = options;
|
|
291
|
+
return await toMatchTextFile(() => markdownTableSnapshot(actual, {
|
|
292
|
+
showSortIndicator,
|
|
293
|
+
normalizers
|
|
294
|
+
}), {
|
|
295
|
+
...matchFileOptions,
|
|
290
296
|
fileExtension: "md"
|
|
291
297
|
});
|
|
292
298
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cronn/element-snapshot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Element snapshots for Playwright",
|
|
5
5
|
"homepage": "https://cronn.github.io/file-snapshots/playwright/element-snapshots/",
|
|
6
6
|
"bugs": {
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@arethetypeswrong/core": "0.18.5",
|
|
34
|
-
"@playwright/test": "1.
|
|
35
|
-
"@types/node": "24.13.
|
|
34
|
+
"@playwright/test": "1.62.1",
|
|
35
|
+
"@types/node": "24.13.3",
|
|
36
36
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
37
37
|
"@vitest/coverage-v8": "4.1.10",
|
|
38
|
-
"eslint": "10.
|
|
38
|
+
"eslint": "10.8.0",
|
|
39
39
|
"eslint-config-prettier": "10.1.8",
|
|
40
40
|
"eslint-plugin-check-file": "3.3.2",
|
|
41
41
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
42
|
-
"publint": "0.3.
|
|
42
|
+
"publint": "0.3.22",
|
|
43
43
|
"rimraf": "6.1.3",
|
|
44
|
-
"tsdown": "0.22.
|
|
44
|
+
"tsdown": "0.22.14",
|
|
45
45
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
46
|
-
"typescript-eslint": "8.
|
|
46
|
+
"typescript-eslint": "8.65.0",
|
|
47
47
|
"vitest": "4.1.10",
|
|
48
|
-
"node": "runtime:24.18.
|
|
48
|
+
"node": "runtime:24.18.1",
|
|
49
49
|
"@cronn/shared-configs": "0.0.0",
|
|
50
50
|
"@cronn/test-utils": "0.0.0",
|
|
51
51
|
"@cronn/vitest-file-snapshots": "2.1.2"
|
|
@@ -56,12 +56,12 @@
|
|
|
56
56
|
"devEngines": {
|
|
57
57
|
"packageManager": {
|
|
58
58
|
"name": "pnpm",
|
|
59
|
-
"version": "11.
|
|
59
|
+
"version": "11.18.0",
|
|
60
60
|
"onFail": "download"
|
|
61
61
|
},
|
|
62
62
|
"runtime": {
|
|
63
63
|
"name": "node",
|
|
64
|
-
"version": "24.18.
|
|
64
|
+
"version": "24.18.1",
|
|
65
65
|
"onFail": "download"
|
|
66
66
|
}
|
|
67
67
|
},
|