@a11y-pulse/tab-orchestrator 0.3.0 → 0.5.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/LICENSE.md +21 -166
- package/README.md +9 -12
- package/dist/adaptor.d.ts +6 -8
- package/dist/adaptors/puppeteer.js +13 -9
- package/dist/adaptors/puppeteer.js.map +1 -1
- package/dist/audit-scaffold.d.ts +6 -7
- package/dist/browser-scripts.d.ts +31 -37
- package/dist/capture-screenshot.d.ts +2 -2
- package/dist/clip.d.ts +3 -3
- package/dist/context-signals.d.ts +3 -4
- package/dist/get-selector.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +39 -88
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/unfocused-pair.d.ts +2 -2
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -226,14 +226,8 @@ function isCenterObscuredScript(el) {
|
|
|
226
226
|
return false;
|
|
227
227
|
}
|
|
228
228
|
const rect = el.getBoundingClientRect();
|
|
229
|
-
const x = Math.min(
|
|
230
|
-
|
|
231
|
-
window.innerWidth - 1
|
|
232
|
-
);
|
|
233
|
-
const y = Math.min(
|
|
234
|
-
Math.max(rect.top + rect.height / 2, 0),
|
|
235
|
-
window.innerHeight - 1
|
|
236
|
-
);
|
|
229
|
+
const x = Math.min(Math.max(rect.left + rect.width / 2, 0), window.innerWidth - 1);
|
|
230
|
+
const y = Math.min(Math.max(rect.top + rect.height / 2, 0), window.innerHeight - 1);
|
|
237
231
|
let hit = document.elementFromPoint(x, y);
|
|
238
232
|
while (hit?.shadowRoot) {
|
|
239
233
|
const inner = hit.shadowRoot.elementFromPoint(x, y);
|
|
@@ -319,9 +313,7 @@ function measureObscuringScript(el, obscurerAttr) {
|
|
|
319
313
|
if (!el) {
|
|
320
314
|
return empty;
|
|
321
315
|
}
|
|
322
|
-
for (const marked of Array.from(
|
|
323
|
-
document.querySelectorAll(`[${obscurerAttr}]`)
|
|
324
|
-
)) {
|
|
316
|
+
for (const marked of Array.from(document.querySelectorAll(`[${obscurerAttr}]`))) {
|
|
325
317
|
marked.removeAttribute(obscurerAttr);
|
|
326
318
|
}
|
|
327
319
|
const rect = el.getBoundingClientRect();
|
|
@@ -463,9 +455,7 @@ function obscurerHandleScript() {
|
|
|
463
455
|
return document.querySelector("[data-a11y-obscurer]");
|
|
464
456
|
}
|
|
465
457
|
function clearObscurerScript(obscurerAttr) {
|
|
466
|
-
for (const marked of Array.from(
|
|
467
|
-
document.querySelectorAll(`[${obscurerAttr}]`)
|
|
468
|
-
)) {
|
|
458
|
+
for (const marked of Array.from(document.querySelectorAll(`[${obscurerAttr}]`))) {
|
|
469
459
|
marked.removeAttribute(obscurerAttr);
|
|
470
460
|
}
|
|
471
461
|
}
|
|
@@ -551,9 +541,7 @@ function drainContextObserverScript(markerAttr) {
|
|
|
551
541
|
if (!state) {
|
|
552
542
|
return empty;
|
|
553
543
|
}
|
|
554
|
-
for (const marked of Array.from(
|
|
555
|
-
document.querySelectorAll(`[${attributedAttr}]`)
|
|
556
|
-
)) {
|
|
544
|
+
for (const marked of Array.from(document.querySelectorAll(`[${attributedAttr}]`))) {
|
|
557
545
|
marked.removeAttribute(attributedAttr);
|
|
558
546
|
}
|
|
559
547
|
const openedWindow = state.openedWindow;
|
|
@@ -568,9 +556,7 @@ function drainContextObserverScript(markerAttr) {
|
|
|
568
556
|
while (active?.shadowRoot?.activeElement) {
|
|
569
557
|
active = active.shadowRoot.activeElement;
|
|
570
558
|
}
|
|
571
|
-
const intended = focusIns.find(
|
|
572
|
-
(el) => el !== document.body && el !== document.documentElement
|
|
573
|
-
) ?? null;
|
|
559
|
+
const intended = focusIns.find((el) => el !== document.body && el !== document.documentElement) ?? null;
|
|
574
560
|
const openingHtml = (node) => {
|
|
575
561
|
const clone = node.cloneNode(false);
|
|
576
562
|
clone.removeAttribute(markerAttr);
|
|
@@ -628,9 +614,7 @@ function attributedHandleScript() {
|
|
|
628
614
|
return document.querySelector("[data-a11y-ctx-attr]");
|
|
629
615
|
}
|
|
630
616
|
function clearAttributedScript() {
|
|
631
|
-
for (const marked of Array.from(
|
|
632
|
-
document.querySelectorAll("[data-a11y-ctx-attr]")
|
|
633
|
-
)) {
|
|
617
|
+
for (const marked of Array.from(document.querySelectorAll("[data-a11y-ctx-attr]"))) {
|
|
634
618
|
marked.removeAttribute("data-a11y-ctx-attr");
|
|
635
619
|
}
|
|
636
620
|
}
|
|
@@ -646,16 +630,16 @@ function clearContextFocusInsScript() {
|
|
|
646
630
|
function locationHrefScript() {
|
|
647
631
|
return location.href;
|
|
648
632
|
}
|
|
633
|
+
function hasFocusScript() {
|
|
634
|
+
return document.hasFocus();
|
|
635
|
+
}
|
|
649
636
|
|
|
650
637
|
// src/clip.ts
|
|
651
638
|
function bufferedClip(rect, pageWidth, pageHeight, buffer) {
|
|
652
639
|
const left = Math.max(0, Math.min(buffer, rect.x));
|
|
653
640
|
const top = Math.max(0, Math.min(buffer, rect.y));
|
|
654
641
|
const right = Math.max(0, Math.min(buffer, pageWidth - rect.x - rect.width));
|
|
655
|
-
const bottom = Math.max(
|
|
656
|
-
0,
|
|
657
|
-
Math.min(buffer, pageHeight - rect.y - rect.height)
|
|
658
|
-
);
|
|
642
|
+
const bottom = Math.max(0, Math.min(buffer, pageHeight - rect.y - rect.height));
|
|
659
643
|
return {
|
|
660
644
|
x: Math.max(0, rect.x - left),
|
|
661
645
|
y: Math.max(0, rect.y - top),
|
|
@@ -832,12 +816,7 @@ function getSelector(root) {
|
|
|
832
816
|
async function captureScreenshot(adaptor, options, handle) {
|
|
833
817
|
const { width: pageWidth, height: pageHeight } = await adaptor.evaluate(pageDimensionsScript);
|
|
834
818
|
const rect = await adaptor.evaluate(elementRectScript, handle);
|
|
835
|
-
const clip = bufferedClip(
|
|
836
|
-
rect,
|
|
837
|
-
pageWidth,
|
|
838
|
-
pageHeight,
|
|
839
|
-
options.screenshotClipBuffer
|
|
840
|
-
);
|
|
819
|
+
const clip = bufferedClip(rect, pageWidth, pageHeight, options.screenshotClipBuffer);
|
|
841
820
|
const scale = adaptor.screenshotClipScale ?? 1;
|
|
842
821
|
return adaptor.screenshotClip(clip, scale);
|
|
843
822
|
}
|
|
@@ -873,9 +852,7 @@ function truncateHtml(html, options = {}) {
|
|
|
873
852
|
async function captureUnfocusedPair(adaptor, options, handle) {
|
|
874
853
|
if (await adaptor.evaluate(isCenterObscuredScript, handle)) {
|
|
875
854
|
await adaptor.evaluate(scrollToCenterScript, handle);
|
|
876
|
-
await new Promise(
|
|
877
|
-
(resolve) => setTimeout(resolve, options.screenshotSettleDelay)
|
|
878
|
-
);
|
|
855
|
+
await new Promise((resolve) => setTimeout(resolve, options.screenshotSettleDelay));
|
|
879
856
|
}
|
|
880
857
|
const { width: pageWidth, height: pageHeight } = await adaptor.evaluate(pageDimensionsScript);
|
|
881
858
|
const focusedRect = await adaptor.evaluate(elementRectScript, handle);
|
|
@@ -895,10 +872,7 @@ async function captureUnfocusedPair(adaptor, options, handle) {
|
|
|
895
872
|
pageHeight,
|
|
896
873
|
options.screenshotClipBuffer
|
|
897
874
|
);
|
|
898
|
-
const unfocusedScreenshot = await adaptor.screenshotClip(
|
|
899
|
-
unfocusedClip,
|
|
900
|
-
scale
|
|
901
|
-
);
|
|
875
|
+
const unfocusedScreenshot = await adaptor.screenshotClip(unfocusedClip, scale);
|
|
902
876
|
const unfocusedStyles = await adaptor.evaluate(elementStylesScript, handle, [
|
|
903
877
|
...options.styleProps
|
|
904
878
|
]);
|
|
@@ -918,9 +892,7 @@ async function captureUnfocusedPair(adaptor, options, handle) {
|
|
|
918
892
|
// src/orchestrator.ts
|
|
919
893
|
function isContextDestroyedError(error) {
|
|
920
894
|
const message = error instanceof Error ? error.message : String(error);
|
|
921
|
-
return /Execution context was destroyed|Target closed|frame was detached|navigat/i.test(
|
|
922
|
-
message
|
|
923
|
-
);
|
|
895
|
+
return /Execution context was destroyed|Target closed|frame was detached|navigat/i.test(message);
|
|
924
896
|
}
|
|
925
897
|
var DEFAULT_SCREENSHOT_SETTLE_DELAY2 = 33;
|
|
926
898
|
var DEFAULT_SCREENSHOT_CLIP_BUFFER = 10;
|
|
@@ -990,11 +962,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
990
962
|
if (activeHandle === void 0) {
|
|
991
963
|
throw new Error("unfocusedPair capture not implemented");
|
|
992
964
|
}
|
|
993
|
-
pairByStop.current ??= captureUnfocusedPair(
|
|
994
|
-
adaptor,
|
|
995
|
-
resolved,
|
|
996
|
-
activeHandle
|
|
997
|
-
);
|
|
965
|
+
pairByStop.current ??= captureUnfocusedPair(adaptor, resolved, activeHandle);
|
|
998
966
|
return pairByStop.current;
|
|
999
967
|
},
|
|
1000
968
|
screenshotClip: () => {
|
|
@@ -1007,11 +975,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1007
975
|
if (activeHandle === void 0) {
|
|
1008
976
|
throw new Error("screenshot capture not implemented");
|
|
1009
977
|
}
|
|
1010
|
-
screenshotByStop.current ??= captureScreenshot(
|
|
1011
|
-
adaptor,
|
|
1012
|
-
resolved,
|
|
1013
|
-
activeHandle
|
|
1014
|
-
);
|
|
978
|
+
screenshotByStop.current ??= captureScreenshot(adaptor, resolved, activeHandle);
|
|
1015
979
|
return screenshotByStop.current;
|
|
1016
980
|
}
|
|
1017
981
|
});
|
|
@@ -1046,6 +1010,13 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1046
1010
|
baselineHref = href;
|
|
1047
1011
|
return { navigation: false, raw };
|
|
1048
1012
|
}
|
|
1013
|
+
async function documentHasFocus() {
|
|
1014
|
+
if (await adaptor.evaluate(hasFocusScript)) {
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1017
|
+
await adaptor.ensureFocusReporting();
|
|
1018
|
+
return adaptor.evaluate(hasFocusScript);
|
|
1019
|
+
}
|
|
1049
1020
|
let failure;
|
|
1050
1021
|
try {
|
|
1051
1022
|
await adaptor.ensureFocusReporting();
|
|
@@ -1075,8 +1046,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1075
1046
|
pairByStop.current = null;
|
|
1076
1047
|
screenshotByStop.current = null;
|
|
1077
1048
|
lastHasAttributed = false;
|
|
1078
|
-
|
|
1079
|
-
if (!hasFocus) {
|
|
1049
|
+
if (!await documentHasFocus()) {
|
|
1080
1050
|
end("lostFocus");
|
|
1081
1051
|
break;
|
|
1082
1052
|
}
|
|
@@ -1092,13 +1062,10 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1092
1062
|
if (attached.size === 0) {
|
|
1093
1063
|
break;
|
|
1094
1064
|
}
|
|
1065
|
+
const focusedAtMeasurement = await documentHasFocus();
|
|
1095
1066
|
let base;
|
|
1096
1067
|
try {
|
|
1097
|
-
base = await adaptor.evaluate(
|
|
1098
|
-
probeActiveElementScript,
|
|
1099
|
-
styleProps,
|
|
1100
|
-
MARKER_ATTR
|
|
1101
|
-
);
|
|
1068
|
+
base = await adaptor.evaluate(probeActiveElementScript, styleProps, MARKER_ATTR);
|
|
1102
1069
|
} catch (error) {
|
|
1103
1070
|
if (remainingHas("contextSignals") && isContextDestroyedError(error)) {
|
|
1104
1071
|
end("navigation");
|
|
@@ -1106,6 +1073,10 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1106
1073
|
}
|
|
1107
1074
|
throw error;
|
|
1108
1075
|
}
|
|
1076
|
+
if (!focusedAtMeasurement && base !== null && !base.isBody) {
|
|
1077
|
+
end("lostFocus");
|
|
1078
|
+
break;
|
|
1079
|
+
}
|
|
1109
1080
|
let contextNav = null;
|
|
1110
1081
|
if (remainingHas("contextSignals")) {
|
|
1111
1082
|
const outcome = await checkContextNavigation();
|
|
@@ -1119,10 +1090,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1119
1090
|
if (remainingHas("contextSignals")) {
|
|
1120
1091
|
let raw;
|
|
1121
1092
|
try {
|
|
1122
|
-
raw = contextNav?.raw ?? await adaptor.evaluate(
|
|
1123
|
-
drainContextObserverScript,
|
|
1124
|
-
MARKER_ATTR
|
|
1125
|
-
);
|
|
1093
|
+
raw = contextNav?.raw ?? await adaptor.evaluate(drainContextObserverScript, MARKER_ATTR);
|
|
1126
1094
|
} catch (error) {
|
|
1127
1095
|
if (!isContextDestroyedError(error)) {
|
|
1128
1096
|
throw error;
|
|
@@ -1131,9 +1099,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1131
1099
|
break;
|
|
1132
1100
|
}
|
|
1133
1101
|
if (raw.hasAttributed) {
|
|
1134
|
-
const attributedRef = await adaptor.evaluateHandle(
|
|
1135
|
-
attributedHandleScript
|
|
1136
|
-
);
|
|
1102
|
+
const attributedRef = await adaptor.evaluateHandle(attributedHandleScript);
|
|
1137
1103
|
let selector;
|
|
1138
1104
|
try {
|
|
1139
1105
|
selector = await adaptor.evaluate(getSelector, attributedRef);
|
|
@@ -1210,10 +1176,7 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1210
1176
|
if (remainingHas("contextSignals")) {
|
|
1211
1177
|
let signals;
|
|
1212
1178
|
try {
|
|
1213
|
-
const raw = contextNav?.raw ?? await adaptor.evaluate(
|
|
1214
|
-
drainContextObserverScript,
|
|
1215
|
-
MARKER_ATTR
|
|
1216
|
-
);
|
|
1179
|
+
const raw = contextNav?.raw ?? await adaptor.evaluate(drainContextObserverScript, MARKER_ATTR);
|
|
1217
1180
|
signals = {
|
|
1218
1181
|
openedWindow: raw.openedWindow,
|
|
1219
1182
|
submittedForm: raw.submittedForm,
|
|
@@ -1240,29 +1203,16 @@ function createTabOrchestrator(adaptor, options = {}) {
|
|
|
1240
1203
|
snapshot.contextSignals = { signals };
|
|
1241
1204
|
}
|
|
1242
1205
|
if (remainingHas("obscuring")) {
|
|
1243
|
-
let raw = await adaptor.evaluate(
|
|
1244
|
-
measureObscuringScript,
|
|
1245
|
-
ref,
|
|
1246
|
-
OBSCURER_ATTR
|
|
1247
|
-
);
|
|
1206
|
+
let raw = await adaptor.evaluate(measureObscuringScript, ref, OBSCURER_ATTR);
|
|
1248
1207
|
if (raw.fullyObscured) {
|
|
1249
|
-
await new Promise(
|
|
1250
|
-
|
|
1251
|
-
);
|
|
1252
|
-
raw = await adaptor.evaluate(
|
|
1253
|
-
measureObscuringScript,
|
|
1254
|
-
ref,
|
|
1255
|
-
OBSCURER_ATTR
|
|
1256
|
-
);
|
|
1208
|
+
await new Promise((resolve) => setTimeout(resolve, OBSCURING_RECHECK_DELAY_MS));
|
|
1209
|
+
raw = await adaptor.evaluate(measureObscuringScript, ref, OBSCURER_ATTR);
|
|
1257
1210
|
}
|
|
1258
1211
|
let obscuredBy = null;
|
|
1259
1212
|
if (raw.hasObscurer) {
|
|
1260
1213
|
const obscurer = await adaptor.evaluateHandle(obscurerHandleScript);
|
|
1261
1214
|
try {
|
|
1262
|
-
const obscurerSelector = await adaptor.evaluate(
|
|
1263
|
-
getSelector,
|
|
1264
|
-
obscurer
|
|
1265
|
-
);
|
|
1215
|
+
const obscurerSelector = await adaptor.evaluate(getSelector, obscurer);
|
|
1266
1216
|
obscuredBy = {
|
|
1267
1217
|
selector: obscurerSelector,
|
|
1268
1218
|
html: truncateHtml(raw.obscuredByHtml ?? "")
|
|
@@ -1337,6 +1287,7 @@ export {
|
|
|
1337
1287
|
elementStylesScript,
|
|
1338
1288
|
focusScript,
|
|
1339
1289
|
getSelector,
|
|
1290
|
+
hasFocusScript,
|
|
1340
1291
|
isCenterObscuredScript,
|
|
1341
1292
|
pageDimensionsScript,
|
|
1342
1293
|
probeActiveElementScript,
|