waygraph 0.15.35 → 0.15.36

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.
@@ -0,0 +1,39 @@
1
+ import type { Checkpoint } from "../types.js";
2
+ import type { Flow } from "./flow.js";
3
+ import type { RunGraphOptions } from "./run-graph.js";
4
+ import type { BrowserContext } from "@playwright/test";
5
+ /** One branch reachable from `flow`, possibly several `.branch()` levels deep. */
6
+ export interface BranchEntry {
7
+ /** `"Away"`, or `"Away > Far"` for a nested branch - the route tags that lead here, in order. */
8
+ path: string;
9
+ flow: Flow<any>;
10
+ }
11
+ /** This Flow's own immediate `.branch()` routes, or `undefined` if it wasn't built by `.branch()`. */
12
+ export declare function branchRoutes(flow: Flow<any>): ReadonlyMap<string, Flow<any> | null> | undefined;
13
+ /**
14
+ * Every branch Flow reachable from `flow`, at any depth, deduped by object identity (the same
15
+ * route Flow reused under two tags is only listed once). Doesn't include `flow` itself - only its
16
+ * `.branch()` continuations.
17
+ */
18
+ export declare function collectBranchFlows(flow: Flow<any>): BranchEntry[];
19
+ /** Why a branch was skipped instead of run. */
20
+ export type BranchSkipReason = "first Block is not nav/page - this branch needs page state a live run would have reached through its prefix, not its own blocks";
21
+ export interface BranchRunResult {
22
+ path: string;
23
+ status: "ok" | "failed" | "skipped";
24
+ result?: Checkpoint<string>;
25
+ error?: string;
26
+ reason?: BranchSkipReason;
27
+ }
28
+ /**
29
+ * Runs every independently-enterable branch of `flow` (one whose own first Block navigates), each
30
+ * with a fresh `MemPage` seeded via {@link seedMemStub} and a fresh page. Branches that assume
31
+ * prior page state (first Block isn't nav/page) are reported as `"skipped"`, not silently run into
32
+ * a confusing failure - see this file's own header for why that's a real, unavoidable limit, not a
33
+ * gap to code around.
34
+ * @example
35
+ * for (const r of await runBranchRegression(loginFlow, context)) {
36
+ * console.log(r.path, r.status, r.error ?? r.reason ?? "");
37
+ * }
38
+ */
39
+ export declare function runBranchRegression(flow: Flow<any>, context: BrowserContext, options?: RunGraphOptions): Promise<BranchRunResult[]>;
@@ -0,0 +1,72 @@
1
+ import { MemPage } from "../mem-page.js";
2
+ import { seedMemStub } from "../mem-stub.js";
3
+ /** This Flow's own immediate `.branch()` routes, or `undefined` if it wasn't built by `.branch()`. */
4
+ export function branchRoutes(flow) {
5
+ const routes = flow.__wgBranchRoutes;
6
+ return routes ? new Map(Object.entries(routes)) : undefined;
7
+ }
8
+ /**
9
+ * Every branch Flow reachable from `flow`, at any depth, deduped by object identity (the same
10
+ * route Flow reused under two tags is only listed once). Doesn't include `flow` itself - only its
11
+ * `.branch()` continuations.
12
+ */
13
+ export function collectBranchFlows(flow) {
14
+ const out = [];
15
+ const seen = new Set();
16
+ const walk = (f, prefix) => {
17
+ const routes = branchRoutes(f);
18
+ if (!routes)
19
+ return;
20
+ for (const [tag, route] of routes) {
21
+ if (!route || seen.has(route))
22
+ continue;
23
+ seen.add(route);
24
+ const path = prefix ? `${prefix} > ${tag}` : tag;
25
+ out.push({ path, flow: route });
26
+ walk(route, path);
27
+ }
28
+ };
29
+ walk(flow, "");
30
+ return out;
31
+ }
32
+ /**
33
+ * Runs every independently-enterable branch of `flow` (one whose own first Block navigates), each
34
+ * with a fresh `MemPage` seeded via {@link seedMemStub} and a fresh page. Branches that assume
35
+ * prior page state (first Block isn't nav/page) are reported as `"skipped"`, not silently run into
36
+ * a confusing failure - see this file's own header for why that's a real, unavoidable limit, not a
37
+ * gap to code around.
38
+ * @example
39
+ * for (const r of await runBranchRegression(loginFlow, context)) {
40
+ * console.log(r.path, r.status, r.error ?? r.reason ?? "");
41
+ * }
42
+ */
43
+ export async function runBranchRegression(flow, context, options) {
44
+ const entries = collectBranchFlows(flow);
45
+ const results = [];
46
+ for (const entry of entries) {
47
+ const first = entry.flow.blocks()[0]?.block;
48
+ const kind = first?.__waygraphKind;
49
+ if (kind !== "nav" && kind !== "page") {
50
+ results.push({
51
+ path: entry.path,
52
+ status: "skipped",
53
+ reason: "first Block is not nav/page - this branch needs page state a live run would have reached through its prefix, not its own blocks",
54
+ });
55
+ continue;
56
+ }
57
+ const mem = new MemPage();
58
+ seedMemStub(mem, entry.flow);
59
+ try {
60
+ const result = await entry.flow.run(context, mem, { ...options, closeOnFinish: true });
61
+ results.push({ path: entry.path, status: "ok", result: result });
62
+ }
63
+ catch (err) {
64
+ results.push({
65
+ path: entry.path,
66
+ status: "failed",
67
+ error: err instanceof Error ? err.message : String(err),
68
+ });
69
+ }
70
+ }
71
+ return results;
72
+ }
@@ -134,7 +134,7 @@ function buildBranchedFlow(before, routes) {
134
134
  }
135
135
  return branchFlow.run(context, mem, { ...options, page: first.page, closeOnFinish });
136
136
  });
137
- return {
137
+ const flow = {
138
138
  resetSession: before.resetSession,
139
139
  ...(before.title !== undefined ? { title: before.title } : {}),
140
140
  ...(before.expectedFailureReason !== undefined ? { expectedFailureReason: before.expectedFailureReason } : {}),
@@ -157,6 +157,10 @@ function buildBranchedFlow(before, routes) {
157
157
  return buildBranchedFlow(before.modBlockVerify(block, nameOrIndex, newCheck), routes);
158
158
  },
159
159
  };
160
+ // Non-enumerable so it doesn't show up on a spread/JSON.stringify of the Flow - read by
161
+ // branchRoutes()/collectBranchFlows() (branch-regression.ts), not part of the public Flow shape.
162
+ Object.defineProperty(flow, "__wgBranchRoutes", { value: routes, enumerable: false, configurable: true });
163
+ return flow;
160
164
  }
161
165
  /**
162
166
  * Fluent builder over {@link Engine.defineFlow} - see `map()`'s own doc
package/dist/engine.d.ts CHANGED
@@ -9,3 +9,4 @@ export * from "./engine/blocks/method.js";
9
9
  export * from "./engine/blocks/page.js";
10
10
  export * from "./engine/blocks/effect.js";
11
11
  export * from "./engine/locate.js";
12
+ export * from "./engine/branch-regression.js";
package/dist/engine.js CHANGED
@@ -10,3 +10,4 @@ export * from "./engine/blocks/method.js";
10
10
  export * from "./engine/blocks/page.js";
11
11
  export * from "./engine/blocks/effect.js";
12
12
  export * from "./engine/locate.js";
13
+ export * from "./engine/branch-regression.js";
package/dist/index.d.ts CHANGED
@@ -3,7 +3,8 @@ export { connect, checkpoint } from "./types.js";
3
3
  export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
4
4
  export { registerMemStub, seedMemStub, getMemStub } from "./mem-stub.js";
5
5
  export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
6
- export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
6
+ export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, branchRoutes, collectBranchFlows, runBranchRegression, } from "./engine.js";
7
+ export type { BranchEntry, BranchRunResult, BranchSkipReason } from "./engine/branch-regression.js";
7
8
  export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
8
9
  export type { WaygraphHighlightStub, WaygraphHighlightFixture, WaygraphSlide, WaygraphTodoItem, WaygraphTodoInput, WaygraphTodoGroup, WaygraphTodoGroupInput, WaygraphTodosOpts, TodoDockUiOpts, BannerPos, BannerUiOpts, TodoDockUiResolved, TodoDockState, TodoListStyle, FixtureDurationFields, HighlightStubPhase, HighlightStubPhaseName, HighlightFixtureMap, ResolvedHighlight, WaygraphHighlight, HighlightTone, HighlightSize, HighlightWeight, HighlightStyleDefaults, DemoPace, DemoPaceName, StubCtx, StubLifecycleFn, StubPhaseResult, StubPhaseFixtures, DevicePreset, DeviceViewport, DeviceState, DeviceOrientation, } from "./highlights.js";
9
10
  export type { Flow, EngineConfig, ComposedBlock, FastForwardComposedBlock, RunGraphOptions, BlockInfo, NavBlock, NavBlockOptions, NavClickBlock, NavClickBlockOptions, MethodBlock, ActionBlock, AssertBlock, AssertBlockOptions, PageBlock, PageBlockOptions, PageMethodEntry, EffectBlock, MemEffectBlock, MemNavBlock, Layout, LayoutOptions, MapBuilderOptions, } from "./engine.js";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ export { connect, checkpoint } from "./types.js";
2
2
  export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
3
3
  export { registerMemStub, seedMemStub, getMemStub } from "./mem-stub.js";
4
4
  export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
5
- export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
5
+ export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, branchRoutes, collectBranchFlows, runBranchRegression, } from "./engine.js";
6
6
  export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
7
7
  export { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./graph.js";
8
8
  export { isFileSelectToken, parseBlocksSelect, matchBlocksSelect, globToRegExp, } from "./blocks-select.js";
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.35",
3
+ "version": "0.15.36",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",