WAVE is test automation for the parts of a system users never see: its APIs, its servers, its databases. Local or remote, reached directly or through SSH jump hosts.
01
What a test can do
Systems it has blocks for
HTTP and HTTPS APIs. Kubernetes. SQL databases. OpenSearch. SFTP. Linux servers over SSH.
Network checks
Ping, and a TCP or UDP port check.
Several systems in one test
One test can reach several of these systems in the same run.
Linux servers
Over SSH, directly or through any number of jump hosts. Once a test has connected to a server, it can run one command, run a whole script, or forward a port.
Work done on the remote server
A remote section is a group of blocks that runs on the server at the other end of an SSH session. Blocks that cannot run there stay on your machine, and each block shows where it runs. That server needs Python already installed. WAVE installs nothing on it and leaves nothing behind.
Control over the connection
On an HTTP request you set the method, the headers, the body, how redirects and retries behave, which TLS versions and ciphers WAVE offers, and which client certificate it presents. On SSH you set the host key policy and the key or password.
Files and formats
Read, write, copy, move and delete files. Parse CSV, Excel, XML and JSON, and use what is inside them in later blocks.
Your own code
Run Python or a shell command as a block. Pass values in, and take values out.
Systems without a block
Each system above has a block that makes it easy to reach. Everything else, you reach with a Python or shell block. If you can reach a system from a command line or from Python, a test can reach it the same way. When enough people ask for a system, we add a block for it. Our first customers help decide which ones come first. If you want a block for a system that does not have one yet, tell us before you buy.
02
Where it runs, and what leaves the machine
Where it runs
On your own machine, on your own network. No account to create, and no license server to call.
Connections out
No telemetry, no update check. Every connection out is one your test opened, to an address you set.
Without internet access
Works on a network with no internet connection at all.
Your data
Tests, credentials, hosts, results and reports stay on your machine. Nothing of yours reaches us unless you send it to us yourself.
Debug traces
If you hit a bug in WAVE, you can collect a trace and send it to us. You choose what goes in it, and you can report a bug without sending one.
Secrets
Any variable can be marked secret. A secret is masked as ******** everywhere it appears: in logs, in reports and on screen. It is encrypted when it is saved.
03
Building a test and running it
Control flow
If and else, switch, loops with break and continue, branches that run in parallel, try, catch and finally, wait until something is true, delay, assert, and stop the run.
Passing a value on
You choose which of a block's outputs to keep, and you name the variable that holds each one. Later blocks read that variable by name. An output you do not keep is dropped when the block finishes.
Calculating a value
A variable can hold a Python expression instead of a fixed value. WAVE calculates it each time a block reads that variable. For anything longer than one expression, use a Python block.
Watching values during a run
Every variable is listed while the test runs, and its value updates as the run continues. Open one and you see what it started as and what it holds now.
How a run is started
From the list of tests, suites or regressions, from a test you have open, or through a REST API.
MCP server
An MCP server your own AI assistant connects to. It is off until you turn it on. In the app's settings you choose whether it listens on your machine only or on your network, and whether it asks for a username and password. Your assistant can read the tests you already have, write a new one or change one, group tests into suites and regressions, start a run, and read the results.
AI inside WAVE
There is none. WAVE has no AI model inside it, and it never calls one.
You can run a single block, one test, one suite, or a whole regression.
Regression"Nightly"2 suites
Suite"Orders service"2 tests
Test"Checkout health"4 blocks
Block
SSHOpen sessionHTTPGet order statusSQLRead order rowAssertStatus matches
Test"Refund flow"9 blocks
Suite"Billing"4 tests
04
When a test fails
Without a debugger, the only way to see what a failed step was holding is to add logging and run the whole thing again. WAVE stops the run at breakpoints and shows you, the way a debugger does for unit tests.
Breakpoints
Set them before the run, or while the test is running.
While paused
Look at any value the run is holding, and change it before carrying on.
Stepping through a run
Step over a block, step into it, run one step again on its own, skip one, or continue.
Running one block
Run a single block on its own, or start the run at any block in the test and let the run continue from there.
05
What a run leaves behind
The report
Every run has a report, and you open it in WAVE. It shows what ran, what passed, what failed, how long each block took, who started the run, and the full log.
Sending a report to someone
Export it as one HTML file that opens in any browser, so whoever reads it does not need WAVE. You can also export it as JSON, so another tool can read the results.
Files a run produced
Files a run wrote are kept with that run. You can browse them and download them.
Past runs
A finished run is a read-only snapshot of the test as it ran. Open it and you see every block with the status it ended in, and the values the run held at the end.
06
Handing a test to someone else
Reading a test
A test is a diagram, not code. Anyone who opens it sees the blocks and the order they run in.
Seats
Each engineer installs WAVE on their own machine. A seat is one engineer on one machine, for twelve months.
Where tests are stored
As plain text files, under one directory that you choose. Values you mark secret are encrypted inside those files. You can keep the directory in version control, where a change to a test shows up as readable text.
Moving tests between machines
Export tests, suites and test data on one machine, and import them on another.
Where storage goes next
The next step after file storage is a server on your own hardware that the whole team connects to, so tests and run history sit in one place. This is not a fixed plan.
07
Functions
What a function is
A piece of a test you build once and publish to your team's library. Anyone on your team can drop it into their own test as one block.
What a function can see
Only what you pass in. It cannot read the variables of the test that uses it, and nothing it does changes them. Anything it produces comes back through its outputs.
Versions
What is inside a published version never changes. A function block binds to one version, and publishing a newer version does not move it. You move it yourself, by opening that block and choosing another version.
Breaking changes
Some changes can only go out as a new major version: removing an input or an output, renaming one, changing the type of one, or making an input required.
Moving functions between machines
Export a function with its version history, and import it on another machine.
One function can have several published versions in use at the same time, within the same test or across different tests.
A named set of values. Each value can be different in each environment. You choose what a profile holds: the host and password a block needs to reach a system, a timeout, a tenant name.
How a test uses a profile
You attach a profile to the blocks that need it, and you give the profile a short name in that test. Those blocks read its values by that name.
Choosing the environment
You pick the environment when you start the run, not when you build the test.
Secrets in a profile
Any value can be marked secret. When you export a profile you choose whether its secrets go out masked, still encrypted, or in plain text. Masked is the default.
Moving profiles between machines
Export a profile on one machine and import it on another. If the other machine does not have one of the environments, WAVE drops the values for that environment and tells you which environments it dropped.
A profile sits between the test and the environment, so the same test works in every environment. The test binds to the profile, not to the values.
Browser and user interface testing. WAVE tests the systems behind the screens. If the work is clicking through a web app, WAVE is the wrong tool.
Load and performance testing. There is no block for it, and nothing in WAVE measures how much traffic a system can take. You can write your own load test inside a Python block, which runs any Python code you write. A later release will run on a Python that can use several CPU cores at once.
Cloud hosting. There is no cloud version of WAVE. Nothing to sign up for, and nothing of yours on our machines. You run it, and you store everything it holds.