@qawolf/cli 1.29.0 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2393 -577
- package/dist/runner-sdk.js +274 -142
- package/dist/types/runnerSdk/types.d.ts +8 -0
- package/package.json +2 -2
- package/skills/qawolf-cli/SKILL.md +56 -2
- package/skills/qawolf-cli/references/run-results.md +8 -0
- package/skills/qawolf-cli/references/runner.md +21 -9
|
@@ -11,6 +11,12 @@ export type RunnerSdkOptions = {
|
|
|
11
11
|
};
|
|
12
12
|
export type SdkResult<Value> = {
|
|
13
13
|
error: string;
|
|
14
|
+
/**
|
|
15
|
+
* What the platform said beyond the headline, and what to do about it:
|
|
16
|
+
* the reason a runner is gone, which of `--runner`, `QAWOLF_RUNNER_ID` or
|
|
17
|
+
* the stored default named it, the command that brings one back.
|
|
18
|
+
*/
|
|
19
|
+
errorDetail?: string;
|
|
14
20
|
ok: false;
|
|
15
21
|
} | {
|
|
16
22
|
ok: true;
|
|
@@ -124,6 +130,8 @@ export type ListedRunner = {
|
|
|
124
130
|
isDefault: boolean;
|
|
125
131
|
launchedHere: boolean;
|
|
126
132
|
runnerName: string;
|
|
133
|
+
/** The QA Wolf page for this runner, showing its screen once it has one. */
|
|
134
|
+
url: string;
|
|
127
135
|
};
|
|
128
136
|
export type KeptAlive = {
|
|
129
137
|
id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qawolf/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"description": "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@qawolf/emails": "1.1.1",
|
|
76
76
|
"@qawolf/flow-targets": "1.0.0",
|
|
77
77
|
"@qawolf/flows": "0.1.4",
|
|
78
|
-
"@qawolf/testkit": "1.
|
|
78
|
+
"@qawolf/testkit": "1.2.1",
|
|
79
79
|
"commander": "14.0.3",
|
|
80
80
|
"env-paths": "4.0.0",
|
|
81
81
|
"picomatch": "4.0.4",
|
|
@@ -125,8 +125,8 @@ that `url`; never guess a route and never send a repository link in its place.
|
|
|
125
125
|
<!-- prettier-ignore -->
|
|
126
126
|
| Command | Kind | What it does |
|
|
127
127
|
| --- | --- | --- |
|
|
128
|
-
| `qawolf agent get` | read |
|
|
129
|
-
| `qawolf agent send` | write |
|
|
128
|
+
| `qawolf agent get` | read | Read what the QA Wolf AI has said and whether it is still working |
|
|
129
|
+
| `qawolf agent send` | write | Ask the QA Wolf AI to do a piece of work, such as covering a journey or fixing a broken flow |
|
|
130
130
|
| `qawolf auth login` | local | Authenticate with QA Wolf in a browser or with an API key |
|
|
131
131
|
| `qawolf auth logout` | local | Remove stored credentials |
|
|
132
132
|
| `qawolf auth switch` | local | Choose which workspace to work in |
|
|
@@ -209,6 +209,60 @@ changes team state; `local` only affects this machine. A parenthesized
|
|
|
209
209
|
note like `local (read with --remote)` means that flag makes the command
|
|
210
210
|
call the QA Wolf API and require auth.
|
|
211
211
|
|
|
212
|
+
## Asking QA Wolf to do the work: the `agent` group
|
|
213
|
+
|
|
214
|
+
`qawolf agent send "<what you want>"` is the one verb that starts work from
|
|
215
|
+
nothing. Every other write acts on a flow, run or issue that already exists.
|
|
216
|
+
Name the journey, the part of the app it covers, and anything the AI cannot
|
|
217
|
+
discover for itself, such as a test account, a feature flag, or how to reach a
|
|
218
|
+
staging environment. For a long message, put it in a file and pass
|
|
219
|
+
`"$(cat prompt.md)"`, so shell quoting cannot split it into arguments.
|
|
220
|
+
|
|
221
|
+
`--environment-id <id-or-alias>` picks the environment and reads
|
|
222
|
+
`QAWOLF_ENVIRONMENT`. A credential that is not bound to one workspace, such as
|
|
223
|
+
an organization or user API key, needs `--workspace-id`.
|
|
224
|
+
|
|
225
|
+
To give the AI a file, such as a spreadsheet of journeys, upload it first with
|
|
226
|
+
`qawolf file requestUpload --file-name <name>`, PUT the bytes to the returned
|
|
227
|
+
URL with the returned content type, then pass the returned path as
|
|
228
|
+
`--file-paths <path>` on the send. The AI reads it from storage, so a plan of
|
|
229
|
+
hundreds of journeys costs nothing to send. Up to 20 paths per send.
|
|
230
|
+
|
|
231
|
+
The work runs for minutes to tens of minutes. **Pass `--follow` and do not poll.**
|
|
232
|
+
The CLI reads the session for you, prints each reply once as it arrives, and
|
|
233
|
+
exits when the session settles: 0 when the work is complete, non-zero when it
|
|
234
|
+
failed or was cancelled. Looping `qawolf agent get` yourself costs a round trip
|
|
235
|
+
per tick and shows you replies you have already seen.
|
|
236
|
+
|
|
237
|
+
A session can stop and ask a question. With `--follow` in `--agent` or `--json`
|
|
238
|
+
mode the CLI prints the question and **exits 0** — a session that asked something
|
|
239
|
+
has handed the work back, it has not failed. Answer it, then pick the session
|
|
240
|
+
back up:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
qawolf agent send "<your answer>" --session <sessionId>
|
|
244
|
+
qawolf agent get --follow
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
In `--agent` or `--json` mode a follow ends with one JSON line holding the whole
|
|
248
|
+
session: `sessionId`, `status`, `url` and `replies`. It is the same object a
|
|
249
|
+
plain `qawolf agent get` answers with. Read the final `status` from that line;
|
|
250
|
+
the exit code alone does not tell a blocked session from a completed one.
|
|
251
|
+
|
|
252
|
+
`agent send` remembers the session it started, so a later `agent get --follow`
|
|
253
|
+
in the same directory needs no id. `--session <id>` or `QAWOLF_SESSION_ID`
|
|
254
|
+
override that.
|
|
255
|
+
|
|
256
|
+
Every session has a `url`, which the CLI prints when it starts or attaches.
|
|
257
|
+
A session opens in whichever workspace the credential is pointed at, which is not
|
|
258
|
+
always the one the user has open in the app, so send that `url` when you report
|
|
259
|
+
on a session rather than describing where it went.
|
|
260
|
+
|
|
261
|
+
Expect quiet stretches. QA Wolf reports a session as working and says nothing
|
|
262
|
+
more until the AI speaks, so several minutes with no output is the session
|
|
263
|
+
working, not the command hanging. `--timeout` bounds the wait; it is 30 minutes
|
|
264
|
+
by default.
|
|
265
|
+
|
|
212
266
|
## Driving a browser: the `runner` group
|
|
213
267
|
|
|
214
268
|
The `runner` commands drive a live cloud browser: `launch` one, `screenshot` to
|
|
@@ -25,6 +25,14 @@ run
|
|
|
25
25
|
`runId` in the response is canonical and can differ from the id you asked for.
|
|
26
26
|
Use the returned value for follow-up calls.
|
|
27
27
|
|
|
28
|
+
`run get` resolves platform runs only. A run id printed by `qawolf runner run`
|
|
29
|
+
belongs to that runner, so `run get` answers exit `8` and no such run on this
|
|
30
|
+
team. Read one of those with `qawolf runner events run-status --run <id>`.
|
|
31
|
+
|
|
32
|
+
A run that has been requested but not yet created answers exit `8` too, and
|
|
33
|
+
says it is still being created. That one clears on its own, so read the message
|
|
34
|
+
rather than the code before deciding whether to poll.
|
|
35
|
+
|
|
28
36
|
Poll `status` until it reaches `passed`, `failed` or `canceled`. The other
|
|
29
37
|
values mean the run is still going.
|
|
30
38
|
|
|
@@ -13,6 +13,8 @@ of starting and billing a second one, and the answer says which happened: read
|
|
|
13
13
|
cheap and safe pattern, and the same id with a different `--name` is refused
|
|
14
14
|
rather than silently ignored.
|
|
15
15
|
|
|
16
|
+
Either answer carries a `url`, which `qawolf runner launch` prints, as does a command that launched its own runner. It is a QA Wolf page showing what the runner is doing, where a person can also take over with their own mouse and keyboard. Hand it to a person who asks what your runner is up to. The page opens for anyone on the runner's team, however the runner was launched. There is nothing to see until the runner's first run starts its screen, so the page waits until then. You read the screen with `screenshot`, not with the page.
|
|
17
|
+
|
|
16
18
|
Commands that target a runner find one in this order: `--runner`, then
|
|
17
19
|
`QAWOLF_RUNNER_ID`, then the runner stored for the current directory (which
|
|
18
20
|
`qawolf runner launch` sets). Setting the environment variable once is the most
|
|
@@ -28,8 +30,8 @@ then launched without `--id` ends up with a pod it is not addressing. Pass
|
|
|
28
30
|
And a runner id that is set is treated as found, whether or not anything is
|
|
29
31
|
running under it. So exporting `QAWOLF_RUNNER_ID=agent-1` turns off the
|
|
30
32
|
auto-launch described next: instead of starting `agent-1`, commands try to reach
|
|
31
|
-
it and fail with exit code `
|
|
32
|
-
Launch that id once yourself and the rest follows.
|
|
33
|
+
it and fail with exit code `8`, naming the id and saying the variable is what
|
|
34
|
+
chose it. Launch that id once yourself and the rest follows.
|
|
33
35
|
|
|
34
36
|
And launching an id that differs from `QAWOLF_RUNNER_ID` prints a warning on
|
|
35
37
|
stderr naming both ids: the variable still outranks the directory default, so
|
|
@@ -83,6 +85,12 @@ directory did not launch it, so a harness handed a runner sees it alongside the
|
|
|
83
85
|
ones it started itself. Use the `id` column with `--runner` to address any of
|
|
84
86
|
them; addressing one does not make it the default.
|
|
85
87
|
|
|
88
|
+
The table leaves out the page address, which beside a 63-character id outgrows a terminal. `--json` carries it as `url` on every runner:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
qawolf runner list --json | jq -r '.[] | [.id, .url] | @tsv'
|
|
92
|
+
```
|
|
93
|
+
|
|
86
94
|
## The order that matters
|
|
87
95
|
|
|
88
96
|
A freshly launched runner has no screen. The virtual desktop starts with the
|
|
@@ -111,11 +119,14 @@ and says so on stderr. Everything else on this page waits for a run.
|
|
|
111
119
|
|
|
112
120
|
Retry on the exit code, not on the message text:
|
|
113
121
|
|
|
114
|
-
- `4` is
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
- `4` is transient. The screen is up but cannot serve this instant: restarting
|
|
123
|
+
after a display-size change, or busy with another request. Retry in a second
|
|
124
|
+
or two, and bound the retries.
|
|
125
|
+
- `8` means there is no such runner. It was never launched, or it was
|
|
126
|
+
terminated, or it idled out. Retrying never brings one back, so stop and
|
|
127
|
+
launch the id or name one that is running. The message says which runner was
|
|
128
|
+
meant and whether `--runner`, `QAWOLF_RUNNER_ID` or this directory's stored
|
|
129
|
+
default chose it — read that line before you pick an id to launch.
|
|
119
130
|
- `2` will not clear on its own. Either nothing has run on this runner yet, so
|
|
120
131
|
run a flow, or the runner has no browser at all, so launch with
|
|
121
132
|
`--name playwright` instead. The message says which.
|
|
@@ -216,7 +227,8 @@ what the page shows.
|
|
|
216
227
|
One failure covers three causes, because a runner cannot tell them apart: no
|
|
217
228
|
live page, no element matching the selector, no variable under that name. All
|
|
218
229
|
three exit `2` and none clears by waiting, so read the message, which carries
|
|
219
|
-
whatever the runner said. An unreachable runner exits `4` and is worth retrying
|
|
230
|
+
whatever the runner said. An unreachable runner exits `4` and is worth retrying;
|
|
231
|
+
a runner that is not running at all exits `8` and is not.
|
|
220
232
|
|
|
221
233
|
Use `inspect` before reaching for `exec`. Reading a value through a snippet
|
|
222
234
|
means printing it and then fishing it back out of the `console` stream, which is
|
|
@@ -586,7 +598,7 @@ the screen, so it is not optional even though the goal here is to drive by hand.
|
|
|
586
598
|
export QAWOLF_API_KEY=... # the only credential
|
|
587
599
|
export QAWOLF_RUNNER_ID=agent-1 # so no command below needs --runner
|
|
588
600
|
|
|
589
|
-
qawolf runner launch --id agent-1 --json # --id, not the variable; read .alreadyRunning
|
|
601
|
+
qawolf runner launch --id agent-1 --json # --id, not the variable; read .alreadyRunning and .url
|
|
590
602
|
qawolf runner run flows/smoke.flow.ts --follow # starts the screen; exit 1 if it failed
|
|
591
603
|
|
|
592
604
|
qawolf runner act navigate --url https://example.com/login --screenshot step-1.jpg # then read step-1.jpg yourself
|