diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 41ca9c8b74d9..720d08ee7b6e 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -53,6 +53,7 @@ export class Vitest { coverageProvider: CoverageProvider | null | undefined logger: Logger pool: ProcessPool | undefined + isFailedModel = false vitenode: ViteNodeServer = undefined! @@ -823,16 +824,23 @@ export class Vitest { this.snapshot.clear() let files = Array.from(this.changedTests) - + const failedTest = this.state.getFailedFilepaths() if (this.filenamePattern) { const filteredFiles = await this.globTestFiles([this.filenamePattern]) files = files.filter(file => filteredFiles.some(f => f[1] === file)) - + if (failedTest.length && this.isFailedModel) { + files = [...new Set(files.concat(failedTest))] + } // A file that does not match the current filename pattern was changed if (files.length === 0) { return } } + else { + if (failedTest.length && this.isFailedModel) { + files = [...new Set(files.concat(failedTest))] + } + } this.changedTests.clear() diff --git a/packages/vitest/src/node/stdin.ts b/packages/vitest/src/node/stdin.ts index 5ae6bc7c4aca..a96957c73b76 100644 --- a/packages/vitest/src/node/stdin.ts +++ b/packages/vitest/src/node/stdin.ts @@ -95,6 +95,12 @@ export function registerConsoleShortcuts( } // rerun all tests if (name === 'a' || name === 'return') { + ctx.isFailedModel = false + return ctx.changeNamePattern('') + } + // rerun current pattern tests + if (name === 'r') { + ctx.isFailedModel = false const files = await ctx.getTestFilepaths() return ctx.changeNamePattern('', files, 'rerun all tests') } @@ -104,6 +110,7 @@ export function registerConsoleShortcuts( } // rerun only failed tests if (name === 'f') { + ctx.isFailedModel = true return ctx.rerunFailed() } // change project filter diff --git a/test/watch/test/stdin.test.ts b/test/watch/test/stdin.test.ts index 12f135013dfa..671becca0c1d 100644 --- a/test/watch/test/stdin.test.ts +++ b/test/watch/test/stdin.test.ts @@ -94,6 +94,37 @@ test('2 - test that is cancelled', async () => { }) }) +test('rerun failed tests', async () => { + const { vitest } = await runVitest({ ..._options }) + const testPath = 'fixtures/error.test.ts' + const testCase = ` + import { test, expect } from 'vitest' + test('fail test', () => { + expect(1).toBe(2) + }) + ` + const testTwoPath = 'fixtures/normal.test.ts' + const testTwoCase = ` + import { test, expect } from 'vitest' + test('normal test', () => { + expect(1).toBe(1) + }) + ` + writeFileSync(testPath, testCase, 'utf8') + writeFileSync(testTwoPath, testTwoCase, 'utf8') + + await vitest.waitForStdout('1 failed') + + writeFileSync(testTwoPath, testCase.replace(/1/g, '2'), 'utf8') + await vitest.waitForStdout('1 pass') + + vitest.write('f') + await vitest.waitForStdout('1 failed') + + writeFileSync(testTwoPath, testCase.replace(/2/g, '3'), 'utf8') + await vitest.waitForStdout('1 failed') +}) + test('rerun current pattern tests', async () => { const { vitest } = await runVitest({ ..._options, testNamePattern: 'sum' })