@vitest/browser 4.0.16 → 4.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.
@@ -23,7 +23,7 @@
23
23
  })();
24
24
  </script>
25
25
  <!-- !LOAD_METADATA! -->
26
- <script type="module" src="./assets/index-CLLxNdKA.js"></script>
26
+ <script type="module" src="./assets/index-DHXSWiHD.js"></script>
27
27
  <link rel="stylesheet" href="./assets/index-DlhE0rqZ.css">
28
28
  </head>
29
29
  <body>
@@ -1,5 +1,6 @@
1
1
  import { g as getBrowserState, a as getConfig, r as relative, b as generateFileHash } from "./utils-uxqdqUz8.js";
2
2
  import { channel, globalChannel, client } from "@vitest/browser/client";
3
+ import { Traces } from "vitest/internal/browser";
3
4
  // @__NO_SIDE_EFFECTS__
4
5
  function getUiAPI() {
5
6
  return window.__vitest_ui_api__;
@@ -10,8 +11,14 @@ class IframeOrchestrator {
10
11
  recreateNonIsolatedIframe = false;
11
12
  iframes = /* @__PURE__ */ new Map();
12
13
  eventTarget = new EventTarget();
14
+ traces;
13
15
  constructor() {
14
16
  debug("init orchestrator", getBrowserState().sessionId);
17
+ const otelConfig = getBrowserState().config.experimental.openTelemetry;
18
+ this.traces = new Traces({
19
+ enabled: !!((otelConfig == null ? void 0 : otelConfig.enabled) && otelConfig.browserSdkPath),
20
+ sdkPath: `/@fs/${otelConfig == null ? void 0 : otelConfig.browserSdkPath}`
21
+ });
15
22
  channel.addEventListener(
16
23
  "message",
17
24
  (e) => this.onIframeEvent(e)
@@ -22,6 +29,21 @@ class IframeOrchestrator {
22
29
  );
23
30
  }
24
31
  async createTesters(options) {
32
+ await this.traces.waitInit();
33
+ this.traces.recordInitSpan(
34
+ this.traces.getContextFromCarrier(getBrowserState().otelCarrier)
35
+ );
36
+ const orchestratorSpan = this.traces.startContextSpan(
37
+ "vitest.browser.orchestrator.run",
38
+ this.traces.getContextFromCarrier(options.otelCarrier)
39
+ );
40
+ orchestratorSpan.span.setAttributes({
41
+ "vitest.browser.files": options.files.map((f) => f.filepath)
42
+ });
43
+ const endSpan = async () => {
44
+ orchestratorSpan.span.end();
45
+ await this.traces.flush();
46
+ };
25
47
  const startTime = performance.now();
26
48
  this.cancelled = false;
27
49
  const config = getConfig();
@@ -35,13 +57,15 @@ class IframeOrchestrator {
35
57
  }
36
58
  }
37
59
  if (config.browser.isolate === false) {
38
- await this.runNonIsolatedTests(container, options, startTime);
60
+ await this.runNonIsolatedTests(container, options, startTime, orchestratorSpan.context);
61
+ await endSpan();
39
62
  return;
40
63
  }
41
64
  this.iframes.forEach((iframe) => iframe.remove());
42
65
  this.iframes.clear();
43
66
  for (let i = 0; i < options.files.length; i++) {
44
67
  if (this.cancelled) {
68
+ await endSpan();
45
69
  return;
46
70
  }
47
71
  const file = options.files[i];
@@ -50,9 +74,11 @@ class IframeOrchestrator {
50
74
  container,
51
75
  file,
52
76
  options,
53
- startTime
77
+ startTime,
78
+ orchestratorSpan.context
54
79
  );
55
80
  }
81
+ await endSpan();
56
82
  }
57
83
  async cleanupTesters() {
58
84
  const config = getConfig();
@@ -75,7 +101,7 @@ class IframeOrchestrator {
75
101
  });
76
102
  this.recreateNonIsolatedIframe = true;
77
103
  }
78
- async runNonIsolatedTests(container, options, startTime) {
104
+ async runNonIsolatedTests(container, options, startTime, otelContext) {
79
105
  if (this.recreateNonIsolatedIframe) {
80
106
  this.recreateNonIsolatedIframe = false;
81
107
  this.iframes.get(ID_ALL).remove();
@@ -84,7 +110,7 @@ class IframeOrchestrator {
84
110
  }
85
111
  if (!this.iframes.has(ID_ALL)) {
86
112
  debug("preparing non-isolated iframe");
87
- await this.prepareIframe(container, ID_ALL, startTime);
113
+ await this.prepareIframe(container, ID_ALL, startTime, otelContext);
88
114
  }
89
115
  const config = getConfig();
90
116
  const { width, height } = config.browser.viewport;
@@ -100,7 +126,7 @@ class IframeOrchestrator {
100
126
  });
101
127
  debug("finished running tests", options.files.join(", "));
102
128
  }
103
- async runIsolatedTestInIframe(container, spec, options, startTime) {
129
+ async runIsolatedTestInIframe(container, spec, options, startTime, otelContext) {
104
130
  const config = getConfig();
105
131
  const { width, height } = config.browser.viewport;
106
132
  const file = spec.filepath;
@@ -108,7 +134,12 @@ class IframeOrchestrator {
108
134
  this.iframes.get(file).remove();
109
135
  this.iframes.delete(file);
110
136
  }
111
- const iframe = await this.prepareIframe(container, file, startTime);
137
+ const iframe = await this.prepareIframe(
138
+ container,
139
+ file,
140
+ startTime,
141
+ otelContext
142
+ );
112
143
  await setIframeViewport(iframe, width, height);
113
144
  await sendEventToIframe({
114
145
  event: "execute",
@@ -127,7 +158,7 @@ class IframeOrchestrator {
127
158
  this.eventTarget.dispatchEvent(event);
128
159
  return error;
129
160
  }
130
- async prepareIframe(container, iframeId, startTime) {
161
+ async prepareIframe(container, iframeId, startTime, otelContext) {
131
162
  const iframe = this.createTestIframe(iframeId);
132
163
  container.appendChild(iframe);
133
164
  await new Promise((resolve, reject) => {
@@ -146,7 +177,8 @@ Expected: ${iframe.src}`
146
177
  sendEventToIframe({
147
178
  event: "prepare",
148
179
  iframeId,
149
- startTime
180
+ startTime,
181
+ otelCarrier: this.traces.getContextCarrier(otelContext)
150
182
  }).then(resolve, (error) => reject(this.dispatchIframeError(error)));
151
183
  }
152
184
  };
@@ -1,8 +1,8 @@
1
1
  import { c as resolve, m as moduleRunner, d as getWorkerState, g as getBrowserState, e as getTestName, a as getConfig } from "./utils-uxqdqUz8.js";
2
2
  import { onCancel, globalChannel, channel, client } from "@vitest/browser/client";
3
3
  import { userEvent, page, server } from "vitest/browser";
4
- import { getSafeTimers, DecodedMap as DecodedMap$1, getOriginalPosition as getOriginalPosition$1, loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker, browserFormat, setupCommonEnv, startCoverageInsideWorker, stopCoverageInsideWorker, startTests, collectTests, SpyModule } from "vitest/internal/browser";
5
- import { VitestTestRunner, NodeBenchmarkRunner } from "vitest/runners";
4
+ import { getSafeTimers, DecodedMap as DecodedMap$1, getOriginalPosition as getOriginalPosition$1, loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker, browserFormat, Traces, setupCommonEnv, startCoverageInsideWorker, stopCoverageInsideWorker, startTests, collectTests, SpyModule } from "vitest/internal/browser";
5
+ import { TestRunner, BenchmarkRunner } from "vitest";
6
6
  const scriptRel = "modulepreload";
7
7
  const assetsURL = function(dep) {
8
8
  return "/" + dep;
@@ -811,11 +811,13 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
811
811
  sourceMapCache = /* @__PURE__ */ new Map();
812
812
  method = "run";
813
813
  commands;
814
+ _otel;
814
815
  constructor(options) {
815
816
  super(options.config);
816
817
  this.config = options.config;
817
818
  this.commands = getBrowserState().commands;
818
819
  this.viteEnvironment = "__browser__";
820
+ this._otel = getBrowserState().traces;
819
821
  }
820
822
  setMethod(method) {
821
823
  this.method = method;
@@ -865,28 +867,28 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
865
867
  if (!this.traces.has(test.id)) {
866
868
  this.traces.set(test.id, []);
867
869
  }
868
- const traces = this.traces.get(test.id);
870
+ const traces2 = this.traces.get(test.id);
869
871
  const { tracePath } = await this.commands.triggerCommand(
870
872
  "__vitest_stopChunkTrace",
871
873
  [{ name }]
872
874
  );
873
- traces.push(tracePath);
875
+ traces2.push(tracePath);
874
876
  };
875
877
  onAfterRunTask = async (task) => {
876
878
  var _a, _b, _c;
877
879
  await ((_a = super.onAfterRunTask) == null ? void 0 : _a.call(this, task));
878
880
  const trace = this.config.browser.trace;
879
- const traces = this.traces.get(task.id) || [];
880
- if (traces.length) {
881
+ const traces2 = this.traces.get(task.id) || [];
882
+ if (traces2.length) {
881
883
  if (trace === "retain-on-failure" && ((_b = task.result) == null ? void 0 : _b.state) === "pass") {
882
884
  await this.commands.triggerCommand(
883
885
  "__vitest_deleteTracing",
884
- [{ traces }]
886
+ [{ traces: traces2 }]
885
887
  );
886
888
  } else {
887
889
  await this.commands.triggerCommand(
888
890
  "__vitest_annotateTraces",
889
- [{ testId: task.id, traces }]
891
+ [{ testId: task.id, traces: traces2 }]
890
892
  );
891
893
  }
892
894
  }
@@ -1024,9 +1026,10 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
1024
1026
  throw new Error(`Failed to import test file ${filepath}`, { cause: err });
1025
1027
  }
1026
1028
  };
1027
- // disable tracing in the browser for now
1028
- trace = void 0;
1029
- __setTraces = void 0;
1029
+ trace = (name, attributes, cb) => {
1030
+ const options = typeof attributes === "object" ? { attributes } : {};
1031
+ return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
1032
+ };
1030
1033
  };
1031
1034
  }
1032
1035
  let cachedRunner = null;
@@ -1037,7 +1040,7 @@ async function initiateRunner(state, mocker, config) {
1037
1040
  if (cachedRunner) {
1038
1041
  return cachedRunner;
1039
1042
  }
1040
- const runnerClass = config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner;
1043
+ const runnerClass = config.mode === "test" ? TestRunner : BenchmarkRunner;
1041
1044
  const BrowserRunner = createBrowserRunner(runnerClass, mocker, state, {
1042
1045
  takeCoverage: () => takeCoverageInsideWorker(config.coverage, moduleRunner)
1043
1046
  });
@@ -1931,19 +1934,28 @@ class CommandsManager {
1931
1934
  var _a, _b;
1932
1935
  const state = getWorkerState();
1933
1936
  const rpc2 = state.rpc;
1934
- const { sessionId } = getBrowserState();
1937
+ const { sessionId, traces: traces2 } = getBrowserState();
1935
1938
  const filepath = state.filepath || ((_b = (_a = state.current) == null ? void 0 : _a.file) == null ? void 0 : _b.filepath);
1936
1939
  args = args.filter((arg) => arg !== void 0);
1937
1940
  if (this._listeners.length) {
1938
1941
  await Promise.all(this._listeners.map((listener) => listener(command, args)));
1939
1942
  }
1940
- return rpc2.triggerCommand(sessionId, command, filepath, args).catch((err) => {
1941
- var _a2;
1942
- clientError.message = err.message;
1943
- clientError.name = err.name;
1944
- clientError.stack = (_a2 = clientError.stack) == null ? void 0 : _a2.replace(clientError.message, err.message);
1945
- throw clientError;
1946
- });
1943
+ return traces2.$(
1944
+ "vitest.browser.tester.command",
1945
+ {
1946
+ attributes: {
1947
+ "vitest.browser.command": command,
1948
+ "code.file.path": filepath
1949
+ }
1950
+ },
1951
+ () => rpc2.triggerCommand(sessionId, command, filepath, args).catch((err) => {
1952
+ var _a2;
1953
+ clientError.message = err.message;
1954
+ clientError.name = err.name;
1955
+ clientError.stack = (_a2 = clientError.stack) == null ? void 0 : _a2.replace(clientError.message, err.message);
1956
+ throw clientError;
1957
+ })
1958
+ );
1947
1959
  }
1948
1960
  }
1949
1961
  const debugVar = getConfig().env.VITEST_BROWSER_DEBUG;
@@ -1951,6 +1963,13 @@ const debug = debugVar && debugVar !== "false" ? (...args) => {
1951
1963
  var _a, _b;
1952
1964
  return (_b = (_a = client.rpc).debug) == null ? void 0 : _b.call(_a, ...args.map(String));
1953
1965
  } : void 0;
1966
+ const otelConfig = getConfig().experimental.openTelemetry;
1967
+ const traces = new Traces({
1968
+ enabled: !!((otelConfig == null ? void 0 : otelConfig.enabled) && (otelConfig == null ? void 0 : otelConfig.browserSdkPath)),
1969
+ sdkPath: `/@fs/${otelConfig == null ? void 0 : otelConfig.browserSdkPath}`
1970
+ });
1971
+ let rootTesterSpan;
1972
+ getBrowserState().traces = traces;
1954
1973
  channel.addEventListener("message", async (e) => {
1955
1974
  await client.waitForConnection();
1956
1975
  const data = e.data;
@@ -1979,9 +1998,19 @@ channel.addEventListener("message", async (e) => {
1979
1998
  }
1980
1999
  case "cleanup": {
1981
2000
  await cleanup().catch((err) => unhandledError(err, "Cleanup Error"));
2001
+ rootTesterSpan == null ? void 0 : rootTesterSpan.span.end();
2002
+ await traces.finish();
1982
2003
  break;
1983
2004
  }
1984
2005
  case "prepare": {
2006
+ await traces.waitInit();
2007
+ const tracesContext = traces.getContextFromCarrier(data.otelCarrier);
2008
+ traces.recordInitSpan(tracesContext);
2009
+ rootTesterSpan = traces.startContextSpan(
2010
+ `vitest.browser.tester.run`,
2011
+ tracesContext
2012
+ );
2013
+ traces.bind(rootTesterSpan.context);
1985
2014
  await prepare(data).catch((err) => unhandledError(err, "Prepare Error"));
1986
2015
  break;
1987
2016
  }
@@ -2070,11 +2099,19 @@ async function executeTests(method, specifications) {
2070
2099
  for (const file of specifications) {
2071
2100
  state.filepath = file.filepath;
2072
2101
  debug == null ? void 0 : debug("running test file", file.filepath);
2073
- if (method === "run") {
2074
- await startTests([file], runner);
2075
- } else {
2076
- await collectTests([file], runner);
2077
- }
2102
+ await traces.$(
2103
+ `vitest.test.runner.${method}.module`,
2104
+ {
2105
+ attributes: { "code.file.path": file.filepath }
2106
+ },
2107
+ async () => {
2108
+ if (method === "run") {
2109
+ await startTests([file], runner);
2110
+ } else {
2111
+ await collectTests([file], runner);
2112
+ }
2113
+ }
2114
+ );
2078
2115
  }
2079
2116
  }
2080
2117
  async function prepare(options) {
@@ -31,7 +31,11 @@ function catchWindowErrors(errorEvent, prop, cb) {
31
31
  cb(e)
32
32
  }
33
33
  else {
34
- console.error(e[prop])
34
+ // `ErrorEvent` doesn't necessary have `ErrotEvent.error` defined
35
+ // but some has `ErrorEvent.message` defined, e.g. ResizeObserver error.
36
+ // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/error
37
+ // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors
38
+ console.error(e.message ? new Error(e.message) : e)
35
39
  }
36
40
  }
37
41
  const addEventListener = window.addEventListener.bind(window)
@@ -9,7 +9,7 @@
9
9
  }
10
10
 
11
11
  const { evaluatedModules } = __vitest_worker__
12
- const moduleId = crypto.randomUUID()
12
+ const moduleId = `${Math.random()}`
13
13
  const viteModule = evaluatedModules.ensureModule(moduleId, moduleId)
14
14
 
15
15
  viteModule.evaluated = false
@@ -38,6 +38,7 @@
38
38
  type: { __VITEST_TYPE__ },
39
39
  sessionId: { __VITEST_SESSION_ID__ },
40
40
  testerId: { __VITEST_TESTER_ID__ },
41
+ otelCarrier: { __VITEST_OTEL_CARRIER__ },
41
42
  provider: { __VITEST_PROVIDER__ },
42
43
  method: { __VITEST_METHOD__ },
43
44
  providedContext: { __VITEST_PROVIDED_CONTEXT__ },
@@ -26,7 +26,7 @@
26
26
  {__VITEST_INJECTOR__}
27
27
  {__VITEST_ERROR_CATCHER__}
28
28
  {__VITEST_SCRIPTS__}
29
- <script type="module" crossorigin src="/__vitest_browser__/orchestrator-8U3FyXSU.js"></script>
29
+ <script type="module" crossorigin src="/__vitest_browser__/orchestrator-S_3e_uzt.js"></script>
30
30
  <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-uxqdqUz8.js">
31
31
  </head>
32
32
  <body>
@@ -5,7 +5,7 @@
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-g_x0OsgY.js"></script>
8
+ <script type="module" crossorigin src="/__vitest_browser__/tester-cVWT4Xmu.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-uxqdqUz8.js">
10
10
  </head>
11
11
  <body>
package/dist/context.js CHANGED
@@ -165,6 +165,36 @@ const kLocator = Symbol.for("$$vitest:locator");
165
165
  function isLocator(element) {
166
166
  return !!element && typeof element === "object" && kLocator in element;
167
167
  }
168
+ const DEFAULT_WHEEL_DELTA = 100;
169
+ function resolveUserEventWheelOptions(options) {
170
+ let delta;
171
+ if (options.delta) {
172
+ delta = options.delta;
173
+ } else {
174
+ switch (options.direction) {
175
+ case "up": {
176
+ delta = { y: -DEFAULT_WHEEL_DELTA };
177
+ break;
178
+ }
179
+ case "down": {
180
+ delta = { y: DEFAULT_WHEEL_DELTA };
181
+ break;
182
+ }
183
+ case "left": {
184
+ delta = { x: -DEFAULT_WHEEL_DELTA };
185
+ break;
186
+ }
187
+ case "right": {
188
+ delta = { x: DEFAULT_WHEEL_DELTA };
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ return {
194
+ delta,
195
+ times: options.times
196
+ };
197
+ }
168
198
 
169
199
  // this file should not import anything directly, only types and utils
170
200
  // @ts-expect-error not typed global
@@ -205,6 +235,9 @@ function createUserEvent(__tl_user_event_base__, options) {
205
235
  tripleClick(element, options) {
206
236
  return convertToLocator(element).tripleClick(options);
207
237
  },
238
+ wheel(elementOrOptions, options) {
239
+ return convertToLocator(elementOrOptions).wheel(options);
240
+ },
208
241
  selectOptions(element, value, options) {
209
242
  return convertToLocator(element).selectOptions(value, options);
210
243
  },
@@ -339,6 +372,26 @@ function createPreviewUserEvent(userEventBase, options) {
339
372
  },
340
373
  async paste() {
341
374
  await userEvent.paste(clipboardData);
375
+ },
376
+ async wheel(element, options) {
377
+ const resolvedElement = isLocator(element) ? element.element() : element;
378
+ const resolvedOptions = resolveUserEventWheelOptions(options);
379
+ const rect = resolvedElement.getBoundingClientRect();
380
+ const centerX = rect.left + rect.width / 2;
381
+ const centerY = rect.top + rect.height / 2;
382
+ const wheelEvent = new WheelEvent("wheel", {
383
+ clientX: centerX,
384
+ clientY: centerY,
385
+ deltaY: resolvedOptions.delta.y ?? 0,
386
+ deltaX: resolvedOptions.delta.x ?? 0,
387
+ deltaMode: 0,
388
+ bubbles: true,
389
+ cancelable: true
390
+ });
391
+ const times = options.times ?? 1;
392
+ for (let count = 0; count < times; count += 1) {
393
+ resolvedElement.dispatchEvent(wheelEvent);
394
+ }
342
395
  }
343
396
  };
344
397
  for (const [name, fn] of Object.entries(vitestUserEvent)) {
@@ -1,6 +1,6 @@
1
- import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/internal/browser";import{k as kAriaCheckedRoles,L as Locator,g as getAriaChecked,a as getAriaRole,b as getAriaDisabled,c as beginAriaCaches,e as endAriaCaches,i as isElementVisible$1,d as getElementAccessibleDescription,f as getElementAccessibleErrorMessage,h as getElementAccessibleName,j as cssEscape,l as convertToSelector,m as getBrowserState,p as processTimeoutOptions}from"./index-CEutxZap.js";import{server}from"vitest/browser";function getAriaCheckedRoles(){return[...kAriaCheckedRoles]}function queryElementFromUserInput(_,K,q){return _ instanceof Locator&&(_=_.query()),_==null?null:getElementFromUserInput(_,K,q)}function getElementFromUserInput(_,K,q){_ instanceof Locator&&(_=_.element());let J=_?.ownerDocument?.defaultView||window;if(_ instanceof J.HTMLElement||_ instanceof J.SVGElement)return _;throw new UserInputElementTypeError(_,K,q)}function getNodeFromUserInput(_,K,q){_ instanceof Locator&&(_=_.element());let J=_.ownerDocument?.defaultView||window;if(_ instanceof J.Node)return _;throw new UserInputNodeTypeError(_,K,q)}function getMessage(_,K,q,J,Y,X){return[`${K}\n`,`${q}:\n${_.utils.EXPECTED_COLOR(redent(display(_,J),2))}`,`${Y}:\n${_.utils.RECEIVED_COLOR(redent(display(_,X),2))}`].join(`
1
+ import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/internal/browser";import{k as kAriaCheckedRoles,L as Locator,g as getAriaChecked,a as getAriaRole,b as getAriaDisabled,c as beginAriaCaches,e as endAriaCaches,i as isElementVisible$1,d as getElementAccessibleDescription,f as getElementAccessibleErrorMessage,h as getElementAccessibleName,j as cssEscape,l as convertToSelector,m as getBrowserState,p as processTimeoutOptions}from"./index-5ZLDAkrH.js";import{server}from"vitest/browser";function getAriaCheckedRoles(){return[...kAriaCheckedRoles]}function queryElementFromUserInput(_,K,q){return _ instanceof Locator&&(_=_.query()),_==null?null:getElementFromUserInput(_,K,q)}function getElementFromUserInput(_,K,q){_ instanceof Locator&&(_=_.element());let J=_?.ownerDocument?.defaultView||window;if(_ instanceof J.HTMLElement||_ instanceof J.SVGElement)return _;throw new UserInputElementTypeError(_,K,q)}function getNodeFromUserInput(_,K,q){_ instanceof Locator&&(_=_.element());let J=_.ownerDocument?.defaultView||window;if(_ instanceof J.Node)return _;throw new UserInputNodeTypeError(_,K,q)}function getMessage(_,K,q,J,Y,X){return[`${K}\n`,`${q}:\n${_.utils.EXPECTED_COLOR(redent(display(_,J),2))}`,`${Y}:\n${_.utils.RECEIVED_COLOR(redent(display(_,X),2))}`].join(`
2
2
  `)}function redent(_,K){return indentString(stripIndent(_),K)}function indentString(_,K){return _.replace(/^(?!\s*$)/gm,` `.repeat(K))}function minIndent(_){let K=_.match(/^[ \t]*(?=\S)/gm);return K?K.reduce((_,K)=>Math.min(_,K.length),1/0):0}function stripIndent(_){let K=minIndent(_);if(K===0)return _;let q=RegExp(`^[ \\t]{${K}}`,`gm`);return _.replace(q,``)}function display(_,K){return typeof K==`string`?K:_.utils.stringify(K)}function toSentence(_,{wordConnector:K=`, `,lastWordConnector:q=` and `}={}){return[_.slice(0,-1).join(K),_.at(-1)].join(_.length>1?q:``)}class GenericTypeError extends Error{constructor(_,K,q,J){super(),Error.captureStackTrace&&Error.captureStackTrace(this,q);let Y=``;try{Y=J.utils.printWithType(`Received`,K,J.utils.printReceived)}catch{}this.message=[J.utils.matcherHint(`${J.isNot?`.not`:``}.${q.name}`,`received`,``),``,`${J.utils.RECEIVED_COLOR(`received`)} value must ${_} or a Locator that returns ${_}.`,Y].join(`
3
- `)}}class UserInputElementTypeError extends GenericTypeError{constructor(_,K,q){super(`an HTMLElement or an SVGElement`,_,K,q)}}class UserInputNodeTypeError extends GenericTypeError{constructor(_,K,q){super(`a Node`,_,K,q)}}function getTag(_){return _ instanceof HTMLFormElement?`FORM`:_.tagName.toUpperCase()}function isInputElement(_){return getTag(_)===`INPUT`}function getSingleElementValue(_){if(_)switch(getTag(_)){case`INPUT`:return getInputValue(_);case`SELECT`:return getSelectValue(_);default:return _.value??getAccessibleValue(_)}}function getSelectValue({multiple:_,options:K}){let q=[...K].filter(_=>_.selected);if(_)return[...q].map(_=>_.value);if(q.length!==0)return q[0].value}function getInputValue(_){switch(_.type){case`number`:return _.value===``?null:Number(_.value);case`checkbox`:return _.checked;default:return _.value}}const rolesSupportingValues=[`meter`,`progressbar`,`slider`,`spinbutton`];function getAccessibleValue(_){if(rolesSupportingValues.includes(_.getAttribute(`role`)||``))return Number(_.getAttribute(`aria-valuenow`))}function normalize(_){return _.replace(/\s+/g,` `).trim()}function matches(_,K){return K instanceof RegExp?K.test(_):_.includes(String(K))}function arrayAsSetComparison(_,K){if(Array.isArray(_)&&Array.isArray(K)){let q=new Set(K);for(let K of new Set(_))if(!q.has(K))return!1;return!0}}const supportedRoles=getAriaCheckedRoles();function toBeChecked(_){let K=getElementFromUserInput(_,toBeChecked,this);if(!(()=>isInputElement(K)&&[`checkbox`,`radio`].includes(K.type))()&&!(()=>supportedRoles.includes(getAriaRole(K)||``)&&[`true`,`false`].includes(K.getAttribute(`aria-checked`)||``))())return{pass:!1,message:()=>`only inputs with type="checkbox" or type="radio" or elements with ${supportedRolesSentence()} and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead`};let q=getAriaChecked(K)===!0;return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeChecked`,`element`,``),``,`Received element ${_} checked:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
3
+ `)}}class UserInputElementTypeError extends GenericTypeError{constructor(_,K,q){super(`an HTMLElement or an SVGElement`,_,K,q)}}class UserInputNodeTypeError extends GenericTypeError{constructor(_,K,q){super(`a Node`,_,K,q)}}function getTag(_){return _ instanceof HTMLFormElement?`FORM`:_.tagName.toUpperCase()}function isInputElement(_){return getTag(_)===`INPUT`}function getSingleElementValue(_){if(_)switch(getTag(_)){case`INPUT`:return getInputValue(_);case`SELECT`:return getSelectValue(_);default:return _.value??getAccessibleValue(_)}}function getSelectValue({multiple:_,options:K}){let q=[...K].filter(_=>_.selected);if(_)return[...q].map(_=>_.value);if(q.length!==0)return q[0].value}function getInputValue(_){switch(_.type){case`number`:return _.value===``?null:Number(_.value);case`checkbox`:return _.checked;default:return _.value}}const rolesSupportingValues=[`meter`,`progressbar`,`slider`,`spinbutton`];function getAccessibleValue(_){if(rolesSupportingValues.includes(_.getAttribute(`role`)||``))return Number(_.getAttribute(`aria-valuenow`))}function normalize(_){return _.replace(/\s+/g,` `).trim()}function matches(_,K){return K instanceof RegExp?K.test(_):_.includes(String(K))}function arrayAsSetComparison(_,K){if(Array.isArray(_)&&Array.isArray(K)){let q=new Set(K);for(let K of new Set(_))if(!q.has(K))return!1;return!0}}const supportedRoles=getAriaCheckedRoles();function toBeChecked(_){let K=getElementFromUserInput(_,toBeChecked,this);if(!(isInputElement(K)&&[`checkbox`,`radio`].includes(K.type))&&!(supportedRoles.includes(getAriaRole(K)||``)&&[`true`,`false`].includes(K.getAttribute(`aria-checked`)||``)))return{pass:!1,message:()=>`only inputs with type="checkbox" or type="radio" or elements with ${supportedRolesSentence()} and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead`};let q=getAriaChecked(K)===!0;return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeChecked`,`element`,``),``,`Received element ${_} checked:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
4
4
  `)}}}function supportedRolesSentence(){return toSentence(supportedRoles.map(_=>`role="${_}"`),{lastWordConnector:` or `})}function toBeEmptyDOMElement(_){let K=getElementFromUserInput(_,toBeEmptyDOMElement,this);return{pass:isEmptyElement(K),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeEmptyDOMElement`,`element`,``),``,`Received:`,` ${this.utils.printReceived(K.innerHTML)}`].join(`
5
5
  `)}}function isEmptyElement(_){return[..._.childNodes].filter(_=>_.nodeType!==Node.COMMENT_NODE).length===0}function toBeDisabled(_){let K=getElementFromUserInput(_,toBeDisabled,this),q=isElementDisabled(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeDisabled`,`element`,``),``,`Received element ${_} disabled:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
6
6
  `)}}}function toBeEnabled(_){let K=getElementFromUserInput(_,toBeEnabled,this),q=isElementDisabled(K);return{pass:!q,message:()=>{let _=q?`is not`:`is`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeEnabled`,`element`,``),``,`Received element ${_} enabled:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
@@ -8,7 +8,7 @@ import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/intern
8
8
  `)}}const FORM_TAGS$1=[`FORM`,`INPUT`,`SELECT`,`TEXTAREA`];function isElementHavingAriaInvalid(_){return _.hasAttribute(`aria-invalid`)&&_.getAttribute(`aria-invalid`)!==`false`}function isSupportsValidityMethod(_){return FORM_TAGS$1.includes(getTag(_))}function isElementInvalid(_){let K=isElementHavingAriaInvalid(_);return isSupportsValidityMethod(_)?K||!_.checkValidity():K}function toBeInvalid(_){let K=getElementFromUserInput(_,toBeInvalid,this),q=isElementInvalid(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeInvalid`,`element`,``),``,`Received element ${_} currently invalid:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
9
9
  `)}}}function toBeValid(_){let K=getElementFromUserInput(_,toBeInvalid,this),q=!isElementInvalid(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeValid`,`element`,``),``,`Received element ${_} currently valid:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
10
10
  `)}}}function toBeInViewport(_,K){let q=getElementFromUserInput(_,toBeInViewport,this),J=K?.ratio??0;return getViewportIntersection(q,J).then(({pass:_,ratio:K})=>({pass:_,message:()=>{let Y=_?`is`:`is not`,X=J>0?` with ratio ${J}`:``,Z=K===void 0?``:` (actual ratio: ${K.toFixed(3)})`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeInViewport`,`element`,``),``,`Received element ${Y} in viewport${X}${Z}:`,` ${this.utils.printReceived(q.cloneNode(!1))}`].join(`
11
- `)}}))}async function getViewportIntersection(_,K){let q=await new Promise(K=>{let q=new IntersectionObserver(_=>{_.length>0?K(_[0].intersectionRatio):K(0),q.disconnect()});q.observe(_),requestAnimationFrame(()=>{})});return{pass:q>0&&q>K-1e-9,ratio:q}}function toBePartiallyChecked(_){let K=getElementFromUserInput(_,toBePartiallyChecked,this);if(!(()=>isInputElement(K)&&K.type===`checkbox`)()&&!(()=>K.getAttribute(`role`)===`checkbox`)())return{pass:!1,message:()=>`only inputs with type="checkbox" or elements with role="checkbox" and a valid aria-checked attribute can be used with .toBePartiallyChecked(). Use .toHaveValue() instead`};let q=isAriaMixed(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBePartiallyChecked`,`element`,``),``,`Received element ${_} partially checked:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
11
+ `)}}))}async function getViewportIntersection(_,K){let q=await new Promise(K=>{let q=new IntersectionObserver(_=>{_.length>0?K(_[0].intersectionRatio):K(0),q.disconnect()});q.observe(_),requestAnimationFrame(()=>{})});return{pass:q>0&&q>K-1e-9,ratio:q}}function toBePartiallyChecked(_){let K=getElementFromUserInput(_,toBePartiallyChecked,this);if(!(isInputElement(K)&&K.type===`checkbox`)&&K.getAttribute(`role`)!==`checkbox`)return{pass:!1,message:()=>`only inputs with type="checkbox" or elements with role="checkbox" and a valid aria-checked attribute can be used with .toBePartiallyChecked(). Use .toHaveValue() instead`};let q=isAriaMixed(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBePartiallyChecked`,`element`,``),``,`Received element ${_} partially checked:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
12
12
  `)}}}function isAriaMixed(_){let K=getAriaChecked(_)===`mixed`;return!K&&isInputElement(_)&&[`checkbox`,`radio`].includes(_.type)&&_.getAttribute(`aria-checked`)===`mixed`?!0:K}const FORM_TAGS=[`SELECT`,`TEXTAREA`],ARIA_FORM_TAGS=[`INPUT`,`SELECT`,`TEXTAREA`],UNSUPPORTED_INPUT_TYPES=[`color`,`hidden`,`range`,`submit`,`image`,`reset`],SUPPORTED_ARIA_ROLES=[`checkbox`,`combobox`,`gridcell`,`listbox`,`radiogroup`,`spinbutton`,`textbox`,`tree`];function isRequiredOnFormTagsExceptInput(_){return FORM_TAGS.includes(getTag(_))&&_.hasAttribute(`required`)}function isRequiredOnSupportedInput(_){return getTag(_)===`INPUT`&&_.hasAttribute(`required`)&&(_.hasAttribute(`type`)&&!UNSUPPORTED_INPUT_TYPES.includes(_.getAttribute(`type`)||``)||!_.hasAttribute(`type`))}function isElementRequiredByARIA(_){return _.hasAttribute(`aria-required`)&&_.getAttribute(`aria-required`)===`true`&&(ARIA_FORM_TAGS.includes(getTag(_))||_.hasAttribute(`role`)&&SUPPORTED_ARIA_ROLES.includes(_.getAttribute(`role`)||``))}function toBeRequired(_){let K=getElementFromUserInput(_,toBeRequired,this),q=isRequiredOnFormTagsExceptInput(K)||isRequiredOnSupportedInput(K)||isElementRequiredByARIA(K);return{pass:q,message:()=>{let _=q?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeRequired`,`element`,``),``,`Received element ${_} required:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
13
13
  `)}}}function toBeVisible(_){let K=getElementFromUserInput(_,toBeVisible,this),q=K.ownerDocument===K.getRootNode({composed:!0});beginAriaCaches();let J=q&&isElementVisible(K);return endAriaCaches(),{pass:J,message:()=>{let _=J?`is`:`is not`;return[this.utils.matcherHint(`${this.isNot?`.not`:``}.toBeVisible`,`element`,``),``,`Received element ${_} visible${q?``:` (element is not in the document)`}:`,` ${this.utils.printReceived(K.cloneNode(!1))}`].join(`
14
14
  `)}}}function isElementVisible(_){let K=isElementVisible$1(_);if(server.browser!==`webkit`)return K;let q=_.closest(`details`);return!q||_===q?K:isElementVisibleInDetails(_)}function isElementVisibleInDetails(_){let K=_;for(;K;){if(K.tagName===`DETAILS`){let q=K.querySelector(`summary`)===_;if(!K.open&&!q)return!1}K=K.parentElement}return _.offsetParent!==null}function toContainElement(_,K){let q=getElementFromUserInput(_,toContainElement,this),J=K===null?null:getElementFromUserInput(K,toContainElement,this);return{pass:q.contains(J),message:()=>[this.utils.matcherHint(`${this.isNot?`.not`:``}.toContainElement`,`element`,`element`),``,this.utils.RECEIVED_COLOR(`${this.utils.stringify(q.cloneNode(!1))} ${this.isNot?`contains:`:`does not contain:`} ${this.utils.stringify(J?J.cloneNode(!1):null)}
@@ -23,5 +23,5 @@ import{recordArtifact,expect,chai}from"vitest";import{getType}from"vitest/intern
23
23
  `)}}}function getMultiElementValue(_){let K=``;for(let q of _){if(K&&K!==q.type)throw Error(`Multiple form elements with the same name must be of the same type`);K=q.type}switch(K){case`radio`:{let K=_.find(_=>_.checked);return K?K.value:void 0}case`checkbox`:return _.filter(_=>_.checked).map(_=>_.value);default:return _.map(_=>_.value)}}function getFormValue(_,K){let q=[..._.querySelectorAll(`[name="${cssEscape(K)}"]`)];if(q.length!==0)switch(q.length){case 1:return getSingleElementValue(q[0]);default:return getMultiElementValue(q)}}function getPureName(_){return/\[\]$/.test(_)?_.slice(0,-2):_}function getAllFormValues(_){let K={};for(let q of _.elements){if(!(`name`in q))continue;let J=q.name;K[getPureName(J)]=getFormValue(_,J)}return K}function toHaveRole(_,K){let q=getElementFromUserInput(_,toHaveRole,this);beginAriaCaches();let J=getAriaRole(q);return endAriaCaches(),{pass:J===K,message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveRole`,`element`,``),`Expected element ${_} have role`,K,`Received`,J)}}}function toHaveSelection(_,K){let q=getElementFromUserInput(_,toHaveSelection,this),J=K!==void 0;if(J&&typeof K!=`string`)throw Error(`expected selection must be a string or undefined`);let Y=getSelection(q);return{pass:J?this.equals(Y,K,[arrayAsSetComparison,...this.customTesters]):!!Y,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveSelection`,`element`,K);return getMessage(this,q,`Expected the element ${_} have selection`,J?K:`(any)`,`Received`,Y)}}}function getSelection(_){let K=_.ownerDocument.getSelection();if(!K)return``;if([`INPUT`,`TEXTAREA`].includes(getTag(_))){let K=_;return[`radio`,`checkbox`].includes(K.type)||K.selectionStart==null||K.selectionEnd==null?``:K.value.toString().substring(K.selectionStart,K.selectionEnd)}if(K.anchorNode===null||K.focusNode===null)return``;let q=K.getRangeAt(0),J=_.ownerDocument.createRange();if(K.containsNode(_,!1))J.selectNodeContents(_),K.removeAllRanges(),K.addRange(J);else if(!(_.contains(K.anchorNode)&&_.contains(K.focusNode))){let Y=_===q.startContainer||_.contains(q.startContainer),X=_===q.endContainer||_.contains(q.endContainer);K.removeAllRanges(),(Y||X)&&(J.selectNodeContents(_),Y&&J.setStart(q.startContainer,q.startOffset),X&&J.setEnd(q.endContainer,q.endOffset),K.addRange(J))}let Y=K.toString();return K.removeAllRanges(),K.addRange(q),Y}const browser=server.config.browser.name,usedValuesProps=new Set(`backgroundPosition.background-position.bottom.left.right.top.height.width.margin-bottom.marginBottom.margin-left.marginLeft.margin-right.marginRight.margin-top.marginTop.min-height.minHeight.min-width.minWidth.padding-bottom.padding-left.padding-right.padding-top.text-indent.paddingBottom.paddingLeft.paddingRight.paddingTop.textIndent`.split(`.`));function toHaveStyle(_,K){let q=getElementFromUserInput(_,toHaveStyle,this),{getComputedStyle:J}=q.ownerDocument.defaultView,Y=typeof K==`object`?getStyleFromObjectCSS(K):computeCSSStyleDeclaration(K),X=J(q),Z=new Set(Array.from(q.style));return{pass:isSubset(Y,q,X,Z),message:()=>{let _=`${this.isNot?`.not`:``}.toHaveStyle`,K=new Set(Object.keys(Y)),J=printoutObjectStyles(Array.from(X).filter(_=>K.has(_)).reduce((_,K)=>(_[K]=(Z.has(K)&&usedValuesProps.has(K)?q.style:X)[K],_),{})),Q=J===``?`Expected styles could not be parsed by the browser. Did you make a typo?`:this.utils.diff(printoutObjectStyles(Y),J);return[this.utils.matcherHint(_,`element`,``),Q].join(`
24
24
 
25
25
  `)}}}function getStyleFromObjectCSS(_){let K=browser===`chrome`||browser===`chromium`?document:document.implementation.createHTMLDocument(``),q=K.createElement(`div`);K.body.appendChild(q);let J=Object.keys(_);J.forEach(K=>{q.style[K]=_[K]});let Y={},X=window.getComputedStyle(q);return J.forEach(_=>{let K=(usedValuesProps.has(_)?q.style:X)[_];K!=null&&(Y[_]=K)}),q.remove(),Y}function computeCSSStyleDeclaration(_){let K=browser===`chrome`||browser===`chromium`||browser===`webkit`?document:document.implementation.createHTMLDocument(``),q=K.createElement(`div`);q.setAttribute(`style`,_.replace(/\n/g,``)),K.body.appendChild(q);let J=window.getComputedStyle(q),Y=Array.from(q.style).reduce((_,K)=>(_[K]=usedValuesProps.has(K)?q.style.getPropertyValue(K):J.getPropertyValue(K),_),{});return q.remove(),Y}function printoutObjectStyles(_){return Object.keys(_).sort().map(K=>`${K}: ${_[K]};`).join(`
26
- `)}function isSubset(_,K,q,J){let Y=Object.keys(_);return Y.length?Y.every(Y=>{let X=_[Y],Z=Y.startsWith(`--`),Q=[Y];return Z||Q.push(Y.toLowerCase()),Q.some(_=>{let Z=J.has(Y)&&usedValuesProps.has(Y)?K.style:q;return Z[_]===X||Z.getPropertyValue(_)===X})}):!1}function toHaveTextContent(_,K,q={normalizeWhitespace:!0}){let J=getNodeFromUserInput(_,toHaveTextContent,this),Y=q.normalizeWhitespace?normalize(J.textContent||``):(J.textContent||``).replace(/\u00A0/g,` `),X=Y!==``&&K===``;return{pass:!X&&matches(Y,K),message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveTextContent`,`element`,``),X?`Checking with empty string will always match, use .toBeEmptyDOMElement() instead`:`Expected element ${_} have text content`,K,`Received`,Y)}}}function toHaveValue(_,K){let q=getElementFromUserInput(_,toHaveValue,this);if(isInputElement(q)&&[`checkbox`,`radio`].includes(q.type))throw Error(`input with type=checkbox or type=radio cannot be used with .toHaveValue(). Use .toBeChecked() for type=checkbox or .toHaveFormValues() instead`);let J=getSingleElementValue(q),Y=K!==void 0,X=K,Z=J;return K==J&&K!==J&&(X=`${K} (${typeof K})`,Z=`${J} (${typeof J})`),{pass:Y?this.equals(J,K,[arrayAsSetComparison,...this.customTesters]):!!J,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveValue`,`element`,K);return getMessage(this,q,`Expected the element ${_} have value`,Y?X:`(any)`,`Received`,Z)}}}const counters=new Map([]);async function toMatchScreenshot(K,q,J=typeof q==`object`?q:{}){if(this.isNot)throw Error(`'toMatchScreenshot' cannot be used with "not"`);if(this.task===void 0||this.currentTestName===void 0)throw Error(`'toMatchScreenshot' cannot be used without test context`);let Y=`${this.task.result?.repeatCount??0}${this.testPath}${this.currentTestName}`,X=counters.get(Y);X===void 0&&(X={current:0},counters.set(Y,X)),X.current+=1;let Z=typeof q==`string`?q:`${this.currentTestName} ${X.current}`,Q=J.screenshotOptions&&`mask`in J.screenshotOptions?{...J,screenshotOptions:{...J.screenshotOptions,mask:J.screenshotOptions.mask.map(convertToSelector)}}:J,$=await getBrowserState().commands.triggerCommand(`__vitest_screenshotMatcher`,[Z,this.currentTestName,{element:convertToSelector(K),...Q}]);if($.pass===!1){let K=[];$.reference&&K.push({name:`reference`,...$.reference}),$.actual&&K.push({name:`actual`,...$.actual}),$.diff&&K.push({name:`diff`,path:$.diff}),K.length>0&&await recordArtifact(this.task,{type:`internal:toMatchScreenshot`,kind:`visual-regression`,message:$.message,attachments:K})}return{pass:$.pass,message:()=>$.pass?``:[this.utils.matcherHint(`toMatchScreenshot`,`element`,``),``,$.message,$.reference?`\nReference screenshot:\n ${this.utils.EXPECTED_COLOR($.reference.path)}`:null,$.actual?`\nActual screenshot:\n ${this.utils.RECEIVED_COLOR($.actual.path)}`:null,$.diff?this.utils.DIM_COLOR(`\nDiff image:\n ${$.diff}`):null,``].filter(_=>_!==null).join(`
26
+ `)}function isSubset(_,K,q,J){let Y=Object.keys(_);return Y.length?Y.every(Y=>{let X=_[Y],Z=Y.startsWith(`--`),Q=[Y];return Z||Q.push(Y.toLowerCase()),Q.some(_=>{let Z=J.has(Y)&&usedValuesProps.has(Y)?K.style:q;return Z[_]===X||Z.getPropertyValue(_)===X})}):!1}function toHaveTextContent(_,K,q={normalizeWhitespace:!0}){let J=getNodeFromUserInput(_,toHaveTextContent,this),Y=q.normalizeWhitespace?normalize(J.textContent||``):(J.textContent||``).replace(/\u00A0/g,` `),X=Y!==``&&K===``;return{pass:!X&&matches(Y,K),message:()=>{let _=this.isNot?`not to`:`to`;return getMessage(this,this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveTextContent`,`element`,``),X?`Checking with empty string will always match, use .toBeEmptyDOMElement() instead`:`Expected element ${_} have text content`,K,`Received`,Y)}}}function toHaveValue(_,K){let q=getElementFromUserInput(_,toHaveValue,this);if(isInputElement(q)&&[`checkbox`,`radio`].includes(q.type))throw Error(`input with type=checkbox or type=radio cannot be used with .toHaveValue(). Use .toBeChecked() for type=checkbox or .toHaveFormValues() instead`);let J=getSingleElementValue(q),Y=K!==void 0,X=K,Z=J;return K==J&&K!==J&&(X=`${K} (${typeof K})`,Z=`${J} (${typeof J})`),{pass:Y?this.equals(J,K,[arrayAsSetComparison,...this.customTesters]):!!J,message:()=>{let _=this.isNot?`not to`:`to`,q=this.utils.matcherHint(`${this.isNot?`.not`:``}.toHaveValue`,`element`,K);return getMessage(this,q,`Expected the element ${_} have value`,Y?X:`(any)`,`Received`,Z)}}}const counters=new Map([]);async function toMatchScreenshot(K,q,J=typeof q==`object`?q:{}){if(this.isNot)throw Error(`'toMatchScreenshot' cannot be used with "not"`);if(this.task===void 0||this.currentTestName===void 0)throw Error(`'toMatchScreenshot' cannot be used without test context`);let Y=`${this.task.result?.repeatCount??0}${this.testPath}${this.currentTestName}`,X=counters.get(Y);X===void 0&&(X={current:0},counters.set(Y,X)),X.current+=1;let Z=typeof q==`string`?q:`${this.currentTestName} ${X.current}`,Q=J.screenshotOptions&&`mask`in J.screenshotOptions?{...J,screenshotOptions:{...J.screenshotOptions,mask:J.screenshotOptions.mask.map(convertToSelector)}}:J,$=await getBrowserState().commands.triggerCommand(`__vitest_screenshotMatcher`,[Z,this.currentTestName,{element:convertToSelector(K),...Q}]);if($.pass===!1){let K=[];$.reference&&K.push({name:`reference`,...$.reference}),$.actual&&K.push({name:`actual`,...$.actual}),$.diff&&K.push({name:`diff`,...$.diff}),K.length>0&&await recordArtifact(this.task,{type:`internal:toMatchScreenshot`,kind:`visual-regression`,message:$.message,attachments:K})}return{pass:$.pass,message:()=>$.pass?``:[this.utils.matcherHint(`toMatchScreenshot`,`element`,``),``,$.message,$.reference?`\nReference screenshot:\n ${this.utils.EXPECTED_COLOR($.reference.path)}`:null,$.actual?`\nActual screenshot:\n ${this.utils.RECEIVED_COLOR($.actual.path)}`:null,$.diff?this.utils.DIM_COLOR(`\nDiff image:\n ${$.diff.path}`):null,``].filter(_=>_!==null).join(`
27
27
  `)}}const matchers={toBeDisabled,toBeEnabled,toBeEmptyDOMElement,toBeInTheDocument,toBeInViewport,toBeInvalid,toBeRequired,toBeValid,toBeVisible,toContainElement,toContainHTML,toHaveAccessibleDescription,toHaveAccessibleErrorMessage,toHaveAccessibleName,toHaveAttribute,toHaveClass,toHaveFocus,toHaveFormValues,toHaveStyle,toHaveTextContent,toHaveValue,toHaveDisplayValue,toBeChecked,toBePartiallyChecked,toHaveRole,toHaveSelection,toMatchScreenshot},kLocator=Symbol.for(`$$vitest:locator`);function element(_,Y){if(_!=null&&!(_ instanceof HTMLElement)&&!(_ instanceof SVGElement)&&!(kLocator in _))throw Error(`Invalid element or locator: ${_}. Expected an instance of HTMLElement, SVGElement or Locator, received ${getType(_)}`);let X=expect.poll(function(){if(_ instanceof Element||_==null)return _;let K=chai.util.flag(this,`negate`),J=chai.util.flag(this,`_name`);if(K&&J===`toBeInTheDocument`)return _.query();if(J===`toHaveLength`)return _.elements();if(J===`toMatchScreenshot`&&!chai.util.flag(this,`_poll.assert_once`)&&chai.util.flag(this,`_poll.assert_once`,!0),chai.util.flag(this,`_isLastPollAttempt`))return _.element();let Y=_.query();if(!Y)throw Error(`Cannot find element with locator: ${JSON.stringify(_)}`);return Y},processTimeoutOptions(Y));return chai.util.flag(X,`_poll.element`,!0),X}expect.extend(matchers),expect.element=element;