waygraph 0.15.38 → 0.15.39

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.
@@ -15,6 +15,10 @@ interface RunFlags {
15
15
  data?: string;
16
16
  /** Fill any requires key with no --data coverage from registerMemStub's registry (--mem-stub). */
17
17
  memStub?: boolean;
18
+ /** run only: explore every .branch() path (runBranchRegression), cloning the session at each branch point. */
19
+ allBranches?: boolean;
20
+ /** --all-branches only: one shared session (no cloning) - follows the single live-dispatch path instead. */
21
+ sharedSession?: boolean;
18
22
  /** Flow/chain spec from --blocks <spec>. */
19
23
  blocks?: string;
20
24
  /** auto path-find: --blocks <fromCheckpoint> <toCheckpoint>. */
package/dist/cli/flags.js CHANGED
@@ -141,6 +141,12 @@ export function parseRunFlags(argv) {
141
141
  else if (a === "--mem-stub") {
142
142
  out.memStub = true;
143
143
  }
144
+ else if (a === "--all-branches") {
145
+ out.allBranches = true;
146
+ }
147
+ else if (a === "--shared-session") {
148
+ out.sharedSession = true;
149
+ }
144
150
  else if (a === "--video" || a.startsWith("--video=")) {
145
151
  if (a.startsWith("--video=")) {
146
152
  out.video = a.slice("--video=".length);
@@ -271,6 +277,12 @@ export function applyRunFlags(flags, opts) {
271
277
  if (flags.memStub) {
272
278
  process.env.WAYGRAPH_MEM_STUB = "1";
273
279
  }
280
+ if (flags.allBranches) {
281
+ process.env.WAYGRAPH_ALL_BRANCHES = "1";
282
+ }
283
+ if (flags.sharedSession) {
284
+ process.env.WAYGRAPH_SHARED_SESSION = "1";
285
+ }
274
286
  if (flags.fast) {
275
287
  process.env.WAYGRAPH_DEMO_FAST = "1";
276
288
  }
package/dist/cli/usage.js CHANGED
@@ -162,6 +162,11 @@ Primary (less is more):
162
162
  waygraph run [--blocks <flow|file|spec>] Execute (no overlay unless --step)
163
163
  --data '{...}'
164
164
  --mem-stub Same as demo's --mem-stub
165
+ --all-branches Bare Flow ref only: explore every MapBuilder.branch()
166
+ path, cloning the session (storageState+URL) at each
167
+ branch point - see runBranchRegression()
168
+ --shared-session With --all-branches: one shared session instead of
169
+ cloning (follows only the live-dispatch path)
165
170
  --non-headless Show browser
166
171
  --video [dir] Record .webm
167
172
  --video-viewport WxH Recording size (default run: 1280x720)
@@ -8,7 +8,7 @@ import { isExpectedChainFailure, parseVideoViewport, runChainedFlows, runJsonRep
8
8
  import { runStepMode } from "./step-mode.js";
9
9
  import { connect } from "../types.js";
10
10
  import { MemPage } from "../mem-page.js";
11
- import { Engine, start, end, chainFlow, isFastForwardBlock } from "../engine.js";
11
+ import { Engine, start, end, chainFlow, isFastForwardBlock, branchRoutes, runBranchRegression } from "../engine.js";
12
12
 
13
13
  async function main() {
14
14
  const projectDir = process.argv[2];
@@ -275,6 +275,9 @@ async function main() {
275
275
  if (r.seedMem) r.seedMem();
276
276
  }
277
277
  }
278
+ if (process.env.WAYGRAPH_ALL_BRANCHES === "1") {
279
+ return runAllBranchesMode(chainFlows, mem, baseURL, headed, engine);
280
+ }
278
281
  if (step || jsonReport || baseURL || videoDir) {
279
282
  const { chromium } = await import("@playwright/test");
280
283
  // --start-maximized (step mode only): viewport: null alone only made
@@ -389,6 +392,53 @@ async function main() {
389
392
  }
390
393
  }
391
394
 
395
+ /**
396
+ * `waygraph run --blocks <flowName> --all-branches`: explore every path through that flow's own
397
+ * `.branch()` tree (see src/engine/branch-regression.ts), not just whichever one the live state
398
+ * would dispatch to. Needs a single, bare Flow reference - a multi-segment chain spec has no one
399
+ * Flow to walk. `--shared-session` opts out of session cloning (WAYGRAPH_SHARED_SESSION=1).
400
+ */
401
+ async function runAllBranchesMode(chainFlows, mem, baseURL, headed, engine) {
402
+ if (!chainFlows || chainFlows.length !== 1) {
403
+ console.error(
404
+ "waygraph run --all-branches: needs a single Flow reference (e.g. --blocks loginFlow), " +
405
+ "not a multi-segment chain spec - nothing else has one branch tree to explore.",
406
+ );
407
+ process.exitCode = 1;
408
+ return;
409
+ }
410
+ const flow = chainFlows[0];
411
+ if (!branchRoutes(flow)) {
412
+ console.error(
413
+ "waygraph run --all-branches: this Flow was not built with MapBuilder.branch() - " +
414
+ "there is no branch tree to explore. Run it normally instead.",
415
+ );
416
+ process.exitCode = 1;
417
+ return;
418
+ }
419
+ const { chromium } = await import("@playwright/test");
420
+ const browser = await chromium.launch({ headless: !headed });
421
+ const cloneSession = process.env.WAYGRAPH_SHARED_SESSION !== "1";
422
+ try {
423
+ const context = await browser.newContext(baseURL ? { baseURL } : undefined);
424
+ const results = await runBranchRegression(flow, context, mem, { cloneSession });
425
+ for (const r of results) {
426
+ const line = `waygraph run --all-branches: ${r.path || "(root)"} -> ${r.status}` +
427
+ (r.result ? ` (${JSON.stringify(r.result)})` : "") +
428
+ (r.error ? ` - ${r.error}` : "");
429
+ console.log(line);
430
+ }
431
+ const failed = results.filter((r) => r.status === "failed");
432
+ if (failed.length) {
433
+ console.error(`waygraph run --all-branches: ${failed.length}/${results.length} path(s) failed`);
434
+ process.exitCode = 1;
435
+ }
436
+ } finally {
437
+ await browser.close();
438
+ }
439
+ void engine;
440
+ }
441
+
392
442
  export function startRunner() {
393
443
  main().catch((err) => {
394
444
  console.error(err && err.stack ? err.stack : String(err));
File without changes
File without changes
File without changes
@@ -0,0 +1,20 @@
1
+ [11:12:59.725] waygraph pilot: stub.before ctx.title("Signing in · mobile")
2
+ [11:12:59.725] waygraph pilot: stub.before ctx.todos n=6 index=0
3
+ [11:12:59.725] waygraph pilot: stub.before ctx.device(mobile)
4
+ [11:12:59.725] waygraph pilot: stub.before ctx.zoom(1.35)
5
+ [11:12:59.725] waygraph pilot: stub.before ring #user-name tone=info label="Username"
6
+ [11:13:00.015] waygraph pilot: stub.after ctx.todos n=6 index=1
7
+ [11:13:01.590] waygraph pilot: stub.before ring #password tone=planned label="Password"
8
+ [11:13:01.964] waygraph pilot: stub.after ctx.todos n=6 index=2
9
+ [11:13:03.710] waygraph pilot: stub.before ring #login-button tone=warning label="Login"
10
+ [11:13:03.904] waygraph pilot: stub.after ctx.title("Inventory · landscape")
11
+ [11:13:03.904] waygraph pilot: stub.after ctx.todos n=6 index=3
12
+ [11:13:03.904] waygraph pilot: stub.after ctx.device(mobile)
13
+ [11:13:03.904] waygraph pilot: stub.after ring .inventory_list tone=success label="Product shelf"
14
+ [11:13:06.313] waygraph pilot: stub.before ctx.title("Open cart · landscape")
15
+ [11:13:06.313] waygraph pilot: stub.before ctx.todos n=6 index=5
16
+ [11:13:06.313] waygraph pilot: stub.before ctx.device(mobile)
17
+ [11:13:06.313] waygraph pilot: stub.before ctx.zoom(1.4)
18
+ [11:13:06.313] waygraph pilot: stub.before ring .shopping_cart_link tone=planned label="Cart"
19
+ [11:13:06.502] waygraph pilot: stub.after ctx.title("Your cart · desktop")
20
+ [11:13:06.502] waygraph pilot: stub.after ring .cart_item tone=success label="Cart items"
@@ -0,0 +1,22 @@
1
+ [11:13:06.492] waygraph pilot: stub.before ctx.title("Signing in · mobile")
2
+ [11:13:06.493] waygraph pilot: stub.before ctx.todos n=6 index=0
3
+ [11:13:06.493] waygraph pilot: stub.before ctx.device(mobile)
4
+ [11:13:06.493] waygraph pilot: stub.before ctx.zoom(1.35)
5
+ [11:13:06.493] waygraph pilot: stub.before ring #user-name tone=info label="Username"
6
+ [11:13:06.696] waygraph pilot: stub.after ctx.todos n=6 index=1
7
+ [11:13:09.771] waygraph pilot: stub.before ring #password tone=planned label="Password"
8
+ [11:13:09.947] waygraph pilot: stub.after ctx.todos n=6 index=2
9
+ [11:13:12.614] waygraph pilot: stub.before ring #login-button tone=warning label="Login"
10
+ [11:13:12.755] waygraph pilot: stub.after ctx.title("Inventory · landscape")
11
+ [11:13:12.756] waygraph pilot: stub.after ctx.todos n=6 index=3
12
+ [11:13:12.756] waygraph pilot: stub.after ctx.device(mobile)
13
+ [11:13:12.756] waygraph pilot: stub.after ring .inventory_list tone=success label="Product shelf"
14
+ [11:13:16.803] waygraph pilot: stub.before ctx.title("Pick a product · tablet")
15
+ [11:13:16.803] waygraph pilot: stub.before ctx.todos n=6 index=3
16
+ [11:13:16.803] waygraph pilot: stub.before ctx.device(tablet)
17
+ [11:13:16.803] waygraph pilot: stub.before ctx.zoom(1.35)
18
+ [11:13:16.803] waygraph pilot: stub.before ring div.inventory_item:has(button[data-test="add-to-cart-sauce-labs-backpack"], button[data-test="remove-sauce-labs-backpack"]) .inventory_item_name tone=info label="Sauce Labs Backpack"
19
+ [11:13:16.803] waygraph pilot: stub.before ring [data-test="add-to-cart-sauce-labs-backpack"] tone=success label="Add to cart"
20
+ [11:13:17.007] waygraph pilot: stub.after ctx.title("In the cart")
21
+ [11:13:17.007] waygraph pilot: stub.after ctx.todos n=6 index=4
22
+ [11:13:17.010] waygraph pilot: stub.after ring .shopping_cart_badge tone=success label="Cart badge"
@@ -0,0 +1,6 @@
1
+ [11:12:58.813] waygraph pilot: stub.before ctx.title("Signing in · mobile")
2
+ [11:12:58.815] waygraph pilot: stub.before ctx.todos n=6 index=0
3
+ [11:12:58.816] waygraph pilot: stub.before ctx.device(mobile)
4
+ [11:12:58.816] waygraph pilot: stub.before ctx.zoom(1.35)
5
+ [11:12:58.816] waygraph pilot: stub.before ring #user-name tone=info label="Username"
6
+ [11:12:59.236] waygraph pilot: stub.after ctx.todos n=6 index=1
@@ -0,0 +1,5 @@
1
+ [11:12:42.451] waygraph pilot: highlight ctx.todos n=3 index=0
2
+ [11:12:42.451] waygraph pilot: highlight ring #user-name tone=planned label="Username"
3
+ [11:12:42.452] waygraph pilot: highlight ring #password tone=info label="Password"
4
+ [11:12:45.225] waygraph pilot: highlight ring #no-such-element-waygraph tone=danger label="Gone"
5
+ [11:12:48.220] waygraph pilot: highlight ring #login-button tone=success label="Login"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.38",
3
+ "version": "0.15.39",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",