@qawolf/cli 1.35.0 → 1.37.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.
@@ -1,4 +1,4 @@
1
- import type { BrowserAction, InspectOnRunnerRequest, JournalStream, PublicApiInput, PublicApiOutput, ReadJournalResponse, RunnerNameForPublicApi, publicContractsV1 } from "@qawolf/api-contracts/v1";
1
+ import type { InspectOnRunnerRequest, JournalStream, PublicApiInput, PublicApiOutput, ReadJournalResponse, RunnerAction, RunnerNameForPublicApi, publicContractsV1 } from "@qawolf/api-contracts/v1";
2
2
  type Runner = typeof publicContractsV1.runner;
3
3
  export type RunnerSdkOptions = {
4
4
  /** A QA Wolf team API key. The SDK never reads the CLI's stored credentials. */
@@ -77,7 +77,7 @@ export type EventsRequest = RunnerRequest & {
77
77
  window: JournalWindow;
78
78
  };
79
79
  export type ActRequest = RunnerRequest & {
80
- action: BrowserAction;
80
+ action: RunnerAction;
81
81
  /**
82
82
  * Ask the runner to answer with a screenshot taken after the action, on
83
83
  * `imageJpegBase64`. One call instead of an act and a screenshot, with no
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qawolf/cli",
3
- "version": "1.35.0",
3
+ "version": "1.37.0",
4
4
  "description": "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
5
5
  "keywords": [
6
6
  "automation",
@@ -71,7 +71,7 @@
71
71
  "@clack/prompts": "1.5.1",
72
72
  "@napi-rs/keyring": "1.3.0",
73
73
  "@oxc-node/core": "0.1.0",
74
- "@qawolf/api-contracts": "0.70.0",
74
+ "@qawolf/api-contracts": "0.74.0",
75
75
  "@qawolf/emails": "1.1.1",
76
76
  "@qawolf/flow-targets": "1.0.0",
77
77
  "@qawolf/flows": "0.1.4",
@@ -168,7 +168,7 @@ that `url`; never guess a route and never send a repository link in its place.
168
168
  | `qawolf install clear` | local | Remove the managed runtime cache (all installed runtime versions) |
169
169
  | `qawolf investigation get` | read | Read what the QA Wolf AI investigating a run has concluded: one finding per cause of its failures, with the question waiting for a person and any answer or dispute the investigation hasn't acted on yet. |
170
170
  | `qawolf issue addFlows` | write | Add flows to a coverage request owned by the caller's team. Flows already covered stay covered. Bug and maintenance reports link to flows through the runs that reproduce them; use run.diagnose to record one. |
171
- | `qawolf issue create` | write | Create a bug or coverage request issue for the caller's team. Maintenance issues cannot be created through the public API. |
171
+ | `qawolf issue create` | write | Create a bug report, maintenance report, or coverage request issue for the caller's team. A user can create a maintenance report only when they can see the workspace's maintenance reports; a team or organization API key credits it to the workspace's automation user. Link its failed flows afterwards with run.diagnose. |
172
172
  | `qawolf issue find` | read | List the team's bug reports, maintenance reports, or coverage requests, newest first. |
173
173
  | `qawolf issue get` | read | Get an issue by id. |
174
174
  | `qawolf issue removeFlows` | write | Remove flows from a coverage request owned by the caller's team. Flows the request does not cover are left alone. Bug and maintenance reports link to flows through the runs that reproduce them, so their flows cannot be set directly. |
@@ -178,12 +178,12 @@ that `url`; never guess a route and never send a repository link in its place.
178
178
  | `qawolf legacyTrigger resume` | write | Resume one legacy trigger, the older per-environment kind; use trigger.resume for a current one. Its copies in pull request environments resume too, and a scheduled one jumps to the next upcoming slot even if it was not paused. For migration only; it goes when legacy triggers go. |
179
179
  | `qawolf run create` | write | Create a run for the selected flows and/or tags in an environment. |
180
180
  | `qawolf run diagnose` | write | Diagnose failed flows in a run as reproductions of a bug or maintenance report owned by the caller's team. The issue's type selects the diagnosis. Each flow must have failed in the run. A flow that is already diagnosed moves to this issue. The diagnosis appears on the run, and the reproduction appears under the issue's reproductions. Coverage requests cannot be diagnosed; use issue.addFlows to cover flows instead. |
181
- | `qawolf run find` | read | List an environment's recent runs, newest first. |
181
+ | `qawolf run find` | read | List an environment's recent runs, newest first, including failed-attempt discovery metadata. |
182
182
  | `qawolf run get` | read | Get a run's status, per-flow results, links, and how many of its bugs are blocking. |
183
+ | `qawolf run getAttemptArtifacts` | read | Get metadata and signed artifact URLs for one finished run attempt. |
183
184
  | `qawolf run reattempt` | write | Request new attempts for a run's flows, in the same run. A flow is eligible once its result is failed or canceled and QA Wolf's automatic retries have finished. A fully investigated run no longer accepts reattempts. Attempts run with the latest flow code. Poll run.get for results. |
184
185
  | `qawolf run stop` | write | Stop a run, including its queued flows and automatic retries. Stopping is asynchronous and can update run-status messages and commit statuses in connected integrations. Repeated requests are safe, and finished runs keep their results. A run that is still being created returns not found; retry once run.get returns the run. If run.get returns a different runId, use that ID. Poll run.get for results. |
185
- | `qawolf run triage` | read | Prototype. Ask Jev, a TypeSafe System One model, whether a flow failure in a run is a bug in the product or a test that needs maintenance. Compares the failing attempt with the flow's last passing run in the same environment. Records nothing. |
186
- | `qawolf runner act` | write | Perform one raw action on a runner's screen: click, double_click, scroll, move, drag, keypress, navigate or type. Use - to read a whole action as JSON from stdin. On a mobile runner only click (button left), drag and type have a touchscreen equivalent; the rest answer action-not-supported-on-mobile |
186
+ | `qawolf runner act` | write | Perform one raw action on a runner's screen. A browser runner takes click, double_click, scroll, move, drag, keypress, navigate and type; a mobile runner takes tap, swipe, fill and type. A browser runner answers mobile actions with action-not-supported-on-browser; a mobile runner answers the other browser actions with action-not-supported-on-mobile. Use - to read a whole action as JSON from stdin |
187
187
  | `qawolf runner actions` | write | Perform a sequence of up to ten raw actions on a runner's screen in one request, as a JSON array of the same actions `runner act` takes. Use - to read the array from stdin. Actions run back to back, so batch only steps whose targets are on the screen you last saw, and end the sequence at the step that changes the page. Each result carries an effect: performed, not-performed, or unknown when the runner stopped answering and the action may have landed |
188
188
  | `qawolf runner events` | read | Print a runner's journal, one entry per line. QA Wolf writes console, recorder, run-events, run-logs, run-status |
189
189
  | `qawolf runner exec` | write | Evaluate a snippet against a runner's live page. Use - to read the snippet from stdin |
@@ -59,8 +59,10 @@ A run that has been requested but not yet created answers exit `8` too, and
59
59
  says it is still being created. That one clears on its own, so read the message
60
60
  rather than the code before deciding whether to poll.
61
61
 
62
- Poll `status` until it reaches `passed`, `failed` or `canceled`. The other
63
- values mean the run is still going.
62
+ Poll `status` until it reaches `passed`, `failed`, `canceled` or `superseded`.
63
+ When it is `superseded`, this run will never change again. Read the replacement
64
+ run in `supersededBy.runId` for the verdict. `queued` and `running` mean the run
65
+ is still going.
64
66
 
65
67
  ## Fields a passing run does not show you
66
68
 
@@ -183,14 +185,19 @@ Every documented field of the `run.get` response. `[]` marks an array, so
183
185
  - `completedAt` — When the run finished executing. Absent while queued or running, and also absent for a terminal run that never completed execution (e.g. every flow was canceled or skipped).
184
186
  - `git` — The branch and commit under test. The fields are present when a deploy notification started the run, and absent for runs started another way, for example manually or with run.create.
185
187
  - `git.commitUrl` — Link to the commit on the code host.
188
+ - `needsReview` — True once every flow has finished its attempts and at least one failed flow still has no diagnosis, including one whose investigation carried over to a later run. `status` stays `running` until that failure is diagnosed, so a caller that is not waiting for a diagnosis can stop polling here and read the run's failed flows.
186
189
  - `runId` — The run this response describes. Treat it as canonical: it can differ from the id you asked for. A deploy notification returns a run id before the run exists, and if a second notification for the same commit is folded into an earlier run, that id resolves to the earlier run instead.
187
- - `status` — One of: queued, running, passed, failed, canceled
190
+ - `status` — One of: queued, running, passed, failed, canceled, superseded
191
+ - `supersededBy` — The run that replaced this one, present only when `status` is `superseded`. A newer deployment to the same branch and environment (and service, when the deployment named one) cancels the older run's unfinished flows and takes over. Deduplication ignores the commit, so the replacement may be testing a later commit than this run did. Only the direct replacement is named; that run can itself be superseded.
192
+ - `supersededBy.runId` — The id of the run.
193
+ - `supersededBy.url` — Absolute URL of the replacement run's page.
188
194
  - `blockingBugCount` — How many bugs this run found are blocking: still open, and priority urgent, high, or unprioritized — unprioritized counts because nobody has ruled it out yet. This is what `failed` is derived from, so it explains a failure rather than adding a second verdict: gate on `status`, then read this to say how many bugs are holding the build. It counts a bug filed against a later run by an investigation that carried over from this one, and it drops a bug once that bug is resolved.
189
195
  - `flows` — The run's flows, ordered alphabetically by name. Only the flows matching flowStatuses when the request set it.
190
196
  - `flows[].attempts` — The flow's finished execution attempts, oldest first, including manual Wolf Browser attempts. Present once at least one attempt has finished, so a flow that passed after retries also lists its failed attempts. Artifact URLs appear only on automated attempts that reached a verdict, stay valid for at least a day (call run.get again for fresh ones), and can return 404 when the attempt did not produce that artifact.
191
197
  - `flows[].attempts[].logsUrl` — Signed URL for the attempt's execution logs.
192
198
  - `flows[].attempts[].traceUrl` — Signed URL for the attempt's Playwright trace (a trace.zip; open it with `npx playwright show-trace`).
193
199
  - `flows[].attempts[].videoUrl` — Signed URL for the attempt's screen recording.
200
+ - `flows[].attempts[].attemptId` — The id of the run attempt.
194
201
  - `flows[].attempts[].kind` — One of: automated, manual
195
202
  - `flows[].attempts[].startedAt` — Absent when the attempt failed before it could start.
196
203
  - `flows[].attempts[].status` — One of: passed, failed, canceled
@@ -126,7 +126,7 @@ Retry on the exit code, not on the message text:
126
126
  launch the id or name one that is running. The message says which runner was
127
127
  meant and whether `--runner`, `QAWOLF_RUNNER_ID` or this directory's stored
128
128
  default chose it — read that line before you pick an id to launch.
129
- - `2` will not clear on its own. Nothing has run on this runner yet, so run a flow; or the runner has no browser at all, so launch with `--name playwright` instead; or the action has no touchscreen equivalent on a mobile runner, so reach for one that has. A `runner actions` sequence also exits `2` before it sends anything, for an argument that is not a JSON array, an array of more than ten actions, and `--screenshot` flags that contradict each other. The message says which.
129
+ - `2` will not clear on its own. Nothing has run on this runner yet, so run a flow; or the runner has no browser at all, so launch with `--name playwright` instead; or the action belongs to the other runner family, so send `tap`, `swipe` or `fill` to a mobile runner and the browser actions to a browser runner. A `runner actions` sequence also exits `2` before it sends anything, for an argument that is not a JSON array, an array of more than ten actions, and `--screenshot` flags that contradict each other. The message says which.
130
130
 
131
131
  ## Seeing and acting: the loop is yours
132
132
 
@@ -167,17 +167,18 @@ Coordinates are pixels on the same screenshot you just read. The runner serves o
167
167
 
168
168
  `act`, `actions`, `run` and `exec` are the commands whose lost answer may still have taken effect. On a `4` from `act` or `actions`, take a screenshot before repeating a click. `exec`'s message says the snippet could not be evaluated, but a lost answer looks the same from outside, so treat a `4` from a snippet that changes something as "may have run" rather than "did not run".
169
169
 
170
- A mobile runner has a touchscreen, not a mouse, so only three of the eight
171
- actions have a touchscreen equivalent and go through: `click` with
172
- `button: "left"` taps, `drag` swipes, and `type` types into whatever the last
173
- tap focused. The rest — `double_click`, `scroll`, `move`, `keypress`,
174
- `navigate` — answer `action-not-supported-on-mobile` rather than doing
175
- something approximate. `navigate` is the one to watch for, since it works on a
176
- browser runner without a run first but has no meaning on mobile at all.
170
+ A mobile runner has a touchscreen, not a mouse, so it has actions of its own:
171
+
172
+ - `tap` touches a point (`--x`, `--y`) or the element `--selector` names. Check the selector first with `inspect elements --selector`, and pass `--strategy ios-predicate` or `shadow` when it is not XPath.
173
+ - `swipe --from x,y --to x,y` moves in a straight line between two points. `--duration-ms` sets how long it takes, up to 10000: a slow swipe scrolls, a fast one flings.
174
+ - `fill --selector ... --text ...` replaces the value of that field, and `--text ""` clears it. To add to what a field already holds, `tap` it and then `type`.
175
+ - `type` types into whatever the last tap focused, the same as on a browser.
176
+
177
+ The browser actions `double_click`, `scroll`, `move`, `keypress` and `navigate` answer `action-not-supported-on-mobile` rather than doing something approximate. `navigate` is the one to watch for, since it works on a browser runner without a run first but has no meaning on mobile at all. `click` with `button: "left"` and `drag` still tap and swipe on mobile, but they are deprecated there, so send `tap` and `swipe`. A browser runner answers `tap`, `swipe` and `fill` with `action-not-supported-on-browser`.
177
178
 
178
179
  ### Several steps in one request: `runner actions`
179
180
 
180
- `qawolf runner actions '<json array>'` performs up to ten of those same actions back to back in one request, for the steps you already know: click the field, type into it, press Enter. One round trip instead of three, with no delay to guess at between them, and `-` reads the array from stdin the way `act -` reads one action.
181
+ `qawolf runner actions '<json array>'` performs up to ten of the browser actions back to back in one request (not `tap`, `swipe` or `fill`), for the steps you already know: click the field, type into it, press Enter. One round trip instead of three, with no delay to guess at between them, and `-` reads the array from stdin the way `act -` reads one action.
181
182
 
182
183
  ```sh
183
184
  qawolf runner actions '[{"type":"click","button":"left","x":480,"y":260},{"type":"type","text":"me@example.com"},{"type":"keypress","keys":["Enter"]}]' --screenshot after-login.jpg