Skip to content

[BUG] Virtual folders with relative rootPath create nested ../../.. folders on case-insensitive filesystems #1266

@sensei-woo

Description

@sensei-woo

Describe the bug

When using virtual folders with relative rootPath on macOS, the test explorer displays deeply nested parent directory references (../../..) instead of the expected flat test tree structure. This happens because the extension resolves relative paths with different case than Node.js's canonical path resolution, causing path.relative() to treat them as unrelated paths.

To Reproduce

  1. On macOS, create a workspace where the folder path differs in case from the canonical path (e.g., access via /Users/me/developer/myproject when canonical is /Users/me/Developer/myproject)
  2. Configure virtual folders with relative rootPath:
    {
      "jest.virtualFolders": [
        {
          "name": "http",
          "rootPath": "apps/backend"
        }
      ]
    }
  3. Open Test Explorer
  4. Observe the nested tree structure with ../.. folders

Expected behavior

Test tree should show:

Jest Test Provider (http)
└─ http (on-demand)
   └─ integration-tests
      └─ http
         └─ __tests__

Actual behavior

Test tree shows:

Jest Test Provider (http)
└─ http (on-demand)
   ├─ ..
   │  └─ ..
   │     └─ ..
   │        └─ ..
   │           └─ Developer
   │              └─ myproject
   │                 └─ apps
   │                    └─ backend
   │                       └─ integration-tests

Environment:

  • vscode-jest version: v6.4.4
  • node -v: v24.8.0
  • npm -v: 10.x
  • jest version: 29.7.0
  • vscode-jest settings:
    • jest.virtualFolders: [{"name": "http", "rootPath": "apps/backend"}]
    • jest.runMode: {"type": "on-demand"}
  • Operating system: macOS 15.x (APFS - case-insensitive, case-preserving)

Prerequisite

  • Yes, able to run jest from command line
  • Run from: apps/backend directory
  • Command: npm run test:integration:http

Root Cause

In virtual-workspace-folder.ts, the effectiveUri is created using path.resolve() which preserves the case from workspace.uri.fsPath. However, Jest reports test files using Node.js's process.cwd() which returns the canonical path (with uppercase "Developer"). When test-item-data.ts:244 calculates path.relative(effectiveUri, jestFilePath), the case mismatch causes it to generate ../../.. traversals.

Workaround

Use absolute paths with canonical case:

{
  "jest.virtualFolders": [
    {
      "name": "http",
      "rootPath": "/Users/me/Developer/myproject/apps/backend"
    }
  ]
}

Proposed Fix

Normalize the path in virtual-workspace-folder.ts:

this.effectiveUri = rootPath
  ? vscode.Uri.file(fs.realpathSync.native(toAbsoluteRootPath(actualWorkspaceFolder, rootPath)))
  : actualWorkspaceFolder.uri;

This ensures effectiveUri uses the canonical case that matches Jest's output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions