Test Runner Panel
A VS Code status bar item and a Test Runner panel (next to Terminal) that show the progress, memory and failures of test runs. It shows any test run that writes a small run.json file, from any project and any language. It reads by itself and acts only when you click Stop or Rerun on a card and then confirm a dialog that says what will happen.
your test script ---- writes ----> <temp>/<project>-test-run-<id>/run.json ---- polled every 2 s ----> VS Code
(any language) (one folder per run) status bar + Test Runner panel
Install
Install Test Runner Panel (publisher wavecoders) from the VS Code Marketplace, or run ext install wavecoders.test-runner-panel in the command palette. It needs VS Code 1.145 or newer and starts by itself when VS Code opens. It does nothing until a test run writes a run.json, or a folder sets testRunner.runCommand.
From a file instead: code --install-extension test-runner-panel-<version>.vsix, or in VS Code the Extensions view, the ... menu, Install from VSIX....
What you see
- Status bar: the live run as
217/447 ▰▰▰▰▱▱▱▱▱▱ 49% (files done of all files; +1 when a second run is live), or the newest run's result when none is live. Next to it, the machine's Free Memory 34%, in the warning colours when free memory is under the run's minimum. Both are hidden until a run exists. Click either to open the panel.
- Panel: a full card for each live run (or the newest run when none is live), and every other run under a folded History (n) · 1 passed · 1 stopped. Opening History shows a dropdown of the earlier runs, newest first, each as
Nov 7, 6:15:11 AM · <title> · passed (the date and time it ended), and the card of the selected run only, with no buttons. A Clear History button to the right of the dropdown hides the earlier runs: it deletes nothing (the run files belong to the programs that wrote them), the panel remembers what you cleared so it stays hidden after a reload, and later runs appear as usual. History is the newest 6 runs of the last 24 hours. A card has: title, state badge, progress bar, files, groups and tests done, coverage N% when the run reports it, elapsed time and an estimate of the time left, one coloured cell per group (hover for its label and file count), on a live card Run Memory (the run's own use against its cap; a finished card has none), the failed tests under a Failed tests (N) fold you can open and close (open for 5 or fewer, folded for more), and the run's events. A banner warns when two runs are live, or when free memory is under the minimum. Below the Run all tests button (at the top when there is none), outside the cards, one Free Memory bar shows the machine's free memory (a single reading, so it is not repeated in every card): as long as the memory left, its figure that percentage (36% (min 12)), green while there is plenty, amber below twice the minimum, red below the minimum (where a run is stopped), with a tick at the minimum; hover it for the memory used. The strictest minimum of the live runs applies, 12% when none is live.
- Stop and Rerun: for a project folder that sets
testRunner.runCommand, the button above the cards is Run all tests, and Stop All Tests while a run is live in that folder. Other runs (an agent's run in another worktree, a folder with no setting) keep a Stop button on their live card and a Rerun button once they end. Either way, before anything is sent the panel checks that the process in the run file really is that run (it is yours and its working folder is the run's cwd), then asks Stop "<title>" (process N) in <folder>?; on Stop run it sends that one process SIGTERM, never a harder kill, and a run that handles the signal ends as stopped. Rerun and Run all tests show the command and folder first and, on Run, start the command as the process of a terminal named Test Runner: <title>, so you can watch it and nothing runs silently. Rerun is disabled while another run is live in the same folder, when the run recorded no command, and when its folder is gone.
- Run all tests: a button above the cards for each project folder whose settings give a command (see Start tests from the panel). It shows the command, asks, then runs it in a terminal.
- Coverage: when a run reports it, the card shows
coverage 19.9% (lines) and the four figures in its tooltip.
- Which runs: by default only the runs of the folders open in this window. A This project / All projects switch at the top changes that (see Which runs show).
- Colours come from your VS Code theme, light or dark.
Memory readings use macOS memory_pressure. Elsewhere the memory bars are absent and everything else works. Swap is deliberately not shown: it stays near full on a busy Mac whatever the tests do, and the memory guard does not look at it.
Start tests from the panel
Give a project a Run all tests button by setting testRunner.runCommand in that folder's settings (.vscode/settings.json), as a list of words:
{ "testRunner.runCommand": ["npm", "run", "test:panel"] }
The button is above the cards, one per folder that sets it (named for the folder when there are several), and Test Runner: Run All Tests in the command palette does the same. A click shows the command and folder and asks; on Run, the command starts as the process of a terminal named Test Runner: <folder> in that folder. While a run is live in that folder the button reads Stop All Tests and stops it, with the same checks and dialog as Stop; the cards of that folder then have no Stop or Rerun of their own. The setting is ignored in a workspace you have not trusted, and the command is always read from the setting, never from a run file. Use the command that runs everything: the project's own runner script with no filter (no --only).
Which runs show
Runs are found in the system temp folder, where every project writes its own, so the panel and the status bar show only the runs that belong to what you have open. A run belongs to a VS Code folder when its working folder (cwd in the run.json) is that folder or inside it. A run of another project is hidden, and the panel says how many (2 runs from other projects hidden). With no folder open, every run shows.
The This project / All projects switch at the top of the panel saves your choice in the user setting testRunner.scope, which you can also edit yourself:
| Value |
Shows |
workspace (default) |
Only the runs of the folders open in this window |
all |
Every run in the temp folder, from any project |
A run from a git worktree of the open repo has a different folder, so it is hidden until you choose All projects. The setting belongs to you, not to a project: it is not read from a folder's .vscode/settings.json.
Connect a project
A project connects by having its test script write a small run.json into the system temp folder: a folder named <project>-test-run-<random>, rewritten at the start, at each group and at the end. The full file contract, the checker (tools/check-run.js), Karma and Jasmine recipes (recipes/), a sample file (sample/run.json) and a step-by-step playbook for an AI agent are in docs/run-json-and-agent-playbook.md, inside the installed extension folder (~/.vscode/extensions/wavecoders.test-runner-panel-<version>/).
Troubleshooting
| Symptom |
Cause and fix |
| Runs exist but the panel shows none, or says some are hidden |
The panel shows only the runs of the folders open in this window. A run of another project, or of a git worktree of this one, is hidden. Choose All projects at the top of the panel, or set testRunner.scope to all. |
| Nothing appears |
The folder name must contain test-run- and sit directly in the temp folder. Run the checker on the file. Runs older than 24 hours, and all but the newest 6, are hidden. |
| The VS Code window and the script see different temp folders |
They run as different users or in a container, or TMPDIR differs. Compare node -e "console.log(require('os').tmpdir())" in both, and set the same TMPDIR. |
stopped unexpectedly |
The script died, or its pid is a child that exited. Use the script's own pid. Or a finished file has no endedAt or exitCode. |
| The bar never moves |
The script is not rewriting the file at each group end. Rewrite on every group change and every 10 s. |
A failed test's click says path refused |
file must be relative to cwd and inside it (no .., no link leading out). |
file not found |
file does not exist under cwd: check cwd is the project folder that holds the tests. |
| No memory bars |
Not macOS, or memory_pressure is unavailable. The rest works. |
| The panel says no runs were found |
Correct while no file exists. Start a run, or check the folder name. |
| There is no Rerun or Stop button on a card |
The run's folder sets testRunner.runCommand, so the button above the cards does both (Run all tests, Stop All Tests). Otherwise: the run file has command: null, another run is live in the same folder (Rerun is then disabled), the folder is gone, or the card is in History (cards there have no buttons). |
What it does not do
It does not run, stop or rerun anything without your click and a confirmation, does not re-run a single failed test, keeps no history beyond 24 hours, and does not record environment variables (a rerun gets the environment of the VS Code terminal, not the original run's, so CHUNK=20 npm run ... is rerun without CHUNK=20). It adds no dependency. Tests that run in another container or on another machine are not seen unless that run's folder is reachable from the VS Code window's temp folder.
macOS and Linux. The memory bars need macOS (memory_pressure); Stop and Rerun read a process's folder and command with /proc (Linux) or lsof and ps (macOS). It has not been tested on Windows, where those tools are missing.
Privacy
The extension collects no data, sends nothing over the network and has no telemetry. It only reads run.json files in your temp folder and the testRunner.runCommand setting.
License
MIT. Copyright (c) 2026 Mike Bonifacio / wavecoders.ca.
| |