Skip to content

Releases: nasimuddin-dev/testpion

TestPion 0.53.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 06:38

Checks only, nothing changes in the app: the registry's "planned" capabilities that were due in 0.53 are re-planned for 0.54 (they are not built yet), and a test that compared a file name in another letter case now agrees with how macOS treats it.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.53.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 06:24

A review release: safer saves and downloads, one row and one badge in every list, tabs that always close and never show a cut-off name, one generic delete with Undo that the command line and MCP can use too, and faster trees. Every item below is something you can see or use.

  • The logo in the top bar sits on the bar's own background: white on the light theme (the wordmark has a dark "Pion" there), unchanged on the dark theme. It no longer sits on a navy badge.

  • Expand all and Collapse all are one toggle button, the same in the JSON tree and the explorer: it offers one, then the other after each press (the right-click menus keep both as items).

  • The same row in every list: collections, environments, AI providers, History entries and the Tests view's runs are now the one row the other trees use. Shift+F10 and the menu key open the menu, F2 renames, Delete deletes (with Undo), * expands, Enter opens, arrows, Home/End and typing a name move between rows. The runs list had no keyboard at all before.

  • The keyboard stays where you were: after deleting a row (key or menu) the focus moves to the next row, and Undo puts it on the restored row.

  • One badge everywhere: HTTP methods, protocols and file types (GET, GQL, gRPC, WS, MCP, AI, API, CSV …) are the same pill of the same width in the explorer, the Tests tree, History, the Runner and the Home view, in one colour per protocol that follows the light and dark themes.

  • Screen readers hear the trees as trees: each row is an item with its level, whether it is open and whether it is selected.

  • One delete message: "Deleted the (kind) “name”" with the same Recently deleted note wherever the item went there (collections, environments, API definitions, datasets, MCP servers).

  • Row tooltips show the full name only when the name is cut; test files rename in place (F2, Rename); the New folder… item has its ellipsis everywhere.

  • Empty states: the Tests view with no test files shows an icon, and the runs list says "No runs yet" (and "No runs match", with Clear filter) with a next step.

  • Faster: typing in a test file no longer redraws the test file tree (a thousand files draw only the rows on screen), the Collections filter works each name out once per keystroke, Expand all writes the saved tree state once, and the explorer reloads only the list a change touched.

  • Every click on a request in the explorer opens it in a tab of its own and shows it (it no longer replaces the tab you had); a request that is already open is just shown.

  • Closing the last tab of Evaluations, Load tests, the AI Playground or Environments now closes it: the view says nothing is open and offers a button for a new one, as the request editors do.

  • A request you sent keeps its tab and its response until you close the tab: a single click on another request opens a new tab instead of replacing it (a preview tab is still replaced while nothing was sent from it). The same for a prompt run in the Playground.

Download and export: safer, and no slower for big outputs

  • Open after a save is for documents only: a raw body, an HTML page, a shell script, or any file whose name ends in something the OS would run (.exe, .cmd, .js, .lnk …) is shown in its folder instead; the toast offers Open only when it applies.
  • A server's download name never runs on a double-click: a Content-Disposition name with a launcher extension gets the Content-Type's extension appended (report.cmd saves as report.cmd.txt, setup.exe as setup.exe.bin).
  • Deeply nested JSON lays out in bounded space: the indent stops growing past 64 levels and the layout stops past 512; a body that would still grow past 8× its size stops the save with a message (save it as Raw body instead) rather than fill the disk.
  • A link inside the workspace cannot carry a read or write outside it: paths are checked by where they really lead, a payload is read only when it is a plain file under payloads/ (a response body, History compare), and a source is accepted only for the output it belongs to (the console's lines cannot be saved under the timeline's no-redaction policy).
  • Workspace export reads datasets field by field: a CSV column named password, a JSON, JSON Lines or YAML property holding a secret becomes a {{variable}} and is listed; files no scan can read (binary, a dataset that does not parse) are named in the summary as exported as is.
  • Importing a workspace export never replays the file's own notes; what the import skipped is said in TestPion's words. Objects in an export or an Insomnia import cannot set a prototype through a __proto__ key.
  • Big saves stream end to end: a data run or evaluation matrix as JSON, HTML or Markdown is written page by page like CSV, a run's ZIP entry by entry, and reports recorded masked are no longer parsed and masked a second time.

Menus

  • Key hints in every row menu: Open Enter, Rename F2, Delete… Del, Expand all * are shown beside the items that the keys run (the menu itself opens with Shift+F10); the docs' menu table shows them too.

For AI agents and scripts

  • testpion item delete <ref> / item restore <id> (--json), the MCP tools delete_item / restore_item and the RPC item.remove / item.restore: one delete-to-Recently-deleted and restore for every kind with the trash capability (collections, environments, datasets, API definitions, MCP servers), by ref (environment:staging, spec:specs/x.yaml, a testpion://open link, {kind, …ids}); the app's own Delete… with Undo goes through the same function. A kind without it answers with the reason.
  • testpion kinds --json / list_kinds / kinds.list add nodes: the menu of every row a kind has in the app (its row, section header and folders), group by group, with each action's id, label key and key.
  • A delete-for-good dialog starts on Cancel: Enter no longer confirms "Delete for good" (Recently deleted), "Delete the folder" or a git branch delete; press the button, or Tab to it. Question dialogs still answer Enter with their primary button.
  • Tab strips never show a cut-off tab: in a pane too narrow for every tab (the request editor side by side with the response, compact density), a tab only partly in view is hidden and counted by the strip's overflow button; the request editor's strip and the document strips (open requests, test files, monitors) share one overflow control, with the active tab ticked.
  • One tooltip style: why an output's Copy / Download is off, and the ⓘ hint of an output bar (the Problems panel's F8 / Shift+F8 keys, which were plain text clipped in a narrow pane), are the same tooltip as every button's.
  • Kind colours are tokens: the GraphQL, gRPC, WebSocket, API definition and dataset badges in tabs, the runner and the Debugger use the kind's colour token, the same in both themes.
  • The output control (Copy / Download / ▾) does less work on every render: its menu and the format it remembers are kept between renders (the console re-renders on every event).

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.52.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 07:38

One registry, one menu: every kind of item a workspace holds is declared once (what it is called, where it is stored and opens, what it can do), and every tree and list row's menu is built from it by one function. (What's new in 0.52)

Behaviour changes: what works differently (read before upgrading)

  • One menu order everywhere: create · open · tree · run · share · tools · git · edit · danger. Run moved after Expand all / Collapse all in the collection and folder menus; the items kept their names.
  • New request ▸ holds a collection's other request kinds (GraphQL, SOAP, gRPC, WebSocket & MQTT); Copy as ▸ holds a request's Copy URL, cURL, PowerShell, fetch and code snippets.
  • Convert scripts to pm.* is now Export ▸ For Postman (pm.*)… in the collection menu (TestPion writes tp.*; pm.* is for Postman).
  • AI providers, test files and folders of test files delete with Undo instead of a confirmation (a folder of more than 200 files still asks).
  • What is open in trees and lists is kept per workspace (the explorer's sections and folders, every list's folders, the Tests tree), across restarts; the open state of earlier versions moves into the first workspace opened.

Menus

  • Expand all and Collapse all on every container and section header: protocol groups, folders of saved gRPC calls and connections (which now have a menu: rename, delete with Undo), the MCP servers, API definitions and Datasets sections and their folders, the folders of monitors, prompts, load tests and evaluations, the Tests tree and its folders.
  • The same row everywhere: ⋯, right-click, Shift+F10 and the menu key open the same menu; F2 renames, Delete deletes (with Undo), * expands everything inside, typing a name jumps to it. Environments get a right-click menu in the sidebar pane, the History pane a menu.
  • Copy link on every item with a link (collections, folders, requests, saved items, servers, API definitions, datasets, test files, runs …).
  • API definitions: Rename (in their folder), Delete with Undo (back in their folder), Lint, Generate tests…, Generate integration flows…, Reveal file, Copy path.
  • Datasets: virtual folders (library/dataset-folders.json; files never move), Preview, Use in a test, Reveal file, Copy path; rename and duplicate keep a dataset's folder.
  • MCP servers: Open in new tab, Copy link, Copy MCP config (.mcp.json / claude_desktop_config.json).
  • Requests: Monitor on a schedule…; folders: Run in CI…, Copy link; test folders: New test file here, Run in CI…, Rename folder.
  • The blank area of the sidebar opens the workspace's menu; of a list, that list's menu.
  • List rows carry their item when dragged (onto a flow canvas, into a folder), like the explorer's rows.

For AI agents and scripts

  • testpion kinds [kind] [--json] and the MCP tool list_kinds (and RPC kinds.list): every kind, its ref shape, storage, where it opens and every capability as true, { na: why } or { planned: release }.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.51.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 05:04

Save and export every output: every response and result now has the same down arrow at the right end of its bar, with Copy beside it and ▾ for the other formats, so anything TestPion shows can be kept as a file, safely. (What's new in 0.51)

Behaviour changes: what works differently (read before upgrading)

  • One down arrow replaces the old per-view buttons. The run results' Export ▾, the response's Save response, the run timeline's Save as HTML, the MCP tool result's Copy result / Save result and the generated code's Copy are gone: the arrow at the right end of the same bar saves the same files (and more formats), and Copy sits beside it. A runs list's Export report… and the palette's Export Results now save the HTML report through the Save as dialog. (Save and export results)
  • Saved logs are always redacted. The console, the application log, run reports, traces, the response's cURL, the flow timeline, data-run and matrix grids and the HTTP Debugger's HAR are masked when they are recorded, so they are saved and copied without secrets and have no Include secrets… (the Redacted mark's tooltip says why). Decoded JWTs, the terminal transcript and generated code (with Show secrets on) still hold their secrets: they are saved masked by default, and ▾ ▸ Include secrets… keeps them after you confirm.
  • Ctrl+Shift+S saves the output you are in (rebindable as Download the focused output in Settings ▸ Keyboard).

Save and export every output

  • One down arrow on every response and result, at the right end of its bar. It covers:
    • every tab of the REST/SOAP response: body (raw bytes as received, JSON pretty or minified, the table as CSV or TSV, HTML, XML, text, HAR), headers, cookies (also cookies.txt for curl -b), JWT, timeline (JSON, HAR with timings, Markdown), checks (JSON, JUnit, Markdown), stream, trace, server-sent events, history and cURL
    • GraphQL responses and subscriptions
    • the gRPC response, messages, metadata and trailers (each as JSON, metadata and trailers also as CSV, or everything in one JSON)
    • WebSocket, Socket.IO, MQTT and Kafka message logs
    • MCP tool results and generated code
    • run results (HTML report, JSON, JUnit, Markdown, CSV, ZIP of them all)
    • the flow run timeline (self-contained HTML), data-run and matrix grids, load results and the evaluation matrix
    • the console, the application log, the terminal, Problems and the HTTP Debugger session (HAR)
  • How it works:
    • Click saves the default format (or the one you chose last on that kind of output), ▾ chooses another or Copy as another text format, and Copy sits beside it.
    • Files are saved through the OS Save as dialog, in the folder you last used for that kind of output in the workspace, with names such as GET-patients-2026-10-17-1405-200.json; then a message offers Show in folder and Open. The browser version downloads them (up to 100 MB).
    • Ctrl+Shift+S, the palette's Download Output… and File ▸ Download Output… work too.
  • Secrets: log-like outputs are saved redacted by default, with a Redacted mark; Include secrets… (confirmed, for that one file) is offered only where the data still holds the secrets. Response bodies are saved as they are, with a notice when one looks like it holds a credential or comes from a production environment.
  • Big outputs: big bodies (a 50 MB body is re-indented as it is read) and long grids (a 10,000-row data run) are streamed from disk into the file, never through the window. Saves over 5 MB show progress with Cancel, and a cancelled or failed save leaves no half-written file (it is written as .part and renamed).
  • Safe files: CSV files guard against spreadsheet formula injection, and file names are safe on every OS (Windows reserved names such as CON or NUL, and invisible direction-changing characters, are taken care of).
  • Not yet: --out / --format on every CLI result command, MCP tools that save results to a file, and a down arrow on History, Traces, AI results, Git diffs, lint reports, charts and monitors come in a later release.

Fixes

  • HTTP Debugger: Export as HAR… saves through the Save as dialog again. It called a backend method that did not exist, so it always fell back to a browser download.
  • JSON tree toolbar: Expand all is no longer cut off, and the JSONPath filter is no longer squeezed against the hint. Expand and collapse are now icon buttons, and the hint moved behind an ⓘ.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.50.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 23:28

Nothing is lost, nothing leaks: a workspace export now holds everything a workspace needs and never a secret, every import says what it could not bring over instead of guessing, and nothing you delete or import over is gone for good. (What's new in 0.50)

Behaviour changes: what works differently (read before upgrading)

  • Exports never contain secrets (listed as replaced). A token typed into a collection's auth or a secret header, every MCP server header and stdio env value (except names such as Content-Type or NODE_ENV), a password in a connection string and a provider key become {{variables}} in the export (Bearer {{PETSTORE_MCP_AUTHORIZATION}}); an environment variable with a secret name or value that isn't marked secret is exported empty and marked secret. The message after export lists each one (replaced: [{ kind, item, field, variable }] with testpion workspace export --json), and the import lists the values needed. (Privacy: exports)
  • Workspace exports include specs, datasets, mocks and protos. The export used to leave out specs/, datasets/, mocks/ and protos/ (and test files of 5 MB or more) without a word, so a re-imported workspace lost its contract checks, data-driven tests and MCP mocks. They are now in the file (text as text, a SQLite dataset as base64) and come back byte for byte; a file over 10 MB (or past 50 MB in all) is left out and named in the message (notes with --json). (Export the whole workspace)
  • The export file is <workspace>.testpion.json (.apsworkspace.json files still import), and testpion workspace export no longer needs -o.
  • Importing an API definition never overwrites. Importing an OpenAPI or AsyncAPI document whose name the workspace already has (a newer version) used to replace specs/<name> silently. It is now saved beside it as specs/<name>-2… with its contract checks, and the message says Saved as specs/x-2.yaml with Replace instead (the old document goes to Recently deleted). The same document imported again is reused. testpion import prints the same note; --replace-spec replaces at once.
  • Deleting an MCP server has Undo instead of a question. In the Collections sidebar it goes at once, with Undo in the message, and comes back in its place with its settings, reconnected if it was connected.
  • Imports never map an unsupported auth to inherit. A Postman, Insomnia, Bruno or Hoppscotch auth TestPion doesn't have (Hawk, NTLM, EdgeGrid, ASAP, WSSE, netrc, anything new) used to fall back to inherit, so the request quietly sent its parent's credentials. It now becomes No auth, with a disabled X-Imported-Auth-<Scheme> header as a reminder and a note naming the request. JWT auth (HS256/384/512) maps to TestPion's JWT auth; an OAuth 2 grant TestPion doesn't run (implicit, device) is imported as authorization code, with a note. (Import fidelity)
  • Imported Bruno scripts use tp.*. bru.setVar → tp.collectionVariables.set, bru.getEnvVar → tp.environment.get …; req, res and test still run as in Bruno, and the import reports the scripts converted like a Postman import. A bru.* call TestPion lacks gets a // TODO(import) line and a note. A Bruno export writes the scripts back with bru.*.
  • Every import note is shown. What did not map one to one is listed after every import: in the Import dialog and Workspace menu ▸ Import… (Check after import (N notes), the first notes and and N more), in testpion import (up to 20, --json lists them all) and in the MCP tool import_definition (notes).

Nothing lost

  • Recently deleted keeps more: MCP servers and API definitions replaced by an import stay for 30 days beside collections, environments and datasets, with Restore (an MCP server back in its place in the list, an API definition at its path). The new Recently deleted icon beside the Filter box of the Collections sidebar lists collections, datasets, API definitions and MCP servers; testpion trash list|restore covers every kind.
  • Sidebar rows no longer repeat or disappear when two collections share request ids. Imports, moves between collections and examples updates give fresh ids to requests whose id is already taken, and a second copy of an example collection left by an older version (such as two "Live streams (SSE)") is merged back into one, the copy kept in Recently deleted. Dragging a row shows one small chip and never leaves a ghost of the row behind.
  • Workspace import checks every path the same way on every OS (no .., absolute or drive paths, backslashes, or folders other than specs/, datasets/, mocks/ and protos/) and names what it skipped.

Nothing leaked

  • One secret detector now serves exports, testpion git check and the masks of logs and AI context: secret names plus value shapes with a confidence (JWT, Bearer/Basic, sk-, ghp_/github_pat_, glpat-, xox?-, AKIA/ASIA, AIza, SG., Twilio SK, npm_, pypi-, private keys, connection strings with a password). git check also flags an MCP server's headers and env together, and a variable holding a provider key or a password URL whatever its name.
  • Bruno .env goes to the secret store. The collection's .env (only .env, never .env.example) is read: {{process.env.X}} becomes {{X}} in a Bruno .env environment (and each imported environment), the values go to the secret store, and missing ones are listed as values needed.

Imports that bring more over

  • Insomnia v5 scripts and template tags. Request scripts of Insomnia 5 YAML files (scripts.preRequest / afterResponse) and folder scripts are imported; a plain JavaScript script stays runnable instead of being commented out. Template tags are no longer left as literal text: {% uuid %}, {% now %}, {% timestamp %} and {% faker %} become dynamic variables, {% base64 %} and {% hash %} a pre-request line, {% response %} of another request is chained (that request's post-response script sets a variable the request uses), {% prompt %} a variable to set; any other tag stays as text with a note naming the request. {{ _['a-b'] }} works, and folder headers are added to the requests inside, with a note.
  • GraphQL SDL import. A GraphQL schema file (.graphql) imports as a GraphQL request for {{graphqlUrl}} with a ready operation for the first Query field; the schema is kept in specs/graphql/ (it used to fail with Unrecognised import format).
  • What each importer maps, and what becomes a note, is on the new Import fidelity page.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.49.1

Choose a tag to compare

@github-actions github-actions released this 17 Oct 18:01

Fixes for 0.49.0, found by the macOS test run: workspaces reached through a link (a macOS /tmp or /var folder, a linked projects folder) now work everywhere.

Fixes

  • Workspaces opened through a symbolic link keep working — a folder under /tmp or /var on macOS (both are links to /private/…), a junction on Windows, a linked home or projects folder. A run started from the folder itself records its files by their real path, and TestPion now relates every such path to the workspace whichever way each one names it, so:
    • --triage and Explain and fix failures with AI find the failing test file and propose a fix of it (on macOS the triage of a CLI run proposed none);
    • Run again, Run in CI (testpion ci --run) and links from a result name the file under tests/;
    • a flow's Runs, its Timeline (testpion flow report --file) and the designer's step results find the runs that included it;
    • the app's own writes made by the real path (agents-md, for one) are not shown as changed outside TestPion, and the window still refreshes for them;
    • the folder is listed once in the workspace list, Delete and Rename recognise the open workspace by either path, and Show in folder opens it;
    • the pre-commit secret guard (testpion git hook install) and the CI files of a flow's Deploy panel are found in the repository the folder really is in;
    • lint-tests names the file under tests/, openapi fuzz --save-tests keeps the spec's path, --watch watches the folder once, and --dry-run reports writes into the workspace as changes of it.
  • A folder beside the app's data folder whose name starts the same (workspaces-old) is no longer taken for one the app created, and an Arazzo source description is read only from inside the workspace or the Arazzo file's folder, not from a folder whose name merely starts the same.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.49.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 17:11

Explain and fix failures with AI

  • Explain and fix failures with AI… on every failed run — the run's ⋯ menu (test, collection, flow and monitor runs), a run's right-click menu in Runs, and the failed run in the Problems panel and Home's Needs attention. TestPion first groups the failures without AI (the same failed check, status and endpoint), so 500 failures from one expired token are a few groups; the dialog shows the failures and groups, the model and the token estimate before anything is sent. Your model sees each group's examples with the evidence — the request, the response, the failed check as the test writes it, and what changed since the same test last passed — and answers with causes (one cause may explain many groups), each with its evidence, a confidence and a fix. (Explain and fix failures)
  • Every fix is proven before you see it: a changed check must pass on the failing response, must not pass on any response (an empty body or an error page), and is run on the last passing response too (it follows an API change when it would have failed there); an edited test file must lint and an edited script pass in the sandbox; a variable fix must be one the failing steps missed and never a secret. When the test is right and the API regressed, the fix is a bug report to copy, with what changed since the last pass.
  • A check fix cannot miss its check: the model names the failing check by its result and its place in the test (checkIndex, as the evidence numbers them) instead of quoting text; a fix that still cannot be made goes back to the model with the reason and the checks it may name (up to twice). For a stale expected value TestPion also works out the update itself from the evidence (the value the API answers now, or a stable form such as type $.id = "string" for a value the server makes up; never for a 5xx, 401 or 403) — it stands in when the model's fix cannot be used and is offered beside a different one under Safer:, so a stale test is never left without a fix (task triage-run v2).
  • You decide: nothing changes before Apply selected fixes; then Rerun the affected tests and Undo.
  • Privacy: failure bodies are masked like every AI context, and Metadata only sends the method and URL (query values as …), statuses, check types and names, the checks as the test writes them, header names, the shape of bodies (field names and types, a text as string (N chars)) and which headers changed since the last pass; the body's changes since then go as shapes only (how many; each change's path and kind as string (N chars), not which fields) — no body values, no failure messages. Names only sends the URL's path, and expected values and most numbers as their type. Without a model you get the grouping with the likely cause of each group.
  • CI: testpion test|run|run-collection … --triage adds a Triage section after a failed run, writes triage.md / triage.json beside the results and — when a model answered — a Triage (AI) section in the JUnit, HTML and Markdown reports. It never changes the exit code. testpion ai triage [--run <id|last>] [--privacy metadata] [--hint …] [--no-ai] [--dry-run] [--apply [--items …]] [--json]; MCP ai_triage_run. (CLI, MCP, in a pipeline)

Why is this flaky?

  • Why is this flaky? on a flaky test (the Problems panel, a result's History tab): TestPion reads its results across runs — pass rate, flips, retries, the environments and statuses of its failures, its time when it passes and when it fails — and your model names the pattern (timing, ordering, shared state, a time-dependent value, an external dependency, a rate limit, a data collision) with evidence and a fix that makes it stable without hiding a failure: a wait (until:), a stable check, isolated data; a retry only as a last resort, always flagged. Skipping or quarantining the test is never offered. (Why is this flaky?)
  • The pattern starts from a signature TestPion computes: how the failing responses differ from passing ones ($.status: "done" when it passes, "running" when it fails) and the pattern it points to (an intermediate state → timing and a wait; 429 → rate limit; 409 → data collision; changed dates → time-dependent; 5xx, timeouts or slow failures → external dependency). The model gets a guide to each pattern's signature and the whole test-file format, and a fix that breaks the YAML or cannot be made goes back with the lint explanation or the check to name (task analyze-flaky v2).
  • Attempt to fix applies the fix and runs the test 5 times through the ordinary runner; the review shows the verdict (Stable: passed 5/5, Still flaky, Failing), then Keep the fix or Undo. testpion ai run analyze-flaky --item test:<path>[:<step>], testpion ai attempt-fix <id> [--times 5] [--allow-production]; MCP ai_analyze_flaky, ai_attempt_fix.

Better generated tests

  • Generate tests now tells the model the exact tp.* script API, read from the script sandbox itself (what tp.response, its assertions and a tp.expect chain really have, with one test that runs), and a script that misuses it goes back naming the right member — tp.response.json().id for a field read from tp.response.body (the raw text), tp.response.json() for pm.response.json(), to.be.ok for Jest's toBeTruthy(), status() for an invented statusCode() — so fewer repairs are needed (task generate-pm-tests v4).

Behaviour changes: what works differently

  • testpion run-collection on a workspace collection records what it ran (the collection, the requests and folders picked, the iterations), so Run again, Run in CI, ci --run last and the triage find its saved requests.
  • Attempt to fix and the triage obey the production guard: in an environment marked as production, Attempt to fix asks first like any run, testpion ai attempt-fix needs --allow-production for data-changing requests, and the MCP tool ai_attempt_fix refuses such an environment unless the server was started with --allow-production.
  • A fix is never applied over a newer file: when the test file or saved request changed after the proposal was made, applying it is refused with it changed since the proposal was made (run the analysis again).
  • Damaged run files are named as such: a run whose summary.json cannot be read says so (with what to do) instead of showing a JSON parser error, and the triage, the flaky analysis, the history and the reports read a damaged or edited results file without failing.
  • Rerunning failed requests brings the requests they need: run-collection --rerun-failed, Rerun failed and Rerun the affected tests also run, first, the earlier requests whose scripts set a {{variable}} the failed ones use (the token request), marked [setup]; their results are reported but do not count toward the rerun's totals.
  • Test-file edits change only what they change: a fix (triage, flaky analysis) or a flow designer edit rewrites only the edited step's text; flow-style lists, quoting, comments and spacing elsewhere stay byte for byte (CRLF files too).
  • --triage outside a workspace says so: triage needs a workspace (-w); nothing recorded (stderr and the JSON envelope's warnings); testpion ai run analyze-flaky without a model (or with --no-ai) prints TestPion's own finding and exits 0.
  • testpion ai run shows a JSON task's answer as its proposal (findings and items) instead of the raw JSON.

Also

  • The proposal review shows what TestPion changed in a model's answer (notes), long verification labels stay on their row, and a text item (a bug report) has Copy.
  • Each AI call from the window now releases its engine context when it ends, so a long session with the assistant no longer holds on to them.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.48.1

Choose a tag to compare

@github-actions github-actions released this 17 Oct 05:20

Fixes for 0.48.0, found by the macOS, Linux and Windows test runs.

Fixes

  • Where an AI proposal may write is decided the same way on every OS: a target path (--path of testpion ai run and testpion flow generate, an RPC's or MCP tool's path, a hand-edited proposal, an undo record, and the MCP tool write_test_file) must be a /-separated path inside tests/ ending in .yaml, .yml or .json. A Windows path (C:\…, C:/…, \\server\share), a backslash (..\x.yaml), .., a leading /, percent-encoding, control characters, empty folder names, names Windows cannot hold (CON, a:b, a trailing dot) and over-long paths are refused before anything is sent — on Linux and macOS a path like C:\Windows\x.yaml used to be accepted as a file name inside tests/. Writing also checks where the file really lands, so a link inside tests/ that leads elsewhere is refused.
  • Runs always end, and are recorded when they do: a collection run with bail (testpion run-collection --bail) stopped at the first failure but then never finished; it now ends there with its results recorded. A run whose results file cannot be written (a full disk, a folder in the way) now fails with that reason instead of waiting forever (and no longer raises an unhandled error).
  • Cancelling a data-driven flow run never starts another row: a row being read from the data at the moment of the cancel (or of a bail by another row) no longer starts, and is no longer counted as a cancelled row; only the rows that were running are.

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.

TestPion 0.48.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 04:23

Behaviour changes: what works differently (read before upgrading)

  • Suggest assertions, Generate tests and Describe a request now open a review instead of adding their result at once. Each suggested check, test or request is checked first and shown with its verification; tick what you want, then Add to the checks, Add to the Post-response script (after your own script, never replacing it) or Open as a new request. Nothing is added before you accept. (Proposals)
  • AI features need a model you set up: your Claude (Anthropic) key, or a provider of the workspace in Settings ▸ AI assistant; a model on your computer (Ollama (local), the new LM Studio (local) preset) works offline, and Local only keeps every AI call on this computer. Without a model, an AI action offers Set up AI and sends nothing. (Set up a model)
  • AI calls can be capped: tokens per call, tokens per day and cost per day (Settings ▸ AI assistant ▸ Limits). A call over a cap is refused before anything is sent, with Change the limits; calls from the CLI, MCP agents and CI count and are capped too. (Cost)
  • More is masked before anything reaches a model: besides secret values and sensitive field names, credentials found by their shape in any field or text (JWTs, Bearer/Basic credentials, private keys, provider API keys, credential query parameters) and personal data (e-mail addresses, phone numbers, Luhn-checked card numbers, IBANs; Mask personal data turns that off). Large contexts are sampled (first, last, failed, one of each shape) and summarised to their shape instead of being cut mid-JSON.

Let AI write the integration flow

  • Right-click a collection or a folder ▸ Generate integration flow with AI… (also in a collection's Export menu, and the flow canvas's Generate with AI, which now offers From a collection or folder beside Describe in words): your model turns the folder's saved requests into one flow — create, read, update, delete in order, the ids and tokens each step returns extracted and passed on, status and key-field checks, one or two error cases — and says what it assumed. It starts from the flow TestPion builds without AI and names saved requests by id: a step naming a request that is not in the folder is dropped (the review says so), and a URL may only gain {{variables}} on the request's own host. (Let AI write the flow)
  • Checked before you see it: the flow is linted (cycles, unknown dependsOn), every {{variable}} must be extracted by a step it waits for (or be one your workspace has), and it runs against a mock of the collection when it has saved examples; a problem goes back to the model up to twice.
  • Reviewed on a canvas: the proposed flow opens as a preview marked AI-generated with its summary, assumptions, what TestPion changed, verification badges and YAML (edit it there; Check again verifies the edit); Try on mock, Regenerate with a hint, Discard, Accept — which writes tests/flows/<collection>-<folder>.yaml and offers Run now and Open (and Undo). Nothing is saved or run before Accept. The dialog shows the token and cost estimate and What will be sent first (requests, body shapes, variable names — never values; Metadata only sends no body values; large folders are sampled). Without a model: Set up AI / Add the key, or Use the draft without AI.
  • Terminal and agents: testpion flow generate --collection <name|id> [--folder <name|id|path>] [--hint …] [--privacy metadata] [--dry-run] [--apply] [--no-ai] [--json], and the MCP tool flow_generate (it proposes; ai_apply_proposal writes). Without a model set up both return the deterministic draft with a note. (CLI, MCP)

Suggested checks and tests are proven before they are offered

  • Suggest assertions runs each suggested check against the response on screen — and the one before it in History: a check that passes now but failed before (an id, a time, a token) is unticked as the value changes, and a check that pins a generated value is flagged; both offer Safer: forms (exists, type, a format regex) that are checked again when you pick one.
  • Generate tests writes one tp.test per item, each run in the sandbox against the response (and the previous one); a failing test is shown unticked with its message, and pm.* / postman.* is refused and sent back to be written as tp.*.
  • Run now in the review sends the request again (the usual way, under the production guard) and checks every item against the new response. Try on mock does the same for a proposed flow.
  • YAML from a model is made safe first: a value starting with {{ written without quotes (url: {{baseUrl}}/pets, a YAML error models often repeat) is quoted before the flow or test file is checked — the review says Fixed N unquoted template values — and a YAML error that remains goes back to the model with its likely cause in plain words (unquoted {{, tabs, indentation, a duplicate key). The flow and test prompts say to quote such values, and the test and check prompts say what a script can read (the response time only when it is known).
  • The model is told the test-file format: the flow and test prompts carry a compact reference made from the same schema and check registry the lint uses (step keys, each response check with an example, one complete flow), and a check written in the wrong shape goes back with the right shape and the allowed types.
  • CLI and MCP parity: testpion ai run suggest-assertions --item request:<collection>:<request> --json (alias of generate-assertions; generate-tests of generate-pm-tests), MCP ai_run_task with the same ids.

AI features you can trust: see what is sent, cap the cost, review every change

  • What will be sent… beside every AI button (the eye icon) and in the assistant's header: the model and whether it stays on this computer, the privacy level (switchable), each context section with its tokens and how a large one was fitted, what was masked and where, the token and cost estimate, and the exact messages — before anything is sent. Hovering an AI button shows the model and the estimate. (What is sent)
  • Privacy levels: Full (redacted), Metadata only (shapes and names, no body values) and Names only; the default in Settings ▸ AI assistant, and each action can change it.
  • Local only: Settings ▸ AI assistant ▸ Local only allows only Ollama, LM Studio or another server on 127.0.0.1 (CLI/CI: TESTPION_AI_LOCAL_ONLY=1); a cloud model is refused before anything is sent.
  • Models per task: a model for small tasks (explanations, triage, commit messages) and one for generation (tests, flows, checks); CLI/CI: TESTPION_AI_PROVIDER, TESTPION_AI_MODEL, TESTPION_AI_MODEL_SMALL / TESTPION_AI_MODEL_LARGE.
  • AI usage: AI Lab ▸ Usage now starts with AI features: every AI call from the app, the CLI, MCP agents and CI, per task, model and surface, with what is left of the caps; testpion ai usage, MCP ai_usage.
  • Proposals, verified, reviewed in one place: suggested checks, tp tests, flows, coverage tests and requests come as a proposal whose items the engine checked first — checks against the response they were written for, scripts run once in the sandbox, test files linted and loaded, flow variables traced, JSON validated. A failing item is sent back to the model (up to twice), then shown unticked with the problem, never hidden; an answer cut at the output limit is refused instead of used. The review shows each item's diff and badges: Accept selected (Ctrl+Enter, one Undo), Regenerate with a hint, Discard. Proposals are kept a day, so one made in the app can be applied from the CLI or by an agent.
  • The same AI from the terminal and for agents: testpion ai tasks|run|apply|undo|discard|proposals|usage (all with --json; ai run --dry-run prints what would be sent) and the MCP tools ai_list_tasks, ai_run_task, ai_proposals, ai_apply_proposal (confirmed), ai_undo_proposal, ai_usage. (CLI, MCP, AI features)

More

  • AI settings that can't break the app: an ai value of the wrong shape in settings.json (a hand edit, another version) falls back to the defaults field by field — no model for a tier, Local only off, full privacy, masking on, no cap — instead of refusing every call.
  • Proposals stay in the workspace: a proposal can only write test files under tests/, and a proposal id or a hand-edited proposal that points elsewhere is refused before anything is written or undone.
  • One AI button everywhere: every AI action of the window (Explain with AI, How to fix (AI), Analyze with AI, Suggest assertions …) is the same control with What will be sent… beside it, and every AI setup problem (a missing key, no model, Local only, a cap) offers its fix the same way.
  • Under the hood: the AI assistant's tasks (27, with the new flow-from-collection) moved from the desktop app into the engine: one task runner with versioned prompts, structured output (JSON schema where the provider has it, validated and repaired), verifiers, proposals and the usage ledger, used by the app, the CLI, the MCP server and (later) the cloud host. Golden cases for every AI task run with the mock provider in npm test; AI_EVAL_LIVE=1 runs them against a real model with a scorecard. ([For contributors](/ai-testing/ai-features#the-prompts-are-tested-fo...
Read more

TestPion 0.47.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 03:22

Behaviour changes: what works differently (read before upgrading)

  • A single click on a request opens a preview tab. In the Collections explorer a click opens the request in a preview tab (its name in italics) that the next click replaces, as test files, monitors, load tests and evaluations already did; double-click the item or the tab, press Enter or change something to keep it. Saved AI prompts, environments and saved Debugger sessions now open in tabs the same way. (Open an item)
  • The rail shows five views, and Ctrl+Alt+3 is now Tests. The rail shows Home, Collections, Tests, Environments and History; More… under them lists Debugger, Monitors, Load, AI Lab, Evaluations, Traces and Git. Ctrl+Alt+1…9 count the shown views, so by default 1 Home, 2 Collections, 3 Tests, 4 Environments, 5 History (3 was the Debugger, 4 Tests …). Right-click the rail to show a view again (Show on the rail, Show every view). (Choose what the rail shows)
  • Deleting no longer asks "Are you sure?" when it can be undone. A request, folder, collection, environment, dataset, gRPC call or connection, saved prompt, load test, evaluation, monitor, MCP server, example or a list's folder goes at once (the Delete key too), with Undo in the message for 8 seconds and Ctrl+Z outside text fields; it comes back with its id, in its place. Deletes that can't be taken back still ask. (Deleting and Undo)
  • Flow steps written with a nested request: now get the file's defaults: auth:, like every other HTTP step (it was ignored, so such steps were sent without auth). A step that must go without it says auth: { type: none }.
  • The Model comparison has its own prompt. It no longer shares the prompt with the AI Playground, whose saved prompts now open in tabs.

Choose what the rail shows

  • Right-click a rail item: Hide from the rail, Move up / Move down, Show on the rail ▸, Show every view, Reset the rail. A view opened from More… (or Ctrl+K, a link) shows on the rail while it is open, with Keep on the rail; the Git view's count shows on More… while Git is hidden there.
  • The tooltips, the shortcuts list and the command palette's hints follow the shown views; Ctrl+K ▸ Rail: Show Every View / Rail: Reset to the Default Views. The choice is this computer's (settings.json rail).

Settings ▸ Keyboard

Every shortcut on one page with a search; the app-wide ones can be rebound (click, press the keys), with clashes named (Use it here swaps) and reserved keys refused with the reason, reset one by one or all, and exported / imported as JSON (testpion-keybindings.json). The shortcuts list, tooltips, the top bar and the palette's hints show your keys; saved for this computer (settings.json keybindings). Also from the ? list (Change the keys…) and Ctrl+K. (Change the keys)

Responses: JSONPath suggestions and Diff vs previous

  • JSONPath filter with suggestions. The Filter with JSONPath field of every JSON tree (response bodies, History, Traces, the Debugger) suggests the body's own paths as you type (arrays as [*]), shows the match count, and says why a path is wrong instead of quietly matching something; a big body is filtered once typing pauses. (Checks from the response)
  • Diff vs previous. A response's actions compare it with the previous response of the same request (sent earlier this session, else from History): status, time, headers and a field-by-field body diff, the same view as History ▸ Compare. Agents and scripts already have it: testpion history diff --json, MCP compare_responses. (Diff vs previous)

Compact density

Settings ▸ Appearance ▸ Density: Compact fits more rows and fields on screen in every view (tighter spacing, fields, list rows and small text), through the design tokens, so every view follows; kept for this computer and applied from the first paint. Ctrl+K ▸ Density: Switch Compact / Comfortable toggles it.

Undefined variables at a glance

The environment switcher (top bar and status bar) shows a red count when the open HTTP request uses {{variables}} the active environment, its collection, the workspace and the globals don't define, updated as you type; click it to add each one (and to the other environments). (Undefined variables)

The HTTP Debugger

  • The reverse proxy fills the Debugger's grid. What Reverse proxy for one API forwards joins the Debugger's session (marked reverse, Reverse proxy in the Application column and filter), so selection, filters, Create flow, Save to collection, HAR export and sessions work on it; the dialog keeps its own list and Save, and Show in Debugger goes there. (Reverse proxy for one API)
  • Capture sessions in History. Each Save to collection, Create flow and Save session adds a History entry (kind capture): the exchanges, hosts, proxy or reverse proxy, the time span, and a link that opens what it became. testpion history list --kind capture --json (and -q/--query), MCP history_list; a new link kind capture opens a saved session. (Sessions)
  • Saved sessions in tabs. A saved session opens in a tab beside Live capture, which keeps capturing; Add to the live capture copies it in.

Flows: inherited auth in the designer

An HTTP step without auth of its own shows the auth it inherits from the file's defaults: auth: (and where it comes from) instead of "No auth", with Override and No auth to change it for that step; testpion flow --json and flow_graph list it as inheritedAuth (typed credentials masked). (Design a flow)

More

  • Files written by anyone show up at once. Every change TestPion makes to the workspace's files (a test file saved through tests.write, generated tests, a dataset, an import, a move to the trash) tells the views which files changed (data.changed with the method, kinds and paths), so the Tests list and the explorer follow straight away, without a "changed outside" message. TestPion now tells its own saves by the file and what it wrote into it, not by a 1.5-second window: a change another program makes right after a save is no longer missed. (Git)
  • A guided tour of the first loop. A short, skippable tour on Home (Send → Save → Save as test → Run → Run in CI), shown once per workspace and from Get started ▸ Take the tour; keyboard friendly. (Get started)
  • One mode switch. The response body's view modes (Pretty, Table, Raw, Preview, Visualize), the Console filter, the WebSocket protocol, a trace payload's view, an MCP tool result and collection docs use the one shared switch (labelled words, not lowercase buttons).
  • Preferences that can't break the app. A rail, keybindings or density value of the wrong shape in settings.json (a hand edit, another version) is ignored: the app starts with the default for it.
  • Quick Open, the command palette and search: Enter opens the row the keyboard is on, even when the list opens under a resting mouse pointer (it opened whatever row landed under the pointer).

Downloads

See the download page for which file to choose and the installation guides.

The installers aren't code-signed yet: Windows SmartScreen and macOS Gatekeeper ask you to confirm the first launch.