@vitest/runner 4.1.0-beta.2 → 4.1.0-beta.3

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.
@@ -578,4 +578,4 @@ function createTaskName(names, separator = " > ") {
578
578
  return names.filter((name) => name !== undefined).join(separator);
579
579
  }
580
580
 
581
- export { calculateSuiteHash as a, createFileTask as b, createChainable as c, generateHash as d, createTagsFilter as e, findTestFileStackTrace as f, generateFileHash as g, createTaskName as h, interpretTaskModes as i, getFullName as j, getNames as k, limitConcurrency as l, getSuites as m, getTasks as n, getTestName as o, partitionSuiteChildren as p, getTests as q, hasFailed as r, someTasksAreOnly as s, hasTests as t, isTestCase as u, validateTags as v, createNoTagsError as w };
581
+ export { createChainable as a, createFileTask as b, calculateSuiteHash as c, createTagsFilter as d, createTaskName as e, findTestFileStackTrace as f, generateFileHash as g, generateHash as h, getFullName as i, getNames as j, getSuites as k, getTasks as l, getTestName as m, getTests as n, hasFailed as o, hasTests as p, interpretTaskModes as q, isTestCase as r, limitConcurrency as s, partitionSuiteChildren as t, someTasksAreOnly as u, validateTags as v, createNoTagsError as w };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TestArtifact, a as Test, S as Suite, b as SuiteHooks, F as FileSpecification, V as VitestRunner, c as File, d as TaskUpdateEvent, e as Task, f as TestAPI, g as SuiteAPI, h as SuiteCollector } from './tasks.d-CLPU8HE4.js';
2
- export { A as AfterAllListener, s as AfterEachListener, B as BeforeAllListener, t as BeforeEachListener, C as CancelReason, u as Fixture, v as FixtureFn, w as FixtureOptions, x as Fixtures, I as ImportDuration, y as InferFixturesTypes, O as OnTestFailedHandler, z as OnTestFinishedHandler, R as Retry, D as RunMode, E as RuntimeContext, G as SequenceHooks, H as SequenceSetupFiles, J as SerializableRetry, K as SuiteFactory, L as TaskBase, M as TaskCustomOptions, N as TaskEventPack, P as TaskHook, Q as TaskMeta, U as TaskPopulated, W as TaskResult, X as TaskResultPack, Y as TaskState, Z as TestAnnotation, _ as TestAnnotationArtifact, $ as TestAnnotationLocation, a0 as TestArtifactBase, a1 as TestArtifactLocation, a2 as TestArtifactRegistry, a3 as TestAttachment, a4 as TestContext, a5 as TestFunction, a6 as TestOptions, n as TestTagDefinition, a7 as TestTags, a8 as Use, a9 as VisualRegressionArtifact, p as VitestRunnerConfig, q as VitestRunnerConstructor, r as VitestRunnerImportSource, i as afterAll, j as afterEach, k as beforeAll, l as beforeEach, o as onTestFailed, m as onTestFinished } from './tasks.d-CLPU8HE4.js';
1
+ import { T as TestArtifact, a as Test, S as Suite, b as SuiteHooks, F as FileSpecification, V as VitestRunner, c as File, d as TaskUpdateEvent, e as Task, f as TestAPI, g as SuiteAPI, h as SuiteCollector } from './tasks.d-WWG4yDf6.js';
2
+ export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, m as Fixture, n as FixtureFn, o as FixtureOptions, p as Fixtures, I as ImportDuration, q as InferFixturesTypes, O as OnTestFailedHandler, r as OnTestFinishedHandler, R as Retry, s as RunMode, t as RuntimeContext, u as SequenceHooks, v as SequenceSetupFiles, w as SerializableRetry, x as SuiteFactory, y as SuiteOptions, z as TaskBase, D as TaskCustomOptions, E as TaskEventPack, G as TaskHook, H as TaskMeta, J as TaskPopulated, K as TaskResult, L as TaskResultPack, M as TaskState, N as TestAnnotation, P as TestAnnotationArtifact, Q as TestAnnotationLocation, U as TestArtifactBase, W as TestArtifactLocation, X as TestArtifactRegistry, Y as TestAttachment, Z as TestContext, _ as TestFunction, $ as TestOptions, a0 as TestTagDefinition, a1 as TestTags, a2 as Use, a3 as VisualRegressionArtifact, a4 as VitestRunnerConfig, a5 as VitestRunnerConstructor, a6 as VitestRunnerImportSource, a7 as afterAll, a8 as afterEach, a9 as aroundAll, aa as aroundEach, ab as beforeAll, ac as beforeEach, ad as onTestFailed, ae as onTestFinished } from './tasks.d-WWG4yDf6.js';
3
3
  import { Awaitable } from '@vitest/utils';
4
4
  import '@vitest/utils/diff';
5
5
 
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { processError } from '@vitest/utils/error';
2
2
  import { isObject, filterOutComments, createDefer, assertTypes, toArray, isNegativeNaN, unique, objectAttr, shuffle } from '@vitest/utils/helpers';
3
3
  import { getSafeTimers } from '@vitest/utils/timers';
4
4
  import { format, formatRegExp, objDisplay } from '@vitest/utils/display';
5
- import { c as createChainable, v as validateTags, h as createTaskName, w as createNoTagsError, f as findTestFileStackTrace, e as createTagsFilter, b as createFileTask, a as calculateSuiteHash, s as someTasksAreOnly, i as interpretTaskModes, l as limitConcurrency, p as partitionSuiteChildren, t as hasTests, r as hasFailed } from './chunk-tasks.js';
5
+ import { a as createChainable, v as validateTags, e as createTaskName, w as createNoTagsError, f as findTestFileStackTrace, d as createTagsFilter, b as createFileTask, c as calculateSuiteHash, u as someTasksAreOnly, q as interpretTaskModes, s as limitConcurrency, t as partitionSuiteChildren, p as hasTests, o as hasFailed } from './chunk-tasks.js';
6
6
  import '@vitest/utils/source-map';
7
7
  import 'pathe';
8
8
 
@@ -24,6 +24,15 @@ class TestRunAbortError extends Error {
24
24
  this.reason = reason;
25
25
  }
26
26
  }
27
+ class AroundHookSetupError extends Error {
28
+ name = "AroundHookSetupError";
29
+ }
30
+ class AroundHookTeardownError extends Error {
31
+ name = "AroundHookTeardownError";
32
+ }
33
+ class AroundHookMultipleCallsError extends Error {
34
+ name = "AroundHookMultipleCallsError";
35
+ }
27
36
 
28
37
  // use WeakMap here to make the Test and Suite object serializable
29
38
  const fnMap = new WeakMap();
@@ -134,6 +143,33 @@ async function callFixtureCleanup(context) {
134
143
  }
135
144
  cleanupFnArrayMap.delete(context);
136
145
  }
146
+ /**
147
+ * Returns the current number of cleanup functions registered for the context.
148
+ * This can be used as a checkpoint to later clean up only fixtures added after this point.
149
+ */
150
+ function getFixtureCleanupCount(context) {
151
+ var _cleanupFnArrayMap$ge;
152
+ return ((_cleanupFnArrayMap$ge = cleanupFnArrayMap.get(context)) === null || _cleanupFnArrayMap$ge === void 0 ? void 0 : _cleanupFnArrayMap$ge.length) ?? 0;
153
+ }
154
+ /**
155
+ * Cleans up only fixtures that were added after the given checkpoint index.
156
+ * This is used by aroundEach to clean up fixtures created inside runTest()
157
+ * while preserving fixtures that were created for aroundEach itself.
158
+ */
159
+ async function callFixtureCleanupFrom(context, fromIndex) {
160
+ const cleanupFnArray = cleanupFnArrayMap.get(context);
161
+ if (!cleanupFnArray || cleanupFnArray.length <= fromIndex) {
162
+ return;
163
+ }
164
+ // Get items added after the checkpoint
165
+ const toCleanup = cleanupFnArray.slice(fromIndex);
166
+ // Clean up in reverse order
167
+ for (const cleanup of toCleanup.reverse()) {
168
+ await cleanup();
169
+ }
170
+ // Remove cleaned up items from the array, keeping items before checkpoint
171
+ cleanupFnArray.length = fromIndex;
172
+ }
137
173
  function withFixtures(runner, fn, testContext) {
138
174
  return (hookContext) => {
139
175
  const context = hookContext || testContext;
@@ -358,6 +394,8 @@ function getDefaultHookTimeout() {
358
394
  }
359
395
  const CLEANUP_TIMEOUT_KEY = Symbol.for("VITEST_CLEANUP_TIMEOUT");
360
396
  const CLEANUP_STACK_TRACE_KEY = Symbol.for("VITEST_CLEANUP_STACK_TRACE");
397
+ const AROUND_TIMEOUT_KEY = Symbol.for("VITEST_AROUND_TIMEOUT");
398
+ const AROUND_STACK_TRACE_KEY = Symbol.for("VITEST_AROUND_STACK_TRACE");
361
399
  function getBeforeHookCleanupCallback(hook, result, context) {
362
400
  if (typeof result === "function") {
363
401
  const timeout = CLEANUP_TIMEOUT_KEY in hook && typeof hook[CLEANUP_TIMEOUT_KEY] === "number" ? hook[CLEANUP_TIMEOUT_KEY] : getDefaultHookTimeout();
@@ -512,6 +550,113 @@ const onTestFinished = createTestHook("onTestFinished", (test, handler, timeout)
512
550
  test.onFinished || (test.onFinished = []);
513
551
  test.onFinished.push(withTimeout(handler, timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"), abortIfTimeout));
514
552
  });
553
+ /**
554
+ * Registers a callback function that wraps around all tests within the current suite.
555
+ * The callback receives a `runSuite` function that must be called to run the suite's tests.
556
+ * This hook is useful for scenarios where you need to wrap an entire suite in a context
557
+ * (e.g., starting a server, opening a database connection that all tests share).
558
+ *
559
+ * **Note:** When multiple `aroundAll` hooks are registered, they are nested inside each other.
560
+ * The first registered hook is the outermost wrapper.
561
+ *
562
+ * **Note:** Unlike `aroundEach`, the `aroundAll` hook does not receive test context or support fixtures,
563
+ * as it runs at the suite level before any individual test context is created.
564
+ *
565
+ * @param {Function} fn - The callback function that wraps the suite. Must call `runSuite()` to run the tests.
566
+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
567
+ * @returns {void}
568
+ * @example
569
+ * ```ts
570
+ * // Example of using aroundAll to wrap suite in a tracing span
571
+ * aroundAll(async (runSuite) => {
572
+ * await tracer.trace('test-suite', runSuite);
573
+ * });
574
+ * ```
575
+ * @example
576
+ * ```ts
577
+ * // Example of using aroundAll with AsyncLocalStorage context
578
+ * aroundAll(async (runSuite) => {
579
+ * await asyncLocalStorage.run({ suiteId: 'my-suite' }, runSuite);
580
+ * });
581
+ * ```
582
+ */
583
+ function aroundAll(fn, timeout) {
584
+ assertTypes(fn, "\"aroundAll\" callback", ["function"]);
585
+ const stackTraceError = new Error("STACK_TRACE_ERROR");
586
+ const resolvedTimeout = timeout ?? getDefaultHookTimeout();
587
+ return getCurrentSuite().on("aroundAll", Object.assign(fn, {
588
+ [AROUND_TIMEOUT_KEY]: resolvedTimeout,
589
+ [AROUND_STACK_TRACE_KEY]: stackTraceError
590
+ }));
591
+ }
592
+ /**
593
+ * Registers a callback function that wraps around each test within the current suite.
594
+ * The callback receives a `runTest` function that must be called to run the test.
595
+ * This hook is useful for scenarios where you need to wrap tests in a context (e.g., database transactions).
596
+ *
597
+ * **Note:** When multiple `aroundEach` hooks are registered, they are nested inside each other.
598
+ * The first registered hook is the outermost wrapper.
599
+ *
600
+ * @param {Function} fn - The callback function that wraps the test. Must call `runTest()` to run the test.
601
+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
602
+ * @returns {void}
603
+ * @example
604
+ * ```ts
605
+ * // Example of using aroundEach to wrap tests in a database transaction
606
+ * aroundEach(async (runTest) => {
607
+ * await database.transaction(() => runTest());
608
+ * });
609
+ * ```
610
+ * @example
611
+ * ```ts
612
+ * // Example of using aroundEach with fixtures
613
+ * aroundEach(async (runTest, { db }) => {
614
+ * await db.transaction(() => runTest());
615
+ * });
616
+ * ```
617
+ */
618
+ function aroundEach(fn, timeout) {
619
+ assertTypes(fn, "\"aroundEach\" callback", ["function"]);
620
+ const stackTraceError = new Error("STACK_TRACE_ERROR");
621
+ const resolvedTimeout = timeout ?? getDefaultHookTimeout();
622
+ const runner = getRunner();
623
+ // Create a wrapper function that supports fixtures in the second argument (context)
624
+ // withFixtures resolves fixtures into context, then we call fn with all 3 args
625
+ const wrappedFn = withAroundEachFixtures(runner, fn);
626
+ // Store timeout and stack trace on the function for use in callAroundEachHooks
627
+ // Setup and teardown phases will each have their own timeout
628
+ return getCurrentSuite().on("aroundEach", Object.assign(wrappedFn, {
629
+ [AROUND_TIMEOUT_KEY]: resolvedTimeout,
630
+ [AROUND_STACK_TRACE_KEY]: stackTraceError
631
+ }));
632
+ }
633
+ /**
634
+ * Wraps an aroundEach listener to support fixtures.
635
+ * Similar to withFixtures, but handles the aroundEach signature where:
636
+ * - First arg is runTest function
637
+ * - Second arg is context (where fixtures are destructured from)
638
+ * - Third arg is suite
639
+ */
640
+ function withAroundEachFixtures(runner, fn) {
641
+ // Create the wrapper that will be returned
642
+ const wrapper = (runTest, context, suite) => {
643
+ // Create inner function that will be passed to withFixtures
644
+ // This function receives context (with fixtures resolved) and calls original fn
645
+ const innerFn = (ctx) => fn(runTest, ctx, suite);
646
+ innerFn.__VITEST_FIXTURE_INDEX__ = 1;
647
+ innerFn.toString = () => fn.toString();
648
+ // Use withFixtures to resolve fixtures, passing context as the hook context
649
+ const fixtureResolver = withFixtures(runner, innerFn);
650
+ return fixtureResolver(context);
651
+ };
652
+ return wrapper;
653
+ }
654
+ function getAroundHookTimeout(hook) {
655
+ return AROUND_TIMEOUT_KEY in hook && typeof hook[AROUND_TIMEOUT_KEY] === "number" ? hook[AROUND_TIMEOUT_KEY] : getDefaultHookTimeout();
656
+ }
657
+ function getAroundHookStackTrace(hook) {
658
+ return AROUND_STACK_TRACE_KEY in hook && hook[AROUND_STACK_TRACE_KEY] instanceof Error ? hook[AROUND_STACK_TRACE_KEY] : undefined;
659
+ }
515
660
  function createTestHook(name, handler) {
516
661
  return (fn, timeout) => {
517
662
  assertTypes(fn, `"${name}" callback`, ["function"]);
@@ -698,7 +843,9 @@ function createSuiteHooks() {
698
843
  beforeAll: [],
699
844
  afterAll: [],
700
845
  beforeEach: [],
701
- afterEach: []
846
+ afterEach: [],
847
+ aroundEach: [],
848
+ aroundAll: []
702
849
  };
703
850
  }
704
851
  const POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
@@ -746,15 +893,31 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
746
893
  }
747
894
  return tagDefinition;
748
895
  }).filter((r) => r != null).sort((tag1, tag2) => (tag2.priority ?? POSITIVE_INFINITY) - (tag1.priority ?? POSITIVE_INFINITY)).reduce((acc, tag) => {
749
- const { name, description, priority, ...options } = tag;
896
+ const { name, description, priority, meta, ...options } = tag;
750
897
  Object.assign(acc, options);
898
+ if (meta) {
899
+ acc.meta = Object.assign(acc.meta ?? Object.create(null), meta);
900
+ }
751
901
  return acc;
752
902
  }, {});
903
+ const testOwnMeta = options.meta;
753
904
  options = {
754
905
  ...tagsOptions,
755
906
  ...options
756
907
  };
757
908
  const timeout = options.timeout ?? runner.config.testTimeout;
909
+ const parentMeta = currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.meta;
910
+ const tagMeta = tagsOptions.meta;
911
+ const testMeta = Object.create(null);
912
+ if (tagMeta) {
913
+ Object.assign(testMeta, tagMeta);
914
+ }
915
+ if (parentMeta) {
916
+ Object.assign(testMeta, parentMeta);
917
+ }
918
+ if (testOwnMeta) {
919
+ Object.assign(testMeta, testOwnMeta);
920
+ }
758
921
  const task = {
759
922
  id: "",
760
923
  name,
@@ -770,7 +933,7 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
770
933
  retry: options.retry ?? runner.config.retry,
771
934
  repeats: options.repeats,
772
935
  mode: options.only ? "only" : options.skip ? "skip" : options.todo ? "todo" : "run",
773
- meta: options.meta ?? Object.create(null),
936
+ meta: testMeta,
774
937
  annotations: [],
775
938
  artifacts: [],
776
939
  tags: testTags
@@ -880,7 +1043,7 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
880
1043
  file: (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.file) ?? ((_collectorContext$cur8 = collectorContext.currentSuite) === null || _collectorContext$cur8 === void 0 ? void 0 : _collectorContext$cur8.file),
881
1044
  shuffle: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.shuffle,
882
1045
  tasks: [],
883
- meta: Object.create(null),
1046
+ meta: (suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.meta) ?? Object.create(null),
884
1047
  concurrent: suiteOptions === null || suiteOptions === void 0 ? void 0 : suiteOptions.concurrent,
885
1048
  tags: unique([...(parentTask === null || parentTask === void 0 ? void 0 : parentTask.tags) || [], ...suiteTags])
886
1049
  };
@@ -944,9 +1107,10 @@ function createSuite() {
944
1107
  let { options, handler: factory } = parseArguments(factoryOrOptions, optionsOrFactory);
945
1108
  const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false;
946
1109
  const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false;
1110
+ const { meta: parentMeta, ...parentOptions } = (currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.options) || {};
947
1111
  // inherit options from current suite
948
1112
  options = {
949
- ...currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.options,
1113
+ ...parentOptions,
950
1114
  ...options
951
1115
  };
952
1116
  const shuffle = this.shuffle ?? options.shuffle ?? (currentSuite === null || currentSuite === void 0 || (_currentSuite$options = currentSuite.options) === null || _currentSuite$options === void 0 ? void 0 : _currentSuite$options.shuffle) ?? (runner === null || runner === void 0 ? void 0 : runner.config.sequence.shuffle);
@@ -967,6 +1131,9 @@ function createSuite() {
967
1131
  if (isSequential != null) {
968
1132
  options.sequential = isSequential && !isConcurrent;
969
1133
  }
1134
+ if (parentMeta) {
1135
+ options.meta = Object.assign(Object.create(null), parentMeta, options.meta);
1136
+ }
970
1137
  return createSuiteCollector(formatName(name), factory, mode, this.each, options, currentSuite === null || currentSuite === void 0 ? void 0 : currentSuite.fixtures());
971
1138
  }
972
1139
  suiteFn.each = function(cases, ...args) {
@@ -1096,10 +1263,13 @@ function createTaskCollector(fn, context) {
1096
1263
  originalWrapper.call(context, formatName(name), optionsOrFn, optionsOrTest);
1097
1264
  }, _context);
1098
1265
  };
1266
+ taskFn.describe = suite;
1099
1267
  taskFn.beforeEach = beforeEach;
1100
1268
  taskFn.afterEach = afterEach;
1101
1269
  taskFn.beforeAll = beforeAll;
1102
1270
  taskFn.afterAll = afterAll;
1271
+ taskFn.aroundEach = aroundEach;
1272
+ taskFn.aroundAll = aroundAll;
1103
1273
  const _test = createChainable([
1104
1274
  "concurrent",
1105
1275
  "sequential",
@@ -1586,6 +1756,157 @@ async function callSuiteHook(suite, currentTask, name, runner, args) {
1586
1756
  }
1587
1757
  return callbacks;
1588
1758
  }
1759
+ function getAroundEachHooks(suite) {
1760
+ const hooks = [];
1761
+ const parentSuite = "filepath" in suite ? null : suite.suite || suite.file;
1762
+ if (parentSuite) {
1763
+ hooks.push(...getAroundEachHooks(parentSuite));
1764
+ }
1765
+ hooks.push(...getHooks(suite).aroundEach);
1766
+ return hooks;
1767
+ }
1768
+ function getAroundAllHooks(suite) {
1769
+ return getHooks(suite).aroundAll;
1770
+ }
1771
+ function makeAroundHookTimeoutError(hookName, phase, timeout, stackTraceError) {
1772
+ const message = `The ${phase} phase of "${hookName}" hook timed out after ${timeout}ms.`;
1773
+ const ErrorClass = phase === "setup" ? AroundHookSetupError : AroundHookTeardownError;
1774
+ const error = new ErrorClass(message);
1775
+ if (stackTraceError === null || stackTraceError === void 0 ? void 0 : stackTraceError.stack) {
1776
+ error.stack = stackTraceError.stack.replace(stackTraceError.message, error.message);
1777
+ }
1778
+ return error;
1779
+ }
1780
+ async function callAroundHooks(runInner, options) {
1781
+ const { hooks, hookName, callbackName, onTimeout, invokeHook } = options;
1782
+ if (!hooks.length) {
1783
+ await runInner();
1784
+ return;
1785
+ }
1786
+ const createTimeoutPromise = (timeout, phase, stackTraceError) => {
1787
+ let timer;
1788
+ const promise = new Promise((_, reject) => {
1789
+ if (timeout > 0 && timeout !== Number.POSITIVE_INFINITY) {
1790
+ var _timer$unref;
1791
+ timer = setTimeout(() => {
1792
+ const error = makeAroundHookTimeoutError(hookName, phase, timeout, stackTraceError);
1793
+ onTimeout === null || onTimeout === void 0 ? void 0 : onTimeout(error);
1794
+ reject(error);
1795
+ }, timeout);
1796
+ (_timer$unref = timer.unref) === null || _timer$unref === void 0 ? void 0 : _timer$unref.call(timer);
1797
+ }
1798
+ });
1799
+ const clear = () => {
1800
+ if (timer) {
1801
+ clearTimeout(timer);
1802
+ timer = undefined;
1803
+ }
1804
+ };
1805
+ return {
1806
+ promise,
1807
+ clear
1808
+ };
1809
+ };
1810
+ const runNextHook = async (index) => {
1811
+ if (index >= hooks.length) {
1812
+ return runInner();
1813
+ }
1814
+ const hook = hooks[index];
1815
+ const timeout = getAroundHookTimeout(hook);
1816
+ const stackTraceError = getAroundHookStackTrace(hook);
1817
+ let useCalled = false;
1818
+ let setupTimeout;
1819
+ let teardownTimeout;
1820
+ // Promise that resolves when use() is called (setup phase complete)
1821
+ let resolveUseCalled;
1822
+ const useCalledPromise = new Promise((resolve) => {
1823
+ resolveUseCalled = resolve;
1824
+ });
1825
+ // Promise that resolves when use() returns (inner hooks complete, teardown phase starts)
1826
+ let resolveUseReturned;
1827
+ const useReturnedPromise = new Promise((resolve) => {
1828
+ resolveUseReturned = resolve;
1829
+ });
1830
+ // Promise that resolves when hook completes
1831
+ let resolveHookComplete;
1832
+ let rejectHookComplete;
1833
+ const hookCompletePromise = new Promise((resolve, reject) => {
1834
+ resolveHookComplete = resolve;
1835
+ rejectHookComplete = reject;
1836
+ });
1837
+ const use = async () => {
1838
+ if (useCalled) {
1839
+ throw new AroundHookMultipleCallsError(`The \`${callbackName}\` callback was called multiple times in the \`${hookName}\` hook. ` + `The callback can only be called once per hook.`);
1840
+ }
1841
+ useCalled = true;
1842
+ resolveUseCalled();
1843
+ // Setup phase completed - clear setup timer
1844
+ setupTimeout.clear();
1845
+ // Run inner hooks - don't time this against our teardown timeout
1846
+ await runNextHook(index + 1);
1847
+ // Start teardown timer after inner hooks complete - only times this hook's teardown code
1848
+ teardownTimeout = createTimeoutPromise(timeout, "teardown", stackTraceError);
1849
+ // Signal that use() is returning (teardown phase starting)
1850
+ resolveUseReturned();
1851
+ };
1852
+ // Start setup timeout
1853
+ setupTimeout = createTimeoutPromise(timeout, "setup", stackTraceError);
1854
+ (async () => {
1855
+ try {
1856
+ await invokeHook(hook, use);
1857
+ if (!useCalled) {
1858
+ throw new AroundHookSetupError(`The \`${callbackName}\` callback was not called in the \`${hookName}\` hook. ` + `Make sure to call \`${callbackName}\` to run the ${hookName === "aroundEach" ? "test" : "suite"}.`);
1859
+ }
1860
+ resolveHookComplete();
1861
+ } catch (error) {
1862
+ rejectHookComplete(error);
1863
+ }
1864
+ })();
1865
+ // Wait for either: use() to be called OR hook to complete (error) OR setup timeout
1866
+ try {
1867
+ await Promise.race([
1868
+ useCalledPromise,
1869
+ hookCompletePromise,
1870
+ setupTimeout.promise
1871
+ ]);
1872
+ } finally {
1873
+ setupTimeout.clear();
1874
+ }
1875
+ // Wait for use() to return (inner hooks complete) OR hook to complete (error during inner hooks)
1876
+ await Promise.race([useReturnedPromise, hookCompletePromise]);
1877
+ // Now teardownTimeout is guaranteed to be set
1878
+ // Wait for hook to complete (teardown) OR teardown timeout
1879
+ try {
1880
+ await Promise.race([hookCompletePromise, teardownTimeout.promise]);
1881
+ } finally {
1882
+ teardownTimeout.clear();
1883
+ }
1884
+ };
1885
+ await runNextHook(0);
1886
+ }
1887
+ async function callAroundAllHooks(suite, runSuiteInner) {
1888
+ await callAroundHooks(runSuiteInner, {
1889
+ hooks: getAroundAllHooks(suite),
1890
+ hookName: "aroundAll",
1891
+ callbackName: "runSuite()",
1892
+ invokeHook: (hook, use) => hook(use, suite)
1893
+ });
1894
+ }
1895
+ async function callAroundEachHooks(suite, test, runTest) {
1896
+ await callAroundHooks(
1897
+ // Take checkpoint right before runTest - at this point all aroundEach fixtures
1898
+ // have been resolved, so we can correctly identify which fixtures belong to
1899
+ // aroundEach (before checkpoint) vs inside runTest (after checkpoint)
1900
+ () => runTest(getFixtureCleanupCount(test.context)),
1901
+ {
1902
+ hooks: getAroundEachHooks(suite),
1903
+ hookName: "aroundEach",
1904
+ callbackName: "runTest()",
1905
+ onTimeout: (error) => abortContextSignal(test.context, error),
1906
+ invokeHook: (hook, use) => hook(use, test.context, suite)
1907
+ }
1908
+ );
1909
+ }
1589
1910
  const packs = new Map();
1590
1911
  const eventsPacks = [];
1591
1912
  const pendingTasksUpdates = [];
@@ -1710,66 +2031,84 @@ async function runTest(test, runner) {
1710
2031
  for (let repeatCount = 0; repeatCount <= repeats; repeatCount++) {
1711
2032
  const retry = getRetryCount(test.retry);
1712
2033
  for (let retryCount = 0; retryCount <= retry; retryCount++) {
1713
- var _test$onFinished, _test$onFailed, _runner$onAfterRetryT, _test$result2, _test$result3;
2034
+ var _test$result2, _test$result3;
1714
2035
  let beforeEachCleanups = [];
1715
- try {
1716
- var _runner$onBeforeTryTa, _runner$onAfterTryTas;
1717
- await ((_runner$onBeforeTryTa = runner.onBeforeTryTask) === null || _runner$onBeforeTryTa === void 0 ? void 0 : _runner$onBeforeTryTa.call(runner, test, {
1718
- retry: retryCount,
1719
- repeats: repeatCount
1720
- }));
1721
- test.result.repeatCount = repeatCount;
1722
- beforeEachCleanups = await $("test.beforeEach", () => callSuiteHook(suite, test, "beforeEach", runner, [test.context, suite]));
1723
- if (runner.runTask) {
1724
- await $("test.callback", () => runner.runTask(test));
1725
- } else {
1726
- const fn = getFn(test);
1727
- if (!fn) {
1728
- throw new Error("Test function is not found. Did you add it using `setFn`?");
2036
+ // fixtureCheckpoint is passed by callAroundEachHooks - it represents the count
2037
+ // of fixture cleanup functions AFTER all aroundEach fixtures have been resolved
2038
+ // but BEFORE the test runs. This allows us to clean up only fixtures created
2039
+ // inside runTest while preserving aroundEach fixtures for teardown.
2040
+ await callAroundEachHooks(suite, test, async (fixtureCheckpoint) => {
2041
+ var _test$onFinished, _test$onFailed, _runner$onAfterRetryT;
2042
+ try {
2043
+ var _runner$onBeforeTryTa, _runner$onAfterTryTas;
2044
+ await ((_runner$onBeforeTryTa = runner.onBeforeTryTask) === null || _runner$onBeforeTryTa === void 0 ? void 0 : _runner$onBeforeTryTa.call(runner, test, {
2045
+ retry: retryCount,
2046
+ repeats: repeatCount
2047
+ }));
2048
+ test.result.repeatCount = repeatCount;
2049
+ beforeEachCleanups = await $("test.beforeEach", () => callSuiteHook(suite, test, "beforeEach", runner, [test.context, suite]));
2050
+ if (runner.runTask) {
2051
+ await $("test.callback", () => runner.runTask(test));
2052
+ } else {
2053
+ const fn = getFn(test);
2054
+ if (!fn) {
2055
+ throw new Error("Test function is not found. Did you add it using `setFn`?");
2056
+ }
2057
+ await $("test.callback", () => fn());
2058
+ }
2059
+ await ((_runner$onAfterTryTas = runner.onAfterTryTask) === null || _runner$onAfterTryTas === void 0 ? void 0 : _runner$onAfterTryTas.call(runner, test, {
2060
+ retry: retryCount,
2061
+ repeats: repeatCount
2062
+ }));
2063
+ if (test.result.state !== "fail") {
2064
+ if (!test.repeats) {
2065
+ test.result.state = "pass";
2066
+ } else if (test.repeats && retry === retryCount) {
2067
+ test.result.state = "pass";
2068
+ }
2069
+ }
2070
+ } catch (e) {
2071
+ failTask(test.result, e, runner.config.diffOptions);
2072
+ }
2073
+ try {
2074
+ var _runner$onTaskFinishe;
2075
+ await ((_runner$onTaskFinishe = runner.onTaskFinished) === null || _runner$onTaskFinishe === void 0 ? void 0 : _runner$onTaskFinishe.call(runner, test));
2076
+ } catch (e) {
2077
+ failTask(test.result, e, runner.config.diffOptions);
2078
+ }
2079
+ try {
2080
+ await $("test.afterEach", () => callSuiteHook(suite, test, "afterEach", runner, [test.context, suite]));
2081
+ if (beforeEachCleanups.length) {
2082
+ await $("test.cleanup", () => callCleanupHooks(runner, beforeEachCleanups));
1729
2083
  }
1730
- await $("test.callback", () => fn());
2084
+ // Only clean up fixtures created inside runTest (after the checkpoint)
2085
+ // Fixtures created for aroundEach will be cleaned up after aroundEach teardown
2086
+ await callFixtureCleanupFrom(test.context, fixtureCheckpoint);
2087
+ } catch (e) {
2088
+ failTask(test.result, e, runner.config.diffOptions);
2089
+ }
2090
+ if ((_test$onFinished = test.onFinished) === null || _test$onFinished === void 0 ? void 0 : _test$onFinished.length) {
2091
+ await $("test.onFinished", () => callTestHooks(runner, test, test.onFinished, "stack"));
1731
2092
  }
1732
- await ((_runner$onAfterTryTas = runner.onAfterTryTask) === null || _runner$onAfterTryTas === void 0 ? void 0 : _runner$onAfterTryTas.call(runner, test, {
2093
+ if (test.result.state === "fail" && ((_test$onFailed = test.onFailed) === null || _test$onFailed === void 0 ? void 0 : _test$onFailed.length)) {
2094
+ await $("test.onFailed", () => callTestHooks(runner, test, test.onFailed, runner.config.sequence.hooks));
2095
+ }
2096
+ test.onFailed = undefined;
2097
+ test.onFinished = undefined;
2098
+ await ((_runner$onAfterRetryT = runner.onAfterRetryTask) === null || _runner$onAfterRetryT === void 0 ? void 0 : _runner$onAfterRetryT.call(runner, test, {
1733
2099
  retry: retryCount,
1734
2100
  repeats: repeatCount
1735
2101
  }));
1736
- if (test.result.state !== "fail") {
1737
- if (!test.repeats) {
1738
- test.result.state = "pass";
1739
- } else if (test.repeats && retry === retryCount) {
1740
- test.result.state = "pass";
1741
- }
1742
- }
1743
- } catch (e) {
1744
- failTask(test.result, e, runner.config.diffOptions);
1745
- }
1746
- try {
1747
- var _runner$onTaskFinishe;
1748
- await ((_runner$onTaskFinishe = runner.onTaskFinished) === null || _runner$onTaskFinishe === void 0 ? void 0 : _runner$onTaskFinishe.call(runner, test));
1749
- } catch (e) {
1750
- failTask(test.result, e, runner.config.diffOptions);
1751
- }
2102
+ }).catch((error) => {
2103
+ failTask(test.result, error, runner.config.diffOptions);
2104
+ });
2105
+ // Clean up fixtures that were created for aroundEach (before the checkpoint)
2106
+ // This runs after aroundEach teardown has completed
1752
2107
  try {
1753
- await $("test.afterEach", () => callSuiteHook(suite, test, "afterEach", runner, [test.context, suite]));
1754
- if (beforeEachCleanups.length) {
1755
- await $("test.cleanup", () => callCleanupHooks(runner, beforeEachCleanups));
1756
- }
1757
2108
  await callFixtureCleanup(test.context);
1758
2109
  } catch (e) {
1759
2110
  failTask(test.result, e, runner.config.diffOptions);
1760
2111
  }
1761
- if ((_test$onFinished = test.onFinished) === null || _test$onFinished === void 0 ? void 0 : _test$onFinished.length) {
1762
- await $("test.onFinished", () => callTestHooks(runner, test, test.onFinished, "stack"));
1763
- }
1764
- if (test.result.state === "fail" && ((_test$onFailed = test.onFailed) === null || _test$onFailed === void 0 ? void 0 : _test$onFailed.length)) {
1765
- await $("test.onFailed", () => callTestHooks(runner, test, test.onFailed, runner.config.sequence.hooks));
1766
- }
1767
- test.onFailed = undefined;
1768
- test.onFinished = undefined;
1769
- await ((_runner$onAfterRetryT = runner.onAfterRetryTask) === null || _runner$onAfterRetryT === void 0 ? void 0 : _runner$onAfterRetryT.call(runner, test, {
1770
- retry: retryCount,
1771
- repeats: repeatCount
1772
- }));
1773
2112
  // skipped with new PendingError
1774
2113
  if (((_test$result2 = test.result) === null || _test$result2 === void 0 ? void 0 : _test$result2.pending) || ((_test$result3 = test.result) === null || _test$result3 === void 0 ? void 0 : _test$result3.state) === "skip") {
1775
2114
  var _test$result4;
@@ -1875,47 +2214,62 @@ async function runSuite(suite, runner) {
1875
2214
  updateTask("suite-finished", suite, runner);
1876
2215
  } else {
1877
2216
  var _runner$onAfterRunSui;
2217
+ let suiteRan = false;
1878
2218
  try {
1879
- try {
1880
- beforeAllCleanups = await $("suite.beforeAll", () => callSuiteHook(suite, suite, "beforeAll", runner, [suite]));
1881
- } catch (e) {
1882
- markTasksAsSkipped(suite, runner);
1883
- throw e;
1884
- }
1885
- if (runner.runSuite) {
1886
- await runner.runSuite(suite);
1887
- } else {
1888
- for (let tasksGroup of partitionSuiteChildren(suite)) {
1889
- if (tasksGroup[0].concurrent === true) {
1890
- await Promise.all(tasksGroup.map((c) => runSuiteChild(c, runner)));
2219
+ await callAroundAllHooks(suite, async () => {
2220
+ suiteRan = true;
2221
+ try {
2222
+ // beforeAll
2223
+ try {
2224
+ beforeAllCleanups = await $("suite.beforeAll", () => callSuiteHook(suite, suite, "beforeAll", runner, [suite]));
2225
+ } catch (e) {
2226
+ failTask(suite.result, e, runner.config.diffOptions);
2227
+ markTasksAsSkipped(suite, runner);
2228
+ return;
2229
+ }
2230
+ // run suite children
2231
+ if (runner.runSuite) {
2232
+ await runner.runSuite(suite);
1891
2233
  } else {
1892
- const { sequence } = runner.config;
1893
- if (suite.shuffle) {
1894
- // run describe block independently from tests
1895
- const suites = tasksGroup.filter((group) => group.type === "suite");
1896
- const tests = tasksGroup.filter((group) => group.type === "test");
1897
- const groups = shuffle([suites, tests], sequence.seed);
1898
- tasksGroup = groups.flatMap((group) => shuffle(group, sequence.seed));
2234
+ for (let tasksGroup of partitionSuiteChildren(suite)) {
2235
+ if (tasksGroup[0].concurrent === true) {
2236
+ await Promise.all(tasksGroup.map((c) => runSuiteChild(c, runner)));
2237
+ } else {
2238
+ const { sequence } = runner.config;
2239
+ if (suite.shuffle) {
2240
+ // run describe block independently from tests
2241
+ const suites = tasksGroup.filter((group) => group.type === "suite");
2242
+ const tests = tasksGroup.filter((group) => group.type === "test");
2243
+ const groups = shuffle([suites, tests], sequence.seed);
2244
+ tasksGroup = groups.flatMap((group) => shuffle(group, sequence.seed));
2245
+ }
2246
+ for (const c of tasksGroup) {
2247
+ await runSuiteChild(c, runner);
2248
+ }
2249
+ }
2250
+ }
2251
+ }
2252
+ } finally {
2253
+ // afterAll runs even if beforeAll or suite children fail
2254
+ try {
2255
+ await $("suite.afterAll", () => callSuiteHook(suite, suite, "afterAll", runner, [suite]));
2256
+ if (beforeAllCleanups.length) {
2257
+ await $("suite.cleanup", () => callCleanupHooks(runner, beforeAllCleanups));
1899
2258
  }
1900
- for (const c of tasksGroup) {
1901
- await runSuiteChild(c, runner);
2259
+ if (suite.file === suite) {
2260
+ const context = getFileContext(suite);
2261
+ await callFixtureCleanup(context);
1902
2262
  }
2263
+ } catch (e) {
2264
+ failTask(suite.result, e, runner.config.diffOptions);
1903
2265
  }
1904
2266
  }
1905
- }
2267
+ });
1906
2268
  } catch (e) {
1907
- failTask(suite.result, e, runner.config.diffOptions);
1908
- }
1909
- try {
1910
- await $("suite.afterAll", () => callSuiteHook(suite, suite, "afterAll", runner, [suite]));
1911
- if (beforeAllCleanups.length) {
1912
- await $("suite.cleanup", () => callCleanupHooks(runner, beforeAllCleanups));
1913
- }
1914
- if (suite.file === suite) {
1915
- const context = getFileContext(suite);
1916
- await callFixtureCleanup(context);
2269
+ // mark tasks as skipped if aroundAll failed before the suite callback was executed
2270
+ if (!suiteRan) {
2271
+ markTasksAsSkipped(suite, runner);
1917
2272
  }
1918
- } catch (e) {
1919
2273
  failTask(suite.result, e, runner.config.diffOptions);
1920
2274
  }
1921
2275
  if (suite.mode === "run" || suite.mode === "queued") {
@@ -2195,4 +2549,4 @@ function manageArtifactAttachment(attachment) {
2195
2549
  }
2196
2550
  }
2197
2551
 
2198
- export { afterAll, afterEach, beforeAll, beforeEach, publicCollect as collectTests, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, recordArtifact, setFn, setHooks, startTests, suite, test, updateTask };
2552
+ export { afterAll, afterEach, aroundAll, aroundEach, beforeAll, beforeEach, publicCollect as collectTests, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, recordArtifact, setFn, setHooks, startTests, suite, test, updateTask };
@@ -109,7 +109,7 @@ interface VitestRunner {
109
109
  repeats: number;
110
110
  }) => unknown;
111
111
  /**
112
- * Called after the retry resolution happend. Unlike `onAfterTryTask`, the test now has a new state.
112
+ * Called after the retry resolution happened. Unlike `onAfterTryTask`, the test now has a new state.
113
113
  * All `after` hooks were also called by this point.
114
114
  */
115
115
  onAfterRetryTask?: (test: Test, options: {
@@ -329,6 +329,64 @@ declare const onTestFailed: TaskHook<OnTestFailedHandler>;
329
329
  * ```
330
330
  */
331
331
  declare const onTestFinished: TaskHook<OnTestFinishedHandler>;
332
+ /**
333
+ * Registers a callback function that wraps around all tests within the current suite.
334
+ * The callback receives a `runSuite` function that must be called to run the suite's tests.
335
+ * This hook is useful for scenarios where you need to wrap an entire suite in a context
336
+ * (e.g., starting a server, opening a database connection that all tests share).
337
+ *
338
+ * **Note:** When multiple `aroundAll` hooks are registered, they are nested inside each other.
339
+ * The first registered hook is the outermost wrapper.
340
+ *
341
+ * **Note:** Unlike `aroundEach`, the `aroundAll` hook does not receive test context or support fixtures,
342
+ * as it runs at the suite level before any individual test context is created.
343
+ *
344
+ * @param {Function} fn - The callback function that wraps the suite. Must call `runSuite()` to run the tests.
345
+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
346
+ * @returns {void}
347
+ * @example
348
+ * ```ts
349
+ * // Example of using aroundAll to wrap suite in a tracing span
350
+ * aroundAll(async (runSuite) => {
351
+ * await tracer.trace('test-suite', runSuite);
352
+ * });
353
+ * ```
354
+ * @example
355
+ * ```ts
356
+ * // Example of using aroundAll with AsyncLocalStorage context
357
+ * aroundAll(async (runSuite) => {
358
+ * await asyncLocalStorage.run({ suiteId: 'my-suite' }, runSuite);
359
+ * });
360
+ * ```
361
+ */
362
+ declare function aroundAll(fn: AroundAllListener, timeout?: number): void;
363
+ /**
364
+ * Registers a callback function that wraps around each test within the current suite.
365
+ * The callback receives a `runTest` function that must be called to run the test.
366
+ * This hook is useful for scenarios where you need to wrap tests in a context (e.g., database transactions).
367
+ *
368
+ * **Note:** When multiple `aroundEach` hooks are registered, they are nested inside each other.
369
+ * The first registered hook is the outermost wrapper.
370
+ *
371
+ * @param {Function} fn - The callback function that wraps the test. Must call `runTest()` to run the test.
372
+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
373
+ * @returns {void}
374
+ * @example
375
+ * ```ts
376
+ * // Example of using aroundEach to wrap tests in a database transaction
377
+ * aroundEach(async (runTest) => {
378
+ * await database.transaction(() => runTest());
379
+ * });
380
+ * ```
381
+ * @example
382
+ * ```ts
383
+ * // Example of using aroundEach with fixtures
384
+ * aroundEach(async (runTest, { db }) => {
385
+ * await db.transaction(() => runTest());
386
+ * });
387
+ * ```
388
+ */
389
+ declare function aroundEach<ExtraContext = object>(fn: AroundEachListener<ExtraContext>, timeout?: number): void;
332
390
 
333
391
  type ChainableFunction<
334
392
  T extends string,
@@ -753,6 +811,10 @@ interface TestOptions {
753
811
  * Custom tags of the test. Useful for filtering tests.
754
812
  */
755
813
  tags?: keyof TestTags extends never ? string[] | string : TestTags[keyof TestTags] | TestTags[keyof TestTags][];
814
+ /**
815
+ * Custom test metadata available to reporters.
816
+ */
817
+ meta?: Partial<TaskMeta>;
756
818
  }
757
819
  interface TestTags {}
758
820
  interface SuiteOptions extends TestOptions {
@@ -770,10 +832,13 @@ interface Hooks<ExtraContext> {
770
832
  afterAll: typeof afterAll;
771
833
  beforeEach: typeof beforeEach<ExtraContext>;
772
834
  afterEach: typeof afterEach<ExtraContext>;
835
+ aroundEach: typeof aroundEach<ExtraContext>;
836
+ aroundAll: typeof aroundAll;
773
837
  }
774
838
  type TestAPI<ExtraContext = object> = ChainableTestAPI<ExtraContext> & ExtendedAPI<ExtraContext> & Hooks<ExtraContext> & {
775
839
  extend: <T extends Record<string, any> = object>(fixtures: Fixtures<T, ExtraContext>) => TestAPI<{ [K in keyof T | keyof ExtraContext] : K extends keyof T ? T[K] : K extends keyof ExtraContext ? ExtraContext[K] : never }>;
776
840
  scoped: (fixtures: Partial<Fixtures<ExtraContext>>) => void;
841
+ describe: SuiteAPI<ExtraContext>;
777
842
  };
778
843
  interface FixtureOptions {
779
844
  /**
@@ -836,11 +901,19 @@ interface BeforeEachListener<ExtraContext = object> {
836
901
  interface AfterEachListener<ExtraContext = object> {
837
902
  (context: TestContext & ExtraContext, suite: Readonly<Suite>): Awaitable<unknown>;
838
903
  }
904
+ interface AroundEachListener<ExtraContext = object> {
905
+ (runTest: () => Promise<void>, context: TestContext & ExtraContext, suite: Readonly<Suite>): Awaitable<unknown>;
906
+ }
907
+ interface AroundAllListener {
908
+ (runSuite: () => Promise<void>, suite: Readonly<Suite | File>): Awaitable<unknown>;
909
+ }
839
910
  interface SuiteHooks<ExtraContext = object> {
840
911
  beforeAll: BeforeAllListener[];
841
912
  afterAll: AfterAllListener[];
842
913
  beforeEach: BeforeEachListener<ExtraContext>[];
843
914
  afterEach: AfterEachListener<ExtraContext>[];
915
+ aroundEach: AroundEachListener<ExtraContext>[];
916
+ aroundAll: AroundAllListener[];
844
917
  }
845
918
  interface TaskCustomOptions extends TestOptions {
846
919
  /**
@@ -848,10 +921,6 @@ interface TaskCustomOptions extends TestOptions {
848
921
  */
849
922
  each?: boolean;
850
923
  /**
851
- * Custom metadata for the task that will be assigned to `task.meta`.
852
- */
853
- meta?: Record<string, unknown>;
854
- /**
855
924
  * Task fixtures.
856
925
  */
857
926
  fixtures?: FixtureItem[];
@@ -1093,5 +1162,5 @@ interface TestArtifactRegistry {}
1093
1162
  */
1094
1163
  type TestArtifact = TestAnnotationArtifact | VisualRegressionArtifact | TestArtifactRegistry[keyof TestArtifactRegistry];
1095
1164
 
1096
- export { createChainable as ab, afterAll as i, afterEach as j, beforeAll as k, beforeEach as l, onTestFinished as m, onTestFailed as o };
1097
- export type { TestAnnotationLocation as $, AfterAllListener as A, BeforeAllListener as B, CancelReason as C, RunMode as D, RuntimeContext as E, FileSpecification as F, SequenceHooks as G, SequenceSetupFiles as H, ImportDuration as I, SerializableRetry as J, SuiteFactory as K, TaskBase as L, TaskCustomOptions as M, TaskEventPack as N, OnTestFailedHandler as O, TaskHook as P, TaskMeta as Q, Retry as R, Suite as S, TestArtifact as T, TaskPopulated as U, VitestRunner as V, TaskResult as W, TaskResultPack as X, TaskState as Y, TestAnnotation as Z, TestAnnotationArtifact as _, Test as a, TestArtifactBase as a0, TestArtifactLocation as a1, TestArtifactRegistry as a2, TestAttachment as a3, TestContext as a4, TestFunction as a5, TestOptions as a6, TestTags as a7, Use as a8, VisualRegressionArtifact as a9, ChainableFunction as aa, SuiteHooks as b, File as c, TaskUpdateEvent as d, Task as e, TestAPI as f, SuiteAPI as g, SuiteCollector as h, TestTagDefinition as n, VitestRunnerConfig as p, VitestRunnerConstructor as q, VitestRunnerImportSource as r, AfterEachListener as s, BeforeEachListener as t, Fixture as u, FixtureFn as v, FixtureOptions as w, Fixtures as x, InferFixturesTypes as y, OnTestFinishedHandler as z };
1165
+ export { afterAll as a7, afterEach as a8, aroundAll as a9, aroundEach as aa, beforeAll as ab, beforeEach as ac, onTestFailed as ad, onTestFinished as ae, createChainable as ag };
1166
+ export type { TestOptions as $, AfterAllListener as A, BeforeAllListener as B, CancelReason as C, TaskCustomOptions as D, TaskEventPack as E, FileSpecification as F, TaskHook as G, TaskMeta as H, ImportDuration as I, TaskPopulated as J, TaskResult as K, TaskResultPack as L, TaskState as M, TestAnnotation as N, OnTestFailedHandler as O, TestAnnotationArtifact as P, TestAnnotationLocation as Q, Retry as R, Suite as S, TestArtifact as T, TestArtifactBase as U, VitestRunner as V, TestArtifactLocation as W, TestArtifactRegistry as X, TestAttachment as Y, TestContext as Z, TestFunction as _, Test as a, TestTagDefinition as a0, TestTags as a1, Use as a2, VisualRegressionArtifact as a3, VitestRunnerConfig as a4, VitestRunnerConstructor as a5, VitestRunnerImportSource as a6, ChainableFunction as af, SuiteHooks as b, File as c, TaskUpdateEvent as d, Task as e, TestAPI as f, SuiteAPI as g, SuiteCollector as h, AfterEachListener as i, AroundAllListener as j, AroundEachListener as k, BeforeEachListener as l, Fixture as m, FixtureFn as n, FixtureOptions as o, Fixtures as p, InferFixturesTypes as q, OnTestFinishedHandler as r, RunMode as s, RuntimeContext as t, SequenceHooks as u, SequenceSetupFiles as v, SerializableRetry as w, SuiteFactory as x, SuiteOptions as y, TaskBase as z };
package/dist/types.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { A as AfterAllListener, s as AfterEachListener, B as BeforeAllListener, t as BeforeEachListener, C as CancelReason, c as File, F as FileSpecification, u as Fixture, v as FixtureFn, w as FixtureOptions, x as Fixtures, I as ImportDuration, y as InferFixturesTypes, O as OnTestFailedHandler, z as OnTestFinishedHandler, R as Retry, D as RunMode, E as RuntimeContext, G as SequenceHooks, H as SequenceSetupFiles, J as SerializableRetry, S as Suite, g as SuiteAPI, h as SuiteCollector, K as SuiteFactory, b as SuiteHooks, e as Task, L as TaskBase, M as TaskCustomOptions, N as TaskEventPack, P as TaskHook, Q as TaskMeta, U as TaskPopulated, W as TaskResult, X as TaskResultPack, Y as TaskState, d as TaskUpdateEvent, a as Test, f as TestAPI, Z as TestAnnotation, _ as TestAnnotationArtifact, $ as TestAnnotationLocation, T as TestArtifact, a0 as TestArtifactBase, a1 as TestArtifactLocation, a2 as TestArtifactRegistry, a3 as TestAttachment, a4 as TestContext, a5 as TestFunction, a6 as TestOptions, n as TestTagDefinition, a7 as TestTags, a8 as Use, a9 as VisualRegressionArtifact, V as VitestRunner, p as VitestRunnerConfig, q as VitestRunnerConstructor, r as VitestRunnerImportSource } from './tasks.d-CLPU8HE4.js';
1
+ export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, c as File, F as FileSpecification, m as Fixture, n as FixtureFn, o as FixtureOptions, p as Fixtures, I as ImportDuration, q as InferFixturesTypes, O as OnTestFailedHandler, r as OnTestFinishedHandler, R as Retry, s as RunMode, t as RuntimeContext, u as SequenceHooks, v as SequenceSetupFiles, w as SerializableRetry, S as Suite, g as SuiteAPI, h as SuiteCollector, x as SuiteFactory, b as SuiteHooks, y as SuiteOptions, e as Task, z as TaskBase, D as TaskCustomOptions, E as TaskEventPack, G as TaskHook, H as TaskMeta, J as TaskPopulated, K as TaskResult, L as TaskResultPack, M as TaskState, d as TaskUpdateEvent, a as Test, f as TestAPI, N as TestAnnotation, P as TestAnnotationArtifact, Q as TestAnnotationLocation, T as TestArtifact, U as TestArtifactBase, W as TestArtifactLocation, X as TestArtifactRegistry, Y as TestAttachment, Z as TestContext, _ as TestFunction, $ as TestOptions, a0 as TestTagDefinition, a1 as TestTags, a2 as Use, a3 as VisualRegressionArtifact, V as VitestRunner, a4 as VitestRunnerConfig, a5 as VitestRunnerConstructor, a6 as VitestRunnerImportSource } from './tasks.d-WWG4yDf6.js';
2
2
  import '@vitest/utils/diff';
3
3
  import '@vitest/utils';
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Suite, c as File, e as Task, n as TestTagDefinition, p as VitestRunnerConfig, a as Test } from './tasks.d-CLPU8HE4.js';
2
- export { aa as ChainableFunction, ab as createChainable } from './tasks.d-CLPU8HE4.js';
1
+ import { S as Suite, c as File, e as Task, a0 as TestTagDefinition, a4 as VitestRunnerConfig, a as Test } from './tasks.d-WWG4yDf6.js';
2
+ export { af as ChainableFunction, ag as createChainable } from './tasks.d-WWG4yDf6.js';
3
3
  import { ParsedStack, Arrayable } from '@vitest/utils';
4
4
  import '@vitest/utils/diff';
5
5
 
package/dist/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- export { a as calculateSuiteHash, c as createChainable, b as createFileTask, e as createTagsFilter, h as createTaskName, f as findTestFileStackTrace, g as generateFileHash, d as generateHash, j as getFullName, k as getNames, m as getSuites, n as getTasks, o as getTestName, q as getTests, r as hasFailed, t as hasTests, i as interpretTaskModes, u as isTestCase, l as limitConcurrency, p as partitionSuiteChildren, s as someTasksAreOnly, v as validateTags } from './chunk-tasks.js';
1
+ export { c as calculateSuiteHash, a as createChainable, b as createFileTask, d as createTagsFilter, e as createTaskName, f as findTestFileStackTrace, g as generateFileHash, h as generateHash, i as getFullName, j as getNames, k as getSuites, l as getTasks, m as getTestName, n as getTests, o as hasFailed, p as hasTests, q as interpretTaskModes, r as isTestCase, s as limitConcurrency, t as partitionSuiteChildren, u as someTasksAreOnly, v as validateTags } from './chunk-tasks.js';
2
2
  import '@vitest/utils/error';
3
3
  import '@vitest/utils/source-map';
4
4
  import 'pathe';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/runner",
3
3
  "type": "module",
4
- "version": "4.1.0-beta.2",
4
+ "version": "4.1.0-beta.3",
5
5
  "description": "Vitest test runner",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -39,7 +39,7 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "pathe": "^2.0.3",
42
- "@vitest/utils": "4.1.0-beta.2"
42
+ "@vitest/utils": "4.1.0-beta.3"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "premove dist && rollup -c",