@vitest/browser 5.0.4 → 5.1.0-beta.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/context.d.ts CHANGED
@@ -241,6 +241,33 @@ export interface UserEvent {
241
241
  * await userEvent.wheel(container, { direction: 'up', times: 5 })
242
242
  */
243
243
  wheel(element: Element | Locator, options: UserEventWheelOptions): Promise<void>
244
+ /**
245
+ * Performs one or more pointer actions.
246
+ *
247
+ * Pass a string to press or release a pointer button, an object to position the pointer and perform an action, or an array to perform actions in order.
248
+ * Key strings use the {@link https://testing-library.com/docs/user-event/pointer|`@testing-library/user-event` pointer syntax}.
249
+ *
250
+ * Unlike `@testing-library/user-event`, Vitest supports only `x` and `y` coordinates and does not support the `node` and `offset` selection fields.
251
+ *
252
+ * @param options - A pointer action or an ordered sequence of pointer actions.
253
+ * @returns A promise that resolves after all pointer actions finish.
254
+ *
255
+ * @since 5.1.0
256
+ * @experimental The Pointer API is experimental and not subject to semver.
257
+ * @see {@link https://vitest.dev/api/browser/interactivity#userevent-pointer}
258
+ *
259
+ * @example
260
+ * // Click the left mouse button.
261
+ * await userEvent.pointer({ target: button, keys: '[MouseLeft]' })
262
+ *
263
+ * @example
264
+ * // Drag from `source` to a point inside `target`.
265
+ * await userEvent.pointer([
266
+ * { target: source, keys: '[MouseLeft>]' },
267
+ * { target, coords: { x: 10, y: 10 }, keys: '[/MouseLeft]' },
268
+ * ])
269
+ */
270
+ pointer(options: UserEventPointerInput): Promise<void>
244
271
  /**
245
272
  * Choose one or more values from a select element. Uses provider's API under the hood.
246
273
  * If select doesn't have `multiple` attribute, only the first value will be selected.
@@ -439,6 +466,62 @@ export interface UserEventWheelDirectionOptions extends UserEventWheelBaseOption
439
466
  */
440
467
  export type UserEventWheelOptions = UserEventWheelDeltaOptions | UserEventWheelDirectionOptions
441
468
 
469
+ /**
470
+ * Input accepted by {@link UserEvent.pointer}.
471
+ *
472
+ * - A string presses or releases a pointer button at the current position.
473
+ * - An object with `keys` positions the pointer and performs a button action.
474
+ * - An object without `keys` moves the pointer.
475
+ * - An array performs its actions in order.
476
+ *
477
+ * @since 5.1.0
478
+ * @experimental
479
+ */
480
+ export type UserEventPointerInput = PointerActionInput | readonly PointerActionInput[]
481
+ /**
482
+ * Array form of pointer input after single-entry inputs and strings actions are expanded.
483
+ *
484
+ * @internal
485
+ */
486
+ export type UserEventPointerInputNormalized = readonly (PointerActionInputObject & {
487
+ coords?: Required<PointerCoords>
488
+ })[]
489
+
490
+ type PointerActionInput = string | PointerActionInputObject
491
+ type PointerActionInputObject = PointerActionKeys | PointerMoveAction
492
+
493
+ interface PointerActionPosition {
494
+ /**
495
+ * Element to move the pointer to before performing the action.
496
+ *
497
+ * If `coords` is omitted, the browser provider chooses a position within the element.
498
+ * If both `target` and `coords` are omitted, the action uses the last known pointer position.
499
+ */
500
+ target?: Element | Locator
501
+ /**
502
+ * Coordinates used to position the pointer.
503
+ *
504
+ * Without `target`, the values are viewport coordinates.
505
+ * With `target`, the values are pixel offsets from the target's top-left corner.
506
+ *
507
+ * This differs from `@testing-library/user-event`, where coordinates describe the final pointer position.
508
+ *
509
+ * Vitest also only supports `x` and `y`. Other coordinates, such as `clientX`, `offsetX`, `pageX`, and `screenX`, are not supported.
510
+ */
511
+ coords?: PointerCoords
512
+ }
513
+
514
+ interface PointerActionKeys extends PointerActionPosition {
515
+ keys: string
516
+ }
517
+
518
+ interface PointerMoveAction extends PointerActionPosition {}
519
+
520
+ interface PointerCoords {
521
+ x?: number
522
+ y?: number
523
+ }
524
+
442
525
  export interface LocatorOptions {
443
526
  /**
444
527
  * Whether to find an exact match: case-sensitive and whole-string. Defaults to `browser.locators.exact`, which is
@@ -5,29 +5,29 @@
5
5
  "src": "../../../../node_modules/.pnpm/rrweb-snapshot@2.1.1_patch_hash=b66b30796877352a5f887f3f4115c4e7265ddc11772af2223da4bd92293716f6/node_modules/rrweb-snapshot/dist/rrweb-snapshot.js",
6
6
  "isDynamicEntry": true
7
7
  },
8
- "_defineProperty-DgkPJYVE.js": {
9
- "file": "__vitest_browser__/defineProperty-DgkPJYVE.js",
8
+ "_defineProperty-B-KFXNh3.js": {
9
+ "file": "__vitest_browser__/defineProperty-B-KFXNh3.js",
10
10
  "name": "defineProperty"
11
11
  },
12
12
  "orchestrator.html": {
13
- "file": "__vitest_browser__/orchestrator-Czo025Y6.js",
13
+ "file": "__vitest_browser__/orchestrator-BGLAewVw.js",
14
14
  "name": "orchestrator",
15
15
  "src": "orchestrator.html",
16
16
  "isEntry": true,
17
17
  "imports": [
18
- "_defineProperty-DgkPJYVE.js"
18
+ "_defineProperty-B-KFXNh3.js"
19
19
  ],
20
20
  "dynamicImports": [
21
21
  "../../../../node_modules/.pnpm/rrweb-snapshot@2.1.1_patch_hash=b66b30796877352a5f887f3f4115c4e7265ddc11772af2223da4bd92293716f6/node_modules/rrweb-snapshot/dist/rrweb-snapshot.js"
22
22
  ]
23
23
  },
24
24
  "tester/tester.html": {
25
- "file": "__vitest_browser__/tester-BH7uPfyB.js",
25
+ "file": "__vitest_browser__/tester-DStcqUww.js",
26
26
  "name": "tester",
27
27
  "src": "tester/tester.html",
28
28
  "isEntry": true,
29
29
  "imports": [
30
- "_defineProperty-DgkPJYVE.js"
30
+ "_defineProperty-B-KFXNh3.js"
31
31
  ]
32
32
  }
33
33
  }
@@ -261,6 +261,19 @@ var moduleRunner = {
261
261
  return importId(id);
262
262
  }
263
263
  };
264
+ function supportsLateImportMaps() {
265
+ const specifier = "__vitest_import_map_probe__";
266
+ const script = document.createElement("script");
267
+ script.type = "importmap";
268
+ script.textContent = JSON.stringify({ imports: { [specifier]: `/${specifier}` } });
269
+ document.head.append(script);
270
+ try {
271
+ import.meta.resolve(specifier);
272
+ return true;
273
+ } catch {
274
+ return false;
275
+ }
276
+ }
264
277
  var now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
265
278
  function getConfig() {
266
279
  return (/* @__PURE__ */ getBrowserState()).config;
@@ -323,4 +336,4 @@ function _defineProperty(e, r, t) {
323
336
  }
324
337
 
325
338
  //#endregion
326
- export { getWorkerState as a, __vitePreload as c, basename as d, relative as f, getOrchestratorState as i, generateFileHash as l, getBrowserState as n, moduleRunner as o, resolve as p, getConfig as r, now as s, _defineProperty as t, getTestName as u };
339
+ export { getWorkerState as a, supportsLateImportMaps as c, getTestName as d, basename as f, getOrchestratorState as i, __vitePreload as l, resolve as m, getBrowserState as n, moduleRunner as o, relative as p, getConfig as r, now as s, _defineProperty as t, generateFileHash as u };
@@ -1,4 +1,4 @@
1
- import { c as __vitePreload, f as relative, l as generateFileHash, n as getBrowserState, r as getConfig, t as _defineProperty } from "./defineProperty-DgkPJYVE.js";
1
+ import { c as supportsLateImportMaps, l as __vitePreload, n as getBrowserState, p as relative, r as getConfig, t as _defineProperty, u as generateFileHash } from "./defineProperty-B-KFXNh3.js";
2
2
  import { channel, client, globalChannel } from "@vitest/browser/client";
3
3
  import { Traces } from "vitest/internal/traces";
4
4
 
@@ -38,7 +38,7 @@ var IframeOrchestrator = class {
38
38
  });
39
39
  channel.addEventListener("message", (e) => this.onIframeEvent(e));
40
40
  globalChannel.addEventListener("message", (e) => this.onGlobalChannelEvent(e));
41
- client.waitForConnection().then(() => client.rpc.onOrchestratorReady()).catch((error) => {
41
+ client.waitForConnection().then(() => client.rpc.onOrchestratorReady({ lateImportMaps: supportsLateImportMaps() })).catch((error) => {
42
42
  debug("failed to notify orchestrator readiness", error);
43
43
  });
44
44
  }
@@ -228,13 +228,14 @@ Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`);
228
228
  watchUnload(iframe, iframeId) {
229
229
  var _iframe$contentWindow;
230
230
  const loads = this.iframeLoads.get(iframe) ?? 0;
231
- (_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 || _iframe$contentWindow.addEventListener("pagehide", () => {
231
+ (_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 || _iframe$contentWindow.addEventListener("pagehide", (event) => {
232
+ if (!event.isTrusted) return;
232
233
  setTimeout(() => {
233
234
  var _this$iframeEvents$ge;
234
235
  if (this.iframes.get(iframeId) !== iframe || !((_this$iframeEvents$ge = this.iframeEvents.get(iframe)) === null || _this$iframeEvents$ge === void 0 ? void 0 : _this$iframeEvents$ge.size) || this.iframeLoads.get(iframe) !== loads) return;
235
236
  this.dispatchIframeError(this.createConnectError(iframe, this.getIframeHref(iframe)));
236
237
  }, IFRAME_UNLOAD_TIMEOUT);
237
- }, { once: true });
238
+ });
238
239
  }
239
240
  createWarningMessage(iframeId, location) {
240
241
  return `The iframe${iframeId === ID_ALL ? "" : ` for "${iframeId}"`} was reloaded ${location}. This can lead to unexpected behavior during tests, duplicated test results or tests hanging.\n\nMake sure that your test code does not change window's location, submit forms without preventing default behavior, or imports unoptimized dependencies.\nIf you are using a framework that manipulates browser history (like React Router), consider using memory-based routing for tests. If you think this is a false positive, open an issue with a reproduction: https://github.com/vitest-dev/vitest/issues/new`;
@@ -1,4 +1,4 @@
1
- import { a as getWorkerState, c as __vitePreload, d as basename, i as getOrchestratorState, n as getBrowserState, o as moduleRunner, p as resolve, r as getConfig, s as now$1, t as _defineProperty, u as getTestName } from "./defineProperty-DgkPJYVE.js";
1
+ import { a as getWorkerState, d as getTestName, f as basename, i as getOrchestratorState, l as __vitePreload, m as resolve, n as getBrowserState, o as moduleRunner, r as getConfig, s as now$1, t as _defineProperty } from "./defineProperty-B-KFXNh3.js";
2
2
  import { channel, client, globalChannel, onCancel, registerPageMarkHandler } from "@vitest/browser/client";
3
3
  import { Traces } from "vitest/internal/traces";
4
4
  import { page, server, userEvent } from "vitest/browser";
@@ -642,30 +642,38 @@ function parseStacktrace(stack, options = {}) {
642
642
  let stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack);
643
643
  const helperIndex = stacks.findLastIndex((s) => s.method.includes("__VITEST_HELPER__"));
644
644
  if (helperIndex >= 0) stacks = stacks.slice(helperIndex + 1);
645
- return stacks.map((stack) => {
646
- var _options$getSourceMap;
647
- if (options.getUrlId) stack.file = options.getUrlId(stack.file);
648
- const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file);
649
- if (!map || typeof map !== "object" || !map.version) return shouldFilter(ignoreStackEntries, stack.file) ? null : stack;
650
- const traceMap = new DecodedMap$1(map, stack.file);
651
- if (stack.line <= 0 || stack.column <= 0) return stack;
652
- const position = getOriginalPosition$1(traceMap, {
653
- line: stack.line,
654
- column: stack.column - 1
655
- });
656
- if (!position) return stack;
657
- const { line, column, source, name } = position;
658
- let file = source || stack.file;
659
- if (/\/\w:\//.test(file)) file = file.slice(1);
660
- if (shouldFilter(ignoreStackEntries, file)) return null;
661
- if (line != null && column != null) return {
662
- line,
663
- column: column + 1,
664
- file,
665
- method: name || stack.method
666
- };
667
- return stack;
668
- }).filter((s) => s != null);
645
+ if (options.firstOnly) {
646
+ for (const stack of stacks) {
647
+ const mapped = mapStackFrame(stack, options, ignoreStackEntries);
648
+ if (mapped) return [mapped];
649
+ }
650
+ return [];
651
+ }
652
+ return stacks.map((stack) => mapStackFrame(stack, options, ignoreStackEntries)).filter((s) => s != null);
653
+ }
654
+ function mapStackFrame(stack, options, ignoreStackEntries) {
655
+ var _options$getSourceMap;
656
+ if (options.getUrlId) stack.file = options.getUrlId(stack.file);
657
+ const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file);
658
+ if (!map || typeof map !== "object" || !map.version) return shouldFilter(ignoreStackEntries, stack.file) ? null : stack;
659
+ const traceMap = new DecodedMap$1(map, stack.file);
660
+ if (stack.line <= 0 || stack.column <= 0) return stack;
661
+ const position = getOriginalPosition$1(traceMap, {
662
+ line: stack.line,
663
+ column: stack.column - 1
664
+ });
665
+ if (!position) return stack;
666
+ const { line, column, source, name } = position;
667
+ let file = source || stack.file;
668
+ if (/\/\w:\//.test(file)) file = file.slice(1);
669
+ if (shouldFilter(ignoreStackEntries, file)) return null;
670
+ if (line != null && column != null) return {
671
+ line,
672
+ column: column + 1,
673
+ file,
674
+ method: name || stack.method
675
+ };
676
+ return stack;
669
677
  }
670
678
  function shouldFilter(ignoreStackEntries, file) {
671
679
  return ignoreStackEntries.some((p) => file.match(p));
@@ -819,6 +827,10 @@ function takeSnapshot(serializedLocator) {
819
827
  },
820
828
  pseudoClassIds: {}
821
829
  };
830
+ if (traceView.ariaSnapshot) {
831
+ const { generateAriaTree, renderAriaTree } = (/* @__PURE__ */ getBrowserState()).aria;
832
+ result.ariaSnapshot = renderAriaTree(generateAriaTree(document.body));
833
+ }
822
834
  for (const className of PSEUDO_CLASS_NAMES) {
823
835
  const elements = document.querySelectorAll(className);
824
836
  const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
@@ -1797,7 +1809,7 @@ var ModuleMocker = class {
1797
1809
  else if (mockType === "autospy") module = this.registry.register("autospy", rawId, resolvedId, mockUrl);
1798
1810
  else if (mockType === "redirect") module = this.registry.register("redirect", rawId, resolvedId, mockUrl, mockRedirect);
1799
1811
  else module = this.registry.register("automock", rawId, resolvedId, mockUrl);
1800
- await this.interceptor.register(module);
1812
+ await this.interceptor.register(module, importer);
1801
1813
  }).finally(() => {
1802
1814
  this.queue.delete(promise);
1803
1815
  });
@@ -1816,11 +1828,7 @@ var ModuleMocker = class {
1816
1828
  this.queue.add(promise);
1817
1829
  }
1818
1830
  wrapDynamicImport(moduleFactory) {
1819
- if (typeof moduleFactory === "function") return new Promise((resolve, reject) => {
1820
- this.prepare().finally(() => {
1821
- moduleFactory().then(resolve, reject);
1822
- });
1823
- });
1831
+ if (typeof moduleFactory === "function") return this.prepare().then(() => moduleFactory());
1824
1832
  return moduleFactory;
1825
1833
  }
1826
1834
  getMockedModuleById(id) {
@@ -1859,9 +1867,13 @@ var VitestBrowserClientMocker = class extends ModuleMocker {
1859
1867
  //#region src/client/tester/mocker-interceptor.ts
1860
1868
  function createModuleMockerInterceptor() {
1861
1869
  return {
1862
- async register(module) {
1863
- const state = /* @__PURE__ */ getBrowserState();
1864
- await rpc().registerMock(state.sessionId, module.toJSON());
1870
+ async register(module, importer) {
1871
+ const { sessionId } = /* @__PURE__ */ getBrowserState();
1872
+ const importMap = await rpc().registerMock(sessionId, module.toJSON(), {
1873
+ importer,
1874
+ testFile: (/* @__PURE__ */ getWorkerState()).filepath
1875
+ });
1876
+ if (importMap) appendImportMap(importMap);
1865
1877
  },
1866
1878
  async delete(id) {
1867
1879
  const state = /* @__PURE__ */ getBrowserState();
@@ -1873,6 +1885,16 @@ function createModuleMockerInterceptor() {
1873
1885
  }
1874
1886
  };
1875
1887
  }
1888
+ function appendImportMap(importMap) {
1889
+ const script = document.createElement("script");
1890
+ script.type = "importmap";
1891
+ script.textContent = JSON.stringify(importMap);
1892
+ document.head.append(script);
1893
+ for (const [specifier, url] of Object.entries(importMap.imports)) {
1894
+ const expected = new URL(url, location.href).href;
1895
+ if (import.meta.resolve(specifier) !== expected) throw new Error(`Cannot mock "${specifier}" with an import map because the browser kept its original URL. The module was already imported before vi.mock was registered, for example by a setup file or by an earlier test file when "isolate" is false.`);
1896
+ }
1897
+ }
1876
1898
  function rpc() {
1877
1899
  return (/* @__PURE__ */ getWorkerState()).rpc;
1878
1900
  }
@@ -1893,7 +1915,8 @@ var ACTION_TRACE_COMMANDS = new Set([
1893
1915
  "__vitest_upload",
1894
1916
  "__vitest_tab",
1895
1917
  "__vitest_keyboard",
1896
- "__vitest_takeScreenshot"
1918
+ "__vitest_takeScreenshot",
1919
+ "__vitest_pointer"
1897
1920
  ]);
1898
1921
  var CommandsManager = class {
1899
1922
  constructor() {
@@ -13,11 +13,7 @@
13
13
  const viteModule = evaluatedModules.ensureModule(moduleId, moduleId)
14
14
 
15
15
  viteModule.evaluated = false
16
- viteModule.promise = new Promise((resolve, reject) => {
17
- __vitest_mocker__.prepare().finally(() => {
18
- moduleCallback().then(resolve, reject)
19
- });
20
- });
16
+ viteModule.promise = __vitest_mocker__.prepare().then(() => moduleCallback())
21
17
  return viteModule.promise.finally(() => {
22
18
  viteModule.evaluated = true
23
19
  viteModule.promise = undefined
@@ -27,8 +27,8 @@
27
27
  }
28
28
  </style>
29
29
  {__VITEST_INJECTOR__} {__VITEST_ERROR_CATCHER__} {__VITEST_SCRIPTS__}
30
- <script type="module" crossorigin src="/__vitest_browser__/orchestrator-Czo025Y6.js"></script>
31
- <link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-DgkPJYVE.js">
30
+ <script type="module" crossorigin src="/__vitest_browser__/orchestrator-BGLAewVw.js"></script>
31
+ <link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-B-KFXNh3.js">
32
32
  </head>
33
33
  <body>
34
34
  <div id="vitest-tester"></div>
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vitest Browser Tester</title>
8
- <script type="module" crossorigin src="/__vitest_browser__/tester-BH7uPfyB.js"></script>
9
- <link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-DgkPJYVE.js">
8
+ <script type="module" crossorigin src="/__vitest_browser__/tester-DStcqUww.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-B-KFXNh3.js">
10
10
  </head>
11
11
  <body>
12
12
  </body>
@@ -44,6 +44,7 @@ interface TraceSnapshot {
44
44
  selectorResolution?: BrowserTraceSelectorResolution;
45
45
  selectorError?: string;
46
46
  pseudoClassIds: Record<PseudoClassName, number[]>;
47
+ ariaSnapshot?: string;
47
48
  }
48
49
  declare const PSEUDO_CLASS_NAMES: readonly [":hover", ":active", ":focus", ":focus-visible", ":focus-within", ":popover-open"];
49
50
  type PseudoClassName = (typeof PSEUDO_CLASS_NAMES)[number];
package/dist/context.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { vi } from 'vitest';
2
- import { __INTERNAL, stringify } from 'vitest/internal/browser';
2
+ import { getSafeTimers, __INTERNAL, stringify } from 'vitest/internal/browser';
3
3
 
4
4
  const now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
5
5
  function ensureAwaited(promise) {
@@ -60,6 +60,24 @@ function resolveActionTimeout(options) {
60
60
  }
61
61
  return getBrowserState().runner._deadline?.derive();
62
62
  }
63
+ const FAKE_TIMERS_TICK = 50;
64
+ /**
65
+ * Wraps provider commands that wait for an element. The provider waits in real time,
66
+ * so fake timers must keep moving for the page to render it. Commands that act right
67
+ * away, such as `keyboard` and `tab`, are not wrapped.
68
+ */
69
+ function advanceFakeTimersWhilePending(promise) {
70
+ if (!vi.isFakeTimers()) {
71
+ return promise;
72
+ }
73
+ const { setInterval, clearInterval } = getSafeTimers();
74
+ const interval = setInterval(() => {
75
+ if (vi.isFakeTimers()) {
76
+ vi.advanceTimersByTime(FAKE_TIMERS_TICK);
77
+ }
78
+ }, FAKE_TIMERS_TICK);
79
+ return promise.finally(() => clearInterval(interval));
80
+ }
63
81
  /**
64
82
  * A browser command that the test awaits. The action derives its own timeout
65
83
  * from the running task, so it fails with a descriptive error before the task does.
@@ -98,7 +116,7 @@ class Action {
98
116
  timeout
99
117
  };
100
118
  const args = typeof this.#args === "function" ? await this.#args(options) : [...this.#args, options];
101
- const promise = getBrowserState().commands.triggerCommand(this.#command, args, this.#errorSource);
119
+ const promise = advanceFakeTimersWhilePending(getBrowserState().commands.triggerCommand(this.#command, args, this.#errorSource));
102
120
  const deadline = getBrowserState().runner._deadline;
103
121
  return deadline && timeout != null ? deadline.track(this.#command.slice("__vitest_".length), promise, timeout, this.#errorSource) : promise;
104
122
  }
@@ -202,6 +220,10 @@ function takeSnapshot(serializedLocator) {
202
220
  },
203
221
  pseudoClassIds: {}
204
222
  };
223
+ if (traceView.ariaSnapshot) {
224
+ const { generateAriaTree, renderAriaTree } = getBrowserState().aria;
225
+ result.ariaSnapshot = renderAriaTree(generateAriaTree(document.body));
226
+ }
205
227
  for (const className of PSEUDO_CLASS_NAMES) {
206
228
  const elements = document.querySelectorAll(className);
207
229
  const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
@@ -297,6 +319,24 @@ function getParent(el) {
297
319
  }
298
320
  return parent;
299
321
  }
322
+ function getIframe() {
323
+ const iframe = window.frameElement;
324
+ if (!iframe) {
325
+ throw new Error(`Cannot find iframe element. This is a bug in Vitest. Please, open a new issue with reproduction.`);
326
+ }
327
+ return iframe;
328
+ }
329
+ function getIframeScale() {
330
+ const iframe = getIframe();
331
+ // DOMMatrix parses the computed 2D transform matrix [a, b, c, d, e, f]
332
+ // `a` and `d` are the x and y scale factors - since we only apply uniform scaling, `a === d`
333
+ const scale = new DOMMatrix(getComputedStyle(iframe).transform).a;
334
+ return scale;
335
+ }
336
+ function getIframeOffset() {
337
+ const iframe = getIframe();
338
+ return iframe.getBoundingClientRect();
339
+ }
300
340
  const provider$1 = getBrowserState().provider;
301
341
  const kElementLocator = Symbol.for("$$vitest:locator-resolved");
302
342
  async function serializeElement(elementOrLocator, options) {
@@ -359,7 +399,6 @@ function resolveUserEventWheelOptions(options) {
359
399
  };
360
400
  }
361
401
 
362
- // this file should not import anything directly, only types and utils
363
402
  // @ts-expect-error not typed global
364
403
  const provider = __vitest_browser_runner__.provider;
365
404
  const sessionId = getBrowserState().sessionId;
@@ -372,6 +411,10 @@ function createUserEvent(__tl_user_event_base__, options) {
372
411
  return createPreviewUserEvent(__tl_user_event_base__, options ?? {});
373
412
  }
374
413
  const keyboard = { unreleased: [] };
414
+ const pointerState = {
415
+ coords: undefined,
416
+ target: undefined
417
+ };
375
418
  // https://playwright.dev/docs/api/class-keyboard
376
419
  // https://webdriver.io/docs/api/browser/keys/
377
420
  const modifier = provider === "playwright" ? "ControlOrMeta" : provider === "webdriverio" ? "Ctrl" : "Control";
@@ -401,6 +444,33 @@ function createUserEvent(__tl_user_event_base__, options) {
401
444
  wheel(elementOrOptions, options) {
402
445
  return convertToLocator(elementOrOptions).wheel(options);
403
446
  },
447
+ pointer(input) {
448
+ return ensureAwaited(async () => {
449
+ const scale = getIframeScale();
450
+ const offset = getIframeOffset();
451
+ const inputArray = Array.isArray(input) ? input : [input];
452
+ const serializedInputArray = await Promise.all(inputArray.map(async (input) => {
453
+ if (typeof input === "string") {
454
+ return { keys: input };
455
+ }
456
+ return {
457
+ ...input,
458
+ target: input.target && await serializeElement(input.target),
459
+ coords: input.coords && {
460
+ x: input.coords.x ? input.coords.x * scale + (input.target ? 0 : offset.x) : 0,
461
+ y: input.coords.y ? input.coords.y * scale + (input.target ? 0 : offset.y) : 0
462
+ }
463
+ };
464
+ }));
465
+ const { coords, target, unreleased } = await advanceFakeTimersWhilePending(triggerCommand("__vitest_pointer", [serializedInputArray, {
466
+ ...pointerState,
467
+ unreleased: keyboard.unreleased
468
+ }]));
469
+ pointerState.target = target;
470
+ pointerState.coords = coords;
471
+ keyboard.unreleased = unreleased;
472
+ });
473
+ },
404
474
  selectOptions(element, value, options) {
405
475
  return convertToLocator(element).selectOptions(value, options);
406
476
  },
@@ -429,14 +499,14 @@ function createUserEvent(__tl_user_event_base__, options) {
429
499
  type(element, text, options) {
430
500
  return ensureAwaited(async (error) => {
431
501
  const serializedElement = await serializeElement(element, options);
432
- const { unreleased } = await triggerCommand("__vitest_type", [
502
+ const { unreleased } = await advanceFakeTimersWhilePending(triggerCommand("__vitest_type", [
433
503
  serializedElement,
434
504
  text,
435
505
  {
436
506
  ...options,
437
507
  unreleased: keyboard.unreleased
438
508
  }
439
- ], error);
509
+ ], error));
440
510
  keyboard.unreleased = unreleased;
441
511
  });
442
512
  },
@@ -563,6 +633,33 @@ function createPreviewUserEvent(userEventBase, options) {
563
633
  for (let count = 0; count < times; count += 1) {
564
634
  resolvedElement.dispatchEvent(wheelEvent);
565
635
  }
636
+ },
637
+ async pointer(input) {
638
+ const inputArray = Array.isArray(input) ? input : [input];
639
+ const normalizedInput = inputArray.map((input) => {
640
+ if (typeof input === "string") {
641
+ return { keys: input };
642
+ }
643
+ const target = input.target;
644
+ return {
645
+ ...input,
646
+ get target() {
647
+ const value = isLocator(target) ? target.element() : target;
648
+ Reflect.defineProperty(this, "target", {
649
+ enumerable: true,
650
+ configurable: true,
651
+ writable: true,
652
+ value
653
+ });
654
+ return value;
655
+ },
656
+ coords: input.coords && {
657
+ x: input.coords.x ?? 0,
658
+ y: input.coords.y ?? 0
659
+ }
660
+ };
661
+ });
662
+ await userEvent.pointer(normalizedInput);
566
663
  }
567
664
  };
568
665
  for (const [name, fn] of Object.entries(vitestUserEvent)) {
@@ -1,4 +1,4 @@
1
- import{Snapshots as e,recordArtifact as t,expect as n,chai as r}from"vitest";import{getType as i}from"vitest/internal/browser";import{i as a,g as o,n as s,a as c,k as l,b as u,c as d,d as f,e as ee,f as te,h as ne,j as re,l as ie,m as ae,o as oe,p as se,q as ce,r as p,_ as m,s as h,t as g,u as _,L as v,v as le,w as ue,x as de,y as fe,z as pe,A as me,B as he,C as ge,D as _e,E as ve}from"./locators-BHr21v4S.js";import{server as ye}from"vitest/browser";var be=Object.defineProperty,xe=(e,t)=>{let n={};for(var r in e)be(n,r,{get:e[r],enumerable:!0});return be(n,Symbol.toStringTag,{value:`Module`}),n};function Se(e,t,n={}){let r=Ce(e,t,n);if(r.errors.length)throw Error(r.errors[0].message);return r.fragment}function Ce(e,t,n={}){let r=new e.LineCounter,i={keepSourceTokens:!0,lineCounter:r,...n},a=e.parseDocument(t,i),o=[],s=e=>[r.linePos(e[0]),r.linePos(e[1])],c=e=>{o.push({message:e.message,range:[r.linePos(e.pos[0]),r.linePos(e.pos[1])]})},l=(t,n)=>{for(let r of n.items){if(r instanceof e.Scalar&&typeof r.value==`string`){let e=Ee.parse(r,i,o);e&&(t.children=t.children||[],t.children.push(e));continue}if(r instanceof e.YAMLMap){u(t,r);continue}o.push({message:`Sequence items should be strings or maps`,range:s(r.range||n.range)})}},u=(t,n)=>{for(let r of n.items){if(t.children=t.children||[],!(r.key instanceof e.Scalar&&typeof r.key.value==`string`)){o.push({message:`Only string keys are supported`,range:s(r.key.range||n.range)});continue}let a=r.key,c=r.value;if(a.value===`text`){if(!(c instanceof e.Scalar&&typeof c.value==`string`)){o.push({message:`Text value should be a string`,range:s(r.value.range||n.range)});continue}t.children.push({kind:`text`,text:y(c.value)});continue}if(a.value===`/children`){if(!(c instanceof e.Scalar&&typeof c.value==`string`)||c.value!==`contain`&&c.value!==`equal`&&c.value!==`deep-equal`){o.push({message:`Strict value should be "contain", "equal" or "deep-equal"`,range:s(r.value.range||n.range)});continue}t.containerMode=c.value;continue}if(a.value.startsWith(`/`)){if(!(c instanceof e.Scalar&&typeof c.value==`string`)){o.push({message:`Property value should be a string`,range:s(r.value.range||n.range)});continue}t.props=t.props??{},t.props[a.value.slice(1)]=y(c.value);continue}let u=Ee.parse(a,i,o);if(u){if(c instanceof e.Scalar){let e=typeof c.value;if(e!==`string`&&e!==`number`&&e!==`boolean`){o.push({message:`Node value should be a string or a sequence`,range:s(r.value.range||n.range)});continue}t.children.push({...u,children:[{kind:`text`,text:y(String(c.value))}]});continue}if(c instanceof e.YAMLSeq){t.children.push(u),l(u,c);continue}o.push({message:`Map values should be strings or sequences`,range:s(r.value.range||n.range)})}}},d={kind:`role`,role:`fragment`};return a.errors.forEach(c),o.length?{errors:o,fragment:d}:a.contents?(a.contents instanceof e.YAMLSeq||o.push({message:`Aria snapshot must be a YAML sequence, elements starting with " -"`,range:s(a.contents.range)}),o.length?{errors:o,fragment:d}:(l(d,a.contents),o.length?{errors:o,fragment:we}:d.children?.length===1&&(!d.containerMode||d.containerMode===`contain`)?{fragment:d.children[0],errors:[]}:{fragment:d,errors:[]})):{fragment:d,errors:[]}}const we={kind:`role`,role:`fragment`};function Te(e){return e.replace(/[\u200b\u00ad]/g,``).replace(/[\r\n\s\t]+/g,` `).trim()}function y(e){return{raw:e,normalized:Te(e)}}var Ee=class e{static parse(t,n,r){try{return new e(t.value)._parse()}catch(e){if(e instanceof b){let i=n.prettyErrors===!1?e.message:`${e.message}:\n\n${t.value}\n${` `.repeat(e.pos)}^\n`;return r.push({message:i,range:[n.lineCounter.linePos(t.range[0]),n.lineCounter.linePos(t.range[0]+e.pos)]}),null}throw e}}constructor(e){m(this,`_input`,void 0),m(this,`_pos`,void 0),m(this,`_length`,void 0),this._input=e,this._pos=0,this._length=e.length}_peek(){return this._input[this._pos]||``}_next(){return this._pos<this._length?this._input[this._pos++]:null}_eof(){return this._pos>=this._length}_isWhitespace(){return!this._eof()&&/\s/.test(this._peek())}_skipWhitespace(){for(;this._isWhitespace();)this._pos++}_readIdentifier(e){this._eof()&&this._throwError(`Unexpected end of input when expecting ${e}`);let t=this._pos;for(;!this._eof()&&/[a-zA-Z]/.test(this._peek());)this._pos++;return this._input.slice(t,this._pos)}_readString(){let e=``,t=!1;for(;!this._eof();){let n=this._next();if(t)e+=n,t=!1;else if(n===`\\`)t=!0;else if(n===`"`)return e;else e+=n}this._throwError(`Unterminated string`)}_throwError(e,t=0){throw new b(e,t||this._pos)}_readRegex(){let e=``,t=!1,n=!1;for(;!this._eof();){let r=this._next();if(t)e+=r,t=!1;else if(r===`\\`)t=!0,e+=r;else if(r===`/`&&!n)return{pattern:e};else r===`[`?(n=!0,e+=r):r===`]`&&n?(e+=r,n=!1):e+=r}this._throwError(`Unterminated regex`)}_readStringOrRegex(){let e=this._peek();return e===`"`?(this._next(),Te(this._readString())):e===`/`?(this._next(),this._readRegex()):null}_readAttributes(e){let t=this._pos;for(;this._skipWhitespace(),this._peek()===`[`;){this._next(),this._skipWhitespace(),t=this._pos;let n=this._readIdentifier(`attribute`);this._skipWhitespace();let r=``;if(this._peek()===`=`)for(this._next(),this._skipWhitespace(),t=this._pos;this._peek()!==`]`&&!this._isWhitespace()&&!this._eof();)r+=this._next();this._skipWhitespace(),this._peek()!==`]`&&this._throwError(`Expected ]`),this._next(),this._applyAttribute(e,n,r||`true`,t)}}_parse(){this._skipWhitespace();let e=this._readIdentifier(`role`);e===`fragment`&&this._throwError(`Invalid role "fragment"`),this._skipWhitespace();let t={kind:`role`,role:e,name:this._readStringOrRegex()||void 0};return this._readAttributes(t),this._skipWhitespace(),this._eof()||this._throwError(`Unexpected input`),t}_applyAttribute(e,t,n,r){if(t===`checked`){this._assert(n===`true`||n===`false`||n===`mixed`,`Value of "checked" attribute must be a boolean or "mixed"`,r),e.checked=n===`true`||n!==`false`&&`mixed`;return}if(t===`disabled`){this._assert(n===`true`||n===`false`,`Value of "disabled" attribute must be a boolean`,r),e.disabled=n===`true`;return}if(t===`expanded`){this._assert(n===`true`||n===`false`,`Value of "expanded" attribute must be a boolean`,r),e.expanded=n===`true`;return}if(t===`active`){this._assert(n===`true`||n===`false`,`Value of "active" attribute must be a boolean`,r),e.active=n===`true`;return}if(t===`level`){this._assert(!Number.isNaN(Number(n)),`Value of "level" attribute must be a number`,r),e.level=Number(n);return}if(t===`pressed`){this._assert(n===`true`||n===`false`||n===`mixed`,`Value of "pressed" attribute must be a boolean or "mixed"`,r),e.pressed=n===`true`||n!==`false`&&`mixed`;return}if(t===`selected`){this._assert(n===`true`||n===`false`,`Value of "selected" attribute must be a boolean`,r),e.selected=n===`true`;return}this._assert(!1,`Unsupported attribute [${t}]`,r)}_assert(e,t,n){e||this._throwError(t||`Assertion error`,n)}},b=class extends Error{constructor(e,t){super(e),m(this,`pos`,void 0),this.pos=t}};function x(e,t){return t?e?typeof t==`string`?e===t:!!e.match(new RegExp(t.pattern)):!1:!0}function S(e,t){if(!t?.normalized)return!0;if(!e)return!1;if(e===t.normalized||e===t.raw)return!0;let n=w(t);return n?!!e.match(n):!1}const C=Symbol(`cachedRegex`);function w(e){if(e[C]!==void 0)return e[C];let{raw:t}=e,n=t.startsWith(`/`)&&t.endsWith(`/`)&&t.length>1,r;try{r=n?new RegExp(t.slice(1,-1)):null}catch{r=null}return e[C]=r,r}function T(e,t,n){if(typeof e==`string`&&t.kind===`text`)return S(e,t.text);if(typeof e!=`object`||!e||t.kind!==`role`||t.role!==`fragment`&&t.role!==e.role||t.checked!==void 0&&t.checked!==e.checked||t.disabled!==void 0&&t.disabled!==e.disabled||t.expanded!==void 0&&t.expanded!==e.expanded||t.level!==void 0&&t.level!==e.level||t.pressed!==void 0&&t.pressed!==e.pressed||t.selected!==void 0&&t.selected!==e.selected||!x(e.name,t.name))return!1;if(t.props){for(let[n,r]of Object.entries(t.props))if(!S(e.props[n]||``,r))return!1}return t.containerMode===`contain`?D(e.children||[],t.children||[]):t.containerMode===`equal`?E(e.children||[],t.children||[],!1):t.containerMode===`deep-equal`||n?E(e.children||[],t.children||[],!0):D(e.children||[],t.children||[])}function E(e,t,n){if(t.length!==e.length)return!1;for(let r=0;r<t.length;++r)if(!T(e[r],t[r],n))return!1;return!0}function D(e,t){if(t.length>e.length)return!1;let n=e.slice(),r=t.slice();for(let e of r){let t=n.shift();for(;t&&!T(t,e,!1);)t=n.shift();if(!t)return!1}return!0}var De=xe({LineCounter:()=>Oe,Scalar:()=>O,YAMLError:()=>j,YAMLMap:()=>k,YAMLSeq:()=>A,parseDocument:()=>ke}),O=class{constructor(e,t=[0,0,0]){m(this,`value`,void 0),m(this,`range`,void 0),this.value=e,this.range=t}},k=class{constructor(e=[0,0,0]){m(this,`items`,void 0),m(this,`range`,void 0),this.items=[],this.range=e}},A=class{constructor(e=[0,0,0]){m(this,`items`,void 0),m(this,`range`,void 0),this.items=[],this.range=e}},Oe=class{constructor(){m(this,`lineStarts`,[0])}addNewLine(e){e>this.lineStarts[this.lineStarts.length-1]&&this.lineStarts.push(e)}linePos(e){let t=0,n=this.lineStarts.length-1;for(;t<n;){let r=t+n+1>>1;this.lineStarts[r]<=e?t=r:n=r-1}return{line:t+1,col:e-this.lineStarts[t]+1}}},j=class extends Error{constructor(e,t){super(e),m(this,`pos`,void 0),this.pos=t}};function ke(e,t={}){let n=t.lineCounter,r=[];if(n)for(let t=0;t<e.length;t++)e[t]===`
1
+ import{Snapshots as e,recordArtifact as t,expect as n,chai as r}from"vitest";import{getType as i}from"vitest/internal/browser";import{i as a,g as o,n as s,a as c,k as l,b as u,c as d,d as f,e as ee,f as te,h as ne,j as re,l as ie,m as ae,o as oe,p as se,q as ce,r as p,_ as m,s as h,t as g,u as _,L as v,v as le,w as ue,x as de,y as fe,z as pe,A as me,B as he,C as ge,D as _e,E as ve}from"./locators-7Z9PPr-9.js";import{server as ye}from"vitest/browser";var be=Object.defineProperty,xe=(e,t)=>{let n={};for(var r in e)be(n,r,{get:e[r],enumerable:!0});return be(n,Symbol.toStringTag,{value:`Module`}),n};function Se(e,t,n={}){let r=Ce(e,t,n);if(r.errors.length)throw Error(r.errors[0].message);return r.fragment}function Ce(e,t,n={}){let r=new e.LineCounter,i={keepSourceTokens:!0,lineCounter:r,...n},a=e.parseDocument(t,i),o=[],s=e=>[r.linePos(e[0]),r.linePos(e[1])],c=e=>{o.push({message:e.message,range:[r.linePos(e.pos[0]),r.linePos(e.pos[1])]})},l=(t,n)=>{for(let r of n.items){if(r instanceof e.Scalar&&typeof r.value==`string`){let e=Ee.parse(r,i,o);e&&(t.children=t.children||[],t.children.push(e));continue}if(r instanceof e.YAMLMap){u(t,r);continue}o.push({message:`Sequence items should be strings or maps`,range:s(r.range||n.range)})}},u=(t,n)=>{for(let r of n.items){if(t.children=t.children||[],!(r.key instanceof e.Scalar&&typeof r.key.value==`string`)){o.push({message:`Only string keys are supported`,range:s(r.key.range||n.range)});continue}let a=r.key,c=r.value;if(a.value===`text`){if(!(c instanceof e.Scalar&&typeof c.value==`string`)){o.push({message:`Text value should be a string`,range:s(r.value.range||n.range)});continue}t.children.push({kind:`text`,text:y(c.value)});continue}if(a.value===`/children`){if(!(c instanceof e.Scalar&&typeof c.value==`string`)||c.value!==`contain`&&c.value!==`equal`&&c.value!==`deep-equal`){o.push({message:`Strict value should be "contain", "equal" or "deep-equal"`,range:s(r.value.range||n.range)});continue}t.containerMode=c.value;continue}if(a.value.startsWith(`/`)){if(!(c instanceof e.Scalar&&typeof c.value==`string`)){o.push({message:`Property value should be a string`,range:s(r.value.range||n.range)});continue}t.props=t.props??{},t.props[a.value.slice(1)]=y(c.value);continue}let u=Ee.parse(a,i,o);if(u){if(c instanceof e.Scalar){let e=typeof c.value;if(e!==`string`&&e!==`number`&&e!==`boolean`){o.push({message:`Node value should be a string or a sequence`,range:s(r.value.range||n.range)});continue}t.children.push({...u,children:[{kind:`text`,text:y(String(c.value))}]});continue}if(c instanceof e.YAMLSeq){t.children.push(u),l(u,c);continue}o.push({message:`Map values should be strings or sequences`,range:s(r.value.range||n.range)})}}},d={kind:`role`,role:`fragment`};return a.errors.forEach(c),o.length?{errors:o,fragment:d}:a.contents?(a.contents instanceof e.YAMLSeq||o.push({message:`Aria snapshot must be a YAML sequence, elements starting with " -"`,range:s(a.contents.range)}),o.length?{errors:o,fragment:d}:(l(d,a.contents),o.length?{errors:o,fragment:we}:d.children?.length===1&&(!d.containerMode||d.containerMode===`contain`)?{fragment:d.children[0],errors:[]}:{fragment:d,errors:[]})):{fragment:d,errors:[]}}const we={kind:`role`,role:`fragment`};function Te(e){return e.replace(/[\u200b\u00ad]/g,``).replace(/[\r\n\s\t]+/g,` `).trim()}function y(e){return{raw:e,normalized:Te(e)}}var Ee=class e{static parse(t,n,r){try{return new e(t.value)._parse()}catch(e){if(e instanceof b){let i=n.prettyErrors===!1?e.message:`${e.message}:\n\n${t.value}\n${` `.repeat(e.pos)}^\n`;return r.push({message:i,range:[n.lineCounter.linePos(t.range[0]),n.lineCounter.linePos(t.range[0]+e.pos)]}),null}throw e}}constructor(e){m(this,`_input`,void 0),m(this,`_pos`,void 0),m(this,`_length`,void 0),this._input=e,this._pos=0,this._length=e.length}_peek(){return this._input[this._pos]||``}_next(){return this._pos<this._length?this._input[this._pos++]:null}_eof(){return this._pos>=this._length}_isWhitespace(){return!this._eof()&&/\s/.test(this._peek())}_skipWhitespace(){for(;this._isWhitespace();)this._pos++}_readIdentifier(e){this._eof()&&this._throwError(`Unexpected end of input when expecting ${e}`);let t=this._pos;for(;!this._eof()&&/[a-zA-Z]/.test(this._peek());)this._pos++;return this._input.slice(t,this._pos)}_readString(){let e=``,t=!1;for(;!this._eof();){let n=this._next();if(t)e+=n,t=!1;else if(n===`\\`)t=!0;else if(n===`"`)return e;else e+=n}this._throwError(`Unterminated string`)}_throwError(e,t=0){throw new b(e,t||this._pos)}_readRegex(){let e=``,t=!1,n=!1;for(;!this._eof();){let r=this._next();if(t)e+=r,t=!1;else if(r===`\\`)t=!0,e+=r;else if(r===`/`&&!n)return{pattern:e};else r===`[`?(n=!0,e+=r):r===`]`&&n?(e+=r,n=!1):e+=r}this._throwError(`Unterminated regex`)}_readStringOrRegex(){let e=this._peek();return e===`"`?(this._next(),Te(this._readString())):e===`/`?(this._next(),this._readRegex()):null}_readAttributes(e){let t=this._pos;for(;this._skipWhitespace(),this._peek()===`[`;){this._next(),this._skipWhitespace(),t=this._pos;let n=this._readIdentifier(`attribute`);this._skipWhitespace();let r=``;if(this._peek()===`=`)for(this._next(),this._skipWhitespace(),t=this._pos;this._peek()!==`]`&&!this._isWhitespace()&&!this._eof();)r+=this._next();this._skipWhitespace(),this._peek()!==`]`&&this._throwError(`Expected ]`),this._next(),this._applyAttribute(e,n,r||`true`,t)}}_parse(){this._skipWhitespace();let e=this._readIdentifier(`role`);e===`fragment`&&this._throwError(`Invalid role "fragment"`),this._skipWhitespace();let t={kind:`role`,role:e,name:this._readStringOrRegex()||void 0};return this._readAttributes(t),this._skipWhitespace(),this._eof()||this._throwError(`Unexpected input`),t}_applyAttribute(e,t,n,r){if(t===`checked`){this._assert(n===`true`||n===`false`||n===`mixed`,`Value of "checked" attribute must be a boolean or "mixed"`,r),e.checked=n===`true`||n!==`false`&&`mixed`;return}if(t===`disabled`){this._assert(n===`true`||n===`false`,`Value of "disabled" attribute must be a boolean`,r),e.disabled=n===`true`;return}if(t===`expanded`){this._assert(n===`true`||n===`false`,`Value of "expanded" attribute must be a boolean`,r),e.expanded=n===`true`;return}if(t===`active`){this._assert(n===`true`||n===`false`,`Value of "active" attribute must be a boolean`,r),e.active=n===`true`;return}if(t===`level`){this._assert(!Number.isNaN(Number(n)),`Value of "level" attribute must be a number`,r),e.level=Number(n);return}if(t===`pressed`){this._assert(n===`true`||n===`false`||n===`mixed`,`Value of "pressed" attribute must be a boolean or "mixed"`,r),e.pressed=n===`true`||n!==`false`&&`mixed`;return}if(t===`selected`){this._assert(n===`true`||n===`false`,`Value of "selected" attribute must be a boolean`,r),e.selected=n===`true`;return}this._assert(!1,`Unsupported attribute [${t}]`,r)}_assert(e,t,n){e||this._throwError(t||`Assertion error`,n)}},b=class extends Error{constructor(e,t){super(e),m(this,`pos`,void 0),this.pos=t}};function x(e,t){return t?e?typeof t==`string`?e===t:!!e.match(new RegExp(t.pattern)):!1:!0}function S(e,t){if(!t?.normalized)return!0;if(!e)return!1;if(e===t.normalized||e===t.raw)return!0;let n=w(t);return n?!!e.match(n):!1}const C=Symbol(`cachedRegex`);function w(e){if(e[C]!==void 0)return e[C];let{raw:t}=e,n=t.startsWith(`/`)&&t.endsWith(`/`)&&t.length>1,r;try{r=n?new RegExp(t.slice(1,-1)):null}catch{r=null}return e[C]=r,r}function T(e,t,n){if(typeof e==`string`&&t.kind===`text`)return S(e,t.text);if(typeof e!=`object`||!e||t.kind!==`role`||t.role!==`fragment`&&t.role!==e.role||t.checked!==void 0&&t.checked!==e.checked||t.disabled!==void 0&&t.disabled!==e.disabled||t.expanded!==void 0&&t.expanded!==e.expanded||t.level!==void 0&&t.level!==e.level||t.pressed!==void 0&&t.pressed!==e.pressed||t.selected!==void 0&&t.selected!==e.selected||!x(e.name,t.name))return!1;if(t.props){for(let[n,r]of Object.entries(t.props))if(!S(e.props[n]||``,r))return!1}return t.containerMode===`contain`?D(e.children||[],t.children||[]):t.containerMode===`equal`?E(e.children||[],t.children||[],!1):t.containerMode===`deep-equal`||n?E(e.children||[],t.children||[],!0):D(e.children||[],t.children||[])}function E(e,t,n){if(t.length!==e.length)return!1;for(let r=0;r<t.length;++r)if(!T(e[r],t[r],n))return!1;return!0}function D(e,t){if(t.length>e.length)return!1;let n=e.slice(),r=t.slice();for(let e of r){let t=n.shift();for(;t&&!T(t,e,!1);)t=n.shift();if(!t)return!1}return!0}var De=xe({LineCounter:()=>Oe,Scalar:()=>O,YAMLError:()=>j,YAMLMap:()=>k,YAMLSeq:()=>A,parseDocument:()=>ke}),O=class{constructor(e,t=[0,0,0]){m(this,`value`,void 0),m(this,`range`,void 0),this.value=e,this.range=t}},k=class{constructor(e=[0,0,0]){m(this,`items`,void 0),m(this,`range`,void 0),this.items=[],this.range=e}},A=class{constructor(e=[0,0,0]){m(this,`items`,void 0),m(this,`range`,void 0),this.items=[],this.range=e}},Oe=class{constructor(){m(this,`lineStarts`,[0])}addNewLine(e){e>this.lineStarts[this.lineStarts.length-1]&&this.lineStarts.push(e)}linePos(e){let t=0,n=this.lineStarts.length-1;for(;t<n;){let r=t+n+1>>1;this.lineStarts[r]<=e?t=r:n=r-1}return{line:t+1,col:e-this.lineStarts[t]+1}}},j=class extends Error{constructor(e,t){super(e),m(this,`pos`,void 0),this.pos=t}};function ke(e,t={}){let n=t.lineCounter,r=[];if(n)for(let t=0;t<e.length;t++)e[t]===`
2
2
  `&&n.addNewLine(t+1);try{return{contents:new Ae(e,r).parseRoot(),errors:r}}catch(e){if(e instanceof j)return r.push(e),{contents:null,errors:r};throw e}}var Ae=class{constructor(e,t){m(this,`lines`,void 0),m(this,`pos`,void 0),m(this,`text`,void 0),m(this,`errors`,void 0),this.text=e,this.errors=t,this.lines=[],this.pos=0;let n=0,r=e.split(`
3
3
  `);for(let e of r){let t=e.replace(/\r$/,``),r=t.replace(/^\s+/,``),i=t.length-r.length;this.lines.push({indent:i,content:r,offset:n+i,lineOffset:n,raw:t}),n+=e.length+1}for(;this.lines.length>0&&this.lines[this.lines.length-1].content===``;)this.lines.pop()}parseRoot(){if(this.lines.length===0)return null;let e=this.parseNode(0);if(this.skipEmpty(),this.pos<this.lines.length){let e=this.currentLine();this.addError(`Unexpected scalar at node end`,e.offset)}return e}currentLine(){return this.lines[this.pos]}parseNode(e){this.skipEmpty();let t=this.currentLine();return!t||t.indent<e?null:t.content.startsWith(`- `)||t.content===`-`?this.parseSequence(t.indent):this.isMapEntry(t.content)?this.parseMap(t.indent):(this.pos++,this.parseScalarValue(t.content,t.offset,t))}parseSequence(e){let t=this.currentLine(),n=new A([t.offset-t.indent,0,0]),r=t.offset;for(;this.pos<this.lines.length;){this.skipEmpty();let t=this.currentLine();if(!t||t.indent<e)break;if(t.indent>e){this.addError(`Bad indentation of a sequence entry`,t.offset);break}if(!t.content.startsWith(`- `)&&t.content!==`-`)break;let i=t.content===`-`?1:2,a=t.content.slice(i),o=t.offset+i;if(this.pos++,a===``||a.trim()===``){let t=this.parseNode(e+1);t&&(n.items.push(t),r=this.peekLastOffset())}else if(this.isMapEntry(a)){let s=this.parseInlineMap(a,o,e+i,t);n.items.push(s),r=s.range[2]}else{let e=this.parseScalarValue(a,o,t);n.items.push(e),r=e.range[2]}}return n.range[1]=r,n.range[2]=r,n}parseMap(e){let t=this.currentLine(),n=new k([t.offset-t.indent,0,0]),r=t.offset;for(;this.pos<this.lines.length;){this.skipEmpty();let t=this.currentLine();if(!t||t.indent<e)break;if(t.indent>e){this.addError(`Bad indentation of a mapping entry`,t.offset);break}if(!this.isMapEntry(t.content))break;let{key:i,valueStr:a,colonOffset:o,valueOffset:s}=this.splitMapEntry(t.content,t.offset),c=new O(i,[t.offset,t.offset+i.length,o]);this.pos++;let l;l=a===``?this.parseMapValue(e,o):this.parseScalarValue(a.trim(),s,t),n.items.push({key:c,value:l}),r=l?this.getNodeEnd(l):o+1}return n.range[1]=r,n.range[2]=r,n}parseInlineMap(e,t,n,r){let i=new k([t,0,0]),a=t,{key:o,valueStr:s,colonOffset:c,valueOffset:l}=this.splitMapEntry(e,t),u=new O(o,[t,t+o.length,c]),d;for(d=s===``?this.parseMapValue(n,c):this.parseScalarValue(s.trim(),l,r),i.items.push({key:u,value:d}),a=d?this.getNodeEnd(d):c+1;this.pos<this.lines.length;){this.skipEmpty();let e=this.currentLine();if(!e||e.indent<n||e.indent>n||!this.isMapEntry(e.content)||e.content.startsWith(`- `))break;let t=this.splitMapEntry(e.content,e.offset),r=new O(t.key,[e.offset,e.offset+t.key.length,t.colonOffset]);this.pos++;let o;o=t.valueStr===``?this.parseMapValue(n,t.colonOffset):this.parseScalarValue(t.valueStr.trim(),t.valueOffset,e),i.items.push({key:r,value:o}),a=o?this.getNodeEnd(o):t.colonOffset+1}return i.range[1]=a,i.range[2]=a,i}parseMapValue(e,t){this.skipEmpty();let n=this.currentLine();return!n||n.indent<e?new O(null,[t+1,t+1,t+1]):n.indent===e&&(n.content.startsWith(`- `)||n.content===`-`)?this.parseNode(e):n.indent>e?this.parseNode(e+1):new O(null,[t+1,t+1,t+1])}getNodeEnd(e){return e.range[2]}peekLastOffset(){if(this.pos>0&&this.pos<=this.lines.length){let e=this.lines[this.pos-1];return e.lineOffset+e.raw.length}return this.text.length}parseScalarValue(e,t,n){let r=e.trim(),i=t+e.indexOf(r),a=i+r.length,o=n.lineOffset+n.raw.length;return r.startsWith(`"`)?this.parseQuotedScalar(r,i,o):r===`true`||r===`false`?new O(r===`true`,[i,a,o]):r===`null`||r===`~`?new O(null,[i,a,o]):r!==``&&je(r)?new O(Number(r),[i,a,o]):new O(r,[i,a,o])}parseQuotedScalar(e,t,n){let r=``,i=1;for(;i<e.length;){let a=e[i];if(a===`\\`){if(i++,i>=e.length){this.addError(`Unterminated double-quoted string`,t+i);break}let n=e[i];switch(n){case`n`:r+=`
4
4
  `;break;case`t`:r+=` `;break;case`r`:r+=`\r`;break;case`"`:r+=`"`;break;case`\\`:r+=`\\`;break;case`/`:r+=`/`;break;default:r+=n}}else if(a===`"`){let e=t+i+1;return new O(r,[t,e,n])}else r+=a;i++}return this.addError(`Unterminated double-quoted string`,t),new O(r,[t,t+e.length,n])}skipEmpty(){for(;this.pos<this.lines.length&&this.lines[this.pos].content===``;)this.pos++}isMapEntry(e){return this.findMapColon(e)>=0}findMapColon(e){let t=!1,n=!1;for(let r=0;r<e.length;r++){let i=e[r];if(n){n=!1;continue}if(i===`\\`&&t){n=!0;continue}if(i===`"`){t=!t;continue}if(!t&&i===`:`&&(r+1>=e.length||e[r+1]===` `))return r}return-1}splitMapEntry(e,t){let n=this.findMapColon(e),r=e.slice(0,n).trim(),i=t+n,a=e.slice(n+1),o=a.trimStart(),s=i+1+(a.length-a.trimStart().length);return r.startsWith(`"`)&&r.endsWith(`"`)?{key:r.slice(1,-1),valueStr:o,colonOffset:i,valueOffset:s}:{key:r,valueStr:o,colonOffset:i,valueOffset:s}}addError(e,t){this.errors.push(new j(e,[t,t+1]))}};function je(e){return e===``||e===`-`||e===`+`?!1:/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(e)}function M(e){return Me(e)?`"`+e.replace(/[\\"\x00-\x1f\x7f-\x9f]/g,e=>{switch(e){case`\\`:return`\\\\`;case`"`:return`\\"`;case`\b`:return`\\b`;case`\f`:return`\\f`;case`