Skip to main content
Two different things can end your involvement with a run in flight, and they are deliberately not the same:

Ctrl-C is a detach, not a cancel

Pressing Ctrl-C while test 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:
Just like a --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.
Interrupting a batch (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 run flips to cancelled and the CLI prints the final run card:
What cancel does — and deliberately does not do:
  • The test is immediately re-runnable. Cancelling frees the test’s run slot, so a follow-up test run won’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> --history lists them like any other run.

Idempotent by design

Cancelling the same run twice is a success, not an error — the second call exits 0 with an advisory:
That makes cancel safe to retry blindly from scripts and cleanup traps. Only two things are refused:

Cancelling several runs at once

test cancel is variadic — after interrupting a batch, paste every ID from the hint:
Multi-id output is a summary instead of a run card:
The exit code reports the worst outcome: any notFound4 (a wrong ID is a caller bug worth failing loudly on), else any transport/auth errors1, else any conflicts6, else 0. Runs that were fresh-cancelled or already cancelled both count as success.

CI cleanup pattern

Cancel’s idempotency makes it a natural trap 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