waygraph 0.15.52 → 0.15.54
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 +8 -1
- package/dist/analysis/graph.d.ts +3 -0
- package/dist/analysis/map-check.d.ts +3 -2
- package/dist/auto-session/helpers.d.ts +10 -0
- package/dist/blocks-select.d.ts +3 -0
- package/dist/blocks-select.js +2 -0
- package/dist/cli/flags.js +3 -1
- package/dist/cli/usage.js +4 -1
- package/dist/cli.js +4 -1
- package/dist/commands/agent-dive-scaffold.d.ts +0 -20
- package/dist/commands/agent-dive-scaffold.js +3 -3
- package/dist/commands/init.js +1 -1
- package/dist/commands/upgrade.d.ts +1 -1
- package/dist/commands/upgrade.js +7 -1
- package/dist/config.d.ts +55 -19
- package/dist/config.js +55 -13
- package/dist/core/block.d.ts +7 -2
- package/dist/core/block.js +7 -3
- package/dist/core/blocks/api.d.ts +1 -0
- package/dist/core/blocks/method.d.ts +2 -0
- package/dist/core/blocks/method.js +1 -0
- package/dist/core/blocks/nav.d.ts +1 -0
- package/dist/core/blocks/page.d.ts +1 -0
- package/dist/core/branch-regression.d.ts +1 -0
- package/dist/core/compose.d.ts +1 -0
- package/dist/core/engine.d.ts +2 -0
- package/dist/core/engine.js +3 -1
- package/dist/core/flow.d.ts +11 -0
- package/dist/core/flow.js +32 -8
- package/dist/core/map-builder.d.ts +34 -1
- package/dist/core/map-builder.js +42 -4
- package/dist/core/run-graph.d.ts +2 -0
- package/dist/core/run-graph.js +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/extensions.d.ts +1 -0
- package/dist/extensions.js +1 -0
- package/dist/highlights/demo-pace.d.ts +4 -1
- package/dist/highlights/demo-pace.js +28 -3
- package/dist/highlights/device.d.ts +2 -0
- package/dist/highlights/device.js +2 -0
- package/dist/highlights/types.d.ts +6 -0
- package/dist/index.d.ts +2 -2
- package/dist/pilot-overlay/action-ring.d.ts +0 -9
- package/dist/pilot-overlay/action-ring.js +1 -1
- package/dist/pilot-overlay/panel.d.ts +2 -1
- package/dist/runner/interaction-patch.js +32 -1
- package/dist/runner/main.js +5 -2
- package/dist/runner/step-mode.js +10 -4
- package/dist/session/auto-explore-run.js +6 -0
- package/dist/session/auto-explore.d.ts +2 -1
- package/dist/session/auto-session-ipc.d.ts +1 -2
- package/dist/session/auto-session-ipc.js +1 -1
- package/dist/session/block-inject.d.ts +0 -13
- package/dist/session/block-inject.js +3 -3
- package/dist/session/overlay-beacon.d.ts +7 -0
- package/dist/session/overlay-beacon.js +5 -0
- package/dist/session/pilot.d.ts +1 -2
- package/dist/session/pilot.js +1 -2
- package/dist/traverse/coverage.d.ts +4 -4
- package/dist/traverse/coverage.js +4 -1
- package/dist/traverse/lease.d.ts +1 -0
- package/dist/traverse/lease.js +1 -0
- package/dist/traverse/run.d.ts +3 -0
- package/dist/types.d.ts +1 -1
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +1 -1
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +2 -2
- package/examples/saucedemo/README.md +11 -12
- package/examples/saucedemo/config/waygraph.config.ts +17 -0
- package/examples/saucedemo/docs/CONVENTION.md +1 -2
- package/examples/saucedemo/docs/HELPERS.md +1 -1
- package/examples/saucedemo/package-lock.json +10 -3
- package/examples/saucedemo/package.json +12 -29
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +0 -49
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +22 -25
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +0 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +38 -96
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +1 -26
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +1 -45
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +14 -77
- package/examples/saucedemo/src/flows/api-demo.flow.ts +17 -11
- package/examples/saucedemo/src/flows/cart-bulk.flow.ts +19 -14
- package/examples/saucedemo/src/flows/cart-continue.flow.ts +10 -8
- package/examples/saucedemo/src/flows/cart-mem.flow.ts +7 -7
- package/examples/saucedemo/src/flows/catalog-logout.flow.ts +13 -8
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +26 -48
- package/examples/saucedemo/src/flows/checkout.flow.ts +70 -86
- package/examples/saucedemo/src/flows/device-showcase.flow.ts +24 -25
- package/examples/saucedemo/src/flows/login.flow.ts +11 -18
- package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +9 -20
- package/examples/saucedemo/src/flows/shop.flow.ts +15 -20
- package/examples/saucedemo/src/flows/smoke.flow.ts +12 -27
- package/examples/saucedemo/src/flows/stub-on-error.flow.ts +24 -43
- package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +26 -34
- package/examples/saucedemo/src/states/checkout.mem-stubs.ts +11 -0
- package/examples/saucedemo/src/stubs/device-showcase.ts +193 -0
- package/examples/saucedemo/src/stubs/login.ts +37 -0
- package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +7 -9
- package/examples/saucedemo/tests/submit-login-branch.spec.ts +18 -5
- package/package.json +12 -5
- package/templates/quickstart/README.md +4 -7
- package/templates/quickstart/config/waygraph.config.ts +17 -0
- package/templates/quickstart/docs/CONVENTION.md +1 -2
- package/templates/quickstart/docs/HELPERS.md +1 -1
- package/templates/quickstart/package.json +14 -14
- package/templates/quickstart/src/blocks/SITE-MAP.md +14 -3
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +0 -49
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +22 -25
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +0 -6
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +38 -96
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +1 -26
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +1 -45
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +14 -77
- package/templates/quickstart/src/flows/api-demo.flow.ts +43 -0
- package/templates/quickstart/src/flows/cart-bulk.flow.ts +19 -14
- package/templates/quickstart/src/flows/cart-continue.flow.ts +10 -8
- package/templates/quickstart/src/flows/cart-mem.flow.ts +7 -7
- package/templates/quickstart/src/flows/catalog-logout.flow.ts +13 -8
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +26 -48
- package/templates/quickstart/src/flows/checkout.flow.ts +70 -63
- package/templates/quickstart/src/flows/device-showcase.flow.ts +24 -25
- package/templates/quickstart/src/flows/login.flow.ts +11 -18
- package/templates/quickstart/src/flows/mem-stub-demo.flow.ts +12 -0
- package/templates/quickstart/src/flows/shop.flow.ts +15 -20
- package/templates/quickstart/src/flows/smoke.flow.ts +12 -27
- package/templates/quickstart/src/flows/stub-on-error.flow.ts +31 -0
- package/templates/quickstart/src/flows/viewer-blocked.flow.ts +26 -34
- package/templates/quickstart/src/states/checkout.mem-stubs.ts +11 -0
- package/templates/quickstart/src/stubs/device-showcase.ts +193 -0
- package/templates/quickstart/src/stubs/login.ts +37 -0
- package/templates/quickstart/tests/chain-flow.spec.ts +7 -10
- package/templates/scaffold/README.md +1 -1
- package/templates/scaffold/STRUCTURE.md +5 -2
- package/templates/scaffold/config/waygraph.config.ts +24 -5
- package/templates/scaffold/package.json +6 -6
- package/templates/scaffold/src/flows/(external)/hoppscotch/auth.flow.ts +36 -0
- package/templates/scaffold/src/flows/(external)/hoppscotch/get.flow.ts +24 -0
- package/templates/scaffold/src/flows/(external)/hoppscotch/post.flow.ts +34 -0
- package/templates/scaffold/src/flows/(user-stories)/email-verification.flow.ts +47 -0
- package/templates/scaffold/src/flows/README.md +35 -14
- package/templates/scaffold/src/flows/{shop.flow.ts → home/cart.flow.ts} +18 -17
- package/templates/scaffold/src/flows/{example.flow.ts → home/hello.flow.ts} +12 -13
- package/templates/scaffold/tests/example.spec.ts +5 -5
- package/templates/scaffold/tests/hoppscotch.spec.ts +3 -3
- package/templates/scaffold/tests/mail-verify.spec.ts +7 -7
- package/templates/skills/waygraph-convention.skill.md +14 -6
- package/examples/saucedemo/playwright.config.ts +0 -19
- package/examples/saucedemo/scripts/drive-auto-cli.mjs +0 -93
- package/examples/saucedemo/scripts/prove-add-to-cart-menu.mjs +0 -126
- package/examples/saucedemo/scripts/prove-auto-graph.mjs +0 -92
- package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +0 -63
- package/templates/quickstart/playwright.config.ts +0 -14
- package/templates/quickstart/scripts/drive-auto-cli.mjs +0 -93
- package/templates/scaffold/src/flows/hoppscotch-auth.flow.ts +0 -35
- package/templates/scaffold/src/flows/hoppscotch-get.flow.ts +0 -23
- package/templates/scaffold/src/flows/hoppscotch-post.flow.ts +0 -33
- package/templates/scaffold/src/flows/mail-verify.flow.ts +0 -46
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible
|
|
|
9
9
|
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, defineApiBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, withDialog, chainFlow, defineLayout, map, MapBuilder, branchRoutes, collectBranchFlows, runBranchRegression, } from "./core.js";
|
|
10
10
|
export type { BranchEntry, BranchRunResult, RunBranchRegressionOptions } from "./core/branch-regression.js";
|
|
11
11
|
export type { ApiBlockOptions, ApiCallResult } from "./core/blocks/api.js";
|
|
12
|
-
export type { MapStepOpts } from "./core/map-builder.js";
|
|
12
|
+
export type { MapStepOpts, MapFlowOpts } from "./core/map-builder.js";
|
|
13
13
|
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";
|
|
14
14
|
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";
|
|
15
15
|
export type { Flow, FlowOptions, EngineConfig, ComposedBlock, FastForwardComposedBlock, RunGraphOptions, BlockInfo, NavBlock, NavBlockOptions, NavClickBlock, NavClickBlockOptions, MethodBlock, ActionBlock, AssertBlock, AssertBlockOptions, PageBlock, PageBlockOptions, PageMethodEntry, EffectBlock, MemEffectBlock, MemNavBlock, Layout, LayoutOptions, MapBuilderOptions, } from "./core.js";
|
|
@@ -30,7 +30,7 @@ export type { AutoSessionInit, SessionSnapshot, SessionSnapshotEdge, SessionSnap
|
|
|
30
30
|
export { pilotStart } from "./session/pilot.js";
|
|
31
31
|
export type { PilotStartResult } from "./session/pilot.js";
|
|
32
32
|
export { defineConfig, resolveBaseUrl } from "./config.js";
|
|
33
|
-
export type { WaygraphConfig, ConfigContext } from "./config.js";
|
|
33
|
+
export type { WaygraphConfig, ConfigContext, VideoSettings, RunSettings, DemoSettings } from "./config.js";
|
|
34
34
|
export { withWebServer } from "./webserver.js";
|
|
35
35
|
export { chromiumExecutablePath } from "./browser.js";
|
|
36
36
|
export { resolveExtension, KNOWN_EXTENSIONS } from "./extensions.js";
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import type { Page } from "@playwright/test";
|
|
2
|
-
type Box = {
|
|
3
|
-
x: number;
|
|
4
|
-
y: number;
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
};
|
|
8
|
-
/** Paint the gray "auto" ring (Playwright is about to act here) at a viewport rectangle. */
|
|
9
|
-
export declare function showPilotRect(page: Page, box: Box, label: string, tone?: string): Promise<void>;
|
|
10
2
|
/**
|
|
11
3
|
* Every Playwright instruction a Block runs against this session's page gets a gray (auto) ring + robot
|
|
12
4
|
* label first, so a human watching a pilot window sees WHAT is being driven. `dwellMs` holds the ring
|
|
13
5
|
* long enough to read before the action fires (0 for headless).
|
|
14
6
|
*/
|
|
15
7
|
export declare function instrumentPilotActions(page: Page, dwellMs: number): void;
|
|
16
|
-
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ensureInstalled } from "./shell.js";
|
|
2
2
|
/** Paint the gray "auto" ring (Playwright is about to act here) at a viewport rectangle. */
|
|
3
|
-
|
|
3
|
+
async function showPilotRect(page, box, label, tone = "auto") {
|
|
4
4
|
await ensureInstalled(page);
|
|
5
5
|
await page
|
|
6
6
|
.evaluate(({ box, label, tone }) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SessionSnapshot } from "../auto-session.js";
|
|
2
2
|
import type { Page } from "@playwright/test";
|
|
3
3
|
/** Minimal shape needed to render the graph tree - matches WaygraphGraph. */
|
|
4
|
-
|
|
4
|
+
interface PilotOverlayGraph {
|
|
5
5
|
nodes: readonly {
|
|
6
6
|
checkpoint: string;
|
|
7
7
|
}[];
|
|
@@ -32,3 +32,4 @@ export interface PilotOverlayInfo {
|
|
|
32
32
|
* operation over.
|
|
33
33
|
*/
|
|
34
34
|
export declare function updatePilotOverlay(page: Page, info: PilotOverlayInfo): Promise<void>;
|
|
35
|
+
export {};
|
|
@@ -21,7 +21,36 @@ export function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stu
|
|
|
21
21
|
// (shorter Next/autoplay gates) and must NOT skip theater, or the whole demo
|
|
22
22
|
// looks like plain waygraph run.
|
|
23
23
|
const skipTheater = () => !!pacing.skipTheater;
|
|
24
|
-
|
|
24
|
+
// `slowMo` here is the demo's own beat: ms to rest after each action (once per call, never per keystroke). The browser
|
|
25
|
+
// itself is launched with slowMo 0 in step mode, so a step whose pace is blitz really does run at full speed.
|
|
26
|
+
const beat = () => (skipTheater() ? 0 : slowMo || 0);
|
|
27
|
+
const pause = (ms) => (ms > 0 ? new Promise((res) => setTimeout(res, ms)) : undefined);
|
|
28
|
+
// Per-character typing delay (WAYGRAPH_TYPING_MS, default 30). 0 for blitz steps.
|
|
29
|
+
const typingMs = () => {
|
|
30
|
+
if (skipTheater()) return 0;
|
|
31
|
+
const n = Number(process.env.WAYGRAPH_TYPING_MS);
|
|
32
|
+
return process.env.WAYGRAPH_TYPING_MS !== undefined && Number.isFinite(n) && n >= 0 ? n : 30;
|
|
33
|
+
};
|
|
34
|
+
const typeDelay = typingMs;
|
|
35
|
+
const keyboard = page.keyboard;
|
|
36
|
+
if (!keyboard.__wgBeatPatched) {
|
|
37
|
+
keyboard.__wgBeatPatched = true;
|
|
38
|
+
const originalType = keyboard.type.bind(keyboard);
|
|
39
|
+
keyboard.type = async (text, options) => {
|
|
40
|
+
await originalType(text, { delay: typingMs(), ...(options || {}) });
|
|
41
|
+
await pause(beat());
|
|
42
|
+
};
|
|
43
|
+
const originalPress = keyboard.press.bind(keyboard);
|
|
44
|
+
keyboard.press = async (key, options) => {
|
|
45
|
+
await originalPress(key, options);
|
|
46
|
+
await pause(beat());
|
|
47
|
+
};
|
|
48
|
+
const originalInsertText = keyboard.insertText.bind(keyboard);
|
|
49
|
+
keyboard.insertText = async (text) => {
|
|
50
|
+
await originalInsertText(text);
|
|
51
|
+
await pause(beat());
|
|
52
|
+
};
|
|
53
|
+
}
|
|
25
54
|
// Click is a single action, not per-character, so it doesn't compound
|
|
26
55
|
// the same way - but slowMo still adds its own pause around the actual
|
|
27
56
|
// click, so trim our own explicit "pop" pauses when it's already active
|
|
@@ -155,6 +184,7 @@ export function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stu
|
|
|
155
184
|
// it - it was sticking around through the whole rest of the step.
|
|
156
185
|
await hideRing(page);
|
|
157
186
|
await restoreTheaterAfterNavigation(page, todoDockRef, deviceRef, stubBeforeRef);
|
|
187
|
+
await pause(beat());
|
|
158
188
|
return result;
|
|
159
189
|
};
|
|
160
190
|
}
|
|
@@ -285,6 +315,7 @@ export function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stu
|
|
|
285
315
|
await hideRing(page);
|
|
286
316
|
// Full document navigation drops #wg-todo-dock + rings; restore carry.
|
|
287
317
|
await restoreTheaterAfterNavigation(page, todoDockRef, deviceRef, stubBeforeRef);
|
|
318
|
+
await pause(beat());
|
|
288
319
|
return result;
|
|
289
320
|
};
|
|
290
321
|
}
|
package/dist/runner/main.js
CHANGED
|
@@ -231,6 +231,9 @@ async function runMain() {
|
|
|
231
231
|
: "waygraph demo: opaque FFCompose in flow -> Playwright slowMo=0 (blitz); set WAYGRAPH_SLOWMO to override",
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
|
+
// Step (demo) mode: slowMo is waygraph's own beat after each action, not Playwright's per-operation slowMo, so a
|
|
235
|
+
// step's pace can remove it and typing is not taxed per keystroke. The browser launches at 0.
|
|
236
|
+
const launchSlowMo = step ? 0 : slowMo;
|
|
234
237
|
const baseURL = process.env.WAYGRAPH_BASE_URL;
|
|
235
238
|
const title = process.env.WAYGRAPH_TITLE;
|
|
236
239
|
// Comma-separated Block names (their real .name, e.g. "login") that
|
|
@@ -263,7 +266,7 @@ async function runMain() {
|
|
|
263
266
|
const fixedVideoViewport = videoDir
|
|
264
267
|
? (videoViewportParsed ?? (step ? DEFAULT_VIDEO_VIEWPORT : DEFAULT_RUN_VIDEO_VIEWPORT))
|
|
265
268
|
: null;
|
|
266
|
-
const engine = new Engine({ headless: !headed, slowMo });
|
|
269
|
+
const engine = new Engine({ headless: !headed, slowMo: launchSlowMo });
|
|
267
270
|
let result;
|
|
268
271
|
// Non-interactive execution (no --step) runs the whole chain as one
|
|
269
272
|
// composed flow with no per-block loop of its own to defer seeding
|
|
@@ -312,7 +315,7 @@ async function runMain() {
|
|
|
312
315
|
launcher: chromium,
|
|
313
316
|
launch: {
|
|
314
317
|
headless: !headed,
|
|
315
|
-
slowMo,
|
|
318
|
+
slowMo: launchSlowMo,
|
|
316
319
|
args: step || fixedVideoViewport ? ["--start-maximized"] : [],
|
|
317
320
|
...(executablePath ? { executablePath } : {}),
|
|
318
321
|
},
|
package/dist/runner/step-mode.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Moved verbatim from the former CHAIN_RUNNER_SCRIPT template string in cli.ts (see src/ARCHITECTURE.md).
|
|
2
2
|
// Runs inside the target project's own waygraph copy - keep it dependency-light and self-contained.
|
|
3
3
|
import { instrumentInteractionHighlighting } from "./interaction-patch.js";
|
|
4
|
-
import { applyHighlightStyleDefaults, demoPaceGateMs, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, formatHighlightCaption, hasAuthoredStubAfter, resolveSlides, resolveStepDemoPace, resolveTodoDockUi, runStubPhase } from "../highlights.js";
|
|
4
|
+
import { applyHighlightStyleDefaults, normalizeDemoPace, demoPaceGateMs, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, formatHighlightCaption, hasAuthoredStubAfter, resolveSlides, resolveStepDemoPace, resolveTodoDockUi, runStubPhase } from "../highlights.js";
|
|
5
5
|
import { markStepRunning, resetPageState, teardownOverlay } from "./teardown.js";
|
|
6
6
|
import { demoLog, logStubPhaseFixtures, logTodoDockFull, paceSpeakFields, summarizeDevice } from "./demo-log.js";
|
|
7
7
|
import { extractVerifyHighlights, presentFailPanel, renderAfterStep, renderBeforeStep } from "./step-panels.js";
|
|
@@ -26,6 +26,8 @@ export async function runStepMode(engine, start, end, context, page, mem, resolv
|
|
|
26
26
|
const demoFast = process.env.WAYGRAPH_DEMO_FAST === "1";
|
|
27
27
|
const stepperMode = process.env.WAYGRAPH_STEPPER === "full" ? "full" : "carousel";
|
|
28
28
|
const pacing = { gatesFast: demoFast, gatesSlow: false, skipTheater: false, demoPace: "normal" };
|
|
29
|
+
// A title set by a stub (`ctx.title`) names the flow from that step on, until another stub sets a new one.
|
|
30
|
+
let stickyTitle;
|
|
29
31
|
const stubBeforeRef = { current: [] };
|
|
30
32
|
/** Live todo dock for Method fill/click advance (same carry as stage.state.lastTodoDock). */
|
|
31
33
|
const todoDockRef = { current: undefined };
|
|
@@ -213,15 +215,18 @@ export async function runStepMode(engine, start, end, context, page, mem, resolv
|
|
|
213
215
|
}
|
|
214
216
|
// Episode pace: block > flow > CLI --fast (only when no authored pace).
|
|
215
217
|
// Authoring wins: withDemoPace("slow"|2|4500) keeps slow dwell even under --fast.
|
|
218
|
+
// `demo.pace` in the config (WAYGRAPH_DEMO_PACE) is the default for flows and steps that set none.
|
|
219
|
+
const defaultPace = process.env.WAYGRAPH_DEMO_PACE ? normalizeDemoPace(process.env.WAYGRAPH_DEMO_PACE) : undefined;
|
|
216
220
|
const stepPace = resolveStepDemoPace({
|
|
217
221
|
blockPace: r.block.demoPace,
|
|
218
|
-
flowPace: r.demoPace,
|
|
222
|
+
flowPace: r.demoPace ?? defaultPace,
|
|
219
223
|
fastForward: !!r.block.fastForward,
|
|
220
224
|
wasFastForward: !!r.wasFastForward,
|
|
221
225
|
});
|
|
222
226
|
const authoredPace =
|
|
223
227
|
(r.block.demoPace != null && r.block.demoPace !== "") ||
|
|
224
|
-
(r.demoPace != null && r.demoPace !== "")
|
|
228
|
+
(r.demoPace != null && r.demoPace !== "") ||
|
|
229
|
+
defaultPace != null;
|
|
225
230
|
const cliFast = demoFast || fastBlockNames.has(r.block.name);
|
|
226
231
|
pacing.demoPace =
|
|
227
232
|
stepPace === "normal" && cliFast && !authoredPace
|
|
@@ -266,8 +271,9 @@ export async function runStepMode(engine, start, end, context, page, mem, resolv
|
|
|
266
271
|
(stage.state.lastTodoDock && stage.state.lastTodoDock.groups[0] && stage.state.lastTodoDock.groups[0].items) ||
|
|
267
272
|
stubBeforePhase.todos ||
|
|
268
273
|
[];
|
|
274
|
+
if (stubBeforePhase.title && String(stubBeforePhase.title).trim()) stickyTitle = String(stubBeforePhase.title).trim();
|
|
269
275
|
const overlayTitle =
|
|
270
|
-
|
|
276
|
+
stickyTitle ||
|
|
271
277
|
(r.episodeTitle && String(r.episodeTitle).trim()) ||
|
|
272
278
|
title ||
|
|
273
279
|
"waygraph demo";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getMemStub } from "../mem-stub.js";
|
|
1
2
|
import { createInterface } from "node:readline/promises";
|
|
2
3
|
import { ensureShadowRoot } from "../ui/shadow.js";
|
|
3
4
|
import { stdin as input, stdout as output } from "node:process";
|
|
@@ -115,6 +116,11 @@ export function seedDefaultMem(library, mem) {
|
|
|
115
116
|
mem.set(k, envParsed[k.name]);
|
|
116
117
|
continue;
|
|
117
118
|
}
|
|
119
|
+
const stub = getMemStub(k);
|
|
120
|
+
if (stub) {
|
|
121
|
+
mem.set(k, stub());
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
118
124
|
const def = defaultMemValueForKey(k.name);
|
|
119
125
|
if (def !== undefined)
|
|
120
126
|
mem.set(k, def);
|
|
@@ -24,7 +24,7 @@ export interface ExploreEdge extends WaygraphEdge {
|
|
|
24
24
|
label?: string;
|
|
25
25
|
instanceOption?: WaygraphInstanceOption;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
interface ExploreSection {
|
|
28
28
|
title: string;
|
|
29
29
|
edges: ExploreEdge[];
|
|
30
30
|
}
|
|
@@ -55,3 +55,4 @@ export declare function buildExploreContext(projectDir: string, opts?: ExploreCo
|
|
|
55
55
|
graph: WaygraphGraph;
|
|
56
56
|
library: Awaited<ReturnType<typeof loadBlockLibrary>>;
|
|
57
57
|
}>;
|
|
58
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AutoSession, type AutoSessionInit, type SessionSnapshot, type InspectDomOptions, type DomSnapshot, type TraceStep, type ApplyPathResult, type ConsoleLogEntry, type StorageSnapshot, type StubFileKind } from "../auto-session.js";
|
|
2
2
|
import type { PilotHighlightFixtures } from "../pilot-overlay.js";
|
|
3
|
-
export type { PilotHighlightFixtures
|
|
3
|
+
export type { PilotHighlightFixtures } from "../pilot-overlay.js";
|
|
4
4
|
export interface SessionMeta {
|
|
5
5
|
sessionId: string;
|
|
6
6
|
socketPath: string;
|
|
@@ -54,7 +54,6 @@ export type HighlightResponse = {
|
|
|
54
54
|
ok: false;
|
|
55
55
|
error: string;
|
|
56
56
|
};
|
|
57
|
-
export declare function readSessionMeta(projectDir: string, sessionId: string): SessionMeta | null;
|
|
58
57
|
/**
|
|
59
58
|
* Resolve session metadata from a project hint (cwd) or the global registry.
|
|
60
59
|
* Fixes "session unreachable" when the agent calls status/send from a different
|
|
@@ -58,7 +58,7 @@ function logPathFor(projectDir, sessionId) {
|
|
|
58
58
|
function generateSessionId() {
|
|
59
59
|
return randomBytes(4).toString("hex");
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
function readSessionMeta(projectDir, sessionId) {
|
|
62
62
|
const p = metaPath(projectDir, sessionId);
|
|
63
63
|
if (!existsSync(p))
|
|
64
64
|
return null;
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This package's own installed root (contains `templates/`/`examples/`, sibling to `dist/`) -
|
|
3
|
-
* this file compiles to `dist/session/block-inject.js`, two levels down, not one. Same class of
|
|
4
|
-
* bug as `cli/util.ts`'s own `packageRoot()` (see its comment) - self-inflicted here by moving
|
|
5
|
-
* this file into `src/session/` without updating the path math to match the new depth.
|
|
6
|
-
*/
|
|
7
|
-
export declare function packageRoot(): string;
|
|
8
|
-
/** Human label for an injected root (used in merged `file` paths). */
|
|
9
|
-
export declare function injectLabel(root: string): string;
|
|
10
1
|
/**
|
|
11
2
|
* Display path for a Block discovered under an inject root (not the host cwd).
|
|
12
3
|
* Primary project files stay relative as-is; injected ones are tagged `@label/...`.
|
|
13
4
|
*/
|
|
14
5
|
export declare function injectTaggedFile(hostDir: string, root: string, relFile: string): string;
|
|
15
|
-
/**
|
|
16
|
-
* Resolve one `--inject` token to an absolute directory (preset name or path).
|
|
17
|
-
*/
|
|
18
|
-
export declare function resolveInjectRoot(token: string, cwd?: string): string;
|
|
19
6
|
export declare function resolveInjectRoots(tokens: string[], cwd?: string): string[];
|
|
20
7
|
/** Roots to scan: host project first, then each inject path (deduped). */
|
|
21
8
|
export declare function exploreRoots(projectDir: string, inject?: string[]): string[];
|
|
@@ -12,11 +12,11 @@ import { homedir } from "node:os";
|
|
|
12
12
|
* bug as `cli/util.ts`'s own `packageRoot()` (see its comment) - self-inflicted here by moving
|
|
13
13
|
* this file into `src/session/` without updating the path math to match the new depth.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
function packageRoot() {
|
|
16
16
|
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
17
17
|
}
|
|
18
18
|
/** Human label for an injected root (used in merged `file` paths). */
|
|
19
|
-
|
|
19
|
+
function injectLabel(root) {
|
|
20
20
|
return basename(root.replace(/\/$/, ""));
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
@@ -50,7 +50,7 @@ const PRESETS = {
|
|
|
50
50
|
/**
|
|
51
51
|
* Resolve one `--inject` token to an absolute directory (preset name or path).
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
function resolveInjectRoot(token, cwd = process.cwd()) {
|
|
54
54
|
const raw = token.trim();
|
|
55
55
|
if (!raw)
|
|
56
56
|
throw new Error("waygraph inject: empty --inject value");
|
|
@@ -10,11 +10,17 @@
|
|
|
10
10
|
* `assertWgOverlayReady(page)` (or WAYGRAPH_PROVE_EXIT=1) passes.
|
|
11
11
|
*/
|
|
12
12
|
import type { Page } from "@playwright/test";
|
|
13
|
+
/** Selector matching every element waygraph's overlay draws into a page. */
|
|
13
14
|
export declare const WG_UI_SEL = "[data-wg-ui=\"1\"]";
|
|
15
|
+
/** Selector of the overlay element that appears when the step panel is ready. */
|
|
14
16
|
export declare const WG_READY_PANEL_SEL = "[data-wg-modal=\"panel\"][data-wg-ready=\"1\"]";
|
|
17
|
+
/** Selector of the overlay element that appears when the auto panel is ready. */
|
|
15
18
|
export declare const WG_READY_AUTO_SEL = "[data-wg-modal=\"auto-panel\"][data-wg-ready=\"1\"]";
|
|
19
|
+
/** Selector of the overlay element that appears when the banner is ready. */
|
|
16
20
|
export declare const WG_READY_BANNER_SEL = "[data-wg-modal=\"banner\"][data-wg-ready=\"1\"]";
|
|
21
|
+
/** The kind of modal the overlay beacon reports. */
|
|
17
22
|
export type WgModalKind = "panel" | "banner" | "auto-panel";
|
|
23
|
+
/** One overlay element a session reports through its beacon. */
|
|
18
24
|
export type WgBeaconRow = {
|
|
19
25
|
id: string | null;
|
|
20
26
|
modal: string | null;
|
|
@@ -31,6 +37,7 @@ export type WgBeaconRow = {
|
|
|
31
37
|
};
|
|
32
38
|
/** Browser-side beacon reader (also installed as window.__wgOverlayBeacon). */
|
|
33
39
|
export declare function readWgOverlayBeaconInPage(): WgBeaconRow[];
|
|
40
|
+
/** Reads the overlay beacon from a page: what waygraph's own UI is showing. */
|
|
34
41
|
export declare function readWgOverlayBeacon(page: Page): Promise<WgBeaconRow[]>;
|
|
35
42
|
/**
|
|
36
43
|
* Hard gate: a blank / missing / opacity-0 modal fails.
|
|
@@ -9,9 +9,13 @@
|
|
|
9
9
|
* Agents: do not claim the stepper works unless
|
|
10
10
|
* `assertWgOverlayReady(page)` (or WAYGRAPH_PROVE_EXIT=1) passes.
|
|
11
11
|
*/
|
|
12
|
+
/** Selector matching every element waygraph's overlay draws into a page. */
|
|
12
13
|
export const WG_UI_SEL = '[data-wg-ui="1"]';
|
|
14
|
+
/** Selector of the overlay element that appears when the step panel is ready. */
|
|
13
15
|
export const WG_READY_PANEL_SEL = '[data-wg-modal="panel"][data-wg-ready="1"]';
|
|
16
|
+
/** Selector of the overlay element that appears when the auto panel is ready. */
|
|
14
17
|
export const WG_READY_AUTO_SEL = '[data-wg-modal="auto-panel"][data-wg-ready="1"]';
|
|
18
|
+
/** Selector of the overlay element that appears when the banner is ready. */
|
|
15
19
|
export const WG_READY_BANNER_SEL = '[data-wg-modal="banner"][data-wg-ready="1"]';
|
|
16
20
|
/** Browser-side beacon reader (also installed as window.__wgOverlayBeacon). */
|
|
17
21
|
export function readWgOverlayBeaconInPage() {
|
|
@@ -37,6 +41,7 @@ export function readWgOverlayBeaconInPage() {
|
|
|
37
41
|
};
|
|
38
42
|
});
|
|
39
43
|
}
|
|
44
|
+
/** Reads the overlay beacon from a page: what waygraph's own UI is showing. */
|
|
40
45
|
export async function readWgOverlayBeacon(page) {
|
|
41
46
|
return page.evaluate(() => {
|
|
42
47
|
const w = window;
|
package/dist/session/pilot.d.ts
CHANGED
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
* new execution primitive.
|
|
30
30
|
*/
|
|
31
31
|
import { type WaygraphGraph } from "../analysis/graph.js";
|
|
32
|
-
import { listBrowserSessions, type SessionMeta } from "./auto-session-ipc.js";
|
|
33
32
|
import { type BrowserStartInit } from "./browser.js";
|
|
34
33
|
import type { SessionSnapshot } from "../auto-session.js";
|
|
34
|
+
/** What `pilotStart` returns: the session id, socket path and first snapshot. */
|
|
35
35
|
export interface PilotStartResult {
|
|
36
36
|
sessionId: string;
|
|
37
37
|
socketPath: string;
|
|
@@ -51,4 +51,3 @@ export interface PilotStartResult {
|
|
|
51
51
|
export declare function pilotStart(init: BrowserStartInit): Promise<PilotStartResult>;
|
|
52
52
|
/** Reattach to an existing browser session — does not spawn a new browser. */
|
|
53
53
|
export declare function pilotAttach(projectDir: string, sessionId: string, inject?: string[]): Promise<PilotStartResult>;
|
|
54
|
-
export { listBrowserSessions, type SessionMeta };
|
package/dist/session/pilot.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* new execution primitive.
|
|
30
30
|
*/
|
|
31
31
|
import { discoverGraph } from "../analysis/graph.js";
|
|
32
|
-
import { requestSession,
|
|
32
|
+
import { requestSession, resolveSessionMeta, } from "./auto-session-ipc.js";
|
|
33
33
|
import { browserStart } from "./browser.js";
|
|
34
34
|
/**
|
|
35
35
|
* Starts a detached session and reads back its own graph + starting
|
|
@@ -77,4 +77,3 @@ export async function pilotAttach(projectDir, sessionId, inject) {
|
|
|
77
77
|
snapshot: status.snapshot,
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
-
export { listBrowserSessions };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** The edge-coverage report `traverse` writes: which graph edges were walked. */
|
|
1
2
|
export interface TraverseCoverageReport {
|
|
2
3
|
version: 1;
|
|
3
4
|
generatedAt: string;
|
|
@@ -27,10 +28,6 @@ export interface TraverseCoverageReport {
|
|
|
27
28
|
leaf?: string;
|
|
28
29
|
}>;
|
|
29
30
|
}
|
|
30
|
-
/** Static graph edge key = Block runtime name. */
|
|
31
|
-
export declare function edgeKeyFromGraphEdge(edge: {
|
|
32
|
-
block: string;
|
|
33
|
-
}): string;
|
|
34
31
|
/** Collect unique edge keys from a WaygraphGraph-like edges list. */
|
|
35
32
|
export declare function collectGraphEdgeKeys(edges: ReadonlyArray<{
|
|
36
33
|
block: string;
|
|
@@ -45,6 +42,7 @@ export declare function normalizeHitKey(hitKey: string, graphKeys: ReadonlySet<s
|
|
|
45
42
|
* Returns 0-1 fraction, or null when unset/invalid.
|
|
46
43
|
*/
|
|
47
44
|
export declare function parseMinEdgeCoverage(raw: unknown): number | null;
|
|
45
|
+
/** Builds the `traverse` coverage report from the edges walked and the graph's edges. */
|
|
48
46
|
export declare function buildCoverageReport(opts: {
|
|
49
47
|
projectDir: string;
|
|
50
48
|
parallel: number;
|
|
@@ -55,5 +53,7 @@ export declare function buildCoverageReport(opts: {
|
|
|
55
53
|
}): TraverseCoverageReport;
|
|
56
54
|
/** Greppable one-liner for agents/CI. */
|
|
57
55
|
export declare function formatCoverageLine(report: TraverseCoverageReport): string;
|
|
56
|
+
/** Where `traverse` writes its coverage report by default. */
|
|
58
57
|
export declare function defaultCoverageOutPath(projectDir: string): string;
|
|
58
|
+
/** Writes the `traverse` coverage report to disk. */
|
|
59
59
|
export declare function writeCoverageReport(path: string, report: TraverseCoverageReport): void;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
/** Static graph edge key = Block runtime name. */
|
|
13
|
-
|
|
13
|
+
function edgeKeyFromGraphEdge(edge) {
|
|
14
14
|
return edge.block;
|
|
15
15
|
}
|
|
16
16
|
/** Collect unique edge keys from a WaygraphGraph-like edges list. */
|
|
@@ -68,6 +68,7 @@ export function parseMinEdgeCoverage(raw) {
|
|
|
68
68
|
return n / 100;
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
|
+
/** Builds the `traverse` coverage report from the edges walked and the graph's edges. */
|
|
71
72
|
export function buildCoverageReport(opts) {
|
|
72
73
|
const all = [...new Set(opts.allEdgeKeys)].sort();
|
|
73
74
|
const graphSet = new Set(all);
|
|
@@ -118,9 +119,11 @@ export function formatCoverageLine(report) {
|
|
|
118
119
|
: "";
|
|
119
120
|
return `[Coverage edges=${report.edgesHit}/${report.edgesTotal} ratio=${pct}%${minPart}]`;
|
|
120
121
|
}
|
|
122
|
+
/** Where `traverse` writes its coverage report by default. */
|
|
121
123
|
export function defaultCoverageOutPath(projectDir) {
|
|
122
124
|
return join(projectDir, ".waygraph-traverse", "coverage.json");
|
|
123
125
|
}
|
|
126
|
+
/** Writes the `traverse` coverage report to disk. */
|
|
124
127
|
export function writeCoverageReport(path, report) {
|
|
125
128
|
mkdirSync(dirname(path), { recursive: true });
|
|
126
129
|
writeFileSync(path, JSON.stringify(report, null, 2) + "\n", "utf-8");
|
package/dist/traverse/lease.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export interface EdgeLeaseRecord {
|
|
|
2
2
|
workerId: string;
|
|
3
3
|
claimedAt: number;
|
|
4
4
|
}
|
|
5
|
+
/** Hands out graph edges to parallel `traverse` workers so no two workers walk the same edge. */
|
|
5
6
|
export declare class EdgeLeaseCoordinator {
|
|
6
7
|
private readonly held;
|
|
7
8
|
private readonly dir;
|
package/dist/traverse/lease.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
+
/** Hands out graph edges to parallel `traverse` workers so no two workers walk the same edge. */
|
|
8
9
|
export class EdgeLeaseCoordinator {
|
|
9
10
|
held = new Map();
|
|
10
11
|
dir;
|
package/dist/traverse/run.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
/** How `traverse` workers share a browser: one session, or a clone per worker. */
|
|
1
2
|
export type TraverseSessionMode = "clone" | "inherit";
|
|
3
|
+
/** What one `traverse` worker did: edges walked and failures. */
|
|
2
4
|
export interface TraverseWorkerResult {
|
|
3
5
|
exitCode: number;
|
|
4
6
|
steps: number;
|
|
5
7
|
edgesHit: string[];
|
|
6
8
|
leaf?: string;
|
|
7
9
|
}
|
|
10
|
+
/** Options for `runTraverse`: workers, session mode, step limit, coverage gate. */
|
|
8
11
|
export interface TraverseOptions {
|
|
9
12
|
baseURL?: string;
|
|
10
13
|
startUrl?: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Page } from "@playwright/test";
|
|
|
2
2
|
import type { MemPage, MemKey } from "./mem-page.js";
|
|
3
3
|
import type { Trait } from "./trait.js";
|
|
4
4
|
import type { HighlightStubPhaseOrFn, WaygraphHighlight, WaygraphSlidesOrFn } from "./highlights.js";
|
|
5
|
-
export type { WaygraphHighlight
|
|
5
|
+
export type { WaygraphHighlight } from "./highlights.js";
|
|
6
6
|
/**
|
|
7
7
|
* A Checkpoint is identified solely by its string tag - a phantom marker with no
|
|
8
8
|
* embedded data. Two Checkpoints with the same tag are the same state everywhere.
|
|
@@ -13,7 +13,7 @@ const homeOrigin = process.env.WAYGRAPH_BASE_URL || "http://127.0.0.1:4277";
|
|
|
13
13
|
/**
|
|
14
14
|
* Same real Blocks, same real Checkpoints, same real fixture server as
|
|
15
15
|
* routed-demo.flow.ts - built with `engine.map()` instead of
|
|
16
|
-
* `engine.defineFlow([start, ..., end])` to prove the fluent builder
|
|
16
|
+
* the deprecated `engine.defineFlow([start, ..., end])` to prove the fluent builder
|
|
17
17
|
* against a real browser/DOM, not just the in-memory fakes
|
|
18
18
|
* tests/nav/map-builder.spec.ts already covers in the main package.
|
|
19
19
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Engine
|
|
1
|
+
import { Engine } from "waygraph";
|
|
2
2
|
import { NavDashboardBlock } from "../map/(app_base)/dashboard/_nav.block.js";
|
|
3
3
|
import { ClickWidgetBlock } from "../map/(app_base)/dashboard/_methods/click-widget.block.js";
|
|
4
4
|
import { NavDocsBlock } from "../map/(external)/docs/_nav.block.js";
|
|
@@ -9,4 +9,4 @@ import "../map/(external)/docs/_page.block.js";
|
|
|
9
9
|
const engine = new Engine();
|
|
10
10
|
|
|
11
11
|
/** Smoke: dashboard -> click widget -> docs, all Blocks under the Waygraph Map folder convention. */
|
|
12
|
-
export const routedDemoFlow = engine.
|
|
12
|
+
export const routedDemoFlow = engine.map().start().gotoPage(NavDashboardBlock).method(ClickWidgetBlock).gotoPage(NavDocsBlock).end();
|
|
@@ -7,7 +7,6 @@ the **reference** for waygraph consumer conventions:
|
|
|
7
7
|
- **Nav** / **Effect** / **Action** file kinds (helpers are TypeScript salt;
|
|
8
8
|
runtime is still `Block`)
|
|
9
9
|
- `instanceOptions` menus for `waygraph auto` (Add/Remove + Open details)
|
|
10
|
-
- Detailed Kind / Helper / Route comments on every Block file
|
|
11
10
|
- Per-route `NAV.md` + root `src/blocks/SITE-MAP.md`
|
|
12
11
|
- Inline `{ ff: true }` fast-forward, no `.ffStart()/.ffEnd()` bracket - see
|
|
13
12
|
`checkoutFlow` (`src/flows/checkout.flow.ts`)
|
|
@@ -44,30 +43,30 @@ npx playwright install chromium
|
|
|
44
43
|
| Graph crawl (Phase B-E) | `npm run traverse` |
|
|
45
44
|
| Parallel crawl + leases | `npm run traverse:parallel` |
|
|
46
45
|
| Coverage JSON + min gate (10%) | `npm run traverse:coverage` |
|
|
47
|
-
| Shop demo
|
|
46
|
+
| Shop demo (login, then shop) | `npm run demo` |
|
|
48
47
|
| Shop demo autoplay | `npm run demo:auto-next` |
|
|
49
|
-
| **Device showcase** (mobile/tablet + portrait/landscape) | `npm run demo:device` |
|
|
50
|
-
| Device showcase + `.webm` | `npm run demo:
|
|
48
|
+
| **Device showcase** (mobile/tablet + portrait/landscape; narration in `src/stubs/device-showcase.ts`) | `npm run demo:device` |
|
|
49
|
+
| Device showcase + `.webm` | `npm run demo:video` |
|
|
51
50
|
| **Cart bulk** demo (add-all → remove-all) | `npm run demo:bulk` |
|
|
52
|
-
| Cart bulk autoplay | `npm run demo:bulk:auto-next` |
|
|
53
51
|
| **Owner checkout** (inline `{ ff: true }`, `ctx.caption()`, banner position) | `npm run demo:checkout` |
|
|
54
|
-
| Owner checkout + `.webm` | `npm run demo:checkout:video` |
|
|
55
52
|
| **FE + BE in one Flow** (`defineApiBlock`, live network panel) | `npm run demo:api` |
|
|
56
|
-
|
|
|
53
|
+
| Record (headless `.webm`) | `npm run record` |
|
|
57
54
|
| List flows | `npm run flows` |
|
|
58
55
|
|
|
56
|
+
Credentials and the selected item come from `registerMemStub` in `src/states/checkout.mem-stubs.ts` (`memStub: true` on the
|
|
57
|
+
flows), so no command needs `--data`. Settings, the base URL and the shared `engine` are in `config/waygraph.config.ts`.
|
|
58
|
+
Narration is chained on Blocks in the flows (`src/flows/`) or shared from `src/stubs/`; the Block files carry none.
|
|
59
|
+
|
|
59
60
|
**Demo vs auto vs run for cart bulk**
|
|
60
61
|
|
|
61
62
|
| | CLI | Needs `.flow.ts`? |
|
|
62
63
|
|--|-----|-------------------|
|
|
63
|
-
| **`run --blocks`** | `
|
|
64
|
-
| **`demo --blocks`** | `npm run demo:bulk` — named flow
|
|
64
|
+
| **`run --blocks`** | `waygraph run --blocks "loginFlow then add-all-to-cart"` | No |
|
|
65
|
+
| **`demo --blocks`** | `npm run demo:bulk` — named flow | Optional (`cartBulkFlow`) |
|
|
65
66
|
| **`auto`** | `npm run auto` / `auto:cli` | No — live menu |
|
|
66
|
-
| **`traverse`** | `npm run traverse`
|
|
67
|
+
| **`traverse`** | `npm run traverse` | No — graph crawl + `.waygraph-traverse/coverage.json` |
|
|
67
68
|
| **`auto --blocks From To`** | path-find on graph | No — checkpoints only |
|
|
68
69
|
|
|
69
|
-
QA watch+record: `npm run demo:bulk:video` (`--auto-play-video`).
|
|
70
|
-
|
|
71
70
|
## Layout (short)
|
|
72
71
|
|
|
73
72
|
```text
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Engine, defineConfig } from "waygraph";
|
|
2
|
+
|
|
3
|
+
const config = defineConfig({
|
|
4
|
+
baseUrl: "https://www.saucedemo.com",
|
|
5
|
+
playwright: {
|
|
6
|
+
workers: 1,
|
|
7
|
+
fullyParallel: false,
|
|
8
|
+
timeout: 30_000,
|
|
9
|
+
use: {
|
|
10
|
+
headless: true,
|
|
11
|
+
launchOptions: { args: ["--no-sandbox", "--disable-dev-shm-usage"] },
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export default config;
|
|
17
|
+
export const engine = new Engine(config);
|
|
@@ -106,5 +106,4 @@ waygraph chain "loginFlow" --step --no-autoplay
|
|
|
106
106
|
|
|
107
107
|
Flags beat env: `--step` / `--no-step`, `--autoplay` / `--no-autoplay`,
|
|
108
108
|
`--base-url <url>`, `--title <text>`. Default BASE_URL resolution order for
|
|
109
|
-
`demo`: `--base-url` > `WAYGRAPH_BASE_URL` > `
|
|
110
|
-
> `playwright.config` `baseURL`.
|
|
109
|
+
`demo`: `--base-url` > `WAYGRAPH_BASE_URL` > `baseUrl` in `config/waygraph.config.ts`.
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"../..": {
|
|
19
|
-
"version": "0.15.
|
|
19
|
+
"version": "0.15.53",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
22
|
+
"open-props": "^1.7.23",
|
|
23
|
+
"tsx": "^4.0.0",
|
|
24
|
+
"urlpattern-polyfill": "^10.1.0"
|
|
23
25
|
},
|
|
24
26
|
"bin": {
|
|
25
27
|
"waygraph": "bin/waygraph"
|
|
@@ -27,7 +29,12 @@
|
|
|
27
29
|
"devDependencies": {
|
|
28
30
|
"@playwright/test": "^1.63.0",
|
|
29
31
|
"@types/node": "^26.0.0",
|
|
30
|
-
"
|
|
32
|
+
"knip": "^6.42.1",
|
|
33
|
+
"typedoc": "^0.28.20",
|
|
34
|
+
"typedoc-plugin-markdown": "^4.14.1",
|
|
35
|
+
"typedoc-vitepress-theme": "^1.1.4",
|
|
36
|
+
"typescript": "^5.6.0",
|
|
37
|
+
"vitepress": "^1.6.4"
|
|
31
38
|
},
|
|
32
39
|
"peerDependencies": {
|
|
33
40
|
"@playwright/test": "^1.40.0"
|