Skip to content

Commit 821aa20

Browse files
authored
feat(runner): Add full names to tasks (#9087)
1 parent 2cc34e0 commit 821aa20

File tree

17 files changed

+453
-9
lines changed

17 files changed

+453
-9
lines changed

packages/runner/src/collect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function collectTests(
4242

4343
runner.onCollectStart?.(file)
4444

45-
clearCollectorContext(filepath, runner)
45+
clearCollectorContext(file, runner)
4646

4747
try {
4848
const setupFiles = toArray(config.setupFiles)

packages/runner/src/suite.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { getHooks, setFn, setHooks, setTestFixture } from './map'
3838
import { getCurrentTest } from './test-state'
3939
import { findTestFileStackTrace } from './utils'
4040
import { createChainable } from './utils/chain'
41+
import { createTaskName } from './utils/tasks'
4142

4243
/**
4344
* Creates a suite of tests, allowing for grouping and hierarchical organization of tests.
@@ -213,14 +214,15 @@ function createDefaultSuite(runner: VitestRunner) {
213214
}
214215

215216
export function clearCollectorContext(
216-
filepath: string,
217+
file: File,
217218
currentRunner: VitestRunner,
218219
): void {
219220
if (!defaultSuite) {
220221
defaultSuite = createDefaultSuite(currentRunner)
221222
}
223+
defaultSuite.file = file
222224
runner = currentRunner
223-
currentTestFilepath = filepath
225+
currentTestFilepath = file.filepath
224226
collectorContext.tasks.length = 0
225227
defaultSuite.clear()
226228
collectorContext.currentSuite = defaultSuite
@@ -297,10 +299,16 @@ function createSuiteCollector(
297299

298300
const task = function (name = '', options: TaskCustomOptions = {}) {
299301
const timeout = options?.timeout ?? runner.config.testTimeout
302+
const currentSuite = collectorContext.currentSuite?.suite
300303
const task: Test = {
301304
id: '',
302305
name,
303-
suite: collectorContext.currentSuite?.suite,
306+
fullName: createTaskName([
307+
currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName,
308+
name,
309+
]),
310+
fullTestName: createTaskName([currentSuite?.fullTestName, name]),
311+
suite: currentSuite,
304312
each: options.each,
305313
fails: options.fails,
306314
context: undefined!,
@@ -439,11 +447,18 @@ function createSuiteCollector(
439447
suiteOptions = { timeout: suiteOptions }
440448
}
441449

450+
const currentSuite = collectorContext.currentSuite?.suite
451+
442452
suite = {
443453
id: '',
444454
type: 'suite',
445455
name,
446-
suite: collectorContext.currentSuite?.suite,
456+
fullName: createTaskName([
457+
currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName,
458+
name,
459+
]),
460+
fullTestName: createTaskName([currentSuite?.fullTestName, name]),
461+
suite: currentSuite,
447462
mode,
448463
each,
449464
file: undefined!,

packages/runner/src/types/tasks.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,40 @@ export interface TaskBase {
1818
* Task name provided by the user. If no name was provided, it will be an empty string.
1919
*/
2020
name: string
21+
/**
22+
* Full name including the file path, any parent suites, and this task's name.
23+
*
24+
* Uses ` > ` as the separator between levels.
25+
*
26+
* @example
27+
* // file
28+
* 'test/task-names.test.ts'
29+
* @example
30+
* // suite
31+
* 'test/task-names.test.ts > meal planning'
32+
* 'test/task-names.test.ts > meal planning > grocery lists'
33+
* @example
34+
* // test
35+
* 'test/task-names.test.ts > meal planning > grocery lists > calculates ingredients'
36+
*/
37+
fullName: string
38+
/**
39+
* Full name excluding the file path, including any parent suites and this task's name. `undefined` for file tasks.
40+
*
41+
* Uses ` > ` as the separator between levels.
42+
*
43+
* @example
44+
* // file
45+
* undefined
46+
* @example
47+
* // suite
48+
* 'meal planning'
49+
* 'meal planning > grocery lists'
50+
* @example
51+
* // test
52+
* 'meal planning > grocery lists > calculates ingredients'
53+
*/
54+
fullTestName?: string
2155
/**
2256
* Task mode.
2357
* - **skip**: task is skipped
@@ -291,6 +325,7 @@ export interface Test<ExtraContext = object> extends TaskPopulated {
291325
* @experimental
292326
*/
293327
artifacts: TestArtifact[]
328+
fullTestName: string
294329
}
295330

296331
export type Task = Test | Suite | File
@@ -630,6 +665,7 @@ export interface SuiteCollector<ExtraContext = object> {
630665
)[]
631666
scoped: (fixtures: Fixtures<any, ExtraContext>) => void
632667
fixtures: () => FixtureItem[] | undefined
668+
file?: File
633669
suite?: Suite
634670
task: (name: string, options?: TaskCustomOptions) => Test<ExtraContext>
635671
collect: (file: File) => Promise<Suite>

packages/runner/src/utils/collect.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ export function createFileTask(
187187
const file: File = {
188188
id: generateFileHash(path, projectName),
189189
name: path,
190+
fullName: path,
190191
type: 'suite',
191192
mode: 'queued',
192193
filepath,

packages/runner/src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export {
1111
export { limitConcurrency } from './limit-concurrency'
1212
export { partitionSuiteChildren } from './suite'
1313
export {
14+
createTaskName,
1415
getFullName,
1516
getNames,
1617
getSuites,

packages/runner/src/utils/tasks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,7 @@ export function getFullName(task: Task, separator = ' > '): string {
8080
export function getTestName(task: Task, separator = ' > '): string {
8181
return getNames(task).slice(1).join(separator)
8282
}
83+
84+
export function createTaskName(names: readonly (string | undefined)[], separator = ' > '): string {
85+
return names.filter(name => name !== undefined).join(separator)
86+
}

packages/ui/client/components/views/ViewReport.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const fileWithTextStacks: RunnerTestFile = {
4848
type: 'suite',
4949
mode: 'run',
5050
filepath: 'test/plain-stack-trace.ts',
51+
fullName: 'test/plain-stack-trace.ts',
5152
meta: {},
5253
result: {
5354
state: 'fail',
@@ -98,6 +99,7 @@ describe('ViewReport', () => {
9899
type: 'suite',
99100
mode: 'run',
100101
filepath: 'test/plain-stack-trace.ts',
102+
fullName: 'test/plain-stack-trace.ts',
101103
meta: {},
102104
result: {
103105
state: 'fail',
@@ -157,6 +159,7 @@ describe('ViewReport', () => {
157159
type: 'suite',
158160
mode: 'run',
159161
filepath: 'test/plain-stack-trace.ts',
162+
fullName: 'test/plain-stack-trace.ts',
160163
meta: {},
161164
result: {
162165
state: 'fail',

packages/ui/client/components/views/ViewReport.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const failed = computed(() => {
4646
id: file!.id,
4747
file: file!,
4848
name: file!.name,
49+
fullName: file!.name,
4950
level: 0,
5051
type: 'suite',
5152
mode: 'run',

packages/vitest/src/node/ast-collect.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { TestProject } from './project'
44
import { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping'
55
import {
66
calculateSuiteHash,
7+
createTaskName,
78
generateHash,
89
interpretTaskModes,
910
someTasksAreOnly,
@@ -193,6 +194,7 @@ export function createFailedFileTask(project: TestProject, filepath: string, err
193194
type: 'suite',
194195
id: /* @__PURE__ */ generateHash(`${testFilepath}${project.config.name || ''}`),
195196
name: testFilepath,
197+
fullName: testFilepath,
196198
mode: 'run',
197199
tasks: [],
198200
start: 0,
@@ -252,6 +254,7 @@ function createFileTask(
252254
type: 'suite',
253255
id: /* @__PURE__ */ generateHash(`${testFilepath}${options.name || ''}`),
254256
name: testFilepath,
257+
fullName: testFilepath,
255258
mode: 'run',
256259
tasks: [],
257260
start: ast.start,
@@ -324,6 +327,8 @@ function createFileTask(
324327
tasks: [],
325328
mode,
326329
name: definition.name,
330+
fullName: createTaskName([latestSuite.fullName, definition.name]),
331+
fullTestName: createTaskName([latestSuite.fullTestName, definition.name]),
327332
end: definition.end,
328333
start: definition.start,
329334
location,
@@ -343,6 +348,8 @@ function createFileTask(
343348
mode,
344349
context: {} as any, // not used on the server
345350
name: definition.name,
351+
fullName: createTaskName([latestSuite.fullName, definition.name]),
352+
fullTestName: createTaskName([latestSuite.fullTestName, definition.name]),
346353
end: definition.end,
347354
start: definition.start,
348355
location,

packages/vitest/src/node/reporters/junit.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ export class JUnitReporter implements Reporter {
327327
id: file.id,
328328
type: 'test',
329329
name: file.name,
330+
fullName: file.name,
331+
fullTestName: file.name,
330332
mode: 'run',
331333
result: file.result,
332334
meta: {},

0 commit comments

Comments
 (0)