@cronn/element-snapshot 0.20.0 → 0.22.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.
@@ -15,6 +15,10 @@
15
15
  if (value === null || !supportedValues.has(value)) return;
16
16
  return value;
17
17
  }
18
+ function booleanOrEnumAttribute(value, supportedStringValues) {
19
+ if (value === "true" || value === "false") return booleanAttribute(value);
20
+ return enumAttribute(value, supportedStringValues);
21
+ }
18
22
  function resolveElementReference(element, attributeName) {
19
23
  const referenceId = element.getAttribute(attributeName);
20
24
  if (referenceId === null) return null;
@@ -120,8 +124,12 @@
120
124
  }
121
125
  //#endregion
122
126
  //#region src/types/elements/container.ts
123
- const CONTAINER_ROLES = new Set([
127
+ const CONTAINER_ROLES = /* @__PURE__ */ new Set([
124
128
  "paragraph",
129
+ "blockquote",
130
+ "code",
131
+ "emphasis",
132
+ "strong",
125
133
  "list",
126
134
  "listitem",
127
135
  "listbox",
@@ -140,9 +148,6 @@
140
148
  "grid",
141
149
  "rowgroup",
142
150
  "row",
143
- "rowheader",
144
- "cell",
145
- "gridcell",
146
151
  "alert",
147
152
  "menu",
148
153
  "tablist",
@@ -187,10 +192,13 @@
187
192
  a: "link",
188
193
  article: "article",
189
194
  aside: "complementary",
195
+ blockquote: "blockquote",
190
196
  button: "button",
197
+ code: "code",
191
198
  dd: "definition",
192
199
  dl: "descriptionlist",
193
200
  dt: "term",
201
+ em: "emphasis",
194
202
  fieldset: "group",
195
203
  footer: "contentinfo",
196
204
  form: "form",
@@ -216,6 +224,7 @@
216
224
  search: "search",
217
225
  section: "region",
218
226
  select: "combobox",
227
+ strong: "strong",
219
228
  table: "table",
220
229
  tbody: "rowgroup",
221
230
  textarea: "textbox",
@@ -266,7 +275,8 @@
266
275
  const explicitRole = element.role;
267
276
  if (isIgnoredRole(explicitRole)) return;
268
277
  if (explicitRole !== null && (hasRoleSpecificSnapshot(explicitRole) || isContainerRole(explicitRole))) return explicitRole;
269
- const roleResolver = ELEMENT_ROLES[getElementTagName(element)];
278
+ const tagName = getElementTagName(element);
279
+ const roleResolver = ELEMENT_ROLES[tagName];
270
280
  if (roleResolver === void 0) return;
271
281
  if (typeof roleResolver === "string") return roleResolver;
272
282
  return roleResolver(element);
@@ -368,14 +378,17 @@
368
378
  }
369
379
  //#endregion
370
380
  //#region src/browser/name.ts
371
- const prohibitsNaming = new Set([
381
+ const prohibitsNaming = /* @__PURE__ */ new Set([
382
+ "code",
383
+ "emphasis",
372
384
  "label",
373
385
  "listitem",
374
386
  "paragraph",
375
387
  "rowgroup",
388
+ "strong",
376
389
  "term"
377
390
  ]);
378
- const supportsNamingByLabel = new Set([
391
+ const supportsNamingByLabel = /* @__PURE__ */ new Set([
379
392
  "checkbox",
380
393
  "combobox",
381
394
  "progressbar",
@@ -385,7 +398,7 @@
385
398
  "spinbutton",
386
399
  "textbox"
387
400
  ]);
388
- const supportsNamingFromChildContent = new Set([
401
+ const supportsNamingFromChildContent = /* @__PURE__ */ new Set([
389
402
  "button",
390
403
  "cell",
391
404
  "columnheader",
@@ -453,11 +466,7 @@
453
466
  }
454
467
  //#endregion
455
468
  //#region src/browser/button.ts
456
- const PRESSED_VALUES = new Set([
457
- "true",
458
- "mixed",
459
- "false"
460
- ]);
469
+ const pressedValues = /* @__PURE__ */ new Set(["mixed"]);
461
470
  function snapshotButton(element) {
462
471
  return {
463
472
  role: "button",
@@ -465,16 +474,11 @@
465
474
  attributes: {
466
475
  ...disableableAttributes(element),
467
476
  expanded: booleanAttribute(element.ariaExpanded),
468
- pressed: resolvePressedAttribute(element)
477
+ pressed: booleanOrEnumAttribute(element.ariaPressed, pressedValues)
469
478
  },
470
479
  children: snapshotChildren(element)
471
480
  };
472
481
  }
473
- function resolvePressedAttribute(element) {
474
- const pressed = enumAttribute(element.ariaPressed, PRESSED_VALUES);
475
- if (pressed === "mixed") return pressed;
476
- return booleanAttribute(pressed === "true");
477
- }
478
482
  //#endregion
479
483
  //#region src/browser/description.ts
480
484
  function discribableAttributes(element) {
@@ -522,7 +526,7 @@
522
526
  ...inputStateAttributes(element)
523
527
  };
524
528
  }
525
- const CHECKED_INPUT_TYPES = new Set(["checkbox", "radio"]);
529
+ const CHECKED_INPUT_TYPES = /* @__PURE__ */ new Set(["checkbox", "radio"]);
526
530
  function resolveInputValue(element) {
527
531
  if (element instanceof HTMLInputElement && CHECKED_INPUT_TYPES.has(element.type)) return;
528
532
  return stringAttribute(element.value);
@@ -646,6 +650,7 @@
646
650
  }
647
651
  //#endregion
648
652
  //#region src/browser/link.ts
653
+ const currentValues = /* @__PURE__ */ new Set(["page", "step"]);
649
654
  function snapshotLink(element) {
650
655
  return {
651
656
  role: "link",
@@ -655,7 +660,10 @@
655
660
  };
656
661
  }
657
662
  function linkAttributes(element) {
658
- return { url: stringAttribute(element.getAttribute("href")) };
663
+ return {
664
+ url: stringAttribute(element.getAttribute("href")),
665
+ current: booleanOrEnumAttribute(element.ariaCurrent, currentValues)
666
+ };
659
667
  }
660
668
  //#endregion
661
669
  //#region src/browser/list.ts
@@ -719,7 +727,7 @@
719
727
  }
720
728
  //#endregion
721
729
  //#region src/types/elements/table.ts
722
- const SORT_TYPES = new Set([
730
+ const SORT_TYPES = /* @__PURE__ */ new Set([
723
731
  "ascending",
724
732
  "descending",
725
733
  "other"
@@ -727,22 +735,54 @@
727
735
  //#endregion
728
736
  //#region src/browser/table.ts
729
737
  function snapshotColumnHeader(element) {
738
+ const cell = snapshotCell("columnheader", element);
730
739
  return {
731
740
  role: "columnheader",
741
+ name: cell.name,
742
+ attributes: {
743
+ ...cell.attributes,
744
+ sort: enumAttribute(element.ariaSort, SORT_TYPES)
745
+ },
746
+ children: cell.children
747
+ };
748
+ }
749
+ function snapshotCellWithRole(role) {
750
+ return (element) => snapshotCell(role, element);
751
+ }
752
+ function snapshotCell(role, element) {
753
+ return {
754
+ role,
732
755
  name: resolveAccessibleName(element),
733
- attributes: { sort: enumAttribute(element.ariaSort, SORT_TYPES) },
756
+ attributes: cellAttributes(element),
734
757
  children: snapshotChildren(element)
735
758
  };
736
759
  }
760
+ function cellAttributes(element) {
761
+ if (element instanceof HTMLTableCellElement) return {
762
+ colSpan: resolveSpan(element.colSpan),
763
+ rowSpan: resolveSpan(element.rowSpan)
764
+ };
765
+ return {
766
+ colSpan: resolveSpan(element.ariaColSpan),
767
+ rowSpan: resolveSpan(element.ariaRowSpan)
768
+ };
769
+ }
770
+ function resolveSpan(value) {
771
+ if (typeof value === "string") value = numericAttribute(value) ?? null;
772
+ if (value === null || value === 1) return;
773
+ return value;
774
+ }
737
775
  //#endregion
738
776
  //#region src/browser/element.ts
739
777
  const ROLE_SNAPSHOTS = {
740
778
  alertdialog: snapshotDialogWithRole("alertdialog"),
741
779
  button: snapshotButton,
780
+ cell: snapshotCellWithRole("cell"),
742
781
  checkbox: snapshotInput,
743
782
  columnheader: snapshotColumnHeader,
744
783
  combobox: snapshotCombobox,
745
784
  dialog: snapshotDialogWithRole("dialog"),
785
+ gridcell: snapshotCellWithRole("gridcell"),
746
786
  group: snapshotGroup,
747
787
  heading: snapshotHeading,
748
788
  img: snapshotImage,
@@ -753,6 +793,7 @@
753
793
  radio: snapshotInput,
754
794
  radiogroup: snapshotRadioGroup,
755
795
  region: snapshotRegion,
796
+ rowheader: snapshotCellWithRole("rowheader"),
756
797
  searchbox: snapshotInput,
757
798
  separator: snapshotSeparator,
758
799
  slider: snapshotInput,
@@ -781,7 +822,7 @@
781
822
  }
782
823
  return snapshotContainer(elementRole, node);
783
824
  }
784
- const UNSUPPORTED_ELEMENTS = new Set([
825
+ const UNSUPPORTED_ELEMENTS = /* @__PURE__ */ new Set([
785
826
  "audio",
786
827
  "figure",
787
828
  "noscript",
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Expect, Locator, MatcherReturnType } from "@playwright/test";
2
2
  import { PlaywrightMatchJsonFileOptions, PlaywrightMatchTextFileOptions, PlaywrightValidationFileMatcherConfig } from "@cronn/playwright-file-snapshots";
3
-
4
3
  //#region src/playwright/markdown-table.d.ts
5
4
  interface MarkdownTableSnapshotOptions {
6
5
  /**
@@ -43,7 +42,7 @@ type PressedValue = true | "mixed";
43
42
  type SetValues<TSet> = TSet extends Set<infer TValue> ? TValue : never;
44
43
  //#endregion
45
44
  //#region src/types/elements/container.d.ts
46
- declare const CONTAINER_ROLES: Set<"paragraph" | "list" | "listitem" | "listbox" | "article" | "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "search" | "descriptionlist" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "rowheader" | "cell" | "gridcell" | "alert" | "menu" | "tablist" | "tabpanel" | "label">;
45
+ declare const CONTAINER_ROLES: Set<"paragraph" | "blockquote" | "code" | "emphasis" | "strong" | "list" | "listitem" | "listbox" | "article" | "banner" | "complementary" | "contentinfo" | "form" | "main" | "navigation" | "search" | "descriptionlist" | "term" | "definition" | "table" | "grid" | "rowgroup" | "row" | "alert" | "menu" | "tablist" | "tabpanel" | "label">;
47
46
  interface ContainerSnapshot extends GenericElementSnapshot<ContainerRole> {}
48
47
  type ContainerRole = SetValues<typeof CONTAINER_ROLES>;
49
48
  interface RegionSnapshot extends GenericElementSnapshot<"region"> {}
@@ -92,7 +91,9 @@ interface OptionAttributes extends SelectableAttributes, DisableableAttributes {
92
91
  interface LinkSnapshot extends GenericElementSnapshot<"link", LinkAttributes> {}
93
92
  interface LinkAttributes {
94
93
  url?: string;
94
+ current?: CurrentValue;
95
95
  }
96
+ type CurrentValue = true | "page" | "step";
96
97
  //#endregion
97
98
  //#region src/types/elements/list.d.ts
98
99
  interface MenuItemSnapshot extends GenericElementSnapshot<"menuitem", MenuitemAttributes> {}
@@ -113,11 +114,17 @@ interface TabAttributes extends DisableableAttributes, SelectableAttributes {}
113
114
  //#endregion
114
115
  //#region src/types/elements/table.d.ts
115
116
  declare const SORT_TYPES: Set<"ascending" | "descending" | "other">;
116
- interface ColumnHeaderSnapshot extends GenericElementSnapshot<"columnheader", ColumnheaderAttributes> {}
117
- interface ColumnheaderAttributes {
117
+ interface ColumnHeaderSnapshot extends GenericElementSnapshot<"columnheader", ColumnHeaderAttributes> {}
118
+ interface ColumnHeaderAttributes extends CellAttributes {
118
119
  sort?: SortType;
119
120
  }
120
121
  type SortType = SetValues<typeof SORT_TYPES>;
122
+ interface CellSnapshot extends GenericElementSnapshot<CellRole, CellAttributes> {}
123
+ type CellRole = "columnheader" | "rowheader" | "cell" | "gridcell";
124
+ interface CellAttributes {
125
+ colSpan?: number;
126
+ rowSpan?: number;
127
+ }
121
128
  //#endregion
122
129
  //#region src/types/elements/text.d.ts
123
130
  interface TextSnapshot {
@@ -127,7 +134,7 @@ interface TextSnapshot {
127
134
  //#endregion
128
135
  //#region src/types/role.d.ts
129
136
  type TextRole = "text";
130
- type ElementRole = "button" | "columnheader" | "group" | "heading" | "img" | "link" | "menuitem" | "option" | "progressbar" | "radiogroup" | "region" | "separator" | "tab" | ContainerRole | DialogRole | InputRole;
137
+ type ElementRole = "button" | "group" | "heading" | "img" | "link" | "menuitem" | "option" | "progressbar" | "radiogroup" | "region" | "separator" | "tab" | CellRole | ContainerRole | DialogRole | InputRole;
131
138
  //#endregion
132
139
  //#region src/types/snapshot.d.ts
133
140
  type NodeRole = ElementRole | TextRole;
@@ -141,7 +148,7 @@ interface GenericElementSnapshot<TRole extends NodeRole = NodeRole, TAttributes
141
148
  attributes: TAttributes;
142
149
  children: Array<NodeSnapshot>;
143
150
  }
144
- type ElementSnapshot = ButtonSnapshot | ColumnHeaderSnapshot | ComboboxSnapshot | ContainerSnapshot | DialogSnapshot | GroupSnapshot | HeadingSnapshot | ImageSnapshot | InputSnapshot | LinkSnapshot | OptionSnapshot | ProgressbarSnapshot | RegionSnapshot | TabSnapshot | MenuItemSnapshot | RadioGroupSnapshot | SeparatorSnapshot;
151
+ type ElementSnapshot = ButtonSnapshot | CellSnapshot | ColumnHeaderSnapshot | ComboboxSnapshot | ContainerSnapshot | DialogSnapshot | GroupSnapshot | HeadingSnapshot | ImageSnapshot | InputSnapshot | LinkSnapshot | OptionSnapshot | ProgressbarSnapshot | RegionSnapshot | TabSnapshot | MenuItemSnapshot | RadioGroupSnapshot | SeparatorSnapshot;
145
152
  //#endregion
146
153
  //#region src/utils/filter.d.ts
147
154
  type FilterPredicate = (snapshot: NodeSnapshot) => boolean;
@@ -262,4 +269,4 @@ declare function excludeRole<TRole extends NodeRole>(role: TRole | Array<TRole>)
262
269
  */
263
270
  declare function getTextContent(snapshots: Array<NodeSnapshot>): string;
264
271
  //#endregion
265
- export { type ButtonSnapshot, 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 };
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cronn/element-snapshot",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Element snapshots for Playwright",
5
5
  "homepage": "https://cronn.github.io/file-snapshots/playwright/element-snapshots/",
6
6
  "bugs": {
@@ -26,28 +26,29 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "package-directory": "8.2.0",
29
- "@cronn/lib-file-snapshots": "1.2.0",
30
- "@cronn/playwright-file-snapshots": "2.2.0"
29
+ "@cronn/playwright-file-snapshots": "2.2.1",
30
+ "@cronn/lib-file-snapshots": "1.2.1"
31
31
  },
32
32
  "devDependencies": {
33
- "@arethetypeswrong/core": "0.18.2",
34
- "@playwright/test": "1.60.0",
35
- "@types/node": "24.12.4",
36
- "@typescript/native-preview": "7.0.0-dev.20260525.1",
37
- "@vitest/coverage-v8": "4.1.7",
38
- "eslint": "10.4.0",
33
+ "@arethetypeswrong/core": "0.18.5",
34
+ "@playwright/test": "1.61.1",
35
+ "@types/node": "24.13.2",
36
+ "@typescript/native": "npm:typescript@^7.0.2",
37
+ "@vitest/coverage-v8": "4.1.10",
38
+ "eslint": "10.7.0",
39
39
  "eslint-config-prettier": "10.1.8",
40
40
  "eslint-plugin-check-file": "3.3.1",
41
41
  "eslint-plugin-unused-imports": "4.4.1",
42
42
  "publint": "0.3.21",
43
43
  "rimraf": "6.1.3",
44
- "tsdown": "0.22.0",
45
- "typescript-eslint": "8.59.4",
46
- "vitest": "4.1.7",
47
- "node": "runtime:>=24.14.1 <25",
48
- "@cronn/test-utils": "0.0.0",
44
+ "tsdown": "0.22.7",
45
+ "typescript": "npm:@typescript/typescript6@^6.0.2",
46
+ "typescript-eslint": "8.63.0",
47
+ "vitest": "4.1.10",
48
+ "node": "runtime:24.18.0",
49
49
  "@cronn/shared-configs": "0.0.0",
50
- "@cronn/vitest-file-snapshots": "2.1.1"
50
+ "@cronn/test-utils": "0.0.0",
51
+ "@cronn/vitest-file-snapshots": "2.1.2"
51
52
  },
52
53
  "peerDependencies": {
53
54
  "@playwright/test": "^1.55"
@@ -55,22 +56,22 @@
55
56
  "devEngines": {
56
57
  "packageManager": {
57
58
  "name": "pnpm",
58
- "version": "11.3.0",
59
+ "version": "11.13.1",
59
60
  "onFail": "download"
60
61
  },
61
62
  "runtime": {
62
63
  "name": "node",
63
- "version": ">=24.14.1 <25",
64
+ "version": "24.18.0",
64
65
  "onFail": "download"
65
66
  }
66
67
  },
67
68
  "engines": {
68
- "node": "^20 || ^22 || >=24"
69
+ "node": "^22 || ^24 || >=26"
69
70
  },
70
71
  "scripts": {
71
72
  "build": "tsdown",
72
73
  "clean": "rimraf .turbo dist playwright-report test-results coverage",
73
- "compile": "tsgo",
74
+ "compile": "tsc",
74
75
  "lint:check": "eslint src/ tests/ --max-warnings=0",
75
76
  "lint:fix": "eslint src/ tests/ --max-warnings=0 --fix",
76
77
  "playwright:install": "playwright install chromium",