Download Latest Version v0.10.0 source code.zip (1.3 MB)
Email in envelope

Get an email when there's a new version of TestSprite

Home / v0.9.0
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-09-03 10.4 kB
v0.9.0 source code.tar.gz 2026-09-03 1.2 MB
v0.9.0 source code.zip 2026-09-03 1.3 MB
Totals: 3 Items   2.5 MB 0

Added

  • test get shows the plan steps. It printed only planStepCount, so a test's actual steps were invisible from the CLI. testsprite test get <test-id> now lists them, numbered, as [type] description, and --output json carries planSteps as the same {type, description} objects test create accepts — V2 and V3 tests alike. The list needs a backend that serves the field; an older backend simply omits it and the count-only line is unchanged. A malformed step from the server renders as [step] / (no description) rather than failing the command.

Changed

  • testsprite setup installs for the agents a project actually uses. It installed for claude whenever --agent was omitted, so a caller using any of the other seven targets got skill files that agent cannot read — and a success message, which made the miss silent. setup now works out which agents to install for. An explicit --agent still wins. Otherwise it installs for every agent it finds evidence of — the one calling it, when the environment identifies itself, together with every agent whose configuration is already in the project — and prints what it found and what each match was based on. The two kinds of evidence add up rather than override, so running it from Claude Code in a repo that also holds Cursor and Cline config wires all three: the agent you happen to be using says nothing about the others working in the same repo. In a terminal that set is shown for confirmation first, pre-filled — press enter to accept it, or give a comma-separated list to narrow it. --yes, non-interactive shells and --output json install it as found. When nothing is detected it installs for claude and says so, along with the flag to choose differently. Configuration this CLI wrote itself is never treated as evidence, so a fallback install does not turn into a permanent answer on the next run. --agent no longer has a default value, and under --output json the summary carries agent.targets, agent.detections (one {target, source, signal} row per detected agent) and agent.detectedBy (flag, detected or fallback); agent.target still holds the first target. agent install with no --target resolves the same way — installing for what it detects, prompting with that set pre-filled on a terminal, and naming the claude fallback when it finds nothing — so no command installs for a fixed agent when it was not told which. At the confirmation prompt an unrecognised name is refused and asked again — up to three tries — before anything is written, instead of being accepted and failing only after credentials were saved; answering none skips the skill install the way --no-agent does, and the prompt says so. The [info] line before the prompt now reports only what was detected; the set actually being installed is announced once the answer is in. The summary carries agentSkippedBy (flag or prompt) saying why agent is null when the install was skipped; under --output json only flag occurs, because that mode never prompts. An unknown --agent value is likewise refused before anything is written, and the error names --agent — it used to surface as a --target error, a flag setup does not have, only after credentials had been saved.

Fixed

  • test run <id> and test rerun <id> now print the dashboard link right away. Without --wait, the queued-run output ended at targetUrl and gave you nothing to open — the link only appeared after a full --wait, or from test open. Both outputs now close with a dashboard line whenever the server supplies one (the backend builds it for the store that actually dispatched the run, so it is the same link test wait would print — never the V2 template that 404s for a V3 workspace). Under --output json the envelope also carries executionUrl, the run-scoped result page, on V3 runs. Both keys are present-or-absent: an older backend, or a run the server cannot link, simply omits them and nothing is printed.
  • test run --local no longer refuses a run because its own tunnel was not ready yet. Bringing the tunnel up resolved as soon as the WebSocket opened — before the client had even sent its authentication frame, let alone had it acknowledged. --local does exactly this sequence (open the tunnel, then trigger the run), so the run could be refused as "tunnel offline" while the tunnel was in fact coming up correctly, and the message told you to start a tunnel you had already started. Being a race, it failed on a cold start and passed on the retry — the worst shape for a feature whose whole job is to be trusted about your local app. Startup now completes only once the server has acknowledged authentication, and it fails with a specific message (rather than hanging) if the server accepts the connection but never acknowledges. Readiness is tracked per connection, so a reconnect re-arms it and a stale acknowledgement from an earlier socket cannot satisfy a fresh start.
  • Localhost errors no longer tell you to do something you cannot do. Two messages a developer running an app on localhost meets early both named a remedy that does not exist. Rejecting a loopback project URL suggested testsprite test run <test-id> --local <port> — but project create, project update, test create, test create --plan-from and test create-batch all run that check before a test id exists, and project create before there is even a project. Those five now explain it in the order you can act on: TestSprite runs your tests from the cloud, so the project's URL has to be one the runner can reach — point it at your deployed or staging URL; then, once a test exists, aim a single run at the app on your machine with --local <port>, which is per-run and does not change the project's URL. Separately, when a tunnel run refused to dial a private/LAN/VPN address it told you to set TS_TUNNEL_ALLOW_PRIVATE_NETWORK_TARGET=true — a variable the CLI never reads and cannot be made to honour. That message now states the real policy (a tunnel run reaches localhost/127.0.0.1/::1 on your machine and the public internet, and refuses private addresses deliberately) and points at making the dependency reachable instead. No guard changed what it accepts or rejects; only the advice was wrong.
  • A borrowed tunnel that dies ends the run instead of waiting out --timeout. test run --local --tunnel-client <id> attaches to a tunnel another terminal owns, and deliberately never stops or deletes it. The side effect was that the borrowing run could not see that tunnel disappear: if the owner pressed Ctrl-C or ran tunnel stop, the run kept polling a doomed run until --timeout expired. The run now checks the borrowed tunnel — at most once every 15 seconds, and never on a run that has already finished — and ends with the same UNAVAILABLE exit code (10) the owned path uses. Only an explicit offline status or a "no such tunnel" answer counts: a network failure, a timeout, or a server error is treated as unknown and retried later, so a blip in our own read can never fail your run. The message is written for this case specifically — it says the tunnel was minted by another process and points at restarting it or dropping --tunnel-client, rather than repeating the owned path's advice to retry (which mints nothing when you name an existing tunnel).
  • The missing-verification-skill warning now judges from the calling agent's view. It fell silent as soon as any supported agent had the skill, so a project set up for one agent read as correctly wired to all eight — exactly the case where an agent drives the CLI with no skill of its own and nothing says so. When the environment identifies the caller, only that agent's install counts, and the warning states that the skill is installed but not for it. A caller the environment cannot identify keeps the any-agent answer, which is all it can support.
  • Refusing a localhost URL names the flag you actually typed. project create --url http://localhost:3000 said Field `target-url` is invalid and pointed at testsprite test run --help — a flag and a command the caller never used. Every caller now names its own field and help command: url / project create and project update, endpoint-url / ci init, upload-url / project docs upload, target-url / test create, test create-batch and test run. Under --output json, details.field matches what was typed. The test run --target-url output is byte-identical.
  • Ctrl-C during test run --local states what happened, not a guarantee. The CLI cancels the run when its own tunnel is torn down, and used to print that "no further credits are spent on a guaranteed failure". A run seen in exactly that state completed and reached PASSED 36 s later and kept its 0.5-credit charge. The message now names the signal, says the run was cancelled and that a cancelled run's verdict is discarded, notes the run may already have been billed, and leads with the command to start a new run — testsprite test run <test-id> --local <port>. --no-cancel-on-interrupt is mentioned only with its consequence: a run left executing has no tunnel, cannot reach your app, and is still billed.
  • A borrowed tunnel whose owner died leads with the cancel, not a retry. When test run --local --tunnel-client <id> detects that the owning process is gone, the message used to say "restart the tunnel and run again" while the first run kept executing and billing server-side. It now names the run, says it was left executing, and gives the idempotent testsprite test cancel <run-id> first, with testsprite test wait <run-id> --timeout <s> as the alternative for watching it instead. Exit 10 and the owner-gone reason are unchanged.
  • test run --all prints the server's project-level dashboard link. The batch's closing "watch it here" line was templated client-side as /dashboard/tests/{projectId} — the V2 grammar — which the portal bounces onto a /dashboard-v3/... path with no route for a V3 workspace. The line now uses the link the server supplies (the per-test dashboardUrl already did); when the server says no correct page exists the line is omitted, and an older backend that sends nothing keeps today's fallback byte-for-byte.
Source: README.md, updated 2026-09-03