@vitest/browser 4.1.4 → 5.0.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.
@@ -1,7 +1,7 @@
1
- import { c as resolve, m as moduleRunner, d as getWorkerState, g as getBrowserState, e as getTestName, a as getConfig } from "./utils-DmkAiRYk.js";
1
+ import { c as resolve, g as getBrowserState, n as now$1, m as moduleRunner, d as getWorkerState, e as getTestName, a as getConfig } from "./utils-BYUpz6v6.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, Traces, setupCommonEnv, startCoverageInsideWorker, stopCoverageInsideWorker, startTests, collectTests, SpyModule } from "vitest/internal/browser";
4
+ import { getSafeTimers, DecodedMap as DecodedMap$1, getOriginalPosition as getOriginalPosition$1, loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker, format, Traces, setupCommonEnv, startCoverageInsideWorker, stopCoverageInsideWorker, startTests, collectTests, SpyModule } from "vitest/internal/browser";
5
5
  import { TestRunner, BenchmarkRunner, recordArtifact } from "vitest";
6
6
  const scriptRel = "modulepreload";
7
7
  const assetsURL = function(dep) {
@@ -690,7 +690,14 @@ function parseStacktrace(stack, options = {}) {
690
690
  const { ignoreStackEntries = stackIgnorePatterns } = options;
691
691
  let stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack);
692
692
  const helperIndex = stacks.findLastIndex(
693
- (s) => s.method === "__VITEST_HELPER__" || s.method === "async*__VITEST_HELPER__" || s.method === "async __VITEST_HELPER__"
693
+ (s) => (
694
+ // this covers cases such as
695
+ // "__VITEST_HELPER__"
696
+ // "__VITEST_HELPER__ [as <object method name>]"
697
+ // "async*__VITEST_HELPER__" (firefox)
698
+ // "async __VITEST_HELPER__" (webkit)
699
+ s.method.includes("__VITEST_HELPER__")
700
+ )
694
701
  );
695
702
  if (helperIndex >= 0) {
696
703
  stacks = stacks.slice(helperIndex + 1);
@@ -819,6 +826,101 @@ class VitestBrowserSnapshotEnvironment {
819
826
  function rpc$1() {
820
827
  return globalThis.__vitest_worker__.rpc;
821
828
  }
829
+ const PSEUDO_CLASS_NAMES = [
830
+ ":hover",
831
+ ":active",
832
+ ":focus",
833
+ ":focus-visible",
834
+ ":focus-within"
835
+ ];
836
+ function getBrowserTraceState() {
837
+ var _a;
838
+ return (_a = getBrowserState()).browserTraceState ?? (_a.browserTraceState = {});
839
+ }
840
+ function getTraceStateKey(testId, repeats, retry) {
841
+ return `${testId}:${repeats}:${retry}`;
842
+ }
843
+ function recordBrowserTraceEntry(task, options) {
844
+ var _a;
845
+ if ((_a = options.selector) == null ? void 0 : _a.startsWith("html >")) {
846
+ options.selector = options.selector.slice(6);
847
+ }
848
+ const attemptInfo = getBrowserState().browserTraceAttempts.get(task.id);
849
+ const relativeStartTime = (options.startTime ?? now$1()) - attemptInfo.startTime;
850
+ const snapshot = takeSnapshot(options.selector);
851
+ const entry = {
852
+ ...options,
853
+ startTime: relativeStartTime,
854
+ snapshot
855
+ };
856
+ const { retry, repeats } = attemptInfo;
857
+ const { recordCanvas } = getBrowserState().config.browser.traceView;
858
+ const state = getBrowserTraceState();
859
+ const traceKey = getTraceStateKey(task.id, repeats, retry);
860
+ state[traceKey] ?? (state[traceKey] = { retry, repeats, recordCanvas, entries: [] });
861
+ state[traceKey].entries.push(entry);
862
+ }
863
+ function takeSnapshot(selector) {
864
+ const { snapshot, createMirror } = getBrowserState().browserTraceDomSnapshot;
865
+ const traceView = getBrowserState().config.browser.traceView;
866
+ const engine = getBrowserState().selectorEngine;
867
+ const mirror = createMirror();
868
+ const serialized = snapshot(document, {
869
+ mirror,
870
+ inlineImages: traceView.inlineImages,
871
+ recordCanvas: traceView.recordCanvas
872
+ });
873
+ const result = {
874
+ serialized,
875
+ viewport: {
876
+ width: window.innerWidth,
877
+ height: window.innerHeight
878
+ },
879
+ scroll: {
880
+ x: window.scrollX,
881
+ y: window.scrollY
882
+ },
883
+ pseudoClassIds: {}
884
+ };
885
+ for (const className of PSEUDO_CLASS_NAMES) {
886
+ const elements = document.querySelectorAll(className);
887
+ const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
888
+ result.pseudoClassIds[className] = ids;
889
+ }
890
+ if (selector) {
891
+ try {
892
+ const el = engine.querySelector(
893
+ engine.parseSelector(selector),
894
+ document.documentElement,
895
+ false
896
+ );
897
+ if (!el) {
898
+ result.selectorResolution = "missing";
899
+ } else {
900
+ const id = mirror.getId(el);
901
+ if (id !== -1) {
902
+ result.selectorId = id;
903
+ result.selectorResolution = "matched";
904
+ } else {
905
+ result.selectorResolution = "missing";
906
+ }
907
+ }
908
+ } catch (error) {
909
+ result.selectorResolution = "error";
910
+ result.selectorError = error instanceof Error ? error.message : String(error);
911
+ }
912
+ }
913
+ return result;
914
+ }
915
+ function getBrowserTrace(testId, repeats, retry) {
916
+ const state = getBrowserTraceState();
917
+ const traceKey = getTraceStateKey(testId, repeats, retry);
918
+ const result = state[traceKey];
919
+ if (result) {
920
+ delete state[traceKey];
921
+ return result;
922
+ }
923
+ }
822
924
  const browserHashMap = /* @__PURE__ */ new Map();
823
925
  function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
824
926
  return class BrowserTestRunner extends runnerClass {
@@ -847,6 +949,18 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
847
949
  const test = args[0];
848
950
  const { retry, repeats } = args[1];
849
951
  const shouldTrace = trace !== "off" && !(trace === "on-all-retries" && retry === 0) && !(trace === "on-first-retry" && retry !== 1);
952
+ const shouldTraceView = this.config.browser.traceView.enabled;
953
+ if (!shouldTraceView && !shouldTrace) {
954
+ getBrowserState().activeTraceTaskIds.delete(test.id);
955
+ getBrowserState().browserTraceAttempts.delete(test.id);
956
+ return;
957
+ }
958
+ if (shouldTraceView) {
959
+ getBrowserState().browserTraceDomSnapshot = await __vitePreload(() => import("./rrweb-snapshot-xhvrgOHx.js"), true ? [] : void 0);
960
+ getBrowserState().browserTraceAttempts.set(test.id, { retry, repeats, startTime: now$1() });
961
+ } else {
962
+ getBrowserState().browserTraceAttempts.delete(test.id);
963
+ }
850
964
  if (!shouldTrace) {
851
965
  getBrowserState().activeTraceTaskIds.delete(test.id);
852
966
  return;
@@ -866,13 +980,34 @@ function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
866
980
  );
867
981
  };
868
982
  onAfterRetryTask = async (test, { retry, repeats }) => {
869
- var _a, _b, _c;
870
- if (!getBrowserState().activeTraceTaskIds.has(test.id)) {
983
+ var _a, _b, _c, _d, _e, _f;
984
+ const hasActiveTraceView = getBrowserState().browserTraceAttempts.has(test.id);
985
+ if (hasActiveTraceView) {
986
+ const status = (_a = test.result) == null ? void 0 : _a.state;
987
+ const stack = status === "fail" ? (_c = (_b = test.result) == null ? void 0 : _b.errors) == null ? void 0 : _c[0].stack : void 0;
988
+ const location2 = test.location ? { ...test.location, file: test.file.filepath } : void 0;
989
+ recordBrowserTraceEntry(test, {
990
+ name: `vitest:onAfterRetryTask`,
991
+ kind: "lifecycle",
992
+ ...status === "pass" || status === "fail" ? { status } : {},
993
+ ...stack ? { stack } : location2 ? { location: location2 } : {}
994
+ });
995
+ const traceData = getBrowserTrace(test.id, repeats, retry);
996
+ if (traceData) {
997
+ await this.commands.triggerCommand(
998
+ "__vitest_recordBrowserTrace",
999
+ [{ testId: test.id, data: traceData }]
1000
+ );
1001
+ }
1002
+ getBrowserState().browserTraceAttempts.delete(test.id);
1003
+ }
1004
+ const hasActiveTrace = getBrowserState().activeTraceTaskIds.has(test.id);
1005
+ if (!hasActiveTrace) {
871
1006
  return;
872
1007
  }
873
1008
  await this.commands.triggerCommand("__vitest_markTrace", [{
874
- name: `onAfterRetryTask [${(_a = test.result) == null ? void 0 : _a.state}]`,
875
- stack: (_c = (_b = test.result) == null ? void 0 : _b.errors) == null ? void 0 : _c[0].stack
1009
+ name: `onAfterRetryTask [${(_d = test.result) == null ? void 0 : _d.state}]`,
1010
+ stack: (_f = (_e = test.result) == null ? void 0 : _e.errors) == null ? void 0 : _f[0].stack
876
1011
  }]);
877
1012
  const name = getTraceName(test, retry, repeats);
878
1013
  if (!this.traces.has(test.id)) {
@@ -1146,7 +1281,7 @@ function setupConsoleLogSpy() {
1146
1281
  console$1.warn = stderr(warn);
1147
1282
  console$1.dir = (item, options) => {
1148
1283
  dir(item, options);
1149
- sendLog("stdout", browserFormat(item));
1284
+ sendLog("stdout", processLog([item]));
1150
1285
  };
1151
1286
  console$1.dirxml = (...args) => {
1152
1287
  dirxml(...args);
@@ -1217,7 +1352,7 @@ function stderr(base) {
1217
1352
  };
1218
1353
  }
1219
1354
  function processLog(args) {
1220
- return browserFormat(...args);
1355
+ return format(args, { multiline: true });
1221
1356
  }
1222
1357
  function sendLog(type, content, disableStack) {
1223
1358
  var _a, _b, _c;
@@ -2017,9 +2152,10 @@ class CommandsManager {
2017
2152
  const { sessionId, traces: traces2 } = getBrowserState();
2018
2153
  const filepath = state.filepath || ((_b = (_a = state.current) == null ? void 0 : _a.file) == null ? void 0 : _b.filepath);
2019
2154
  args = args.filter((arg) => arg !== void 0);
2020
- const actionTraceGroupName = ACTION_TRACE_COMMANDS.has(command) ? command : void 0;
2155
+ const actionTraceGroupName = ACTION_TRACE_COMMANDS.has(command) ? `vitest:${command.slice("__vitest_".length)}` : void 0;
2021
2156
  const currentTest = getWorkerState().current;
2022
- const shouldMarkTrace = actionTraceGroupName && !!currentTest && getBrowserState().activeTraceTaskIds.has(currentTest.id);
2157
+ const hasActiveTrace = !!actionTraceGroupName && !!currentTest && getBrowserState().activeTraceTaskIds.has(currentTest.id);
2158
+ const hasActiveTraceView = !!actionTraceGroupName && !!currentTest && getBrowserState().browserTraceAttempts.has(currentTest.id);
2023
2159
  if (this._listeners.length) {
2024
2160
  await Promise.all(this._listeners.map((listener) => listener(command, args)));
2025
2161
  }
@@ -2033,7 +2169,7 @@ class CommandsManager {
2033
2169
  },
2034
2170
  async () => {
2035
2171
  var _a2;
2036
- if (shouldMarkTrace) {
2172
+ if (hasActiveTrace) {
2037
2173
  await rpc2.triggerCommand(
2038
2174
  sessionId,
2039
2175
  "__vitest_groupTraceStart",
@@ -2044,15 +2180,29 @@ class CommandsManager {
2044
2180
  }]
2045
2181
  );
2046
2182
  }
2183
+ let status = "pass";
2184
+ const startTime = now$1();
2047
2185
  try {
2048
2186
  return await rpc2.triggerCommand(sessionId, command, filepath, args);
2049
2187
  } catch (err) {
2188
+ status = "fail";
2050
2189
  clientError.message = err.message;
2051
2190
  clientError.name = err.name;
2052
2191
  clientError.stack = (_a2 = clientError.stack) == null ? void 0 : _a2.replace(clientError.message, err.message);
2053
2192
  throw clientError;
2054
2193
  } finally {
2055
- if (shouldMarkTrace) {
2194
+ if (hasActiveTraceView) {
2195
+ recordBrowserTraceEntry(currentTest, {
2196
+ name: actionTraceGroupName,
2197
+ kind: "action",
2198
+ status,
2199
+ startTime,
2200
+ duration: now$1() - startTime,
2201
+ selector: typeof args[0] === "string" ? args[0] : void 0,
2202
+ stack: clientError.stack
2203
+ });
2204
+ }
2205
+ if (hasActiveTrace) {
2056
2206
  await rpc2.triggerCommand(
2057
2207
  sessionId,
2058
2208
  "__vitest_groupTraceEnd",
@@ -2065,7 +2215,6 @@ class CommandsManager {
2065
2215
  );
2066
2216
  }
2067
2217
  }
2068
- globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
2069
2218
  getBrowserState().provider;
2070
2219
  const debugVar = getConfig().env.VITEST_BROWSER_DEBUG;
2071
2220
  const debug = debugVar && debugVar !== "false" ? (...args) => {
@@ -2143,6 +2292,7 @@ const iframeId = url.searchParams.get("iframeId");
2143
2292
  const commands = new CommandsManager();
2144
2293
  getBrowserState().commands = commands;
2145
2294
  getBrowserState().activeTraceTaskIds = /* @__PURE__ */ new Set();
2295
+ getBrowserState().browserTraceAttempts = /* @__PURE__ */ new Map();
2146
2296
  getBrowserState().iframeId = iframeId;
2147
2297
  let contextSwitched = false;
2148
2298
  async function prepareTestEnvironment(options) {