Skip to content

Conversation

@jasonwbarnett
Copy link
Contributor

Summary

  • Escape parentheses and brackets in test file paths before passing them to Jest
  • Add test case for Next.js App Router style paths with special characters

Fixes #416

Problem

Jest interprets CLI arguments as regex patterns. When paths containing (main) or [catalogId] are passed to Jest, these characters are interpreted as regex metacharacters instead of literal characters, causing Jest to fail to match any test files.

This commonly affects Next.js App Router projects which use:

  • (folderName) for route groups
  • [param] for dynamic route segments

Solution

Added escapeJestPathPattern() function that escapes parentheses and brackets in file paths:

  • src/app/(main)/test.tsx becomes src/app/\(main\)/test.tsx
  • src/app/[id]/test.tsx becomes src/app/\[id\]/test.tsx

Other regex metacharacters (like dots) are intentionally not escaped because they work fine in practice and escaping them would break existing behavior.

Test plan

  • Added unit test TestJestCommandNameAndArgs_WithSpecialCharactersInPath verifying correct escaping
  • Existing TestJestCommandNameAndArgs_* tests continue to pass
  • Manual verification that escaped paths match correctly in Jest

🤖 Generated with Claude Code

Jest interprets CLI arguments as regex patterns. This causes issues with
Next.js App Router paths that use parentheses for route groups (e.g.,
`(main)`) and brackets for dynamic routes (e.g., `[catalogId]`).

When paths like `src/app/(main)/test.spec.tsx` are passed to Jest, the
`(main)` is interpreted as a regex capture group instead of a literal
directory name, causing Jest to fail to match any test files.

This fix escapes parentheses and brackets in test file paths before
passing them to Jest, converting:
- `src/app/(main)/test.tsx` -> `src/app/\(main\)/test.tsx`
- `src/app/[id]/test.tsx` -> `src/app/\[id\]/test.tsx`

Other regex metacharacters (like dots) are intentionally not escaped
because they work fine in practice and escaping them breaks existing
behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@jasonwbarnett jasonwbarnett requested a review from a team as a code owner December 11, 2025 18:28
@jasonwbarnett
Copy link
Contributor Author

Alternative Approach: --runTestsByPath

Jest has a CLI flag --runTestsByPath that treats arguments as literal file paths instead of regex patterns. This could be a cleaner alternative to escaping:

// Current default
j.TestCommand = "npx jest {{testExamples}} --json --testLocationInResults --outputFile {{resultPath}}"

// With --runTestsByPath
j.TestCommand = "npx jest --runTestsByPath {{testExamples}} --json --testLocationInResults --outputFile {{resultPath}}"

Trade-offs

Approach Pros Cons
Escaping (this PR) Works with existing regex behavior, backwards compatible More complex code, might miss edge cases
--runTestsByPath Simpler, cleaner, better performance per Jest docs Could be a breaking change if anyone relies on regex matching in paths

The --runTestsByPath approach is recommended by Jest for CI pipelines. Worth considering as an alternative or future improvement.

@malclocke
Copy link
Contributor

@jasonwbarnett thanks for this PR, and for logging the related issue 🙇

At first glance it looks like the --runTestsByPath approach might be a more robust solution, and would avoid us having to potentially revisit the implementation shown here to add more regex characters to escape in future.

I need to double check but I believe we will only ever pass file names to the TestCommand for Jest, whereas I think only the RetryTestCommand receives regex arguments.

I'll do some experimenting and get back to you.

@jasonwbarnett
Copy link
Contributor Author

Hey @malclocke, just wanted to follow up on this. It's been about 3 weeks since your last update - totally understand if the holidays got in the way (we just got back from Christmas and New Years ourselves).

Any updates on your experiments with the --runTestsByPath approach? Happy to pivot to that if it turns out to be more robust. Let me know if there's anything I can help with on my end.

@niceking
Copy link
Collaborator

niceking commented Jan 7, 2026

Hey @jasonwbarnett! Yeah the team's still mostly on holidays and ramping back up. We'll try look at this this month, but for now you could compile your own bktec with these changes and run with that until we merge it to main?

@nprizal
Copy link
Contributor

nprizal commented Jan 19, 2026

Hi @jasonwbarnett , I agree that the --runTestsByPath is the better solution for this. As @malclocke said, we always pass file names to the Jest command, and use regex only for retry which use different command. So adding --runTestsByPath CLI option to the TestCommand should not break the existing behavior. I've tested it locally and on our Jest suite it works correctly.

Also according to Jest documentation, the --runTestsByPath is more optimized when provided with multiple patterns which will be better for bktec as we are passing list of test files to Jest.

The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files.

Do you want to update the PR with the --runTestsByPath approach?

@jasonwbarnett
Copy link
Contributor Author

Hello 👋

I can pivot to use the --runTestsByPath approach. It wasn't clear to me based on @malclocke whether or not any existing code depended on being able to pass regular expressions. I'll move forward assuming we're all good. I should have something posted by end of week.

@nprizal
Copy link
Contributor

nprizal commented Jan 28, 2026

Hello @jasonwbarnett! Yes we are all good. We pass test name as regex when retrying failed test, but this command is configured under a separate config RetryCommand. So adding --runTestsByPath to the TestCommand won't cause any problems.

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.

Jest runner fails to match test files with parentheses or brackets in paths (Next.js App Router)

4 participants