@unotest/web 0.10.0 → 0.12.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/.claude/skills/write-e2e-test/SKILL.md +11 -7
- package/.claude/skills/write-e2e-test-ground/SKILL.md +11 -7
- package/CHANGELOG.md +198 -0
- package/dist/config/schema.d.ts +55 -21
- package/dist/config/schema.js +1 -1
- package/dist/driver/index.d.ts +4 -2
- package/dist/driver/index.js +1 -1
- package/dist/dsl/index.d.ts +13 -2
- package/dist/dsl/index.js +1 -1
- package/dist/dsl/web-dsl-language-service.js +1 -1
- package/dist/inspection/page-inject.d.ts +1 -1
- package/dist/{interfaces-BxviHxnr.d.ts → interfaces-XvuefHHC.d.ts} +13 -0
- package/dist/mcp/server.js +1 -1
- package/dist/runner/cli.d.ts +11 -1
- package/dist/runner/cli.js +1 -1
- package/dist/runner/init/chrome-probe.js +1 -1
- package/dist/runner/init.js +1 -1
- package/dist/runner/install-chromium.js +1 -1
- package/dist/runner/prepare-fix.js +1 -1
- package/dist/runner/scaffold-workspace.js +1 -1
- package/dist/runner/serve-fixture.js +1 -1
- package/dist/runner/web-runner-adapter.js +1 -1
- package/guides/agent-integration.md +24 -0
- package/guides/dsl-reference.md +166 -20
- package/package.json +7 -44
- package/src/mcp/prompts/agent-test-author.md +12 -3
|
@@ -306,9 +306,11 @@ What's **not allowed** (parser / runtime will reject): `import` /
|
|
|
306
306
|
`export` / `require`, top-level `await`, `class`, JSX, `while` /
|
|
307
307
|
`do…while` / `continue` / `++`. Bounded `for (i = 0; i < N; i = i + 1)`
|
|
308
308
|
loops ARE supported, and `break` is legal inside a loop body — poll with
|
|
309
|
-
`for` + `if (…) { break; }` + `pause(ms) //
|
|
309
|
+
`for` + `if (…) { break; }` + `pause(ms) // lint-ok: …`. Index access
|
|
310
310
|
reads data (`docs[0].count`, bare variable only, never a Locator);
|
|
311
|
-
`
|
|
311
|
+
`obj.prop[i]` does not parse — assign the member first:
|
|
312
|
+
`m = state.matches; last = m[m.length - 1];`. `arr[i] = v` stays
|
|
313
|
+
rejected.
|
|
312
314
|
|
|
313
315
|
Navigation:
|
|
314
316
|
- `goto(url, opts?)`, `reload(opts?)`, `getUrl()`, `goBack()`, `goForward()`.
|
|
@@ -377,7 +379,7 @@ Disambiguate with `.filter({hasText: '…'})` or `.filter({has: …})` —
|
|
|
377
379
|
Waits:
|
|
378
380
|
- `waitFor(loc, opts?)`, `waitForText(text, opts?)`,
|
|
379
381
|
`waitForCount(loc, n, opts?)`, `waitForUrl(pattern)`, `pause(ms)` —
|
|
380
|
-
`pause` requires `//
|
|
382
|
+
`pause` requires a trailing `// lint-ok: <why>` comment on the same line (linter
|
|
381
383
|
flags `lint:pause-explicit` otherwise).
|
|
382
384
|
- `waitForText` waits for ≥1 VISIBLE occurrence (repeated text in a feed
|
|
383
385
|
is fine); substring by default — `{exact: true}` or a regex
|
|
@@ -395,20 +397,22 @@ State reads:
|
|
|
395
397
|
`getInputValue(loc)`.
|
|
396
398
|
|
|
397
399
|
Sandbox primitives:
|
|
398
|
-
- `shell("cmd", "arg",
|
|
400
|
+
- `shell("cmd", "arg", …, options?)` — `execFile` style, no shell interpretation. Non-zero exit fails the step; pass `{allowNonZero: true}` to inspect `res.code` yourself. Wall-clock budget `{timeoutMs}` (default 120s).
|
|
401
|
+
- `waitForFile(path, pattern?, {timeoutMs})` — poll a file until it exists / matches; use it to await output of background processes started via `shell()`.
|
|
399
402
|
- `dbQuery(sql, …params)`, `dbExec(sql, …params)` — parameterized.
|
|
400
403
|
- `apiCall(method, path, body?, headers?, opts?)` — path-only against
|
|
401
404
|
`sandbox.apiBaseUrl`; another host via `{base: 'API_BASE_X'}` — the
|
|
402
405
|
NAME of a `unotest/.env` variable, never a URL. Multipart upload:
|
|
403
|
-
|
|
406
|
+
pass `upload('fixtures/doc.pdf', {field?, fields?})` as the body
|
|
404
407
|
(relative path inside the project / `sandbox.uploadDir`; don't set
|
|
405
|
-
Content-Type yourself).
|
|
408
|
+
Content-Type yourself). A JSON body with a `file` key posts as plain
|
|
409
|
+
JSON — there is no key-name magic.
|
|
406
410
|
|
|
407
411
|
Escape hatch:
|
|
408
412
|
- `evaluate(\`js body\`, …args)` — raw backticks, no `${}`. Linter
|
|
409
413
|
warns `lint:evaluate-discouraged`. Use only when nothing above fits.
|
|
410
414
|
|
|
411
|
-
Time helpers: `nowMs()`, `today()`, `daysFromNow(n)`.
|
|
415
|
+
Time helpers: `nowMs()`, `today()`, `daysFromNow(n)`. Marker helper: `randomWord(len)` — random lowercase letters, digit-free.
|
|
412
416
|
|
|
413
417
|
## Helpers convention
|
|
414
418
|
|
|
@@ -437,9 +437,11 @@ What's **not allowed** (parser / runtime will reject): `import` /
|
|
|
437
437
|
`export` / `require`, top-level `await`, `class`, JSX, `while` /
|
|
438
438
|
`do…while` / `continue` / `++`. Bounded `for (i = 0; i < N; i = i + 1)`
|
|
439
439
|
loops ARE supported, and `break` is legal inside a loop body — poll with
|
|
440
|
-
`for` + `if (…) { break; }` + `pause(ms) //
|
|
440
|
+
`for` + `if (…) { break; }` + `pause(ms) // lint-ok: …`. Index access
|
|
441
441
|
reads data (`docs[0].count`, bare variable only, never a Locator);
|
|
442
|
-
`
|
|
442
|
+
`obj.prop[i]` does not parse — assign the member first:
|
|
443
|
+
`m = state.matches; last = m[m.length - 1];`. `arr[i] = v` stays
|
|
444
|
+
rejected.
|
|
443
445
|
|
|
444
446
|
Navigation:
|
|
445
447
|
- `goto(url, opts?)`, `reload(opts?)`, `getUrl()`, `goBack()`, `goForward()`.
|
|
@@ -508,7 +510,7 @@ Disambiguate with `.filter({hasText: '…'})` or `.filter({has: …})` —
|
|
|
508
510
|
Waits:
|
|
509
511
|
- `waitFor(loc, opts?)`, `waitForText(text, opts?)`,
|
|
510
512
|
`waitForCount(loc, n, opts?)`, `waitForUrl(pattern)`, `pause(ms)` —
|
|
511
|
-
`pause` requires `//
|
|
513
|
+
`pause` requires a trailing `// lint-ok: <why>` comment on the same line (linter
|
|
512
514
|
flags `lint:pause-explicit` otherwise).
|
|
513
515
|
- `waitForText` waits for ≥1 VISIBLE occurrence (repeated text in a feed
|
|
514
516
|
is fine); substring by default — `{exact: true}` or a regex
|
|
@@ -526,20 +528,22 @@ State reads:
|
|
|
526
528
|
`getInputValue(loc)`.
|
|
527
529
|
|
|
528
530
|
Sandbox primitives:
|
|
529
|
-
- `shell("cmd", "arg",
|
|
531
|
+
- `shell("cmd", "arg", …, options?)` — `execFile` style, no shell interpretation. Non-zero exit fails the step; pass `{allowNonZero: true}` to inspect `res.code` yourself. Wall-clock budget `{timeoutMs}` (default 120s).
|
|
532
|
+
- `waitForFile(path, pattern?, {timeoutMs})` — poll a file until it exists / matches; use it to await output of background processes started via `shell()`.
|
|
530
533
|
- `dbQuery(sql, …params)`, `dbExec(sql, …params)` — parameterized.
|
|
531
534
|
- `apiCall(method, path, body?, headers?, opts?)` — path-only against
|
|
532
535
|
`sandbox.apiBaseUrl`; another host via `{base: 'API_BASE_X'}` — the
|
|
533
536
|
NAME of a `unotest/.env` variable, never a URL. Multipart upload:
|
|
534
|
-
|
|
537
|
+
pass `upload('fixtures/doc.pdf', {field?, fields?})` as the body
|
|
535
538
|
(relative path inside the project / `sandbox.uploadDir`; don't set
|
|
536
|
-
Content-Type yourself).
|
|
539
|
+
Content-Type yourself). A JSON body with a `file` key posts as plain
|
|
540
|
+
JSON — there is no key-name magic.
|
|
537
541
|
|
|
538
542
|
Escape hatch:
|
|
539
543
|
- `evaluate(\`js body\`, …args)` — raw backticks, no `${}`. Linter
|
|
540
544
|
warns `lint:evaluate-discouraged`. Use only when nothing above fits.
|
|
541
545
|
|
|
542
|
-
Time helpers: `nowMs()`, `today()`, `daysFromNow(n)`.
|
|
546
|
+
Time helpers: `nowMs()`, `today()`, `daysFromNow(n)`. Marker helper: `randomWord(len)` — random lowercase letters, digit-free.
|
|
543
547
|
|
|
544
548
|
## Helpers convention
|
|
545
549
|
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,204 @@ All notable changes to `@unotest/web` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.12.0] - 2026-08-14
|
|
9
|
+
|
|
10
|
+
### Minor Changes
|
|
11
|
+
|
|
12
|
+
- 479aa25: The active variable environment is now agent-visible instead of
|
|
13
|
+
docs-only. `explore_start` and `run_test` replies carry an
|
|
14
|
+
`environment` field: the active env name (`UNOTEST_ENV`, `null` = base)
|
|
15
|
+
plus every `.env` / `.secrets` layer file with an `exists` flag. A
|
|
16
|
+
missing external variable error now also lists the searched layers
|
|
17
|
+
(`Looked in environment "dev" (UNOTEST_ENV): unotest/.env,
|
|
18
|
+
unotest/.env.dev (no such file)`). Tool descriptions for `run_test` /
|
|
19
|
+
`explore_start` explain the env mechanism — MCP sessions inherit
|
|
20
|
+
`UNOTEST_ENV` from the server process (set it in the client's `env`
|
|
21
|
+
block); CLI runs take `--env <name>`. The shipped agent guide gains a
|
|
22
|
+
"Variable environments" section.
|
|
23
|
+
- 479aa25: Feedback batch from a real-world integration (bot-service): shell()
|
|
24
|
+
safety, run diagnostics, boolean-attribute probes, linter ergonomics.
|
|
25
|
+
|
|
26
|
+
**BREAKING — `shell()` fails the step on a non-zero exit code.**
|
|
27
|
+
Previously a non-zero exit resolved silently and a forgotten `res.code`
|
|
28
|
+
check produced false-green tests. Migration: calls where non-zero is
|
|
29
|
+
expected (probes, `grep -q`) pass `{allowNonZero: true}` as the last
|
|
30
|
+
argument and keep checking `res.code`; calls that asserted
|
|
31
|
+
`assertTrue(out.code == 0, ...)` can drop the assert. More shell()
|
|
32
|
+
hardening: a missing binary is a distinct "failed to start" error (was a
|
|
33
|
+
fake `code: 1`), output over 10 MiB fails loudly (was silent
|
|
34
|
+
truncation), and every call has a wall-clock budget
|
|
35
|
+
(`sandbox.shellTimeoutMs`, default 120 s, or per-call `{timeoutMs}`) —
|
|
36
|
+
a detached grandchild holding the stdio pipes no longer hangs the
|
|
37
|
+
scenario forever; the timeout error explains the detach recipe.
|
|
38
|
+
|
|
39
|
+
New capabilities:
|
|
40
|
+
|
|
41
|
+
- `waitForFile(path, pattern?, {timeoutMs})` — poll a file until it
|
|
42
|
+
exists / contains a substring or regex; the file-side `waitForText`
|
|
43
|
+
for background processes. Returns the content.
|
|
44
|
+
- `sandbox.exportSecrets: [names]` — explicit allowlist of `.secrets*`
|
|
45
|
+
variables exported into `shell()` subprocess env (still masked in
|
|
46
|
+
logs). Secrets stay out of `process.env` otherwise.
|
|
47
|
+
- `isDisabled(loc)` / `isEnabled(loc)` — honest disabled probe (native
|
|
48
|
+
`:disabled` incl. fieldset inheritance, or `aria-disabled`);
|
|
49
|
+
`hasAttribute(loc, name)` — presence probe for boolean attributes
|
|
50
|
+
(`getAttribute` reads `""` for present and absent alike).
|
|
51
|
+
- Generators: `randomWord(len)` (letters only — digit-free markers),
|
|
52
|
+
`nowMs()`, `today()`, `daysFromNow(n)` (previously documented in the
|
|
53
|
+
skills but not implemented).
|
|
54
|
+
- Failed runs report the enclosing step: `✗ test: … in step "…"` in the
|
|
55
|
+
console, `stepLabel` in the failure bundle and `inspect_runtime`.
|
|
56
|
+
- Every CLI run prints a one-line header: active environment, layer
|
|
57
|
+
files (missing ones flagged) and effective `baseUrl`; `run_test` /
|
|
58
|
+
`explore_start` replies echo `baseUrl` next to `environment`.
|
|
59
|
+
- `run_test` accepts per-call `env` — the spawned runner child gets
|
|
60
|
+
`UNOTEST_ENV=<env>` for that run only.
|
|
61
|
+
- Linter: `// lint-ok: <reason>` silences warning/info diagnostics on
|
|
62
|
+
its line (reason required; errors never suppressible); new
|
|
63
|
+
`lint:echo-assert` warns when `waitForText`/`assertText` overlaps a
|
|
64
|
+
value the scenario itself filled (chat echo trap);
|
|
65
|
+
`lint:goto-concat` / `lint:regex-invalid` are now configurable in
|
|
66
|
+
`linter.rules` (they were emitted but missing from the config schema).
|
|
67
|
+
- A `_helpers` file that fails to parse is reported as the root cause in
|
|
68
|
+
`unotest-web lint` (and explore replies list `unparsableHelperFiles`)
|
|
69
|
+
instead of silently cascading into "Unknown function" at every call
|
|
70
|
+
site. The viewer logs the same condition (patch).
|
|
71
|
+
|
|
72
|
+
### Patch Changes
|
|
73
|
+
|
|
74
|
+
- Updated dependencies [40300d3]
|
|
75
|
+
- Updated dependencies [479aa25]
|
|
76
|
+
- Updated dependencies [5dd59af]
|
|
77
|
+
- Updated dependencies [7069d24]
|
|
78
|
+
- @unotest/dsl@0.12.0
|
|
79
|
+
- @unotest/viewer@0.12.0
|
|
80
|
+
- @unotest/core@0.12.0
|
|
81
|
+
- @unotest/grounder-client@0.12.0
|
|
82
|
+
- @unotest/protocol@0.12.0
|
|
83
|
+
|
|
84
|
+
## [0.11.0] - 2026-08-13
|
|
85
|
+
|
|
86
|
+
### Minor Changes
|
|
87
|
+
|
|
88
|
+
- eb568a6: `e2e` CLI argument diagnostics: extra positional arguments are rejected
|
|
89
|
+
instead of silently ignored (with a "did you mean: unotest-web e2e <name>"
|
|
90
|
+
hint for a duplicated subcommand); an argument that resolves to a
|
|
91
|
+
directory gets its own message instead of the misleading ".js extension"
|
|
92
|
+
error; unknown scenario names now suggest close matches from
|
|
93
|
+
`unotest/e2e/**` (new `suggestClosest` / `levenshteinDistance` utilities
|
|
94
|
+
in `@unotest/core`). The `collection` command also rejects extra
|
|
95
|
+
positionals.
|
|
96
|
+
- a195713: Failure artifacts are always on, and steps can carry screenshots.
|
|
97
|
+
|
|
98
|
+
- On any scenario failure the runner writes `screenshot.png` +
|
|
99
|
+
`page.html` (runtime DOM, open shadow roots included, secrets
|
|
100
|
+
redacted) to `unotest/.runs/<runId>/failure/` — no `UNOTEST_DEBUG`
|
|
101
|
+
needed. The `.unotest/failures/` bundle gains the same `page.html`;
|
|
102
|
+
its screenshot keeps honouring `failureBundle.tier2`.
|
|
103
|
+
- New env flag `UNOTEST_STEP_SCREENSHOTS=1` captures a PNG after every
|
|
104
|
+
executed step into `unotest/.runs/<runId>/screenshot/`.
|
|
105
|
+
- Protocol: `screenshot` events may carry the step's `file`/`line`/`col`.
|
|
106
|
+
- Viewer: a step row with a captured screenshot shows a camera icon and
|
|
107
|
+
toggles an inline preview on click (both `screenshot()` DSL captures
|
|
108
|
+
and per-step ones).
|
|
109
|
+
|
|
110
|
+
- d0ae620: Parse errors now carry an exact position and a caret code frame.
|
|
111
|
+
|
|
112
|
+
- Every lexer failure is a `ParseError` with `line`/`column` (previously
|
|
113
|
+
bare `Error` with no position).
|
|
114
|
+
- New `formatCodeFrame(source, line, column)` / `formatParseError`
|
|
115
|
+
exports in `@unotest/dsl`.
|
|
116
|
+
- The web runner's "parse error in <file>" message now includes
|
|
117
|
+
`<file>:<line>:<col>` plus the code frame — no more hunting for an
|
|
118
|
+
"unexpected LBRACKET" by eye.
|
|
119
|
+
- Token columns are now uniformly 1-based at the token start.
|
|
120
|
+
Previously identifier/number/string tokens were 0-based while
|
|
121
|
+
operators were 1-based, so carets and editor squiggles missed by one.
|
|
122
|
+
Migration note: `line:col` breakpoint keys stored in
|
|
123
|
+
`.debugger[-suffix].json` against word-initial statements shift by
|
|
124
|
+
+1 — re-set those breakpoints once.
|
|
125
|
+
|
|
126
|
+
- 98b0736: BREAKING: multipart uploads in `apiCall` are now opted into explicitly
|
|
127
|
+
with the new `upload(path, {field?, fields?})` DSL function — the
|
|
128
|
+
`{file, field?, fields?}` body-shape magic is removed.
|
|
129
|
+
|
|
130
|
+
A JSON body containing a `file` key now always posts as JSON (the old
|
|
131
|
+
key-name detection broke JSON APIs with a legitimate `file` field —
|
|
132
|
+
`{file: 'x.jsonl'}` tried to read a file from disk and died with
|
|
133
|
+
ENOENT).
|
|
134
|
+
|
|
135
|
+
Migration:
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
// before
|
|
139
|
+
apiCall("POST", "/documents", {
|
|
140
|
+
file: "fixtures/doc.pdf",
|
|
141
|
+
fields: { source: "e2e" },
|
|
142
|
+
});
|
|
143
|
+
// after
|
|
144
|
+
apiCall(
|
|
145
|
+
"POST",
|
|
146
|
+
"/documents",
|
|
147
|
+
upload("fixtures/doc.pdf", { fields: { source: "e2e" } })
|
|
148
|
+
);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`upload()` must be the body itself (a nested `{doc: upload(...)}` is
|
|
152
|
+
rejected with a pointer to the correct usage). Path containment in
|
|
153
|
+
`sandbox.uploadDir` and the Content-Type rules are unchanged.
|
|
154
|
+
|
|
155
|
+
### Patch Changes
|
|
156
|
+
|
|
157
|
+
- ce25926: Fixes and DX follow-ups from the real-time-polls field check:
|
|
158
|
+
|
|
159
|
+
- **Fix: `unotest/.runs/<runId>/failure/` was never written.** The
|
|
160
|
+
runner derived the run dir from its internal runtime id (`r-N…`)
|
|
161
|
+
while the on-disk dir is named by `makeRunId(scenario)`, so the
|
|
162
|
+
always-on failure artifacts silently skipped. The CLI now passes its
|
|
163
|
+
run dir into the runner (`RunJsScenarioOptions.runDir`), and the
|
|
164
|
+
failure screenshot + page.html land where documented.
|
|
165
|
+
- **`init` re-syncs tool-owned skill copies.** `.claude/skills/*` and
|
|
166
|
+
`.claude/hooks/*` shipped by the package are overwritten on a plain
|
|
167
|
+
`init` re-run when they diverge from the installed version (status
|
|
168
|
+
`updated`) — stale skills after a package upgrade no longer require
|
|
169
|
+
`--force`. User-scaffolded files keep the skip-unless-`--force`
|
|
170
|
+
behaviour.
|
|
171
|
+
- The MCP `agent-test-author` prompt caught up with the runtime:
|
|
172
|
+
multipart via `upload(...)` and the `obj.prop[i]` workaround are now
|
|
173
|
+
documented there too, and both facts are enforced by
|
|
174
|
+
`check-skill-prompt-sync`.
|
|
175
|
+
|
|
176
|
+
- 7ac23d5: Screenshots are no longer saved as blank white PNGs. `goto()` resolves
|
|
177
|
+
on the `load` event, which on any client-rendered app fires before the
|
|
178
|
+
first frame carries content — so a per-step capture
|
|
179
|
+
(`UNOTEST_STEP_SCREENSHOTS=1`) of a step that ended on `goto()`, or a
|
|
180
|
+
`screenshot()` call placed right after one, froze the pre-render frame.
|
|
181
|
+
Both paths now settle first: wait for the network to go quiet, then for
|
|
182
|
+
a painted frame, capped at 2s total. A page that never goes quiet
|
|
183
|
+
(polling, live feeds) spends the cap once per capture and is then shot
|
|
184
|
+
as-is; the wait never fails a run. The failure screenshot deliberately
|
|
185
|
+
skips the settle — it must show the page as it was at the failure.
|
|
186
|
+
|
|
187
|
+
Adds `DriverPage.waitForLoadState(state, opts?)` — diagnostics-only,
|
|
188
|
+
backing the settle. It is not exposed to the DSL: a test that waits on
|
|
189
|
+
"the network went quiet" instead of on visible app state is the flaky
|
|
190
|
+
pattern the linter rejects.
|
|
191
|
+
|
|
192
|
+
- Updated dependencies [eb568a6]
|
|
193
|
+
- Updated dependencies [a195713]
|
|
194
|
+
- Updated dependencies [ce25926]
|
|
195
|
+
- Updated dependencies [5a8e92b]
|
|
196
|
+
- Updated dependencies [d0ae620]
|
|
197
|
+
- Updated dependencies [2a68997]
|
|
198
|
+
- Updated dependencies [c01b72f]
|
|
199
|
+
- Updated dependencies [dea90e9]
|
|
200
|
+
- @unotest/core@0.11.0
|
|
201
|
+
- @unotest/protocol@0.11.0
|
|
202
|
+
- @unotest/viewer@0.11.0
|
|
203
|
+
- @unotest/dsl@0.11.0
|
|
204
|
+
- @unotest/grounder-client@0.11.0
|
|
205
|
+
|
|
8
206
|
## [0.10.0] - 2026-08-06
|
|
9
207
|
|
|
10
208
|
### Minor Changes
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -90,19 +90,19 @@ declare const FailureBundleConfigSchema: z.ZodObject<{
|
|
|
90
90
|
type FailureBundleConfig = z.infer<typeof FailureBundleConfigSchema>;
|
|
91
91
|
declare const DialogPolicySchema: z.ZodEnum<["accept", "dismiss", "manual"]>;
|
|
92
92
|
type DialogPolicy = z.infer<typeof DialogPolicySchema>;
|
|
93
|
-
declare const LinterRuleIdSchema: z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>;
|
|
93
|
+
declare const LinterRuleIdSchema: z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "lint:goto-concat", "lint:regex-invalid", "lint:echo-assert", "lint:lint-ok-missing-reason", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>;
|
|
94
94
|
type LinterRuleId = z.infer<typeof LinterRuleIdSchema>;
|
|
95
95
|
declare const LinterSeveritySchema: z.ZodEnum<["off", "warn", "error"]>;
|
|
96
96
|
type LinterSeverity = z.infer<typeof LinterSeveritySchema>;
|
|
97
97
|
declare const LinterConfigSchema: z.ZodObject<{
|
|
98
98
|
enabled: z.ZodBoolean;
|
|
99
|
-
rules: z.ZodRecord<z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>, z.ZodEnum<["off", "warn", "error"]>>;
|
|
99
|
+
rules: z.ZodRecord<z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "lint:goto-concat", "lint:regex-invalid", "lint:echo-assert", "lint:lint-ok-missing-reason", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>, z.ZodEnum<["off", "warn", "error"]>>;
|
|
100
100
|
}, "strip", z.ZodTypeAny, {
|
|
101
101
|
enabled: boolean;
|
|
102
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
102
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
103
103
|
}, {
|
|
104
104
|
enabled: boolean;
|
|
105
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
105
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
106
106
|
}>;
|
|
107
107
|
type LinterConfig = z.infer<typeof LinterConfigSchema>;
|
|
108
108
|
declare const McpConfigSchema: z.ZodObject<{
|
|
@@ -116,6 +116,17 @@ type McpConfig = z.infer<typeof McpConfigSchema>;
|
|
|
116
116
|
declare const SandboxConfigSchema: z.ZodObject<{
|
|
117
117
|
/** Default cwd for `shell(cmd, ...args)`. Defaults to `process.cwd()`. */
|
|
118
118
|
shellCwd: z.ZodOptional<z.ZodString>;
|
|
119
|
+
/** Wall-clock budget for one `shell()` call, ms. Default 120 000. A call
|
|
120
|
+
* that exceeds it fails the step (the child gets SIGTERM, then SIGKILL) —
|
|
121
|
+
* without this, a grandchild process inheriting stdio pipes hangs the
|
|
122
|
+
* scenario forever. Per-call override: `shell(..., {timeoutMs})`. */
|
|
123
|
+
shellTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
124
|
+
/** Names of `.secrets*` variables exported into `shell()` subprocess env.
|
|
125
|
+
* Secrets are deliberately kept OUT of process.env (see
|
|
126
|
+
* scenario-variables.ts) — this is the explicit opt-in for the listener /
|
|
127
|
+
* seeder subprocess that genuinely needs a token. Values are still
|
|
128
|
+
* masked in logs by the SecretRegistry. */
|
|
129
|
+
exportSecrets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
119
130
|
/** Database connection string consumed by `dbQuery` / `dbExec`. URL form
|
|
120
131
|
* picks the dialect: `postgres://`, `mysql://`, `sqlite:`. */
|
|
121
132
|
database: z.ZodOptional<z.ZodString>;
|
|
@@ -124,17 +135,21 @@ declare const SandboxConfigSchema: z.ZodObject<{
|
|
|
124
135
|
* URLs are rejected at runtime. Additional bases come from env
|
|
125
136
|
* variables via `apiCall(..., {base: "API_BASE_X"})`. */
|
|
126
137
|
apiBaseUrl: z.ZodOptional<z.ZodString>;
|
|
127
|
-
/** Root for `
|
|
128
|
-
*
|
|
129
|
-
*
|
|
138
|
+
/** Root for `upload()` fixtures. Relative upload paths resolve
|
|
139
|
+
* against it and may not escape it. Defaults to the project root
|
|
140
|
+
* (the runner's cwd). */
|
|
130
141
|
uploadDir: z.ZodOptional<z.ZodString>;
|
|
131
142
|
}, "strip", z.ZodTypeAny, {
|
|
132
143
|
shellCwd?: string | undefined;
|
|
144
|
+
shellTimeoutMs?: number | undefined;
|
|
145
|
+
exportSecrets?: string[] | undefined;
|
|
133
146
|
database?: string | undefined;
|
|
134
147
|
apiBaseUrl?: string | undefined;
|
|
135
148
|
uploadDir?: string | undefined;
|
|
136
149
|
}, {
|
|
137
150
|
shellCwd?: string | undefined;
|
|
151
|
+
shellTimeoutMs?: number | undefined;
|
|
152
|
+
exportSecrets?: string[] | undefined;
|
|
138
153
|
database?: string | undefined;
|
|
139
154
|
apiBaseUrl?: string | undefined;
|
|
140
155
|
uploadDir?: string | undefined;
|
|
@@ -158,14 +173,14 @@ declare const WebServerConfigSchema: z.ZodObject<{
|
|
|
158
173
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
159
174
|
}, "strip", z.ZodTypeAny, {
|
|
160
175
|
url: string;
|
|
176
|
+
timeoutMs: number;
|
|
161
177
|
command: string;
|
|
162
178
|
reuseExistingServer: boolean;
|
|
163
|
-
timeoutMs: number;
|
|
164
179
|
}, {
|
|
165
180
|
url: string;
|
|
166
181
|
command: string;
|
|
167
|
-
reuseExistingServer?: boolean | undefined;
|
|
168
182
|
timeoutMs?: number | undefined;
|
|
183
|
+
reuseExistingServer?: boolean | undefined;
|
|
169
184
|
}>;
|
|
170
185
|
type WebServerConfig = z.infer<typeof WebServerConfigSchema>;
|
|
171
186
|
declare const UnotestConfigSchema: z.ZodObject<{
|
|
@@ -192,14 +207,14 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
192
207
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
193
208
|
}, "strip", z.ZodTypeAny, {
|
|
194
209
|
url: string;
|
|
210
|
+
timeoutMs: number;
|
|
195
211
|
command: string;
|
|
196
212
|
reuseExistingServer: boolean;
|
|
197
|
-
timeoutMs: number;
|
|
198
213
|
}, {
|
|
199
214
|
url: string;
|
|
200
215
|
command: string;
|
|
201
|
-
reuseExistingServer?: boolean | undefined;
|
|
202
216
|
timeoutMs?: number | undefined;
|
|
217
|
+
reuseExistingServer?: boolean | undefined;
|
|
203
218
|
}>>;
|
|
204
219
|
browsers: z.ZodArray<z.ZodEnum<["chromium", "firefox", "webkit"]>, "many">;
|
|
205
220
|
channel: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"chrome">, z.ZodLiteral<"msedge">, z.ZodLiteral<"chrome-beta">, z.ZodNull]>>;
|
|
@@ -297,13 +312,13 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
297
312
|
defaultNavigationTimeoutMs: z.ZodNumber;
|
|
298
313
|
linter: z.ZodObject<{
|
|
299
314
|
enabled: z.ZodBoolean;
|
|
300
|
-
rules: z.ZodRecord<z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>, z.ZodEnum<["off", "warn", "error"]>>;
|
|
315
|
+
rules: z.ZodRecord<z.ZodEnum<["lint:deep-css", "lint:xpath", "lint:obfuscated-class", "lint:pause-explicit", "lint:disambig-by-index", "lint:evaluate-discouraged", "lint:scenario-in-root", "lint:mustache-in-dsl", "lint:goto-concat", "lint:regex-invalid", "lint:echo-assert", "lint:lint-ok-missing-reason", "validator:unknown-function", "validator:arity", "validator:arg-kind", "validator:step-coverage", "validator:step-shape", "validator:meta-shape", "validator:function-shape", "validator:for-shape", "validator:if-shape", "validator:var-shape", "validator:unsupported-statement", "validator:unsupported-expression", "validator:string-concat", "validator:semantic-loss", "validator:list-arg", "validator:wrapped-format"]>, z.ZodEnum<["off", "warn", "error"]>>;
|
|
301
316
|
}, "strip", z.ZodTypeAny, {
|
|
302
317
|
enabled: boolean;
|
|
303
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
318
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
304
319
|
}, {
|
|
305
320
|
enabled: boolean;
|
|
306
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
321
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
307
322
|
}>;
|
|
308
323
|
mcp: z.ZodObject<{
|
|
309
324
|
transport: z.ZodLiteral<"stdio">;
|
|
@@ -315,6 +330,17 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
315
330
|
sandbox: z.ZodObject<{
|
|
316
331
|
/** Default cwd for `shell(cmd, ...args)`. Defaults to `process.cwd()`. */
|
|
317
332
|
shellCwd: z.ZodOptional<z.ZodString>;
|
|
333
|
+
/** Wall-clock budget for one `shell()` call, ms. Default 120 000. A call
|
|
334
|
+
* that exceeds it fails the step (the child gets SIGTERM, then SIGKILL) —
|
|
335
|
+
* without this, a grandchild process inheriting stdio pipes hangs the
|
|
336
|
+
* scenario forever. Per-call override: `shell(..., {timeoutMs})`. */
|
|
337
|
+
shellTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
338
|
+
/** Names of `.secrets*` variables exported into `shell()` subprocess env.
|
|
339
|
+
* Secrets are deliberately kept OUT of process.env (see
|
|
340
|
+
* scenario-variables.ts) — this is the explicit opt-in for the listener /
|
|
341
|
+
* seeder subprocess that genuinely needs a token. Values are still
|
|
342
|
+
* masked in logs by the SecretRegistry. */
|
|
343
|
+
exportSecrets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
318
344
|
/** Database connection string consumed by `dbQuery` / `dbExec`. URL form
|
|
319
345
|
* picks the dialect: `postgres://`, `mysql://`, `sqlite:`. */
|
|
320
346
|
database: z.ZodOptional<z.ZodString>;
|
|
@@ -323,17 +349,21 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
323
349
|
* URLs are rejected at runtime. Additional bases come from env
|
|
324
350
|
* variables via `apiCall(..., {base: "API_BASE_X"})`. */
|
|
325
351
|
apiBaseUrl: z.ZodOptional<z.ZodString>;
|
|
326
|
-
/** Root for `
|
|
327
|
-
*
|
|
328
|
-
*
|
|
352
|
+
/** Root for `upload()` fixtures. Relative upload paths resolve
|
|
353
|
+
* against it and may not escape it. Defaults to the project root
|
|
354
|
+
* (the runner's cwd). */
|
|
329
355
|
uploadDir: z.ZodOptional<z.ZodString>;
|
|
330
356
|
}, "strip", z.ZodTypeAny, {
|
|
331
357
|
shellCwd?: string | undefined;
|
|
358
|
+
shellTimeoutMs?: number | undefined;
|
|
359
|
+
exportSecrets?: string[] | undefined;
|
|
332
360
|
database?: string | undefined;
|
|
333
361
|
apiBaseUrl?: string | undefined;
|
|
334
362
|
uploadDir?: string | undefined;
|
|
335
363
|
}, {
|
|
336
364
|
shellCwd?: string | undefined;
|
|
365
|
+
shellTimeoutMs?: number | undefined;
|
|
366
|
+
exportSecrets?: string[] | undefined;
|
|
337
367
|
database?: string | undefined;
|
|
338
368
|
apiBaseUrl?: string | undefined;
|
|
339
369
|
uploadDir?: string | undefined;
|
|
@@ -368,13 +398,15 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
368
398
|
defaultNavigationTimeoutMs: number;
|
|
369
399
|
linter: {
|
|
370
400
|
enabled: boolean;
|
|
371
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
401
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
372
402
|
};
|
|
373
403
|
mcp: {
|
|
374
404
|
transport: "stdio";
|
|
375
405
|
};
|
|
376
406
|
sandbox: {
|
|
377
407
|
shellCwd?: string | undefined;
|
|
408
|
+
shellTimeoutMs?: number | undefined;
|
|
409
|
+
exportSecrets?: string[] | undefined;
|
|
378
410
|
database?: string | undefined;
|
|
379
411
|
apiBaseUrl?: string | undefined;
|
|
380
412
|
uploadDir?: string | undefined;
|
|
@@ -382,9 +414,9 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
382
414
|
baseUrl?: string | undefined;
|
|
383
415
|
webServer?: {
|
|
384
416
|
url: string;
|
|
417
|
+
timeoutMs: number;
|
|
385
418
|
command: string;
|
|
386
419
|
reuseExistingServer: boolean;
|
|
387
|
-
timeoutMs: number;
|
|
388
420
|
} | undefined;
|
|
389
421
|
channel?: "chrome" | "msedge" | "chrome-beta" | null | undefined;
|
|
390
422
|
storageState?: string | undefined;
|
|
@@ -418,13 +450,15 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
418
450
|
defaultNavigationTimeoutMs: number;
|
|
419
451
|
linter: {
|
|
420
452
|
enabled: boolean;
|
|
421
|
-
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
453
|
+
rules: Partial<Record<"lint:deep-css" | "lint:xpath" | "lint:obfuscated-class" | "lint:pause-explicit" | "lint:disambig-by-index" | "lint:evaluate-discouraged" | "lint:scenario-in-root" | "lint:mustache-in-dsl" | "lint:goto-concat" | "lint:regex-invalid" | "lint:echo-assert" | "lint:lint-ok-missing-reason" | "validator:unknown-function" | "validator:arity" | "validator:arg-kind" | "validator:step-coverage" | "validator:step-shape" | "validator:meta-shape" | "validator:function-shape" | "validator:for-shape" | "validator:if-shape" | "validator:var-shape" | "validator:unsupported-statement" | "validator:unsupported-expression" | "validator:string-concat" | "validator:semantic-loss" | "validator:list-arg" | "validator:wrapped-format", "off" | "warn" | "error">>;
|
|
422
454
|
};
|
|
423
455
|
mcp: {
|
|
424
456
|
transport: "stdio";
|
|
425
457
|
};
|
|
426
458
|
sandbox: {
|
|
427
459
|
shellCwd?: string | undefined;
|
|
460
|
+
shellTimeoutMs?: number | undefined;
|
|
461
|
+
exportSecrets?: string[] | undefined;
|
|
428
462
|
database?: string | undefined;
|
|
429
463
|
apiBaseUrl?: string | undefined;
|
|
430
464
|
uploadDir?: string | undefined;
|
|
@@ -433,8 +467,8 @@ declare const UnotestConfigSchema: z.ZodObject<{
|
|
|
433
467
|
webServer?: {
|
|
434
468
|
url: string;
|
|
435
469
|
command: string;
|
|
436
|
-
reuseExistingServer?: boolean | undefined;
|
|
437
470
|
timeoutMs?: number | undefined;
|
|
471
|
+
reuseExistingServer?: boolean | undefined;
|
|
438
472
|
} | undefined;
|
|
439
473
|
channel?: "chrome" | "msedge" | "chrome-beta" | null | undefined;
|
|
440
474
|
storageState?: string | undefined;
|
package/dist/config/schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var _0x24740a=_0x202c;(function(_0x2e7bfe,_0x17cbeb){var _0x5d30b8={_0x2648ae:0x193,_0x5ea1b9:0x19f,_0x1fb823:0x19d,_0x2f0413:0x1a8,_0x2e20ee:0x192},_0x482484=_0x202c,_0x3038a0=_0x2e7bfe();while(!![]){try{var _0x3f2fa8=-parseInt(_0x482484(0x189))/0x1+-parseInt(_0x482484(_0x5d30b8._0x2648ae))/0x2+-parseInt(_0x482484(_0x5d30b8._0x5ea1b9))/0x3*(-parseInt(_0x482484(0x1b3))/0x4)+-parseInt(_0x482484(_0x5d30b8._0x1fb823))/0x5+parseInt(_0x482484(_0x5d30b8._0x2f0413))/0x6+-parseInt(_0x482484(_0x5d30b8._0x2e20ee))/0x7+parseInt(_0x482484(0x1a5))/0x8;if(_0x3f2fa8===_0x17cbeb)break;else _0x3038a0['push'](_0x3038a0['shift']());}catch(_0x3f5318){_0x3038a0['push'](_0x3038a0['shift']());}}}(_0x4907,0x97be5));function _0x4907(){var _0x351a15=['B2jQzwn0','otK0otG5Ewr1EeHv','BgLUDdPYzwDLEc1PBNzHBgLK','Dw5VDgvZDc9LmMuVx2HLBhbLCNm','Dw5PB24','lNvUB3rLC3qVzMfPBhvYzxm','y3jHC2G','BgLUDdPKAxnHBwjPzY1IEs1PBMrLEa','DMfSAwrHDg9YoMXPC3qTyxjN','BgLUDdPLDMfSDwf0zs1KAxnJB3vYywDLza','mJyZmdGYnfLUr2HSuG','mJe4mZq0nKPorhLkuG','DxjS','DMfSAwrHDg9YoNvUA25VD24TzNvUy3rPB24','BNvSBa','DMfSAwrHDg9YoNnLBwfUDgLJlwXVC3m','DMfSAwrHDg9YoMLMlxnOyxbL','D2vIA2L0','BwfUDwfS','CMvJB3jK','DMfSAwrHDg9YoNn0CMLUzY1JB25Jyxq','mJe0odCWmgnHCwXHCa','BgL0zxjHBa','ntKXDfrWzhPP','BgLUDdPNB3rVlwnVBMnHDa','DMfSAwrHDg9YoNn0zxaTC2HHCgu','y2HYB21L','zxjYB3i','yxjYyxK','mtmWodC3mJHItgfuB3m','DMfSAwrHDg9YoNvUC3vWCg9YDgvKlwv4ChjLC3nPB24','zw51Bq','nJa5ntKWnhnNDvbezG','C3rKAw8','BMv0D29YAW','DMfSAwrHDg9YoMfYzY1RAw5K','BgLUDdP4Cgf0Aa','BNvTyMvY','DhjHBNnPzw50','B3b0Aw9UywW','DMfSAwrHDg9YoMzVCI1ZAgfWzq','BgLUDdPLy2HVlwfZC2vYDa','BgLUDdPTDxn0ywnOzs1PBI1KC2W','mtC1mdbcD3zWrLm','BgLUDdPSAw50lw9Rlw1PC3nPBMCTCMvHC29U','DMfSAwrHDg9YoNvUC3vWCg9YDgvKlxn0yxrLBwvUDa','Cg9ZAxrPDMu','yM9VBgvHBG','BxnLzgDL','Aw50','zgvMyxvSDa','zMLYzwzVEa','BwLU','DMfSAwrHDg9YoNzHCI1ZAgfWzq','Dw5VDgvZDc9LmMu','DMfSAwrHDg9YoM1LDgeTC2HHCgu','DMfSAwrHDg9YoMfYAxr5','y2HYB21LlwjLDge','C3rYAw5N','D2fYBG','y2HYB21PDw0','BgLUDdPKzwvWlwnZCW','zgLZBwLZCW'];_0x4907=function(){return _0x351a15;};return _0x4907();}import{z}from'zod';var BrowserSchema=z[_0x24740a(0x1a7)](['chromium',_0x24740a(0x17c),_0x24740a(0x199)]),BrowserChannelSchema=z[_0x24740a(0x18c)]([z[_0x24740a(0x19e)](_0x24740a(0x1a2)),z[_0x24740a(0x19e)](_0x24740a(0x1b8)),z[_0x24740a(0x19e)](_0x24740a(0x182)),z[_0x24740a(0x196)]()])[_0x24740a(0x1af)](),ViewportSchema=z[_0x24740a(0x188)]({'width':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()[_0x24740a(0x1b6)](),'height':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()[_0x24740a(0x1b6)]()}),RetryReasonSchema=z[_0x24740a(0x1a7)]([_0x24740a(0x1ae),_0x24740a(0x1aa),_0x24740a(0x18e)]),RetryConfigSchema=z[_0x24740a(0x188)]({'count':z[_0x24740a(0x1ad)]()['int']()['min'](0x0)['max'](0xa),'on':z[_0x24740a(0x1a4)](RetryReasonSchema)}),FailureBundleConfigSchema=z['object']({'tier1':z['literal'](!![])['default'](!![]),'tier2':z[_0x24740a(0x1b7)](),'tier3':z[_0x24740a(0x188)]({'network':z[_0x24740a(0x1b7)](),'video':z['boolean']()}),'retention':z['object']({'runs':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()[_0x24740a(0x1b6)](),'days':z[_0x24740a(0x1ad)]()['int']()[_0x24740a(0x1b6)]()}),'storageDir':z[_0x24740a(0x183)]()[_0x24740a(0x17d)](0x1)}),DialogPolicySchema=z['enum'](['accept',_0x24740a(0x187),_0x24740a(0x19a)]),LinterRuleIdSchema=z[_0x24740a(0x1a7)]([_0x24740a(0x186),_0x24740a(0x1ac),'lint:obfuscated-class','lint:pause-explicit',_0x24740a(0x18f),_0x24740a(0x191),'lint:scenario-in-root',_0x24740a(0x1b2),_0x24740a(0x1a0),_0x24740a(0x18a),_0x24740a(0x1b1),_0x24740a(0x1b4),_0x24740a(0x195),_0x24740a(0x181),_0x24740a(0x1ab),'validator:step-coverage',_0x24740a(0x1a1),_0x24740a(0x180),'validator:function-shape',_0x24740a(0x1b0),_0x24740a(0x198),_0x24740a(0x17e),_0x24740a(0x1b5),_0x24740a(0x1a6),_0x24740a(0x19c),_0x24740a(0x197),_0x24740a(0x190),'validator:wrapped-format']),LinterSeveritySchema=z[_0x24740a(0x1a7)](['off',_0x24740a(0x184),'error']),LinterConfigSchema=z[_0x24740a(0x188)]({'enabled':z[_0x24740a(0x1b7)](),'rules':z[_0x24740a(0x19b)](LinterRuleIdSchema,LinterSeveritySchema)}),McpConfigSchema=z['object']({'transport':z[_0x24740a(0x19e)](_0x24740a(0x1a9))}),SandboxConfigSchema=z[_0x24740a(0x188)]({'shellCwd':z['string']()['optional'](),'shellTimeoutMs':z[_0x24740a(0x1ad)]()['int']()[_0x24740a(0x1b6)]()[_0x24740a(0x1af)](),'exportSecrets':z['array'](z['string']())[_0x24740a(0x1af)](),'database':z[_0x24740a(0x183)]()['optional'](),'apiBaseUrl':z[_0x24740a(0x183)]()[_0x24740a(0x194)]()[_0x24740a(0x1af)](),'uploadDir':z[_0x24740a(0x183)]()['optional']()}),WebServerConfigSchema=z[_0x24740a(0x188)]({'command':z[_0x24740a(0x183)]()[_0x24740a(0x17d)](0x1),'url':z[_0x24740a(0x183)]()[_0x24740a(0x194)](),'reuseExistingServer':z[_0x24740a(0x1b7)]()['default'](!![]),'timeoutMs':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()['positive']()[_0x24740a(0x1ba)](0xea60)}),UnotestConfigSchema=z[_0x24740a(0x188)]({'baseUrl':z[_0x24740a(0x183)]()[_0x24740a(0x194)]()[_0x24740a(0x1af)](),'webServer':WebServerConfigSchema[_0x24740a(0x1af)](),'browsers':z[_0x24740a(0x1a4)](BrowserSchema)[_0x24740a(0x17d)](0x1),'channel':BrowserChannelSchema,'viewport':ViewportSchema,'retry':RetryConfigSchema,'failureBundle':FailureBundleConfigSchema,'dialogPolicy':DialogPolicySchema,'storageState':z['string']()[_0x24740a(0x1af)](),'testDir':z[_0x24740a(0x183)]()[_0x24740a(0x17d)](0x1),'helpersDir':z[_0x24740a(0x183)]()[_0x24740a(0x17d)](0x1),'defaultTimeoutMs':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()[_0x24740a(0x1b6)](),'defaultNavigationTimeoutMs':z[_0x24740a(0x1ad)]()[_0x24740a(0x1b9)]()[_0x24740a(0x1b6)](),'linter':LinterConfigSchema,'mcp':McpConfigSchema,'sandbox':SandboxConfigSchema}),DEFAULT_CONFIG={'browsers':[_0x24740a(0x185)],'viewport':{'width':0x500,'height':0x2d0},'retry':{'count':0x0,'on':['transient']},'failureBundle':{'tier1':!![],'tier2':!![],'tier3':{'network':![],'video':![]},'retention':{'runs':0x14,'days':0x7},'storageDir':_0x24740a(0x18d)},'dialogPolicy':'accept','testDir':_0x24740a(0x17f),'helpersDir':_0x24740a(0x18b),'defaultTimeoutMs':0xbb8,'defaultNavigationTimeoutMs':0x7530,'linter':{'enabled':!![],'rules':{'lint:deep-css':'warn','lint:xpath':_0x24740a(0x184),'lint:obfuscated-class':_0x24740a(0x184),'lint:pause-explicit':_0x24740a(0x184),'lint:disambig-by-index':'off','lint:evaluate-discouraged':'warn','lint:scenario-in-root':_0x24740a(0x1a3),'lint:mustache-in-dsl':'error','lint:goto-concat':_0x24740a(0x184),'lint:regex-invalid':_0x24740a(0x1a3),'lint:echo-assert':_0x24740a(0x184),'lint:lint-ok-missing-reason':_0x24740a(0x184),'validator:unknown-function':_0x24740a(0x1a3)}},'mcp':{'transport':_0x24740a(0x1a9)},'sandbox':{}};function _0x202c(_0x5b55f0,_0x1e1548){_0x5b55f0=_0x5b55f0-0x17c;var _0x49075b=_0x4907();var _0x202c4b=_0x49075b[_0x5b55f0];if(_0x202c['tyZDFh']===undefined){var _0xe49ede=function(_0x401a06){var _0x337267='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x3744b8='',_0x98677e='';for(var _0x5d0a3c=0x0,_0x50befd,_0x1f34a4,_0x56a82f=0x0;_0x1f34a4=_0x401a06['charAt'](_0x56a82f++);~_0x1f34a4&&(_0x50befd=_0x5d0a3c%0x4?_0x50befd*0x40+_0x1f34a4:_0x1f34a4,_0x5d0a3c++%0x4)?_0x3744b8+=String['fromCharCode'](0xff&_0x50befd>>(-0x2*_0x5d0a3c&0x6)):0x0){_0x1f34a4=_0x337267['indexOf'](_0x1f34a4);}for(var _0x2145f6=0x0,_0xfee7e3=_0x3744b8['length'];_0x2145f6<_0xfee7e3;_0x2145f6++){_0x98677e+='%'+('00'+_0x3744b8['charCodeAt'](_0x2145f6)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x98677e);};_0x202c['pPVuVN']=_0xe49ede,_0x202c['TGtDoY']={},_0x202c['tyZDFh']=!![];}var _0x95650d=_0x49075b[0x0],_0x58923e=_0x5b55f0+_0x95650d,_0x39365d=_0x202c['TGtDoY'][_0x58923e];return!_0x39365d?(_0x202c4b=_0x202c['pPVuVN'](_0x202c4b),_0x202c['TGtDoY'][_0x58923e]=_0x202c4b):_0x202c4b=_0x39365d,_0x202c4b;}export{BrowserChannelSchema,BrowserSchema,DEFAULT_CONFIG,DialogPolicySchema,FailureBundleConfigSchema,LinterConfigSchema,LinterRuleIdSchema,LinterSeveritySchema,McpConfigSchema,RetryConfigSchema,RetryReasonSchema,SandboxConfigSchema,UnotestConfigSchema,ViewportSchema,WebServerConfigSchema};
|
package/dist/driver/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as ElementHint, N as NetworkEntry, W as WebDriver, L as LaunchOptions, C as ContextOptions, D as DriverContext } from '../interfaces-
|
|
2
|
-
export { A as ActionTimeout, a as CheckOptions, b as ClickOptions, c as CookieOptions, d as DriverPage, F as FillOptions, G as GotoOptions, H as HoverOptions, e as NavigationOptions, P as PressOptions, R as ReloadOptions, S as ScreenshotOptions, f as SelectOptions, V as Viewport, g as WaitOptions, h as WaitState } from '../interfaces-
|
|
1
|
+
import { E as ElementHint, N as NetworkEntry, W as WebDriver, L as LaunchOptions, C as ContextOptions, D as DriverContext } from '../interfaces-XvuefHHC.js';
|
|
2
|
+
export { A as ActionTimeout, a as CheckOptions, b as ClickOptions, c as CookieOptions, d as DriverPage, F as FillOptions, G as GotoOptions, H as HoverOptions, e as NavigationOptions, P as PressOptions, R as ReloadOptions, S as ScreenshotOptions, f as SelectOptions, V as Viewport, g as WaitOptions, h as WaitState } from '../interfaces-XvuefHHC.js';
|
|
3
3
|
import '@unotest/protocol';
|
|
4
4
|
import '../config/schema.js';
|
|
5
5
|
import 'zod';
|
|
@@ -27,6 +27,8 @@ interface FakeBehavior {
|
|
|
27
27
|
inputValueByDefault?: string;
|
|
28
28
|
/** Default isVisible() response. Default: true. */
|
|
29
29
|
isVisibleByDefault?: boolean;
|
|
30
|
+
/** Default isDisabled() response. Default: false. */
|
|
31
|
+
isDisabledByDefault?: boolean;
|
|
30
32
|
/** Default checkedState() response — null = "not a checkable element",
|
|
31
33
|
* the shape a plain <input type=text> reports. Default: null. */
|
|
32
34
|
checkedStateByDefault?: boolean | null;
|