Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions packages/runner/src/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,22 +342,26 @@ function createSuiteCollector(
})
setTestFixture(context, options.fixtures)

// custom can be called from any place, let's assume the limit is 15 stacks
const limit = Error.stackTraceLimit
Error.stackTraceLimit = 15
const stackTraceError = new Error('STACK_TRACE_ERROR')
Error.stackTraceLimit = limit
Copy link
Member

@sheremet-va sheremet-va Apr 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this works like that. Since we don't access .stack here, does stackTraceLimit matter at all? Shouldn't it wrap .stack?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, but it turns out this is actually fine based on this repro

// repro.js
console.log("[default Error.stackTraceLimit]", Error.stackTraceLimit)

function testThrow(depth) {
  if (depth === 0) {
    const original = Error.stackTraceLimit;
    Error.stackTraceLimit = 1;
    const error1 = new Error('1')
    Error.stackTraceLimit = 2;
    const error2 = new Error('2')
    Error.stackTraceLimit = 3;
    const error3 = new Error('3')
    Error.stackTraceLimit = original;
    return {
      stack1: error1.stack,
      stack2: error2.stack,
      stack3: error3.stack,
    }
  }
  return testThrow(depth - 1)
}

console.log(testThrow(10))
$ node repro.js 
[default Error.stackTraceLimit] 10
{
  stack1: 'Error: 1\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:7:20)',
  stack2: 'Error: 2\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:9:20)\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:19:10)',
  stack3: 'Error: 3\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:11:20)\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:19:10)\n' +
    '    at testThrow (file:///home/hiroshi/code/personal/reproductions/vitest-error-stack-perf/repro.js:19:10)'
}


if (handler) {
setFn(
task,
withTimeout(
withAwaitAsyncAssertions(withFixtures(handler, context), task),
timeout,
false,
stackTraceError,
),
)
}

if (runner.config.includeTaskLocation) {
const limit = Error.stackTraceLimit
// custom can be called from any place, let's assume the limit is 15 stacks
Error.stackTraceLimit = 15
const error = new Error('stacktrace').stack!
Error.stackTraceLimit = limit
const error = stackTraceError.stack!
const stack = findTestFileStackTrace(error, task.each ?? false)
if (stack) {
task.location = stack
Expand Down
2 changes: 2 additions & 0 deletions test/config/fixtures/hook-timeout/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ describe('onFinished', () => {
ctx.onTestFinished(() => new Promise(() => {}), 80)
})
})

it("test timeout", () => new Promise(() => {}), 123)
32 changes: 22 additions & 10 deletions test/config/test/__snapshots__/hook-timeout.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
5|
6| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/10]⎯

FAIL basic.test.ts > afterAll
Error: Hook timed out in 30ms.
Expand All @@ -28,7 +28,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
17|
18| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/10]⎯

FAIL basic.test.ts > cleanup-beforeAll
Error: Hook timed out in 50ms.
Expand All @@ -41,10 +41,10 @@ If this is a long-running hook, pass a timeout value as the last argument or con
29|
30| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/10]⎯


⎯⎯⎯⎯⎯⎯⎯ Failed Tests 5 ⎯⎯⎯⎯⎯⎯⎯
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯

FAIL basic.test.ts > beforeEach > ok
Error: Hook timed out in 20ms.
Expand All @@ -57,7 +57,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
11|
12| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/10]⎯

FAIL basic.test.ts > afterEach > ok
Error: Hook timed out in 40ms.
Expand All @@ -70,7 +70,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
23|
24| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/10]⎯

FAIL basic.test.ts > cleanup-beforeEach > ok
Error: Hook timed out in 60ms.
Expand All @@ -83,7 +83,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
35|
36| it('ok', () => {})

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/10]⎯

FAIL basic.test.ts > onFailed > fail
Error: fail
Expand All @@ -95,7 +95,7 @@ Error: fail
43| })
44| })

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/10]⎯

FAIL basic.test.ts > onFailed > fail
Error: Hook timed out in 70ms.
Expand All @@ -108,7 +108,7 @@ If this is a long-running hook, pass a timeout value as the last argument or con
42| throw new Error('fail')
43| })

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/10]⎯

FAIL basic.test.ts > onFinished > ok
Error: Hook timed out in 80ms.
Expand All @@ -121,7 +121,19 @@ If this is a long-running hook, pass a timeout value as the last argument or con
49| })
50| })

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/9]⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/10]⎯

FAIL basic.test.ts > test timeout
Error: Test timed out in 123ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ basic.test.ts:52:1
50| })
51|
52| it("test timeout", () => new Promise(() => {}), 123)
| ^
53|

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/10]⎯

"
`;
Loading