@letsrunit/playwright 0.6.0 → 0.7.1

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/index.d.ts CHANGED
@@ -15,7 +15,7 @@ declare function setFieldValue(el: Locator, value: Value, options?: SetOptions):
15
15
  declare function formatHtml(page: string | Page): Promise<string>;
16
16
 
17
17
  /**
18
- * Locates an element using Playwright selectors, with fallbacks.
18
+ * Locates an element using Playwright selectors, with lazy fallbacks.
19
19
  */
20
20
  declare function fuzzyLocator(page: Page, selector: string): Promise<Locator>;
21
21
 
package/dist/index.js CHANGED
@@ -14,9 +14,12 @@ async function browse(browser, options = {}) {
14
14
  locale: "en-US",
15
15
  ...options
16
16
  });
17
- await context.addInitScript(() => {
18
- window.__name = window.__name || ((fn) => fn);
19
- });
17
+ await context.addInitScript(
18
+ /* v8 ignore next */
19
+ () => {
20
+ window.__name = window.__name || ((fn) => fn);
21
+ }
22
+ );
20
23
  return await context.newPage();
21
24
  }
22
25
 
@@ -101,6 +104,7 @@ async function waitForMeta(page, timeout = 2500) {
101
104
  await waitForIdle(page);
102
105
  page.getByRole("navigation");
103
106
  await page.waitForFunction(
107
+ /* v8 ignore start */
104
108
  () => {
105
109
  const head = document.head;
106
110
  if (!head) return false;
@@ -108,12 +112,14 @@ async function waitForMeta(page, timeout = 2500) {
108
112
  document.title.trim() || head.querySelector('meta[property^="og:"]') || head.querySelector('meta[name^="twitter:"]') || head.querySelector('script[type="application/ld+json"]')
109
113
  );
110
114
  },
115
+ /* v8 ignore stop */
111
116
  { timeout }
112
117
  ).catch(() => {
113
118
  });
114
119
  }
115
120
  async function waitForDomIdle(page, { quiet = 500, timeout = 1e4 } = {}) {
116
121
  await page.waitForFunction(
122
+ /* v8 ignore start */
117
123
  (q) => new Promise((resolve) => {
118
124
  let last = performance.now();
119
125
  const obs = new MutationObserver(() => last = performance.now());
@@ -133,23 +139,31 @@ async function waitForDomIdle(page, { quiet = 500, timeout = 1e4 } = {}) {
133
139
  };
134
140
  tick();
135
141
  }),
142
+ /* v8 ignore stop */
136
143
  quiet,
137
144
  { timeout }
138
145
  );
139
146
  }
140
147
  async function waitForAnimationsToFinish(root) {
141
148
  await root.page().waitForFunction(
149
+ /* v8 ignore start */
142
150
  (el) => {
143
151
  const animations = el.getAnimations?.({ subtree: true }) ?? [];
144
152
  return animations.every((a) => a.playState !== "running");
145
153
  },
154
+ /* v8 ignore stop */
146
155
  await root.elementHandle()
147
156
  );
148
157
  await root.evaluate(() => new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(() => r()))));
149
158
  }
150
159
  async function waitForUrlChange(page, prevUrl, timeout) {
151
160
  try {
152
- await page.waitForFunction((u) => location.href !== u, prevUrl, { timeout });
161
+ await page.waitForFunction(
162
+ /* v8 ignore next */
163
+ (u) => location.href !== u,
164
+ prevUrl,
165
+ { timeout }
166
+ );
153
167
  return true;
154
168
  } catch {
155
169
  return false;
@@ -161,12 +175,14 @@ async function waitUntilEnabled(page, target, timeout) {
161
175
  const handle = await target.elementHandle().catch(() => null);
162
176
  if (!handle) return;
163
177
  await page.waitForFunction(
178
+ /* v8 ignore start */
164
179
  (el) => {
165
180
  if (!el || !el.isConnected) return true;
166
181
  const aria = el.getAttribute("aria-disabled");
167
182
  const disabled = el.disabled || aria === "true" || el.getAttribute("disabled") !== null;
168
183
  return !disabled;
169
184
  },
185
+ /* v8 ignore stop */
170
186
  handle,
171
187
  { timeout }
172
188
  ).catch(() => {
@@ -213,7 +229,12 @@ async function elementKind(target) {
213
229
  const role = await target.getAttribute("role", { timeout: PROBE }).catch(() => null);
214
230
  if (role === "link") return "link";
215
231
  if (role === "button") return "button";
216
- const tag = await target.evaluate((el) => el.tagName.toLowerCase(), null, { timeout: PROBE }).catch(() => "");
232
+ const tag = await target.evaluate(
233
+ /* v8 ignore next */
234
+ (el) => el.tagName.toLowerCase(),
235
+ null,
236
+ { timeout: PROBE }
237
+ ).catch(() => "");
217
238
  if (tag === "a") return "link";
218
239
  if (tag === "button") return "button";
219
240
  if (tag === "input") {
@@ -255,9 +276,7 @@ async function getCalendar(root, options) {
255
276
  if (!container) return null;
256
277
  const found = await container.locator(gridSelector).all();
257
278
  const tables = [];
258
- if (await isCalendarGrid(container)) {
259
- tables.push(container);
260
- }
279
+ if (await isCalendarGrid(container)) tables.push(container);
261
280
  for (const grid of found) {
262
281
  if (await isCalendarGrid(grid)) {
263
282
  tables.push(grid);
@@ -467,33 +486,37 @@ async function getCandidateLocs(el, options) {
467
486
  if (candidates.length < 2 || candidates.length > 3) return [];
468
487
  return Promise.all(
469
488
  candidates.map(async (c) => {
470
- const info = await c.evaluate((node) => {
471
- const e = node;
472
- const attrs = {};
473
- for (const attr of e.attributes) {
474
- attrs[attr.name] = attr.value;
475
- }
476
- let options2 = [];
477
- if (e.tagName.toLowerCase() === "select") {
478
- options2 = Array.from(e.options).map((o) => ({
479
- value: o.value,
480
- text: o.text
481
- }));
482
- }
483
- return {
484
- tag: e.tagName.toLowerCase(),
485
- type: e.getAttribute("type"),
486
- name: e.getAttribute("name"),
487
- id: e.getAttribute("id"),
488
- ariaLabel: e.getAttribute("aria-label"),
489
- placeholder: e.getAttribute("placeholder"),
490
- min: e.getAttribute("min"),
491
- max: e.getAttribute("max"),
492
- inputMode: e.getAttribute("inputmode"),
493
- attrs,
494
- options: options2
495
- };
496
- }, options);
489
+ const info = await c.evaluate(
490
+ /* v8 ignore start */
491
+ (node) => {
492
+ const e = node;
493
+ const attrs = {};
494
+ for (const attr of e.attributes) {
495
+ attrs[attr.name] = attr.value;
496
+ }
497
+ let options2 = [];
498
+ if (e.tagName.toLowerCase() === "select") {
499
+ options2 = Array.from(e.options).map((o) => ({
500
+ value: o.value,
501
+ text: o.text
502
+ }));
503
+ }
504
+ return {
505
+ tag: e.tagName.toLowerCase(),
506
+ type: e.getAttribute("type"),
507
+ name: e.getAttribute("name"),
508
+ id: e.getAttribute("id"),
509
+ ariaLabel: e.getAttribute("aria-label"),
510
+ placeholder: e.getAttribute("placeholder"),
511
+ min: e.getAttribute("min"),
512
+ max: e.getAttribute("max"),
513
+ inputMode: e.getAttribute("inputmode"),
514
+ attrs,
515
+ options: options2
516
+ };
517
+ },
518
+ options
519
+ );
497
520
  return { el: c, ...info };
498
521
  })
499
522
  );
@@ -529,50 +552,70 @@ async function behavioralProbe(candidateLocs, scores, options) {
529
552
  for (let i = 0; i < candidateLocs.length; i++) {
530
553
  const loc = candidateLocs[i];
531
554
  if (loc.tag === "input") {
532
- const can_be_day = await loc.el.evaluate((node) => {
533
- const e = node;
534
- const old = e.value;
535
- e.value = "31";
536
- const valid = e.checkValidity();
537
- e.value = old;
538
- return valid;
539
- }, options);
555
+ const can_be_day = await loc.el.evaluate(
556
+ /* v8 ignore start */
557
+ (node) => {
558
+ const e = node;
559
+ const old = e.value;
560
+ e.value = "31";
561
+ const valid = e.checkValidity();
562
+ e.value = old;
563
+ return valid;
564
+ },
565
+ options
566
+ );
540
567
  if (can_be_day) scores[i].day += 1;
541
- const cannot_be_day = await loc.el.evaluate((node) => {
542
- const e = node;
543
- const old = e.value;
544
- e.value = "32";
545
- const valid = !e.checkValidity();
546
- e.value = old;
547
- return valid;
548
- }, options);
568
+ const cannot_be_day = await loc.el.evaluate(
569
+ /* v8 ignore start */
570
+ (node) => {
571
+ const e = node;
572
+ const old = e.value;
573
+ e.value = "32";
574
+ const valid = !e.checkValidity();
575
+ e.value = old;
576
+ return valid;
577
+ },
578
+ options
579
+ );
549
580
  if (cannot_be_day) scores[i].day += 1;
550
- const can_be_month = await loc.el.evaluate((node) => {
551
- const e = node;
552
- const old = e.value;
553
- e.value = "12";
554
- const valid = e.checkValidity();
555
- e.value = old;
556
- return valid;
557
- }, options);
581
+ const can_be_month = await loc.el.evaluate(
582
+ /* v8 ignore start */
583
+ (node) => {
584
+ const e = node;
585
+ const old = e.value;
586
+ e.value = "12";
587
+ const valid = e.checkValidity();
588
+ e.value = old;
589
+ return valid;
590
+ },
591
+ options
592
+ );
558
593
  if (can_be_month) scores[i].month += 1;
559
- const cannot_be_month = await loc.el.evaluate((node) => {
560
- const e = node;
561
- const old = e.value;
562
- e.value = "13";
563
- const valid = !e.checkValidity();
564
- e.value = old;
565
- return valid;
566
- }, options);
594
+ const cannot_be_month = await loc.el.evaluate(
595
+ /* v8 ignore start */
596
+ (node) => {
597
+ const e = node;
598
+ const old = e.value;
599
+ e.value = "13";
600
+ const valid = !e.checkValidity();
601
+ e.value = old;
602
+ return valid;
603
+ },
604
+ options
605
+ );
567
606
  if (cannot_be_month) scores[i].month += 1;
568
- const can_be_year = await loc.el.evaluate((node) => {
569
- const e = node;
570
- const old = e.value;
571
- e.value = "2024";
572
- const valid = e.checkValidity();
573
- e.value = old;
574
- return valid;
575
- }, options);
607
+ const can_be_year = await loc.el.evaluate(
608
+ /* v8 ignore start */
609
+ (node) => {
610
+ const e = node;
611
+ const old = e.value;
612
+ e.value = "2024";
613
+ const valid = e.checkValidity();
614
+ e.value = old;
615
+ return valid;
616
+ },
617
+ options
618
+ );
576
619
  if (can_be_year) scores[i].year += 1;
577
620
  }
578
621
  }
@@ -688,22 +731,26 @@ function parseDateString(value, order, sep) {
688
731
  return dt;
689
732
  }
690
733
  async function inferLocaleAndPattern(el, options) {
691
- return el.evaluate(() => {
692
- const lang = document.documentElement.getAttribute("lang") || navigator.language || "en-US";
693
- const dtf = new Intl.DateTimeFormat(lang, { year: "numeric", month: "2-digit", day: "2-digit" });
694
- const parts = dtf.formatToParts(new Date(2033, 10, 22));
695
- const order = [];
696
- let sep = "/";
697
- for (const p of parts) {
698
- if (p.type === "day" || p.type === "month" || p.type === "year") order.push(p.type);
699
- if (p.type === "literal") {
700
- const lit = p.value.trim();
701
- if (lit) sep = lit;
734
+ return el.evaluate(
735
+ /* v8 ignore start */
736
+ () => {
737
+ const lang = document.documentElement.getAttribute("lang") || navigator.language || "en-US";
738
+ const dtf = new Intl.DateTimeFormat(lang, { year: "numeric", month: "2-digit", day: "2-digit" });
739
+ const parts = dtf.formatToParts(new Date(2033, 10, 22));
740
+ const order = [];
741
+ let sep = "/";
742
+ for (const p of parts) {
743
+ if (p.type === "day" || p.type === "month" || p.type === "year") order.push(p.type);
744
+ if (p.type === "literal") {
745
+ const lit = p.value.trim();
746
+ if (lit) sep = lit;
747
+ }
702
748
  }
703
- }
704
- const finalOrder = order.length === 3 ? order : ["day", "month", "year"];
705
- return { locale: lang, order: finalOrder, sep };
706
- }, options);
749
+ const finalOrder = order.length === 3 ? order : ["day", "month", "year"];
750
+ return { locale: lang, order: finalOrder, sep };
751
+ },
752
+ options
753
+ );
707
754
  }
708
755
  async function fillAndReadBack(el, s, options, nextInput) {
709
756
  await el.clear(options);
@@ -711,9 +758,16 @@ async function fillAndReadBack(el, s, options, nextInput) {
711
758
  if (nextInput) {
712
759
  await nextInput.focus(options);
713
760
  } else {
714
- await el.evaluate((el2) => el2.blur(), options);
761
+ await el.evaluate(
762
+ /* v8 ignore next */
763
+ (el2) => el2.blur(),
764
+ options
765
+ );
715
766
  }
716
- await el.evaluate(() => new Promise(requestAnimationFrame));
767
+ await el.evaluate(
768
+ /* v8 ignore next */
769
+ () => new Promise(requestAnimationFrame)
770
+ );
717
771
  return await el.inputValue(options);
718
772
  }
719
773
  function isAmbiguous(value, value2) {
@@ -853,10 +907,13 @@ async function setSingleDate({ el, tag, type }, value, options) {
853
907
  "input[type=date], input[type=datetime-local], input[type=month], input[type=week], input[type=time]"
854
908
  );
855
909
  if (await inputs.count() === 1) {
856
- const isVisible = await inputs.evaluate((e) => {
857
- const style = window.getComputedStyle(e);
858
- return style.display !== "none" && style.visibility !== "hidden" && e.getAttribute("type") !== "hidden";
859
- });
910
+ const isVisible = await inputs.evaluate(
911
+ /* v8 ignore next */
912
+ (e) => {
913
+ const style = window.getComputedStyle(e);
914
+ return style.display !== "none" && style.visibility !== "hidden" && e.getAttribute("type") !== "hidden";
915
+ }
916
+ );
860
917
  if (isVisible) {
861
918
  target = inputs;
862
919
  targetType = await target.getAttribute("type", options) || null;
@@ -909,11 +966,20 @@ async function setNativeInput({ el, tag }, value, options) {
909
966
  // src/field/aria-select.ts
910
967
  async function selectAria({ el }, value, options) {
911
968
  if (typeof value !== "string" && typeof value !== "number") return false;
912
- const role = await el.getAttribute("role", options).catch(() => null);
969
+ const role = await el.getAttribute("role", options).catch(
970
+ /* v8 ignore next */
971
+ () => null
972
+ );
913
973
  if (role !== "combobox") return false;
914
- const ariaControls = await el.getAttribute("aria-controls", options).catch(() => null);
974
+ const ariaControls = await el.getAttribute("aria-controls", options).catch(
975
+ /* v8 ignore next */
976
+ () => null
977
+ );
915
978
  if (!ariaControls) return false;
916
- const ariaExpanded = await el.getAttribute("aria-expanded", options).catch(() => null);
979
+ const ariaExpanded = await el.getAttribute("aria-expanded", options).catch(
980
+ /* v8 ignore next */
981
+ () => null
982
+ );
917
983
  if (ariaExpanded !== "true") await el.click(options);
918
984
  const stringValue = String(value);
919
985
  const listbox = el.page().locator(`#${ariaControls}`);
@@ -962,14 +1028,20 @@ async function setRadioGroup({ el }, value, options) {
962
1028
  const ariaRadio = el.locator(`[role="radio"][value="${stringValue}"]`);
963
1029
  if (await ariaRadio.count() >= 1) {
964
1030
  const item = ariaRadio.first();
965
- const ariaChecked = await item.getAttribute("aria-checked", options).catch(() => null);
1031
+ const ariaChecked = await item.getAttribute("aria-checked", options).catch(
1032
+ /* v8 ignore next */
1033
+ () => null
1034
+ );
966
1035
  if (ariaChecked !== "true") await item.click(options);
967
1036
  return true;
968
1037
  }
969
1038
  const ariaRadioByLabel = el.getByLabel(stringValue, { exact: true }).locator('[role="radio"]');
970
1039
  if (await ariaRadioByLabel.count() >= 1) {
971
1040
  const item = ariaRadioByLabel.first();
972
- const ariaChecked = await item.getAttribute("aria-checked", options).catch(() => null);
1041
+ const ariaChecked = await item.getAttribute("aria-checked", options).catch(
1042
+ /* v8 ignore next */
1043
+ () => null
1044
+ );
973
1045
  if (ariaChecked !== "true") await item.click(options);
974
1046
  return true;
975
1047
  }
@@ -1093,9 +1165,15 @@ async function setSliderByKeyboard(slider, initialValue, targetValue, options) {
1093
1165
  // src/field/toggle.ts
1094
1166
  async function setToggle({ el }, value, options) {
1095
1167
  if (typeof value !== "boolean" && value !== null) return false;
1096
- const role = await el.getAttribute("role", options).catch(() => null);
1168
+ const role = await el.getAttribute("role", options).catch(
1169
+ /* v8 ignore next */
1170
+ () => null
1171
+ );
1097
1172
  if (role !== "checkbox" && role !== "switch") return false;
1098
- const ariaChecked = await el.getAttribute("aria-checked", options).catch(() => null);
1173
+ const ariaChecked = await el.getAttribute("aria-checked", options).catch(
1174
+ /* v8 ignore next */
1175
+ () => null
1176
+ );
1099
1177
  const isChecked = ariaChecked === "true";
1100
1178
  if (Boolean(value) !== isChecked) await el.click(options);
1101
1179
  return true;
@@ -1134,7 +1212,10 @@ async function setFieldValue(el, value, options) {
1134
1212
  el = await pickFieldElement(el);
1135
1213
  }
1136
1214
  const tag = await el.evaluate((e) => e.tagName.toLowerCase(), options);
1137
- const type = await el.getAttribute("type", options).then((s) => s && s.toLowerCase()).catch(() => null);
1215
+ const type = await el.getAttribute("type", options).then((s) => s && s.toLowerCase()).catch(
1216
+ /* v8 ignore next */
1217
+ () => null
1218
+ );
1138
1219
  const loc = { el, tag, type };
1139
1220
  await setValue(loc, value, options);
1140
1221
  }
@@ -1146,47 +1227,51 @@ async function formatHtml(page) {
1146
1227
 
1147
1228
  // src/fuzzy-locator.ts
1148
1229
  async function fuzzyLocator(page, selector) {
1149
- const primary = page.locator(selector).first();
1150
- if (await primary.count()) return primary;
1151
- return await tryRelaxNameToHasText(page, selector) || await tryTagInsteadOfRole(page, selector) || await tryRoleNameProximity(page, selector) || await tryFieldAlternative(page, selector) || await tryAsField(page, selector) || primary;
1152
- }
1153
- async function firstMatch(page, sel, opts = {}) {
1154
- for (const selector of Array.isArray(sel) ? sel : [sel]) {
1155
- const loc = page.locator(selector, opts).first();
1156
- if (await loc.count()) return loc;
1230
+ const primary = page.locator(selector);
1231
+ const candidates = [
1232
+ tryRelaxNameToHasText(page, selector),
1233
+ tryTagInsteadOfRole(page, selector),
1234
+ tryRoleNameProximity(page, selector),
1235
+ tryFieldAlternative(page, selector),
1236
+ tryAsField(page, selector)
1237
+ ];
1238
+ let combined = primary;
1239
+ for (const candidate of candidates) {
1240
+ if (!candidate) continue;
1241
+ combined = combined.or(candidate);
1157
1242
  }
1158
- return null;
1243
+ return combined.first();
1159
1244
  }
1160
- async function tryRelaxNameToHasText(page, selector) {
1245
+ function tryRelaxNameToHasText(page, selector) {
1161
1246
  const matchAnyNameFull = selector.match(/^(role=.*)\[name="([^"]+)"i?](.*)$/i);
1162
1247
  if (!matchAnyNameFull) return null;
1163
1248
  const [, pre, nameText, post] = matchAnyNameFull;
1164
1249
  const containsSelector = `${pre}${post}`;
1165
- return firstMatch(page, containsSelector, { hasText: nameText });
1250
+ return page.locator(containsSelector, { hasText: nameText });
1166
1251
  }
1167
- async function tryTagInsteadOfRole(page, selector) {
1252
+ function tryTagInsteadOfRole(page, selector) {
1168
1253
  const matchAnyNameFull = selector.match(/^role=(link|button|option)\s*\[name="([^"]+)"i?](.*)$/i);
1169
1254
  if (!matchAnyNameFull) return null;
1170
1255
  const [, role, nameText, post] = matchAnyNameFull;
1171
1256
  const tag = role === "link" ? "a" : role;
1172
1257
  const containsSelector = `css=${tag}${post}`;
1173
- return firstMatch(page, containsSelector, { hasText: nameText });
1258
+ return page.locator(containsSelector, { hasText: nameText });
1174
1259
  }
1175
- async function tryRoleNameProximity(page, selector) {
1260
+ function tryRoleNameProximity(page, selector) {
1176
1261
  const matchRole = selector.match(/^role=(\w+)\s*\[name="([^"]+)"i?](.*)$/i);
1177
1262
  if (!matchRole) return null;
1178
1263
  const [, role, name, rest] = matchRole;
1179
1264
  const proximitySelector = `text=${name} >> .. >> role=${role}${rest}`;
1180
- return firstMatch(page, proximitySelector);
1265
+ return page.locator(proximitySelector);
1181
1266
  }
1182
- async function tryFieldAlternative(page, selector) {
1267
+ function tryFieldAlternative(page, selector) {
1183
1268
  const matchField = selector.match(/^field="([^"]+)"i?$/i);
1184
1269
  if (!matchField) return null;
1185
1270
  const [, field] = matchField;
1186
1271
  if (!/^[a-zA-Z0-9_-]+$/.test(field)) return null;
1187
- return firstMatch(page, `#${field} > input`);
1272
+ return page.locator(`#${field} > input`);
1188
1273
  }
1189
- async function tryAsField(page, selector) {
1274
+ function tryAsField(page, selector) {
1190
1275
  const matchRole = selector.match(/^role=(\w+)\s*\[name="([^"]+)"i?](.*)$/i);
1191
1276
  if (!matchRole) return null;
1192
1277
  const [, role, name, rest] = matchRole;
@@ -1206,7 +1291,7 @@ async function tryAsField(page, selector) {
1206
1291
  "option"
1207
1292
  ]);
1208
1293
  if (!fieldRoles.has(role.toLowerCase())) return null;
1209
- return firstMatch(page, `field=${name}${rest}`);
1294
+ return page.locator(`field=${name}${rest}`);
1210
1295
  }
1211
1296
 
1212
1297
  // src/selector/date-selector.ts
@@ -2934,8 +3019,12 @@ async function tryClick(page, selectors, _label) {
2934
3019
  return false;
2935
3020
  }
2936
3021
  async function closeNativeJsAlerts(page) {
2937
- page.on("dialog", (d) => d.accept().catch(() => {
2938
- }));
3022
+ page.on(
3023
+ "dialog",
3024
+ /* v8 ignore next */
3025
+ (d) => d.accept().catch(() => {
3026
+ })
3027
+ );
2939
3028
  }
2940
3029
  async function sweepKnownCMPs(page, preferReject) {
2941
3030
  for (const cmp of knownCMPSelectors) {
@@ -3014,6 +3103,7 @@ async function sweepOverlays(page, regex) {
3014
3103
  const acceptRxSource = regex.accept.source;
3015
3104
  const acceptRxFlags = regex.accept.flags;
3016
3105
  return await page.evaluate(
3106
+ /* v8 ignore start */
3017
3107
  ([source, flags]) => {
3018
3108
  const acceptRx = new RegExp(source, flags);
3019
3109
  const isBig = (el) => {
@@ -3029,7 +3119,7 @@ async function sweepOverlays(page, regex) {
3029
3119
  }).slice(0, 5);
3030
3120
  for (const el of candidates) {
3031
3121
  const btn = el.querySelector(
3032
- '[aria-label*="close" i], button[aria-label*="close" i], button:has(svg), .close, [data-close], .btn-close'
3122
+ "[aria-label*=\u201Dclose\u201D i], button[aria-label*=\u201Dclose\u201D i], button:has(svg), .close, [data-close], .btn-close"
3033
3123
  );
3034
3124
  if (btn) {
3035
3125
  btn.click();
@@ -3054,8 +3144,12 @@ async function sweepOverlays(page, regex) {
3054
3144
  }
3055
3145
  return false;
3056
3146
  },
3147
+ /* v8 ignore stop */
3057
3148
  [acceptRxSource, acceptRxFlags]
3058
- ).catch(() => false);
3149
+ ).catch(
3150
+ /* v8 ignore next */
3151
+ () => false
3152
+ );
3059
3153
  }
3060
3154
  async function suppressInterferences(page, opts = {}) {
3061
3155
  const timeoutMs = opts.timeoutMs ?? 4e3;