Ctrl-C is a detach, not a cancel
Pressing Ctrl-C whiletest run --wait, test wait, test rerun --wait, or test flaky is polling stops the watching, never the run. The CLI tells you exactly that on the way out:
--timeout expiry, the CLI prints a partial object ({ "runId": "...", "status": "running" }) to stdout before exiting, so a script that gets interrupted still captures the runId. The exit code is the conventional 128 + signal: 130 for SIGINT (Ctrl-C), 143 for SIGTERM, 129 for SIGHUP.
In --output json mode, stderr carries a machine-readable envelope instead of prose:
A second Ctrl-C while the first is being handled exits immediately, no cleanup — the escape hatch when even the goodbye message is too slow.
test run --all --wait, multi-id test wait/test rerun) prints the same partial listing every run that was already dispatched, so nothing already billed goes unaccounted for.
Actually stopping a run
- The test is immediately re-runnable. Cancelling frees the test’s run slot, so a follow-up
test runwon’t hit the “run already in flight” conflict. - The test’s last verdict is untouched. A test that was passed before the cancelled run stays passed — cancelling never overwrites history with a fake failure.
- No refund. Credits charged when the run was triggered stay charged. Cancelling limits future cost (a pending auto-heal pass that hasn’t engaged yet won’t, so its fee is never charged) but never claws back a charge already made.
- The engine may finish in the background. Work already started in the cloud can run to completion, but its result is discarded — it will never overwrite the cancelled status or the test’s verdict.
- Cancelled runs stay in history.
testsprite test result <test-id> --historylists them like any other run.
Idempotent by design
Cancelling the same run twice is a success, not an error — the second call exits0 with an advisory:
Cancelling several runs at once
test cancel is variadic — after interrupting a batch, paste every ID from the hint:
notFound → 4 (a wrong ID is a caller bug worth failing loudly on), else any transport/auth errors → 1, else any conflicts → 6, else 0. Runs that were fresh-cancelled or already cancelled both count as success.
CI cleanup pattern
Cancel’s idempotency makes it a naturaltrap target — detach honestly on interrupt, then stop the spend:
Where to Go Next
Running Tests
Triggering runs, waiting for verdicts, and resuming
Exit Codes
The full exit-code and signal contract
Reading Results
Run history, steps, and failure bundles
CI/CD Integration
Wire the CLI into GitHub Actions or any pipeline