`task` fixture is undefined in file-scoped fixtures
Describe the bug
When using test.extend() with scope: "file", the task fixture is undefined. The same fixture definition works correctly without the file scope.
Expected behavior
task should be defined and accessible in file-scoped fixtures, at minimum providing task.file so fixtures can access file-level metadata like the filepath.
Actual behavior
task is undefined when the fixture has scope: "file".
Apologies if this is intentional, I couldn't find anything in the docs that suggests the built-in task fixture should ever be undefined.
Reproduction
https://stackblitz.com/edit/vitest-dev-vitest-ggimrrx6?file=test%2Frepro.test.ts
import { it as vitestIt, describe, expect } from "vitest"
const itFails = vitestIt.extend<{ foobar: string }>({
foobar: [
async ({ task }, use) => {
// Worth noting that `expect` when taken from the dependencies is also undefined, so this uses global expect
expect(task).toBeDefined()
await use("foobar")
},
{ scope: "file", auto: true },
]
})
const itWorks = vitestIt.extend<{ foobar: string }>({
foobar: async ({ task, expect }, use) => {
// But here expect is defined and works
expect(task).toBeDefined()
await use("foobar")
}
})
describe("file-scope-fixture-repro", () => {
itFails("should work", async ({ foobar, expect }) => {
expect(foobar).toBe("foobar")
})
itWorks("should work", async ({ foobar, expect }) => {
expect(foobar).toBe("foobar")
})
})
System Info
System:
OS: macOS 15.7.1
CPU: (10) arm64 Apple M4
Memory: 138.77 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.14.0 - /opt/homebrew/opt/node@22/bin/node
Yarn: 1.22.22 - /opt/homebrew/bin/yarn
npm: 10.9.3 - /Users/johnilquezada/Development/prismock/node_modules/.bin/npm
bun: 1.2.16 - /opt/homebrew/bin/bun
Browsers:
Chrome: 142.0.7444.176
Safari: 18.6
npmPackages:
@vitest/coverage-v8: 4.0.14 => 4.0.14
vitest: 4.0.15 => 4.0.15
vitest-mock-extended: 3.1.0 => 3.1.0
Used Package Manager
npm
Validations
- [x] Follow our Code of Conduct
- [x] Read the Contributing Guidelines.
- [x] Read the docs.
- [x] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [x] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [x] The provided reproduction is a minimal reproducible example of the bug.
Fixture with { scope: "file", auto: true } means that itFails/foobar to be invoked before any test case (i.e. task) starts, so there's no well defined meaning for task there. Can you explain your use case of using task in { scope: "file", auto: true } fixture?
@hi-ogawa Hey there, I was hoping to be able to access file-level metadata, i.e. task.file. I specifically wanted to get the file path. But, since I'm using it.extend in a separate file, import.meta.url doesn't reflect the test file that's actually running. That said, I stumbled upon another way to get the path.
import { expect } from "vitest"
const testFilePath = expect.getState().testPath
It may also be interesting to be able to access the list of tests in the file via task.file.tasks, but in terms of concrete use-cases this isn't a blocker for me anymore, and sounds like it's not exactly a "bug" either so I think this can be closed.
One suggestion may be to call this out in the docs. It wasn't immediately obvious that task.file wouldn't be available in the file scope, but in hindsight the naming task implies that it's strictly task-scoped.