Skip to content

Conversation

@BLamy
Copy link

@BLamy BLamy commented Oct 29, 2025

Make it so I can copy the test output in a format consumable by an LLM

image

Example Output

Test: first pass: 2 => 1 (11.296134000000052ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 2 to be 1 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:12:15)

    10 |     [1, 1], [2, 1], [3, 1]
    11 |   ])(`first pass: %i => %i`, (a, b) => {
>  12 |     expect(a).toBe(b)
                           ^ expected 2 to be 1 // Object.is equality
    13 |   })
    14 |   it.each([

================================================================================

Test: first pass: 3 => 1 (1.7611650000000054ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 3 to be 1 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:12:15)

    10 |     [1, 1], [2, 1], [3, 1]
    11 |   ])(`first pass: %i => %i`, (a, b) => {
>  12 |     expect(a).toBe(b)
                           ^ expected 3 to be 1 // Object.is equality
    13 |   })
    14 |   it.each([

================================================================================

Test: last pass: 3 => 1 (0.9905889999999999ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 3 to be 1 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:17:15)

    15 |     [1, 1], [2, 2], [3, 1]
    16 |   ])(`last pass: %i => %i`, (a, b) => {
>  17 |     expect(a).toBe(b)
                           ^ expected 3 to be 1 // Object.is equality
    18 |   })
    19 |   it.each([

================================================================================

Test: first fail: 3 => 1 (0.6461950000000343ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 3 to be 1 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:22:15)

    20 |     [1, 1], [2, 2], [3, 1]
    21 |   ])(`first fail: %i => %i`, (a, b) => {
>  22 |     expect(a).toBe(b)
                           ^ expected 3 to be 1 // Object.is equality
    23 |   })
    24 |   it.each([

================================================================================

Test: last fail: 3 => 1 (1.9933630000000448ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 3 to be 1 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:27:15)

    25 |     [1, 1], [2, 2], [3, 1]
    26 |   ])(`last fail: %i => %i`, (a, b) => {
>  27 |     expect(a).toBe(b)
                           ^ expected 3 to be 1 // Object.is equality
    28 |   })
    29 |   it.each([

================================================================================

Test: all fail: 1 => 0 (0.6465260000001081ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 1 to be +0 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:32:15)

    30 |     [1, 0], [2, 0], [3, 0]
    31 |   ])(`all fail: %i => %i`, (a, b) => {
>  32 |     expect(a).toBe(b)
                           ^ expected 1 to be +0 // Object.is equality
    33 |   })
    34 |   it.each([

================================================================================

Test: all fail: 2 => 0 (0.5327340000000049ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 2 to be +0 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:32:15)

    30 |     [1, 0], [2, 0], [3, 0]
    31 |   ])(`all fail: %i => %i`, (a, b) => {
>  32 |     expect(a).toBe(b)
                           ^ expected 2 to be +0 // Object.is equality
    33 |   })
    34 |   it.each([

================================================================================

Test: all fail: 3 => 0 (1.173998000000097ms)
File: /workspaces/vscode/samples/basic/test/each.test.ts

Error:
expected 3 to be +0 // Object.is equality

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/each.test.ts:32:15)

    30 |     [1, 0], [2, 0], [3, 0]
    31 |   ])(`all fail: %i => %i`, (a, b) => {
>  32 |     expect(a).toBe(b)
                           ^ expected 3 to be +0 // Object.is equality
    33 |   })
    34 |   it.each([

================================================================================

Test: fail (5.867705000000001ms)
File: /workspaces/vscode/samples/basic/test/bug.test.ts

Error:
expected 1 to deeply equal 2

Stack trace:
  at  (/workspaces/vscode/samples/basic/test/bug.test.ts:3:13)

     1 | import { expect, test } from 'vitest';
     2 | test('fail', () => {
>   3 |   expect(1).toEqual(2);
                         ^ expected 1 to deeply equal 2
     4 | })

================================================================================

Test: fails with error thrown (5.684620999999993ms)
File: /workspaces/vscode/samples/basic/test/throw.test.ts

Error:
Something went wrong

Stack trace:
  at doSomething (/workspaces/vscode/samples/basic/src/add.ts:16:9)

    14 | 
    15 | function doSomething() {
>  16 |   throw new Error('Something went wrong');
                     ^ Something went wrong
    17 | }
    18 | 

  at addError (/workspaces/vscode/samples/basic/src/add.ts:11:3)

     9 | 
    10 | export function addError(from: number, to: number) {
>  11 |   doSomething()
               ^ Something went wrong
    12 |   return add(from, to)
    13 | }

  at  (/workspaces/vscode/samples/basic/test/throw.test.ts:10:12)

     8 | 
     9 |   it('fails with error thrown', () => {
>  10 |     expect(addError(1, 1)).toBe(2)
                        ^ Something went wrong
    11 |   })
    12 | })

BLamy and others added 4 commits October 29, 2025 05:44
- Add TestResult interface to track test results (status, messages, duration, timestamp)
- Extend TestCase class with lastResult property and setResult() method
- Update TestRunner.markTestCase() to persist test results in TestCase instances
- Add TestTree.getFailingTests() to collect all failing tests
- Add vitest.copyFailingTestsOutput command that:
  - Collects all failing tests from the test tree
  - Formats output with test name, file path, duration, error messages, and stack traces
  - Copies formatted output to clipboard
  - Shows notification with count of failing tests
- Register command in package.json and testing/item/context menu

Co-authored-by: Ona <no-reply@ona.com>
- Read source files to display code context around errors
- Show 2 lines before and after the error line
- Add line numbers with 4-digit padding
- Add arrow (>) to highlight the error line
- Add caret (^) pointer to exact column position
- Include error message inline with the pointer
- Fallback to simple location if file cannot be read

Example output:
  at functionName (file.ts:41:19)

    39 | // Check that the page has a title
    40 | const title = await page.title();
  > 41 | expect(title).toBeTruthy();
          |                   ^ expected undefined to be true

Co-authored-by: Ona <no-reply@ona.com>
Co-authored-by: Ona <no-reply@ona.com>
- Exclude .pnpm-store directory
- Exclude .devcontainer directory
- Exclude tsconfig.tsbuildinfo
- Exclude packages node_modules, src, and tsconfig.json

This reduces the VSIX package size from 388MB to 629KB.

Co-authored-by: Ona <no-reply@ona.com>
const tokenSource = new vscode.CancellationTokenSource()
await profile.runHandler(request, tokenSource.token)
}),
vscode.commands.registerCommand('vitest.copyFailingTestsOutput', async () => {
Copy link
Member

Choose a reason for hiding this comment

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

I am confused why you don't use the test item here to get the errors from there? With this implementation, the copy button will copy all errors whenever you call this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants