@unotest/web 0.6.2 → 0.9.1

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,10 +1,13 @@
1
- import { h as LocatorValue, W as WebDriver, D as DriverContext, d as DriverPage } from '../interfaces-iTfjd1zT.js';
2
- export { i as LocatorStep, j as appendStep, k as describeLocator, l as isLocatorValue, r as rootedAt } from '../interfaces-iTfjd1zT.js';
1
+ import { i as LocatorValue, W as WebDriver, D as DriverContext, d as DriverPage } from '../interfaces-dbZG10RS.js';
2
+ export { j as LocatorStep, k as appendStep, l as describeLocator, m as isLocatorValue, r as rootedAt } from '../interfaces-dbZG10RS.js';
3
3
  import { Matcher, RegexLiteral } from '@unotest/protocol';
4
- import { Statement, BlockStatement } from '@unotest/dsl';
4
+ import { ExecutionWalker, ExecutionEvent, RunResult, RunOptions } from '@unotest/dsl/executor';
5
+ export { ExecutionError, ExecutionEvent, RunOptions, RunResult } from '@unotest/dsl/executor';
5
6
  import { SandboxConfig } from '../config/schema.js';
6
- export { L as LintDiagnostic, a as LintOptions, b as LintSeverity, l as lintAst } from '../linter-DzAzJpab.js';
7
+ import { RuntimeExecState } from '@unotest/core';
8
+ export { L as LintDiagnostic, b as LintOptions, a as LintSeverity, l as lintAst } from '../linter-CM2CpIyW.js';
7
9
  import 'zod';
10
+ import '@unotest/dsl';
8
11
 
9
12
  /** Test/codegen convenience: build a RegexLiteral inline. The DSL
10
13
  * parser produces these for `/pattern/flags` literals at runtime;
@@ -65,83 +68,6 @@ declare function chainGetByTitle(loc: LocatorValue, text: Matcher, options?: {
65
68
  exact?: boolean;
66
69
  }): LocatorValue;
67
70
 
68
- interface ExecutionError {
69
- message: string;
70
- /** Error class name (e.g. "AssertionError", "LocatorError"). Lets consumers
71
- * classify failure vs. infra error without parsing the message. */
72
- name?: string;
73
- stack?: string;
74
- /** Path to a screenshot saved on failure (driver-side). */
75
- screenshotPath?: string;
76
- /** Path to the a11y / semantic-dom snapshot saved on failure. */
77
- snapshotPath?: string;
78
- /** Optional rich detail (top-3 NearMisses, etc.). Free-form for the explainer. */
79
- details?: unknown;
80
- }
81
- type ExecutionEvent = {
82
- kind: 'step-start';
83
- node: Statement;
84
- file: string;
85
- line: number;
86
- col: number;
87
- callStack?: readonly string[];
88
- } | {
89
- kind: 'step-end';
90
- node: Statement;
91
- file: string;
92
- line: number;
93
- col: number;
94
- ok: true;
95
- callStack?: readonly string[];
96
- } | {
97
- kind: 'step-end';
98
- node: Statement;
99
- file: string;
100
- line: number;
101
- col: number;
102
- ok: false;
103
- error: ExecutionError;
104
- callStack?: readonly string[];
105
- } | {
106
- kind: 'paused';
107
- reason: 'step' | 'failure' | 'breakpoint';
108
- file: string;
109
- line: number;
110
- col: number;
111
- };
112
- interface RunOptions {
113
- /** "auto" = run until completion / failure. "step" = pause after each statement. */
114
- mode: 'auto' | 'step';
115
- /** When true, on uncaught error we emit `paused: 'failure'` instead of throwing. */
116
- pauseOnFailure: boolean;
117
- /** Safety budget — abort with synthetic failure if exceeded. */
118
- maxSteps?: number;
119
- /** Wall-clock budget — same semantics. */
120
- maxDurationMs?: number;
121
- /** Maximum user-function nesting depth. Default 32. Guards against runaway
122
- * recursion that wouldn't trip `maxSteps` (deep expression-tree calls). */
123
- maxCallDepth?: number;
124
- /** Mutable set of "line:col" keys. Executor checks membership before each
125
- * statement; on hit, emits `paused: 'breakpoint'`. set-bp/clear-bp commands
126
- * from the debug-commands-watcher mutate this set in place — same instance
127
- * reference is shared with the watcher. */
128
- breakpoints?: Set<string>;
129
- /** Ref-object atomic flag for "pause on next statement". The pause-command
130
- * watcher sets `value = true`; the executor reads it at every step-start,
131
- * yields `paused: 'step'` if set, and resets to false. Ref-object (not raw
132
- * boolean) so the watcher's mutation is visible to the executor without
133
- * re-passing options. */
134
- pauseRequested?: {
135
- value: boolean;
136
- };
137
- }
138
- interface RunResult {
139
- outcome: 'completed' | 'failed' | 'aborted';
140
- stepsExecuted: number;
141
- durationMs: number;
142
- error?: ExecutionError;
143
- }
144
-
145
71
  /** Read-only lookup over external scenario variables. */
146
72
  interface VariableStore {
147
73
  has(name: string): boolean;
@@ -175,6 +101,10 @@ interface TestRuntimeDeps {
175
101
  /** External variable store (`unotest/.env` + `.secrets`). Resolves bare
176
102
  * UPPER_SNAKE identifiers. Defaults to an empty store when omitted. */
177
103
  readonly variables?: VariableStore;
104
+ /** Resolved base URL (`config.baseUrl`, auto-wired from APP_BASE_URL). Used
105
+ * to fail a relative `goto('/path')` with a clear message when no base is
106
+ * configured, instead of an opaque Playwright "invalid URL". */
107
+ readonly baseUrl?: string;
178
108
  /** Injectable clock — defaults to Date.now. Tests pass a fake. */
179
109
  readonly nowFn?: () => number;
180
110
  }
@@ -184,6 +114,7 @@ declare class TestRuntime {
184
114
  readonly context: DriverContext;
185
115
  readonly logger: Logger;
186
116
  readonly sandbox: SandboxConfig;
117
+ readonly baseUrl?: string;
187
118
  private readonly variables;
188
119
  private readonly nowFn;
189
120
  private readonly scope;
@@ -232,34 +163,11 @@ declare class FunctionRegistry {
232
163
  names(): string[];
233
164
  }
234
165
 
235
- declare class AstExecutor {
236
- private readonly registry;
166
+ declare class AstExecutor extends ExecutionWalker<TestRuntime> {
237
167
  constructor(registry: FunctionRegistry);
238
- private entryFile;
239
- private fnFile;
240
- /** Project-root-relative posix file the current step lives in: origin of
241
- * the innermost user-function frame, else the entry file. `callStack`
242
- * only ever holds user-function names (pushed in callUserFunction), so
243
- * every frame has a `fnFile` entry; the `?? entryFile` is a defensive
244
- * fallback, not a normal path. */
245
- private fileForStack;
246
- run(program: BlockStatement, testName: string, runtime: TestRuntime, opts: RunOptions, helpers?: BlockStatement[], entryFile?: string, fnFile?: ReadonlyMap<string, string>): AsyncGenerator<ExecutionEvent, RunResult>;
247
- private runBlock;
248
- private runStatement;
249
- private execStatement;
250
- private evalExpression;
251
- private callUserFunction;
252
- private runLoop;
253
- /** Run one loop-body pass. Returns `true` if a `break` fired (caller stops
254
- * the loop), `false` for normal completion or `continue` (both end this
255
- * iteration the same way). Each pass counts as a step so an empty-bodied
256
- * infinite loop still trips `maxSteps`; `checkBudgets` enforces wall-clock. */
257
- private runLoopIteration;
258
- private applyIncrement;
259
- private checkBudgets;
260
168
  }
261
169
 
262
- type RuntimeState = 'starting' | 'running' | 'paused-step' | 'paused-failure' | 'completed' | 'failed' | 'aborted';
170
+ type RuntimeState = RuntimeExecState;
263
171
  interface ActiveRuntime {
264
172
  id: string;
265
173
  scenarioName: string;
@@ -317,6 +225,14 @@ interface TestRuntimeManagerDeps {
317
225
  declare class TestRuntimeManager {
318
226
  private readonly deps;
319
227
  private readonly runtimes;
228
+ /** Final snapshot of recently-aborted runtimes. `abort()` removes the live
229
+ * runtime from `runtimes`, so a trailing `inspect()` (the runtime-state
230
+ * writer's final flush, or the agent reading after `abort_runtime`) would
231
+ * otherwise miss the terminal `aborted` state and report the stale pre-abort
232
+ * `paused-*`. We keep the captured terminal snapshot here so inspect reflects
233
+ * `aborted`. Bounded — only the last few matter (a writer flushes once). */
234
+ private readonly terminalTombstones;
235
+ private static readonly MAX_TOMBSTONES;
320
236
  private nextId;
321
237
  constructor(deps: TestRuntimeManagerDeps);
322
238
  register(opts: {
@@ -330,7 +246,17 @@ declare class TestRuntimeManager {
330
246
  step(id: string): Promise<ExecutionEvent | RunResult>;
331
247
  resume(id: string): Promise<ExecutionEvent | RunResult>;
332
248
  abort(id: string): Promise<void>;
249
+ /** Snapshot a just-aborted (still-live) runtime into the tombstone map so a
250
+ * later inspect() reflects `aborted`. Bounded LRU; best-effort. */
251
+ private rememberTombstone;
333
252
  inspect(id: string): RuntimeSnapshot;
253
+ /** The live active page of a runtime — used by the locator picker to
254
+ * attach its overlay to the page held open during a debug pause.
255
+ * Returns null when the runtime is gone or has no page yet. */
256
+ currentPage(id: string): DriverPage | null;
257
+ /** The runtime's driver context (for capture artifacts — console/network).
258
+ * Null when the runtime isn't registered. */
259
+ currentContext(id: string): DriverContext | null;
334
260
  list(): RuntimeSummary[];
335
261
  private armTtl;
336
262
  private clearTtl;
@@ -340,4 +266,4 @@ declare class TestRuntimeManager {
340
266
  /** Build a fully-populated FunctionRegistry. */
341
267
  declare function buildDefaultRegistry(): FunctionRegistry;
342
268
 
343
- export { AstExecutor, type DslArg, type DslArray, type DslFunction, type DslObject, type DslValue, type ExecutionError, type ExecutionEvent, FunctionRegistry, LocatorValue, type RunOptions, type RunResult, TestRuntime, TestRuntimeManager, buildDefaultRegistry, chainGetByAltText, chainGetByLabel, chainGetByPlaceholder, chainGetByRole, chainGetByTestId, chainGetByText, chainGetByTitle, contentFrame, filter, first, getByAltText, getByLabel, getByPlaceholder, getByRole, getByTestId, getByText, getByTitle, last, locator, nth, re };
269
+ export { AstExecutor, type DslArg, type DslArray, type DslFunction, type DslObject, type DslValue, FunctionRegistry, LocatorValue, TestRuntime, TestRuntimeManager, buildDefaultRegistry, chainGetByAltText, chainGetByLabel, chainGetByPlaceholder, chainGetByRole, chainGetByTestId, chainGetByText, chainGetByTitle, contentFrame, filter, first, getByAltText, getByLabel, getByPlaceholder, getByRole, getByTestId, getByText, getByTitle, last, locator, nth, re };