@vosjs/cli 0.82.0 → 0.83.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/README.md +4 -1
- package/package.json +6 -6
- package/schema/actions.schema.json +3 -2
package/README.md
CHANGED
|
@@ -190,7 +190,7 @@ vos look https://app.acme.com/projects --session acme --click '[data-testid="new
|
|
|
190
190
|
|
|
191
191
|
It writes `<out>/look.png` (the viewport; `--out look` by default) and lists every control in view (buttons, links, tabs, menu items, checkboxes, switches, options, fields, editable regions, and anything with a test id) with its tag, role, accessible name, test id, link path and query, rect in viewport px, whether it is disabled, inside an open dialog or covered by something on top of it, and ONE proposed selector: its test id; else its `aria-label`, inside the open dialog it sits in; else a link's own `href`, query kept (two tiles to `?vos=a` and `?vos=b` are two links); else role and name (`role=button[name="Continue"]`, what `page.locator` reads), narrowed by its dialog or landmark when that is what makes it one; else a field's own `name` or `placeholder`, a written id, or its words inside its dialog or landmark. Never a position in the tree. Each proposal is counted with the recorder's own selector engine and marked `UNIQUE` (it reaches this element and no other) or `AMBIGUOUS` (it reaches others too, and the recorder would take the first). A control whose words hold an address, a key or a card number is listed with those words withheld, and the frame's exposures are said the way a rehearsal says them. Looking never spends or destroys: a `--click` whose target's words begin with a stem that does (delet, remov, revok, eras, discard, publish, deploy, purchas, subscri, unsubscri, pay, buy, generat, submit, send, transfer, upgrad, confirm, leav, destroy, so `Allow deleting` and `Revoke` are caught with `Delete`), or say move to trash, empty trash or cancel subscription, is refused in words before it is pressed (exit 2), and `--type` fills a field without pressing Enter. A look cannot know every spend: `Make a video` or `Create` on a primary button may start paid work and passes, because refusing every Make would refuse half of every app. The list is a floor under looking; in a recorded flow, a step's `guard: "spend"` in `actions.json` is the fence. A sign-in in front of the page is the wall check's verdict, exit 4; the sign-in page is still looked at, since it is what a `setup` step scripts past. `--wait <ms>` adds a pause before the look for a page that animates in; `--json` prints the whole look as one done event (`url`, `screenshot`, `controls`, `exposures`, `wall`).
|
|
192
192
|
|
|
193
|
-
**`setup`: the steps that run before the camera rolls.** A sign-in form, a cookie banner, the "choose your editor" modal, an onboarding tour: things a take must get past and must not show. `actions.json` takes `setup: [...]` beside `steps`, with the verbs `goto`, `click`, `type`, `press`, `wait`. They run after the first navigation and before a frame is captured, as plain actions with no cursor, no frames, no pace and nothing in `meta.steps`; then the recorder opens `url` again and the take begins where the setup left it. A `type` step's `text` may be `{ "env": "DEMO_PASSWORD" }`, read from the shell at run time and never logged or stored (the log names the field, never the value; a literal typed into a password field is refused by `validate`, because `actions.json` is committed and pushed with the take). A selector that never appears fails the take before anything is recorded (exit 2), because a take that begins at a half-finished sign-in is the wall by another name; rehearse the setup with `--dry-run` like everything else. This is rung 2 of the session ladder made scriptable: a local or self-hosted instance with a seeded user, no state file needed.
|
|
193
|
+
**`setup`: the steps that run before the camera rolls.** A sign-in form, a cookie banner, the "choose your editor" modal, an onboarding tour: things a take must get past and must not show. `actions.json` takes `setup: [...]` beside `steps`, with the verbs `goto`, `click`, `type`, `press`, `wait`, and the guard `if`. They run after the first navigation and before a frame is captured, as plain actions with no cursor, no frames, no pace and nothing in `meta.steps`; then the recorder opens `url` again and the take begins where the setup left it. A `type` step's `text` may be `{ "env": "DEMO_PASSWORD" }`, read from the shell at run time and never logged or stored (the log names the field, never the value; a literal typed into a password field is refused by `validate`, because `actions.json` is committed and pushed with the take). A selector that never appears fails the take before anything is recorded (exit 2), because a take that begins at a half-finished sign-in is the wall by another name; rehearse the setup with `--dry-run` like everything else. This is rung 2 of the session ladder made scriptable: a local or self-hosted instance with a seeded user, no state file needed.
|
|
194
194
|
|
|
195
195
|
```json
|
|
196
196
|
"setup": [
|
|
@@ -203,9 +203,12 @@ It writes `<out>/look.png` (the viewport; `--out look` by default) and lists eve
|
|
|
203
203
|
|
|
204
204
|
**`teardown`: the steps that run after it.** A flow that CREATES something in the account (an API key, a project, an invite) creates it on every rehearsal and every take, since `--dry-run` clicks for real. `teardown: [...]` beside `setup` removes it again: the same verbs and the same rules (a `{ "env": "NAME" }` text, no literal in a password field, http and https only), run off camera once the screencast has stopped, on the take's own page and session, so nothing of it is captured or lands in `meta.steps`. It runs after a rehearsal too, and when the take stops early (a failed `await`, `--strict` on a page that stopped answering, the cap) or throws once its first step ran; not when the take never began (a setup that failed, a wall). The steps together get 60 s. A teardown never fails the take or changes the exit code: it stops at the first step that fails, the done event carries `teardown: { ran, of, failed?: { step, do, selector?, error } }`, and the summary says `teardown: 3 step(s) ran` or `TEARDOWN FAILED at teardown[1] (click #confirm): <reason>. What the take created may still be in the product; remove it by hand.` A `{ env }` the shell does not hold refuses the take before it begins, since the take would create what its teardown cannot remove.
|
|
205
205
|
|
|
206
|
+
**`if`: a guard for either list.** `{ "do": "if", "selector": "…" }` looks for its selector (3 s, or its `ms`): on the page, the steps after it run; not on the page, they are skipped and the list ends there, which is never a failure. A take that deletes on camera what it created, and keeps a teardown as the net for a take that stops early, starts the undoing with one, so a good take says `teardown: nothing to undo, <selector> is not on the page` instead of a failure; the done event carries `skipped: { step, selector, rest }`. A setup that signs in guards its sign-in the same way (`if` the email field), so a session already signed in passes. A step that fails after a guard still fails.
|
|
207
|
+
|
|
206
208
|
```json
|
|
207
209
|
"teardown": [
|
|
208
210
|
{ "do": "goto", "url": "http://localhost:3000/settings/keys" },
|
|
211
|
+
{ "do": "if", "selector": "[data-testid=key-row]:first-child" },
|
|
209
212
|
{ "do": "click", "selector": "[data-testid=key-row]:first-child button[aria-label=Revoke]" },
|
|
210
213
|
{ "do": "click", "selector": "role=button[name=\"Revoke key\"]" }
|
|
211
214
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vosjs/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
4
4
|
"description": "The vos CLI: record the real product from a scripted browser flow, auto-zoom from the cursor track, cut as data in doc.json, render deterministic video, deliver a release's video cuts per destination spec, and sync with vos.so. One binary, every verb, MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,13 +52,13 @@
|
|
|
52
52
|
"mediabunny": "^1.55.7",
|
|
53
53
|
"playwright": "^1.49.0",
|
|
54
54
|
"@vosjs/core": "^0.31.0",
|
|
55
|
-
"@vosjs/
|
|
56
|
-
"@vosjs/elements": "^0.12.1",
|
|
57
|
-
"@vosjs/render-core": "^0.10.0",
|
|
55
|
+
"@vosjs/render-core": "^0.11.0",
|
|
58
56
|
"@vosjs/shared": "^0.7.0",
|
|
57
|
+
"@vosjs/elements": "^0.12.1",
|
|
58
|
+
"@vosjs/editor": "^1.6.0",
|
|
59
59
|
"@vosjs/studio-core": "^0.46.0",
|
|
60
|
-
"@vosjs/
|
|
61
|
-
"@vosjs/
|
|
60
|
+
"@vosjs/timeline": "^0.5.0",
|
|
61
|
+
"@vosjs/tween": "^0.8.3"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@types/node": "^22",
|
|
@@ -1078,7 +1078,8 @@
|
|
|
1078
1078
|
"properties": {
|
|
1079
1079
|
"do": {
|
|
1080
1080
|
"type": "string",
|
|
1081
|
-
"enum": ["wait", "click", "type", "press", "goto"]
|
|
1081
|
+
"enum": ["wait", "click", "type", "press", "goto", "if"],
|
|
1082
|
+
"description": "if: a guard; when its selector is not on the page, the steps after it are skipped and the list ends there, which is not a failure"
|
|
1082
1083
|
},
|
|
1083
1084
|
"id": {
|
|
1084
1085
|
"type": "string"
|
|
@@ -1114,7 +1115,7 @@
|
|
|
1114
1115
|
},
|
|
1115
1116
|
"ms": {
|
|
1116
1117
|
"type": "number",
|
|
1117
|
-
"description": "wait: the pause; click: the read after the page settled, held from its last visual change (default 150); type and scroll: the settle after (defaults 150/200)"
|
|
1118
|
+
"description": "wait: the pause; click: the read after the page settled, held from its last visual change (default 150); type and scroll: the settle after (defaults 150/200); if: how long to look for its selector (default 3000)"
|
|
1118
1119
|
}
|
|
1119
1120
|
},
|
|
1120
1121
|
"description": "One setup or teardown step: a plain action, with no cursor and no frames."
|