@setsquare/review-sdk 0.0.1 → 0.1.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.
Files changed (105) hide show
  1. package/NOTICE +3 -2
  2. package/README.md +220 -0
  3. package/dist/autoscan.d.ts +15 -1
  4. package/dist/autoscan.d.ts.map +1 -1
  5. package/dist/autoscan.js +168 -13
  6. package/dist/autoscan.js.map +1 -1
  7. package/dist/brand.d.ts +51 -2
  8. package/dist/brand.d.ts.map +1 -1
  9. package/dist/brand.js +560 -5
  10. package/dist/brand.js.map +1 -1
  11. package/dist/checks/context-change.d.ts +96 -0
  12. package/dist/checks/context-change.d.ts.map +1 -0
  13. package/dist/checks/context-change.js +655 -0
  14. package/dist/checks/context-change.js.map +1 -0
  15. package/dist/checks/focus.d.ts +154 -0
  16. package/dist/checks/focus.d.ts.map +1 -0
  17. package/dist/checks/focus.js +1123 -0
  18. package/dist/checks/focus.js.map +1 -0
  19. package/dist/checks/heuristics.d.ts +116 -0
  20. package/dist/checks/heuristics.d.ts.map +1 -0
  21. package/dist/checks/heuristics.js +931 -0
  22. package/dist/checks/heuristics.js.map +1 -0
  23. package/dist/checks/keyboard.d.ts +106 -0
  24. package/dist/checks/keyboard.d.ts.map +1 -0
  25. package/dist/checks/keyboard.js +452 -0
  26. package/dist/checks/keyboard.js.map +1 -0
  27. package/dist/checks/reflow.d.ts +75 -0
  28. package/dist/checks/reflow.d.ts.map +1 -0
  29. package/dist/checks/reflow.js +285 -0
  30. package/dist/checks/reflow.js.map +1 -0
  31. package/dist/checks/rule-pack.d.ts +1 -1
  32. package/dist/checks/rule-pack.d.ts.map +1 -1
  33. package/dist/checks/rule-pack.js +350 -45
  34. package/dist/checks/rule-pack.js.map +1 -1
  35. package/dist/checks/shortcuts.d.ts +71 -0
  36. package/dist/checks/shortcuts.d.ts.map +1 -0
  37. package/dist/checks/shortcuts.js +196 -0
  38. package/dist/checks/shortcuts.js.map +1 -0
  39. package/dist/checks/versions.d.ts.map +1 -1
  40. package/dist/checks/versions.js +33 -1
  41. package/dist/checks/versions.js.map +1 -1
  42. package/dist/contract.d.ts +18 -0
  43. package/dist/contract.d.ts.map +1 -1
  44. package/dist/covers.d.ts +56 -0
  45. package/dist/covers.d.ts.map +1 -0
  46. package/dist/covers.js +135 -0
  47. package/dist/covers.js.map +1 -0
  48. package/dist/dedupe.d.ts +23 -0
  49. package/dist/dedupe.d.ts.map +1 -1
  50. package/dist/dedupe.js +96 -2
  51. package/dist/dedupe.js.map +1 -1
  52. package/dist/document.d.ts.map +1 -1
  53. package/dist/document.js +144 -0
  54. package/dist/document.js.map +1 -1
  55. package/dist/envelope.d.ts +8 -0
  56. package/dist/envelope.d.ts.map +1 -1
  57. package/dist/envelope.js +28 -0
  58. package/dist/envelope.js.map +1 -1
  59. package/dist/fixture.d.ts.map +1 -1
  60. package/dist/fixture.js +12 -0
  61. package/dist/fixture.js.map +1 -1
  62. package/dist/html-report.d.ts +24 -7
  63. package/dist/html-report.d.ts.map +1 -1
  64. package/dist/html-report.js +608 -136
  65. package/dist/html-report.js.map +1 -1
  66. package/dist/index.d.ts +13 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +13 -0
  69. package/dist/index.js.map +1 -1
  70. package/dist/links.d.ts +43 -0
  71. package/dist/links.d.ts.map +1 -1
  72. package/dist/links.js +43 -0
  73. package/dist/links.js.map +1 -1
  74. package/dist/observe.d.ts +8 -0
  75. package/dist/observe.d.ts.map +1 -1
  76. package/dist/observe.js +45 -1
  77. package/dist/observe.js.map +1 -1
  78. package/dist/options.d.ts +53 -0
  79. package/dist/options.d.ts.map +1 -1
  80. package/dist/options.js +3 -0
  81. package/dist/options.js.map +1 -1
  82. package/dist/reading-level.d.ts +22 -1
  83. package/dist/reading-level.d.ts.map +1 -1
  84. package/dist/reading-level.js +122 -19
  85. package/dist/reading-level.js.map +1 -1
  86. package/dist/reporter.d.ts.map +1 -1
  87. package/dist/reporter.js +31 -15
  88. package/dist/reporter.js.map +1 -1
  89. package/dist/scan.d.ts +36 -1
  90. package/dist/scan.d.ts.map +1 -1
  91. package/dist/scan.js +16 -2
  92. package/dist/scan.js.map +1 -1
  93. package/dist/screens.d.ts +55 -4
  94. package/dist/screens.d.ts.map +1 -1
  95. package/dist/screens.js +243 -43
  96. package/dist/screens.js.map +1 -1
  97. package/dist/summary.d.ts +22 -0
  98. package/dist/summary.d.ts.map +1 -1
  99. package/dist/summary.js +197 -22
  100. package/dist/summary.js.map +1 -1
  101. package/dist/viewports.d.ts +105 -0
  102. package/dist/viewports.d.ts.map +1 -0
  103. package/dist/viewports.js +134 -0
  104. package/dist/viewports.js.map +1 -0
  105. package/package.json +5 -4
@@ -0,0 +1,196 @@
1
+ import { CHARACTER_KEY_SHORTCUTS_HELP_URL } from '../links.js';
2
+ import { sanitiseLabel } from '../sanitise.js';
3
+ /**
4
+ * WCAG 2.1.4 Character Key Shortcuts (A): a single-character shortcut with no
5
+ * way to turn it off or remap it makes a page unusable for anyone using speech
6
+ * input, because every dictated word is a volley of shortcuts.
7
+ *
8
+ * A small rule and a real failure — and the only one in this package that
9
+ * needs to run BEFORE the customer's own code. There is no way to enumerate a
10
+ * page's event listeners after the fact: `getEventListeners` is a DevTools
11
+ * API and does not exist in page script. So the only route is to wrap
12
+ * `addEventListener` at init time and watch what gets registered.
13
+ *
14
+ * ---------------------------------------------------------------------------
15
+ * **Opt-in, and off by default, because of the footprint.**
16
+ *
17
+ * Everything else this SDK does happens after a page has loaded and can be
18
+ * undone. This patches a DOM method before any of the customer's scripts run,
19
+ * for the whole life of the page. Even proven inert, that is a larger presence
20
+ * in someone's application than a scanner has any business having by default —
21
+ * and "it is only a pass-through" is exactly the reasoning that precedes a
22
+ * subtle break in someone else's product.
23
+ *
24
+ * So it is a choice, `keyShortcuts: true`, and while it is off the criterion
25
+ * reports as a check that exists and did not run here, which is what it is.
26
+ *
27
+ * **Inertness, concretely.** The wrapper records `(type, target)` and the key
28
+ * literals it can read out of the handler's own source, then delegates with
29
+ * the ORIGINAL arguments — never a wrapped listener. That last part is what
30
+ * keeps `removeEventListener` working: a wrapped listener is a different
31
+ * function object and would never match, so a page that adds and removes a
32
+ * handler would silently keep it forever. The fixture asserts exactly that.
33
+ * ---------------------------------------------------------------------------
34
+ */
35
+ export const SETSQUARE_SHORTCUTS_CHECK_VERSION = 'setsquare-shortcuts@1';
36
+ export const KEY_SHORTCUTS_RULE_ID = 'setsquare-key-shortcuts';
37
+ /** Handlers to look at. Beyond this a page is instrumenting, not shortcutting. */
38
+ const MAX_HANDLERS = 40;
39
+ /**
40
+ * Installed before any page script. See the class comment for why this is
41
+ * opt-in; see `fixture.ts` for where it is installed.
42
+ *
43
+ * A source string rather than a function, because `addInitScript` serialises
44
+ * it and a closure over anything in this module would not survive.
45
+ */
46
+ export const KEY_LISTENER_SCRIPT = `
47
+ (() => {
48
+ const found = [];
49
+ Object.defineProperty(window, '__setsquareKeyListeners', {
50
+ value: found,
51
+ // Non-enumerable so it does not appear in a customer's own iteration over
52
+ // window, and non-writable so page code cannot clobber it by accident.
53
+ enumerable: false,
54
+ writable: false,
55
+ configurable: true,
56
+ });
57
+
58
+ const KEY_EVENTS = new Set(['keydown', 'keypress', 'keyup']);
59
+ const MODIFIER = /\\b(ctrlKey|metaKey|altKey|shiftKey|getModifierState)\\b/;
60
+
61
+ /*
62
+ * Which keys a handler reacts to, read out of its own source.
63
+ *
64
+ * The instrumentation can see THAT a key listener exists and never which key
65
+ * it cares about — so without this the finding would be "this page has a
66
+ * keydown handler", which is true of most of the web and useful to nobody.
67
+ * Reading the source is a heuristic and is treated as one: everything this
68
+ * rule reports is needs-review.
69
+ *
70
+ * A handler that consults a modifier is not what 2.1.4 is about, so it is
71
+ * left alone. That is most of the false positives.
72
+ */
73
+ const keysIn = (source) => {
74
+ if (typeof source !== 'string' || source.length === 0) return [];
75
+ if (source.indexOf('[native code]') !== -1) return [];
76
+ if (MODIFIER.test(source)) return [];
77
+
78
+ const keys = new Set();
79
+ const literal = /(?:\\.key\\s*={2,3}\\s*|case\\s+)['"]([^'"\\\\]{1})['"]/g;
80
+ let match;
81
+ while ((match = literal.exec(source)) !== null) {
82
+ const key = match[1];
83
+ // Printable, single character, not whitespace. Enter, Escape and Tab are
84
+ // multi-character names and fall out here, which is right: 2.1.4 is
85
+ // about character keys.
86
+ if (key.trim().length === 1) keys.add(key);
87
+ }
88
+
89
+ const code = /(?:keyCode|which)\\s*={2,3}\\s*(\\d{2,3})/g;
90
+ while ((match = code.exec(source)) !== null) {
91
+ const value = Number(match[1]);
92
+ // Letters and digits only. The named keys have codes too, and reporting
93
+ // Escape as a character shortcut would be wrong.
94
+ if (value >= 48 && value <= 57) keys.add(String(value - 48));
95
+ else if (value >= 65 && value <= 90) keys.add(String.fromCharCode(value).toLowerCase());
96
+ }
97
+
98
+ return [...keys];
99
+ };
100
+
101
+ const original = EventTarget.prototype.addEventListener;
102
+ EventTarget.prototype.addEventListener = function (type, listener, options) {
103
+ try {
104
+ if (KEY_EVENTS.has(type) && (this === document || this === window) && found.length < 40) {
105
+ let source = '';
106
+ try {
107
+ source = typeof listener === 'function' ? Function.prototype.toString.call(listener) : '';
108
+ } catch {}
109
+ const keys = keysIn(source);
110
+ if (keys.length > 0) {
111
+ found.push({ type, target: this === window ? 'window' : 'document', keys });
112
+ }
113
+ }
114
+ } catch {}
115
+
116
+ /*
117
+ * The original arguments, never a wrapper. A wrapped listener is a
118
+ * different function object, so removeEventListener would never match it
119
+ * and a page that adds and removes a handler would silently keep it for
120
+ * ever. That is the failure this line exists to prevent.
121
+ */
122
+ return original.call(this, type, listener, options);
123
+ };
124
+ })();
125
+ `;
126
+ /**
127
+ * Read what the instrumentation saw. Returns nothing when it was never
128
+ * installed, which is the honest answer for an opt-in check that is off.
129
+ */
130
+ export async function runKeyShortcuts(page) {
131
+ try {
132
+ const rows = await page.evaluate(() => {
133
+ const found = window['__setsquareKeyListeners'];
134
+ return Array.isArray(found) ? found.slice(0, 40) : undefined;
135
+ });
136
+ if (rows === undefined)
137
+ return {};
138
+ return keyShortcutEvidence(rows);
139
+ }
140
+ catch {
141
+ return {};
142
+ }
143
+ }
144
+ const SHORTCUTS_WCAG = { criteria: ['2.1.4'], level: 'A', versionTags: [] };
145
+ /**
146
+ * The verdict, and it is always needs-review or inapplicable — never a
147
+ * violation, and the reason is worth stating rather than assuming.
148
+ *
149
+ * 2.1.4 is satisfied if the shortcut can be turned off, remapped, or is only
150
+ * active when a specific component has focus. All three are page-level
151
+ * affordances: the first two live in a settings screen we are not looking at,
152
+ * and the third is a property of the handler's own logic. We can see that a
153
+ * handler compares against `j`; we cannot see whether the user was ever
154
+ * offered a way to stop it. Reporting a violation from what we CAN see would
155
+ * be asserting the part we cannot.
156
+ */
157
+ export function keyShortcutEvidence(rows) {
158
+ const usable = rows.filter((row) => row.keys.length > 0).slice(0, MAX_HANDLERS);
159
+ if (usable.length === 0) {
160
+ // The instrumentation ran and found no unmodified character handler. That
161
+ // is a real observation about the page, not an absence of one.
162
+ return { inapplicable: { ruleId: KEY_SHORTCUTS_RULE_ID, wcag: SHORTCUTS_WCAG } };
163
+ }
164
+ const keys = [...new Set(usable.flatMap((row) => row.keys))].sort();
165
+ const first = usable[0];
166
+ return {
167
+ finding: {
168
+ ruleId: KEY_SHORTCUTS_RULE_ID,
169
+ status: 'incomplete',
170
+ impact: 'moderate',
171
+ wcag: SHORTCUTS_WCAG,
172
+ helpUrl: CHARACTER_KEY_SHORTCUTS_HELP_URL,
173
+ evidence: {
174
+ failureSummary: `A ${first.type} handler on ${first.target} reacts to the character key(s) ` +
175
+ `${keys.map((key) => `"${key}"`).join(', ')} without consulting a modifier. ` +
176
+ `${usable.length} handler(s) found. WCAG 2.1.4 is satisfied if the shortcut can be ` +
177
+ `turned off, remapped, or is only active when a specific component has focus — all ` +
178
+ `three are affordances this check cannot see, so it is not reported as a failure. ` +
179
+ `A person confirms one of them exists. This matters most for speech input, where ` +
180
+ `every dictated word is a volley of these.`,
181
+ },
182
+ // Selectors are the wrong shape for a document-level handler, so the
183
+ // targets are the handlers themselves, named by what they listen to.
184
+ targets: {
185
+ nodeCount: usable.length,
186
+ selectors: usable
187
+ .slice(0, 10)
188
+ .map((handler) => `${handler.target} ${handler.type} [${handler.keys.join(' ')}]`)
189
+ .map((label) => sanitiseLabel(label))
190
+ .filter((label) => label !== undefined),
191
+ selectorsTruncated: usable.length > 10,
192
+ },
193
+ },
194
+ };
195
+ }
196
+ //# sourceMappingURL=shortcuts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../../src/checks/shortcuts.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/checks/versions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAKnE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAO1E,CAAC"}
1
+ {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/checks/versions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAa9C;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAanE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAyB1E,CAAC"}
@@ -1,5 +1,11 @@
1
1
  import { readingLevelEnabled } from '../runtime.js';
2
2
  import { SETSQUARE_DYNAMIC_CHECKS_VERSION } from './dynamic.js';
3
+ import { SETSQUARE_FOCUS_CHECKS_VERSION } from './focus.js';
4
+ import { SETSQUARE_KEYBOARD_CHECKS_VERSION } from './keyboard.js';
5
+ import { SETSQUARE_CONTEXT_CHECK_VERSION } from './context-change.js';
6
+ import { SETSQUARE_REFLOW_CHECK_VERSION } from './reflow.js';
7
+ import { SETSQUARE_HEURISTICS_VERSION } from './heuristics.js';
8
+ import { SETSQUARE_SHORTCUTS_CHECK_VERSION } from './shortcuts.js';
3
9
  import { SETSQUARE_RULE_PACK_VERSION } from './rule-pack.js';
4
10
  import { READING_LEVEL_CHECK_VERSION } from '../reading-level.js';
5
11
  /**
@@ -15,7 +21,15 @@ import { READING_LEVEL_CHECK_VERSION } from '../reading-level.js';
15
21
  * teach people to ignore the warning that exists to catch real drift.
16
22
  */
17
23
  export function setsquareCheckVersions(policy) {
18
- const versions = [SETSQUARE_DYNAMIC_CHECKS_VERSION];
24
+ const versions = [
25
+ SETSQUARE_DYNAMIC_CHECKS_VERSION,
26
+ SETSQUARE_FOCUS_CHECKS_VERSION,
27
+ SETSQUARE_KEYBOARD_CHECKS_VERSION,
28
+ SETSQUARE_REFLOW_CHECK_VERSION,
29
+ SETSQUARE_CONTEXT_CHECK_VERSION,
30
+ SETSQUARE_SHORTCUTS_CHECK_VERSION,
31
+ SETSQUARE_HEURISTICS_VERSION,
32
+ ];
19
33
  if (policy.target === 'AAA')
20
34
  versions.push(SETSQUARE_RULE_PACK_VERSION);
21
35
  if (readingLevelEnabled())
@@ -41,5 +55,23 @@ export const SETSQUARE_CHECK_CRITERIA = new Map([
41
55
  ['setsquare-target-size-aaa', ['2.5.5']],
42
56
  ['setsquare-visual-presentation', ['1.4.8']],
43
57
  ['setsquare-link-purpose', ['2.4.9']],
58
+ ['setsquare-focus-obscured', ['2.4.11']],
59
+ ['setsquare-focus-obscured-enhanced', ['2.4.12']],
60
+ ['setsquare-focus-visible', ['2.4.7']],
61
+ ['setsquare-focus-appearance', ['2.4.13']],
62
+ ['setsquare-keyboard-trap', ['2.1.2']],
63
+ ['setsquare-reflow', ['1.4.10']],
64
+ ['setsquare-on-focus', ['3.2.1']],
65
+ ['setsquare-on-input', ['3.2.2']],
66
+ ['setsquare-key-shortcuts', ['2.1.4']],
67
+ ['setsquare-meaningful-sequence', ['1.3.2']],
68
+ ['setsquare-sensory-characteristics', ['1.3.3']],
69
+ ['setsquare-headings-and-labels', ['2.4.6']],
70
+ ['setsquare-section-headings', ['2.4.10']],
71
+ ['setsquare-abbreviations', ['3.1.4']],
72
+ ['setsquare-location', ['2.4.8']],
73
+ ['setsquare-captions', ['1.2.1', '1.2.2', '1.2.3']],
74
+ ['setsquare-captions-aa', ['1.2.4', '1.2.5']],
75
+ ['setsquare-captions-aaa', ['1.2.6', '1.2.7', '1.2.8', '1.2.9']],
44
76
  ]);
45
77
  //# sourceMappingURL=versions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/checks/versions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAkB;IACvD,MAAM,QAAQ,GAAG,CAAC,gCAAgC,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK;QAAE,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxE,IAAI,mBAAmB,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACtE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA2C,IAAI,GAAG,CAAC;IACtF,CAAC,wBAAwB,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,2BAA2B,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,2BAA2B,EAAE,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,+BAA+B,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,wBAAwB,EAAE,CAAC,OAAO,CAAC,CAAC;CACtC,CAAC,CAAC"}
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/checks/versions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,iCAAiC,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAkB;IACvD,MAAM,QAAQ,GAAG;QACf,gCAAgC;QAChC,8BAA8B;QAC9B,iCAAiC;QACjC,8BAA8B;QAC9B,+BAA+B;QAC/B,iCAAiC;QACjC,4BAA4B;KAC7B,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK;QAAE,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxE,IAAI,mBAAmB,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACtE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA2C,IAAI,GAAG,CAAC;IACtF,CAAC,wBAAwB,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,2BAA2B,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,2BAA2B,EAAE,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,+BAA+B,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,wBAAwB,EAAE,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,0BAA0B,EAAE,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC,mCAAmC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,4BAA4B,EAAE,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC,oBAAoB,EAAE,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,oBAAoB,EAAE,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,+BAA+B,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,mCAAmC,EAAE,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC,+BAA+B,EAAE,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,4BAA4B,EAAE,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,oBAAoB,EAAE,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC,uBAAuB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC,wBAAwB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;CACjE,CAAC,CAAC"}
@@ -165,6 +165,24 @@ export interface ScanResultRecord {
165
165
  };
166
166
  /** How the page was judged ready. Absent on explicit scans — no heuristic ran. */
167
167
  settle?: AxeScan['settle'];
168
+ /**
169
+ * This record carries ONLY Setsquare's driven checks — no axe run happened.
170
+ *
171
+ * Emitted at teardown for a page that was already scanned mid-test and has
172
+ * not changed since. That skip is right for axe (nothing to find twice) and
173
+ * wrong for the driven checks, which never run mid-test at all: focusing,
174
+ * pressing Tab and resizing are unsafe while a test is still asserting, so
175
+ * they only ever happen at teardown. Without this record a page that settled
176
+ * during its test got no focus, keyboard, reflow or context evidence — which
177
+ * was quietly true of text-spacing and status messages for months, and
178
+ * meant the criteria those checks exist for stayed at "no automated result"
179
+ * on exactly the fast, static pages most suites are made of.
180
+ *
181
+ * `toScans` MERGES these into the scan sharing their `visitRef` rather than
182
+ * emitting a second row: two rows for one context would collide in dedupe
183
+ * and one kind of evidence would silently win.
184
+ */
185
+ checksOnly?: true;
168
186
  }
169
187
  export type ScanRecord = ObservationRecord | ScanResultRecord;
170
188
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Level 3: a test says which success criteria it covers.
3
+ *
4
+ * Auto-scan gets a grid from a suite nobody edited, and `setsquare.scan()`
5
+ * reaches the states auto-scan cannot. This reaches the CRITERIA neither can:
6
+ * the ones no automated engine evaluates at all.
7
+ *
8
+ * A suite that checks reflow at 320px, drives focus across a soft navigation
9
+ * or asserts that a focus ring is visible is already covering criteria axe
10
+ * has no rule for — and until this existed, the conformance report said "no
11
+ * automated result" for every one of them. Not because anyone decided that:
12
+ * a Playwright spec lands in the envelope as a pass/fail row with no
13
+ * criterion attached, so the projection could not see it. This is the join.
14
+ *
15
+ * ```ts
16
+ * test('no horizontal overflow at 320px', async ({ page }) => {
17
+ * setsquare.covers('1.4.10');
18
+ * await page.setViewportSize({ width: 320, height: 800 });
19
+ * …
20
+ * });
21
+ * ```
22
+ *
23
+ * **What this is not.** We do not check that a test declaring `1.4.10` tests
24
+ * reflow, and we never will — there is no way to. So the report renders it as
25
+ * your assertion and not as our finding: its own cell state, worded "covered
26
+ * by your own test", never merged into the state that means every automated
27
+ * rule passed. The declaration is exactly as strong as the test behind it,
28
+ * and the report says whose claim it is.
29
+ */
30
+ export declare function covers(...criteria: string[]): void;
31
+ /**
32
+ * The annotation type the declaration travels under.
33
+ *
34
+ * Defined beside both the writer above and the reader below so the string
35
+ * cannot drift between them — the same reasoning that keeps the sanitisation
36
+ * limits in one file shared by the schema and the SDK.
37
+ */
38
+ export declare const COVERS_ANNOTATION = "setsquare-covers";
39
+ /**
40
+ * Read the declarations back off one attempt's annotations.
41
+ *
42
+ * Tolerates a missing `annotations` array rather than assuming it: the SDK's
43
+ * declared peer range reaches back to Playwright 1.45, and `TestResult.annotations`
44
+ * only arrived in 1.49. On an older runner the declarations are simply not
45
+ * there, which is the right degradation — the report loses a state it never had.
46
+ *
47
+ * Unknown ids are dropped here rather than thrown, because by this point the
48
+ * throw has already happened in the worker. Anything invalid reaching the
49
+ * reporter came from a hand-written annotation, and a reporter is the wrong
50
+ * place to fail a run that has finished.
51
+ */
52
+ export declare function coversFromAnnotations(annotations: readonly {
53
+ type: string;
54
+ description?: string;
55
+ }[] | undefined): string[];
56
+ //# sourceMappingURL=covers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"covers.d.ts","sourceRoot":"","sources":["../src/covers.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,MAAM,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CA4DlD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,SAAS,GACzE,MAAM,EAAE,CAUV"}
package/dist/covers.js ADDED
@@ -0,0 +1,135 @@
1
+ import { test } from '@playwright/test';
2
+ import { MAX_CRITERIA_PER_TEST } from '@setsquare/schema/limits';
3
+ import { WCAG22_CRITERION_IDS, wcagCriterion } from '@setsquare/schema/wcag22';
4
+ import { WCAG22_SPEC_URL } from './links.js';
5
+ import { isDisabled } from './options.js';
6
+ /**
7
+ * Level 3: a test says which success criteria it covers.
8
+ *
9
+ * Auto-scan gets a grid from a suite nobody edited, and `setsquare.scan()`
10
+ * reaches the states auto-scan cannot. This reaches the CRITERIA neither can:
11
+ * the ones no automated engine evaluates at all.
12
+ *
13
+ * A suite that checks reflow at 320px, drives focus across a soft navigation
14
+ * or asserts that a focus ring is visible is already covering criteria axe
15
+ * has no rule for — and until this existed, the conformance report said "no
16
+ * automated result" for every one of them. Not because anyone decided that:
17
+ * a Playwright spec lands in the envelope as a pass/fail row with no
18
+ * criterion attached, so the projection could not see it. This is the join.
19
+ *
20
+ * ```ts
21
+ * test('no horizontal overflow at 320px', async ({ page }) => {
22
+ * setsquare.covers('1.4.10');
23
+ * await page.setViewportSize({ width: 320, height: 800 });
24
+ * …
25
+ * });
26
+ * ```
27
+ *
28
+ * **What this is not.** We do not check that a test declaring `1.4.10` tests
29
+ * reflow, and we never will — there is no way to. So the report renders it as
30
+ * your assertion and not as our finding: its own cell state, worded "covered
31
+ * by your own test", never merged into the state that means every automated
32
+ * rule passed. The declaration is exactly as strong as the test behind it,
33
+ * and the report says whose claim it is.
34
+ */
35
+ export function covers(...criteria) {
36
+ if (criteria.length === 0) {
37
+ throw new TypeError('setsquare.covers() needs at least one WCAG success criterion id.');
38
+ }
39
+ const seen = new Set();
40
+ for (const criterion of criteria) {
41
+ /*
42
+ * An unknown id throws, and that is the one place this SDK deliberately
43
+ * does throw into a customer's test.
44
+ *
45
+ * Everywhere else the discipline is absolute: a scan that fails warns and
46
+ * returns "not scanned", because our evidence-gathering has no standing to
47
+ * overturn the suite's own verdict. This is a different thing. A typo here
48
+ * is not our code failing on their page — it is a claim that cannot be
49
+ * satisfied, and the only alternative to throwing is dropping it silently,
50
+ * which leaves someone believing they have coverage they do not have. That
51
+ * is the failure mode this whole feature exists to close, so it cannot be
52
+ * the failure mode of the feature itself.
53
+ *
54
+ * It can never fire on a correct declaration, so it can never turn a build
55
+ * red for an accessibility reason. WCAG 2.2 is a frozen Recommendation;
56
+ * the valid set will not change under anyone.
57
+ */
58
+ const known = wcagCriterion(criterion);
59
+ if (!known || known.removedIn) {
60
+ throw new TypeError(`setsquare.covers("${criterion}") is not a WCAG 2.2 success criterion. ` +
61
+ `Ids look like "1.4.10" or "2.4.11"` +
62
+ (known?.removedIn
63
+ ? `; ${criterion} was removed in WCAG ${known.removedIn}.`
64
+ : `. See ${WCAG22_SPEC_URL}`));
65
+ }
66
+ seen.add(criterion);
67
+ }
68
+ if (seen.size > MAX_CRITERIA_PER_TEST) {
69
+ throw new TypeError(`setsquare.covers() accepts at most ${MAX_CRITERIA_PER_TEST} criteria per test; ` +
70
+ `this test declared ${seen.size}. A test asserting twenty of the eighty-six ` +
71
+ `is claiming more than one test can plausibly check.`);
72
+ }
73
+ // Off means off, here as everywhere: the switch exists so somebody can answer
74
+ // "is it you or is it me" in one command. Validation still runs, because a
75
+ // typo is a typo whether or not evidence is being gathered.
76
+ if (isDisabled())
77
+ return;
78
+ const info = test.info();
79
+ for (const criterion of seen) {
80
+ /*
81
+ * Carried on Playwright's own annotation channel rather than an attachment.
82
+ * Annotations are already on `TestResult` where the reporter reads outcomes,
83
+ * they survive into Playwright's own HTML report — so the declaration is
84
+ * visible even to someone not using Setsquare's — and they cost nothing.
85
+ */
86
+ info.annotations.push({ type: COVERS_ANNOTATION, description: criterion });
87
+ }
88
+ }
89
+ /**
90
+ * The annotation type the declaration travels under.
91
+ *
92
+ * Defined beside both the writer above and the reader below so the string
93
+ * cannot drift between them — the same reasoning that keeps the sanitisation
94
+ * limits in one file shared by the schema and the SDK.
95
+ */
96
+ export const COVERS_ANNOTATION = 'setsquare-covers';
97
+ /**
98
+ * Read the declarations back off one attempt's annotations.
99
+ *
100
+ * Tolerates a missing `annotations` array rather than assuming it: the SDK's
101
+ * declared peer range reaches back to Playwright 1.45, and `TestResult.annotations`
102
+ * only arrived in 1.49. On an older runner the declarations are simply not
103
+ * there, which is the right degradation — the report loses a state it never had.
104
+ *
105
+ * Unknown ids are dropped here rather than thrown, because by this point the
106
+ * throw has already happened in the worker. Anything invalid reaching the
107
+ * reporter came from a hand-written annotation, and a reporter is the wrong
108
+ * place to fail a run that has finished.
109
+ */
110
+ export function coversFromAnnotations(annotations) {
111
+ if (!annotations)
112
+ return [];
113
+ const valid = new Set(WCAG22_CRITERION_IDS);
114
+ const found = new Set();
115
+ for (const annotation of annotations) {
116
+ if (annotation.type !== COVERS_ANNOTATION)
117
+ continue;
118
+ const id = annotation.description?.trim();
119
+ if (id && valid.has(id))
120
+ found.add(id);
121
+ }
122
+ return [...found].sort(compareCriteria).slice(0, MAX_CRITERIA_PER_TEST);
123
+ }
124
+ /** Dotted ids sort numerically: 1.4.10 after 1.4.9, not after 1.4.1. */
125
+ function compareCriteria(a, b) {
126
+ const pa = a.split('.').map(Number);
127
+ const pb = b.split('.').map(Number);
128
+ for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
129
+ const d = (pa[i] ?? 0) - (pb[i] ?? 0);
130
+ if (d !== 0)
131
+ return d;
132
+ }
133
+ return 0;
134
+ }
135
+ //# sourceMappingURL=covers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"covers.js","sourceRoot":"","sources":["../src/covers.ts"],"names":[],"mappings":"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"}
package/dist/dedupe.d.ts CHANGED
@@ -43,6 +43,29 @@ export interface DedupeInput {
43
43
  * `/items/:id/edit`), so it collapses exactly what should collapse. The surface
44
44
  * name then comes from whichever scan WINS, which is how an explicit label ends
45
45
  * up on the row instead of competing with an inferred one for a place in the list.
46
+ *
47
+ * ## The viewport joined the tuple on 2026-09-12, and it had to
48
+ *
49
+ * It was missing, and the consequence was not theoretical: adding a tablet and
50
+ * a mobile Playwright project to this repository's own marketing site produced
51
+ * three scans of every surface and this function collapsed them to one. Ties
52
+ * break LAST-wins, so the last project configured won every bucket and the
53
+ * entire grid became mobile evidence — with the desktop and tablet scans
54
+ * silently dropped and the report showing no sign that anything had been lost.
55
+ * A run that looked at three widths reported one, and the two it discarded were
56
+ * the two the reader would have assumed were there.
57
+ *
58
+ * The argument is the one already made above for the theme: collapsing two
59
+ * themes reports a themed surface as clean when only one of its themes was
60
+ * looked at, and a viewport is the same shape of claim. A rule only ever sees
61
+ * the viewport it ran in — a navigation that collapses into a menu below a
62
+ * breakpoint is a different DOM, not a narrower one — so a scan at 1280 has no
63
+ * opinion whatsoever about the same page at 390.
64
+ *
65
+ * A single-viewport run is unaffected: every scan carries the same value, so
66
+ * every key is unchanged. It costs the common case nothing and it is the
67
+ * difference between viewport evidence existing and viewport evidence being
68
+ * thrown away.
46
69
  */
47
70
  export declare function contextKey(scan: AxeScan): string;
48
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"dedupe.d.ts","sourceRoot":"","sources":["../src/dedupe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,cAAc,EAAE,OAAO,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAGhD;AA6BD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAoBvF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,GACtE,GAAG,CAAC,MAAM,CAAC,CAQb"}
1
+ {"version":3,"file":"dedupe.d.ts","sourceRoot":"","sources":["../src/dedupe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,cAAc,EAAE,OAAO,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAShD;AA6BD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA0BvF;AA8DD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,GACtE,GAAG,CAAC,MAAM,CAAC,CAQb"}