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.
Files changed (156) hide show
  1. package/README.md +8 -1
  2. package/dist/analysis/graph.d.ts +3 -0
  3. package/dist/analysis/map-check.d.ts +3 -2
  4. package/dist/auto-session/helpers.d.ts +10 -0
  5. package/dist/blocks-select.d.ts +3 -0
  6. package/dist/blocks-select.js +2 -0
  7. package/dist/cli/flags.js +3 -1
  8. package/dist/cli/usage.js +4 -1
  9. package/dist/cli.js +4 -1
  10. package/dist/commands/agent-dive-scaffold.d.ts +0 -20
  11. package/dist/commands/agent-dive-scaffold.js +3 -3
  12. package/dist/commands/init.js +1 -1
  13. package/dist/commands/upgrade.d.ts +1 -1
  14. package/dist/commands/upgrade.js +7 -1
  15. package/dist/config.d.ts +55 -19
  16. package/dist/config.js +55 -13
  17. package/dist/core/block.d.ts +7 -2
  18. package/dist/core/block.js +7 -3
  19. package/dist/core/blocks/api.d.ts +1 -0
  20. package/dist/core/blocks/method.d.ts +2 -0
  21. package/dist/core/blocks/method.js +1 -0
  22. package/dist/core/blocks/nav.d.ts +1 -0
  23. package/dist/core/blocks/page.d.ts +1 -0
  24. package/dist/core/branch-regression.d.ts +1 -0
  25. package/dist/core/compose.d.ts +1 -0
  26. package/dist/core/engine.d.ts +2 -0
  27. package/dist/core/engine.js +3 -1
  28. package/dist/core/flow.d.ts +11 -0
  29. package/dist/core/flow.js +32 -8
  30. package/dist/core/map-builder.d.ts +34 -1
  31. package/dist/core/map-builder.js +42 -4
  32. package/dist/core/run-graph.d.ts +2 -0
  33. package/dist/core/run-graph.js +1 -0
  34. package/dist/errors.d.ts +1 -0
  35. package/dist/extensions.d.ts +1 -0
  36. package/dist/extensions.js +1 -0
  37. package/dist/highlights/demo-pace.d.ts +4 -1
  38. package/dist/highlights/demo-pace.js +28 -3
  39. package/dist/highlights/device.d.ts +2 -0
  40. package/dist/highlights/device.js +2 -0
  41. package/dist/highlights/types.d.ts +6 -0
  42. package/dist/index.d.ts +2 -2
  43. package/dist/pilot-overlay/action-ring.d.ts +0 -9
  44. package/dist/pilot-overlay/action-ring.js +1 -1
  45. package/dist/pilot-overlay/panel.d.ts +2 -1
  46. package/dist/runner/interaction-patch.js +32 -1
  47. package/dist/runner/main.js +5 -2
  48. package/dist/runner/step-mode.js +10 -4
  49. package/dist/session/auto-explore-run.js +6 -0
  50. package/dist/session/auto-explore.d.ts +2 -1
  51. package/dist/session/auto-session-ipc.d.ts +1 -2
  52. package/dist/session/auto-session-ipc.js +1 -1
  53. package/dist/session/block-inject.d.ts +0 -13
  54. package/dist/session/block-inject.js +3 -3
  55. package/dist/session/overlay-beacon.d.ts +7 -0
  56. package/dist/session/overlay-beacon.js +5 -0
  57. package/dist/session/pilot.d.ts +1 -2
  58. package/dist/session/pilot.js +1 -2
  59. package/dist/traverse/coverage.d.ts +4 -4
  60. package/dist/traverse/coverage.js +4 -1
  61. package/dist/traverse/lease.d.ts +1 -0
  62. package/dist/traverse/lease.js +1 -0
  63. package/dist/traverse/run.d.ts +3 -0
  64. package/dist/types.d.ts +1 -1
  65. package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +1 -1
  66. package/examples/routed-demo/src/flows/routed-demo.flow.ts +2 -2
  67. package/examples/saucedemo/README.md +11 -12
  68. package/examples/saucedemo/config/waygraph.config.ts +17 -0
  69. package/examples/saucedemo/docs/CONVENTION.md +1 -2
  70. package/examples/saucedemo/docs/HELPERS.md +1 -1
  71. package/examples/saucedemo/package-lock.json +10 -3
  72. package/examples/saucedemo/package.json +12 -29
  73. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +0 -49
  74. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +22 -25
  75. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +0 -6
  76. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +38 -96
  77. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +1 -26
  78. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +1 -45
  79. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +14 -77
  80. package/examples/saucedemo/src/flows/api-demo.flow.ts +17 -11
  81. package/examples/saucedemo/src/flows/cart-bulk.flow.ts +19 -14
  82. package/examples/saucedemo/src/flows/cart-continue.flow.ts +10 -8
  83. package/examples/saucedemo/src/flows/cart-mem.flow.ts +7 -7
  84. package/examples/saucedemo/src/flows/catalog-logout.flow.ts +13 -8
  85. package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +26 -48
  86. package/examples/saucedemo/src/flows/checkout.flow.ts +70 -86
  87. package/examples/saucedemo/src/flows/device-showcase.flow.ts +24 -25
  88. package/examples/saucedemo/src/flows/login.flow.ts +11 -18
  89. package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +9 -20
  90. package/examples/saucedemo/src/flows/shop.flow.ts +15 -20
  91. package/examples/saucedemo/src/flows/smoke.flow.ts +12 -27
  92. package/examples/saucedemo/src/flows/stub-on-error.flow.ts +24 -43
  93. package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +26 -34
  94. package/examples/saucedemo/src/states/checkout.mem-stubs.ts +11 -0
  95. package/examples/saucedemo/src/stubs/device-showcase.ts +193 -0
  96. package/examples/saucedemo/src/stubs/login.ts +37 -0
  97. package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +7 -9
  98. package/examples/saucedemo/tests/submit-login-branch.spec.ts +18 -5
  99. package/package.json +12 -5
  100. package/templates/quickstart/README.md +4 -7
  101. package/templates/quickstart/config/waygraph.config.ts +17 -0
  102. package/templates/quickstart/docs/CONVENTION.md +1 -2
  103. package/templates/quickstart/docs/HELPERS.md +1 -1
  104. package/templates/quickstart/package.json +14 -14
  105. package/templates/quickstart/src/blocks/SITE-MAP.md +14 -3
  106. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +0 -49
  107. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +22 -25
  108. package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +0 -6
  109. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +38 -96
  110. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +1 -26
  111. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +1 -45
  112. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +14 -77
  113. package/templates/quickstart/src/flows/api-demo.flow.ts +43 -0
  114. package/templates/quickstart/src/flows/cart-bulk.flow.ts +19 -14
  115. package/templates/quickstart/src/flows/cart-continue.flow.ts +10 -8
  116. package/templates/quickstart/src/flows/cart-mem.flow.ts +7 -7
  117. package/templates/quickstart/src/flows/catalog-logout.flow.ts +13 -8
  118. package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +26 -48
  119. package/templates/quickstart/src/flows/checkout.flow.ts +70 -63
  120. package/templates/quickstart/src/flows/device-showcase.flow.ts +24 -25
  121. package/templates/quickstart/src/flows/login.flow.ts +11 -18
  122. package/templates/quickstart/src/flows/mem-stub-demo.flow.ts +12 -0
  123. package/templates/quickstart/src/flows/shop.flow.ts +15 -20
  124. package/templates/quickstart/src/flows/smoke.flow.ts +12 -27
  125. package/templates/quickstart/src/flows/stub-on-error.flow.ts +31 -0
  126. package/templates/quickstart/src/flows/viewer-blocked.flow.ts +26 -34
  127. package/templates/quickstart/src/states/checkout.mem-stubs.ts +11 -0
  128. package/templates/quickstart/src/stubs/device-showcase.ts +193 -0
  129. package/templates/quickstart/src/stubs/login.ts +37 -0
  130. package/templates/quickstart/tests/chain-flow.spec.ts +7 -10
  131. package/templates/scaffold/README.md +1 -1
  132. package/templates/scaffold/STRUCTURE.md +5 -2
  133. package/templates/scaffold/config/waygraph.config.ts +24 -5
  134. package/templates/scaffold/package.json +6 -6
  135. package/templates/scaffold/src/flows/(external)/hoppscotch/auth.flow.ts +36 -0
  136. package/templates/scaffold/src/flows/(external)/hoppscotch/get.flow.ts +24 -0
  137. package/templates/scaffold/src/flows/(external)/hoppscotch/post.flow.ts +34 -0
  138. package/templates/scaffold/src/flows/(user-stories)/email-verification.flow.ts +47 -0
  139. package/templates/scaffold/src/flows/README.md +35 -14
  140. package/templates/scaffold/src/flows/{shop.flow.ts → home/cart.flow.ts} +18 -17
  141. package/templates/scaffold/src/flows/{example.flow.ts → home/hello.flow.ts} +12 -13
  142. package/templates/scaffold/tests/example.spec.ts +5 -5
  143. package/templates/scaffold/tests/hoppscotch.spec.ts +3 -3
  144. package/templates/scaffold/tests/mail-verify.spec.ts +7 -7
  145. package/templates/skills/waygraph-convention.skill.md +14 -6
  146. package/examples/saucedemo/playwright.config.ts +0 -19
  147. package/examples/saucedemo/scripts/drive-auto-cli.mjs +0 -93
  148. package/examples/saucedemo/scripts/prove-add-to-cart-menu.mjs +0 -126
  149. package/examples/saucedemo/scripts/prove-auto-graph.mjs +0 -92
  150. package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +0 -63
  151. package/templates/quickstart/playwright.config.ts +0 -14
  152. package/templates/quickstart/scripts/drive-auto-cli.mjs +0 -93
  153. package/templates/scaffold/src/flows/hoppscotch-auth.flow.ts +0 -35
  154. package/templates/scaffold/src/flows/hoppscotch-get.flow.ts +0 -23
  155. package/templates/scaffold/src/flows/hoppscotch-post.flow.ts +0 -33
  156. package/templates/scaffold/src/flows/mail-verify.flow.ts +0 -46
@@ -1,11 +1,13 @@
1
- import { Engine, start, end, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavCartBlock } from "../blocks/saucedemo-web/cart/nav-cart.block.js";
3
4
  import { NavContinueShoppingBlock } from "../blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.js";
4
5
 
5
- const engine = new Engine();
6
-
7
- // Open cart and continue shopping - wires orphan nav-continue-shopping Block.
8
- export const cartContinueFlow = withTitle(
9
- engine.defineFlow([start, NavCartBlock, NavContinueShoppingBlock, end]),
10
- "Cart then continue shopping",
11
- );
6
+ export const cartContinueFlow = engine
7
+ .map()
8
+ .start()
9
+ .gotoPage(
10
+ NavCartBlock.stubBefore((ctx) => ctx.title("Cart then continue shopping")),
11
+ )
12
+ .gotoPage(NavContinueShoppingBlock)
13
+ .end();
@@ -1,9 +1,9 @@
1
- import { Engine, start, end } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { RemoveFromCartBlock } from "../blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.js";
3
4
 
4
- const engine = new Engine();
5
-
6
- // Registers remove-from-cart in the discoverable graph so waygraph auto can
7
- // offer live "Remove … from cart" rows. Not a product checkout path - Add /
8
- // Remove pairing for interactive explore.
9
- export const cartMemFlow = engine.defineFlow([start, RemoveFromCartBlock, end]);
5
+ export const cartMemFlow = engine
6
+ .map()
7
+ .start()
8
+ .method(RemoveFromCartBlock)
9
+ .end();
@@ -1,12 +1,17 @@
1
- import { Engine, start, end, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavItemDetailBlock } from "../blocks/saucedemo-web/inventory/nav-item-detail.block.js";
3
4
  import { NavBackToInventoryBlock } from "../blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.js";
4
5
  import { SubmitLogoutBlock } from "../blocks/saucedemo-web/methods/submit-logout.method.block.js";
5
6
 
6
- const engine = new Engine();
7
-
8
- // Browse one product, return to inventory, log out - wires orphan catalog + logout Blocks.
9
- export const catalogLogoutFlow = withTitle(
10
- engine.defineFlow([start, NavItemDetailBlock, NavBackToInventoryBlock, SubmitLogoutBlock, end]),
11
- "Catalog browse then logout",
12
- );
7
+ export const catalogLogoutFlow = engine
8
+ .map()
9
+ .start()
10
+ .gotoPage(
11
+ NavItemDetailBlock.stubBefore((ctx) =>
12
+ ctx.title("Catalog browse then logout"),
13
+ ),
14
+ )
15
+ .gotoPage(NavBackToInventoryBlock)
16
+ .method(SubmitLogoutBlock)
17
+ .end();
@@ -1,13 +1,5 @@
1
- import { Engine, start, end, withTitle } from "waygraph";
2
- import type {
3
- LoginPage,
4
- LoggedIn,
5
- ItemInCart,
6
- CartPage,
7
- CheckoutInfoPage,
8
- CheckoutOverviewPage,
9
- OrderComplete,
10
- } from "../states/checkout.states.js";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
11
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
12
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
13
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
@@ -22,41 +14,27 @@ import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-o
22
14
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
23
15
  import { NavBackToProductsBlock } from "../blocks/saucedemo-web/inventory-item/nav-back-to-products.block.js";
24
16
 
25
- const engine = new Engine({ headless: false, slowMo: 250 });
26
-
27
- // Same atomic checkout chain, plus click-based nav-back-to-products
28
- // (proves OrderComplete -> LoggedIn without a goto teleport).
29
- export const checkoutThenBrowseAgainFlow = withTitle(
30
- engine.defineFlow<
31
- LoginPage,
32
- LoginPage,
33
- LoginPage,
34
- LoggedIn,
35
- ItemInCart,
36
- CartPage,
37
- CheckoutInfoPage,
38
- CheckoutInfoPage,
39
- CheckoutInfoPage,
40
- CheckoutInfoPage,
41
- CheckoutOverviewPage,
42
- OrderComplete,
43
- LoggedIn
44
- >([
45
- start,
46
- NavLoginBlock,
47
- FillUsernameBlock,
48
- FillPasswordBlock,
49
- SubmitLoginForFlow,
50
- AddToCartBlock,
51
- NavCartBlock,
52
- NavCheckoutInfoBlock,
53
- FillFirstNameBlock,
54
- FillLastNameBlock,
55
- FillPostalCodeBlock,
56
- SubmitCheckoutInfoBlock,
57
- FinishOrderBlock,
58
- NavBackToProductsBlock,
59
- end,
60
- ]),
61
- "Owner: Checkout, then click Back Home (click-based NavBlock demo)",
62
- );
17
+ /** Full checkout, then the "Back Home" click-based Nav Block returns to the catalogue. */
18
+ export const checkoutThenBrowseAgainFlow = engine
19
+ .map({ memStub: true })
20
+ .start()
21
+ .gotoPage(
22
+ NavLoginBlock.stubBefore((ctx) =>
23
+ ctx.title(
24
+ "Owner: Checkout, then click Back Home (click-based NavBlock demo)",
25
+ ),
26
+ ),
27
+ )
28
+ .method(FillUsernameBlock)
29
+ .method(FillPasswordBlock)
30
+ .method(SubmitLoginForFlow)
31
+ .method(AddToCartBlock)
32
+ .gotoPage(NavCartBlock)
33
+ .gotoPage(NavCheckoutInfoBlock)
34
+ .method(FillFirstNameBlock)
35
+ .method(FillLastNameBlock)
36
+ .method(FillPostalCodeBlock)
37
+ .method(SubmitCheckoutInfoBlock)
38
+ .method(FinishOrderBlock)
39
+ .gotoPage(NavBackToProductsBlock)
40
+ .end();
@@ -1,4 +1,5 @@
1
- import { Engine, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
3
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
4
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
@@ -13,88 +14,71 @@ import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-o
13
14
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
14
15
  import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
15
16
 
16
- const engine = new Engine({ headless: false, slowMo: 250 });
17
-
18
- /**
19
- * Owner checkout via map() with inline `{ ff: true }` (no separate
20
- * FfOwnerAuthBlock, no HighlightFixtureMap, no .ffStart()/.ffEnd() bracket -
21
- * the three auth steps below merge into one fast-forward block just by
22
- * flagging each one). Auth collapses to one blitz step; post-login blocks
23
- * keep their own ctx stubBefore/stubAfter. Call-site decorate example on
24
- * fill-username when --ff-expand shows inners again.
25
- *
26
- * Also demonstrates two other recent conventions on the checkout-step-one
27
- * leg: ctx.caption() (bottom subtitle-bar, ported from zsign's help-center
28
- * clip engine) narrating each field, and ctx.titlePos() moving the banner
29
- * left -> center -> right across three consecutive steps.
30
- */
31
- export const checkoutFlow = withTitle(
32
- engine
33
- .map()
34
- .start()
35
- .gotoPage(NavLoginBlock, { ff: true })
36
- .method(
37
- FillUsernameBlock.stubBefore((ctx) => {
38
- ctx.ring("username", {
39
- selector: LoginSel.username,
40
- label: "Demo user",
41
- detail: "standard_user from Mem - library block stays neutral underneath",
42
- tag: "AC",
43
- duration: true,
44
- focus: true,
45
- });
46
- }),
47
- { ff: true },
48
- )
49
- .method(
50
- FillPasswordBlock.stubBefore((ctx) => {
51
- ctx.ring("password", {
52
- selector: LoginSel.password,
53
- label: "Password",
54
- detail: "Filled from Mem credentials.",
55
- duration: 1500,
56
- focus: true,
57
- });
58
- }),
59
- { ff: true },
60
- )
61
- .method(
62
- SubmitLoginForFlow.stubBefore((ctx) => {
63
- ctx.ring("submit", {
64
- selector: LoginSel.loginButton,
65
- label: "Sign in",
66
- tag: "GATE",
67
- duration: true,
68
- fastMode: 500,
69
- focus: true,
70
- weight: "bold",
71
- });
72
- }),
73
- { ff: true },
74
- )
75
- .method(AddToCartBlock)
76
- .gotoPage(NavCartBlock)
77
- .gotoPage(NavCheckoutInfoBlock)
78
- .method(
79
- FillFirstNameBlock.stubBefore((ctx) => {
80
- ctx.caption("Enter the first name on the order");
81
- ctx.titlePos("left");
82
- }),
83
- )
84
- .method(
85
- FillLastNameBlock.stubBefore((ctx) => {
86
- ctx.caption("Enter the last name on the order");
87
- ctx.titlePos("center");
88
- }),
89
- )
90
- .method(
91
- FillPostalCodeBlock.stubBefore((ctx) => {
92
- ctx.caption("Enter a postal code to calculate shipping");
93
- ctx.titlePos("right");
94
- }),
95
- )
96
- .method(SubmitCheckoutInfoBlock.stubBefore((ctx) => ctx.hideCaption()))
97
- .method(FinishOrderBlock)
98
- .end(),
99
- "Owner: Full Checkout",
100
- );
17
+ export const checkoutFlow = engine
18
+ .map({ memStub: true })
19
+ .start()
20
+ .gotoPage(NavLoginBlock, { ff: true })
21
+ .method(
22
+ FillUsernameBlock.stubBefore((ctx) => {
23
+ ctx.ring("username", {
24
+ selector: LoginSel.username,
25
+ label: "Demo user",
26
+ detail:
27
+ "standard_user from Mem - library block stays neutral underneath",
28
+ tag: "AC",
29
+ duration: true,
30
+ focus: true,
31
+ });
32
+ }),
33
+ { ff: true },
34
+ )
35
+ .method(
36
+ FillPasswordBlock.stubBefore((ctx) => {
37
+ ctx.ring("password", {
38
+ selector: LoginSel.password,
39
+ label: "Password",
40
+ detail: "Filled from Mem credentials.",
41
+ duration: 1500,
42
+ focus: true,
43
+ });
44
+ }),
45
+ { ff: true },
46
+ )
47
+ .method(
48
+ SubmitLoginForFlow.stubBefore((ctx) => {
49
+ ctx.ring("submit", {
50
+ selector: LoginSel.loginButton,
51
+ label: "Sign in",
52
+ tag: "GATE",
53
+ duration: true,
54
+ fastMode: 500,
55
+ focus: true,
56
+ weight: "bold",
57
+ });
58
+ }),
59
+ { ff: true },
60
+ )
61
+ .method(AddToCartBlock.stubBefore((ctx) => ctx.title("Owner: Full Checkout")))
62
+ .gotoPage(NavCartBlock)
63
+ .gotoPage(NavCheckoutInfoBlock)
64
+ .method(
65
+ FillFirstNameBlock.stubBefore((ctx) => {
66
+ ctx.caption("Enter the first name on the order");
67
+ ctx.titlePos("left");
68
+ }),
69
+ )
70
+ .method(
71
+ FillLastNameBlock.stubBefore((ctx) => {
72
+ ctx.caption("Enter the last name on the order");
73
+ ctx.titlePos("center");
74
+ }),
75
+ )
76
+ .method(
77
+ FillPostalCodeBlock.stubBefore((ctx) => {
78
+ ctx.caption("Enter a postal code to calculate shipping");
79
+ ctx.titlePos("right");
80
+ }),
81
+ )
82
+ .method(SubmitCheckoutInfoBlock.stubBefore((ctx) => ctx.hideCaption()))
83
+ .method(FinishOrderBlock)
84
+ .end();
@@ -1,32 +1,31 @@
1
- import { Engine, start, end, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
3
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
4
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
5
6
  import { SubmitLoginForFlow } from "../blocks/saucedemo-web/methods/submit-login-for-flow.js";
6
7
  import { AddToCartBlock } from "../blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.js";
7
8
  import { NavCartBlock } from "../blocks/saucedemo-web/cart/nav-cart.block.js";
9
+ import { deviceShowcase as d } from "../stubs/device-showcase.js";
8
10
 
9
- const engine = new Engine();
10
-
11
- /**
12
- * Short device/orientation showcase (0.13.3+):
13
- * login mobile portrait -> land on inventory landscape ->
14
- * add-to-cart tablet portrait -> open cart tablet landscape -> desktop
15
- *
16
- * Run:
17
- * npm run demo:device
18
- * npm run demo:device:video
19
- */
20
- export const deviceShowcaseFlow = withTitle(
21
- engine.defineFlow([
22
- start,
23
- NavLoginBlock,
24
- FillUsernameBlock,
25
- FillPasswordBlock,
26
- SubmitLoginForFlow,
27
- AddToCartBlock,
28
- NavCartBlock,
29
- end,
30
- ]),
31
- "Device showcase",
32
- );
11
+ /** Sign in on a phone, shop on a tablet, open the cart in landscape: the device and zoom narration in src/stubs/device-showcase.ts. */
12
+ export const deviceShowcaseFlow = engine
13
+ .map({ memStub: true })
14
+ .start()
15
+ .gotoPage(NavLoginBlock)
16
+ .method(
17
+ FillUsernameBlock.stubBefore(d.username.before).stubAfter(d.username.after),
18
+ )
19
+ .method(
20
+ FillPasswordBlock.stubBefore(d.password.before).stubAfter(d.password.after),
21
+ )
22
+ .method(
23
+ SubmitLoginForFlow.stubBefore(d.submit.before).stubAfter(d.submit.after),
24
+ )
25
+ .method(
26
+ AddToCartBlock.stubBefore(d.addToCart.before).stubAfter(d.addToCart.after),
27
+ )
28
+ .gotoPage(
29
+ NavCartBlock.stubBefore(d.openCart.before).stubAfter(d.openCart.after),
30
+ )
31
+ .end();
@@ -1,23 +1,16 @@
1
- import { Engine, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
3
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
4
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
5
6
  import { SubmitLoginForFlow } from "../blocks/saucedemo-web/methods/submit-login-for-flow.js";
6
7
 
7
- const engine = new Engine();
8
-
9
- // The step-mode overlay prepends "Episode N: " itself - the title here is
10
- // just the label, not the full heading.
11
- // map() + ctx stubs on the Method blocks (see fill-username / fill-password /
12
- // submit-login) - no HighlightFixtureMap.
13
- export const loginFlow = withTitle(
14
- engine
15
- .map()
16
- .start()
17
- .gotoPage(NavLoginBlock)
18
- .method(FillUsernameBlock)
19
- .method(FillPasswordBlock)
20
- .method(SubmitLoginForFlow)
21
- .end(),
22
- "Sign In",
23
- );
8
+ /** Standard user signs in. Credentials come from the memStub in src/states/checkout.mem-stubs.ts unless --data / mem set them. */
9
+ export const loginFlow = engine
10
+ .map({ memStub: true })
11
+ .start()
12
+ .gotoPage(NavLoginBlock.stubBefore((ctx) => ctx.title("Sign In")))
13
+ .method(FillUsernameBlock)
14
+ .method(FillPasswordBlock)
15
+ .method(SubmitLoginForFlow)
16
+ .end();
@@ -1,23 +1,12 @@
1
- import { Engine, withMemStub, registerMemStub } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
3
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
4
- import { LoginCreds } from "../states/checkout.mem-keys.js";
5
5
 
6
- /**
7
- * Test-only fixture for waygraph's own `--mem-stub` CLI flag
8
- * (tests/cli/mem-stub.spec.ts) - not part of the saucedemo showcase's own
9
- * demo/story. Registers a fake LoginCreds so `waygraph run
10
- * mem-stub-demo.flow.ts --mem-stub` succeeds with zero --data, proving the
11
- * registry + preflight fallback work against the real CLI, not just the
12
- * in-process engine tests in tests/core/mem-stub.spec.ts.
13
- */
14
- registerMemStub(LoginCreds.key, () => ({
15
- username: "standard_user",
16
- password: "secret_sauce",
17
- }));
18
-
19
- const engine = new Engine();
20
-
21
- export const memStubDemoFlow = withMemStub(
22
- engine.map().start().gotoPage(NavLoginBlock).method(FillUsernameBlock).end(),
23
- );
6
+ /** memStub: the credentials are never supplied; src/states/checkout.mem-stubs.ts fills them. */
7
+ export const memStubDemoFlow = engine
8
+ .map({ memStub: true })
9
+ .start()
10
+ .gotoPage(NavLoginBlock)
11
+ .method(FillUsernameBlock)
12
+ .end();
@@ -1,4 +1,5 @@
1
- import { Engine, withTitle } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
2
3
  import { AddToCartBlock } from "../blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.js";
3
4
  import { NavCartBlock } from "../blocks/saucedemo-web/cart/nav-cart.block.js";
4
5
  import { NavCheckoutInfoBlock } from "../blocks/saucedemo-web/cart/nav-checkout-info.block.js";
@@ -8,22 +9,16 @@ import { FillPostalCodeBlock } from "../blocks/saucedemo-web/checkout-step-one/m
8
9
  import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.js";
9
10
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
10
11
 
11
- const engine = new Engine();
12
-
13
- // Episode-2 half of chainFlow(loginFlow, shopFlow) - assumes already LoggedIn
14
- // (AddToCartBlock's In is the Checkpoint<string> wildcard).
15
- export const shopFlow = withTitle(
16
- engine
17
- .map()
18
- .start()
19
- .method(AddToCartBlock)
20
- .gotoPage(NavCartBlock)
21
- .gotoPage(NavCheckoutInfoBlock)
22
- .method(FillFirstNameBlock)
23
- .method(FillLastNameBlock)
24
- .method(FillPostalCodeBlock)
25
- .method(SubmitCheckoutInfoBlock)
26
- .method(FinishOrderBlock)
27
- .end(),
28
- "Shop & Checkout",
29
- );
12
+ /** Add the selected item, check out and place the order. Starts signed in (run it after loginFlow). */
13
+ export const shopFlow = engine
14
+ .map({ memStub: true })
15
+ .start()
16
+ .method(AddToCartBlock.stubBefore((ctx) => ctx.title("Shop & Checkout")))
17
+ .gotoPage(NavCartBlock)
18
+ .gotoPage(NavCheckoutInfoBlock)
19
+ .method(FillFirstNameBlock)
20
+ .method(FillLastNameBlock)
21
+ .method(FillPostalCodeBlock)
22
+ .method(SubmitCheckoutInfoBlock)
23
+ .method(FinishOrderBlock)
24
+ .end();
@@ -1,33 +1,18 @@
1
- import { Engine, start, end } from "waygraph";
2
- import type { LoginPage, LoggedIn, ItemInCart } from "../states/checkout.states.js";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
3
3
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
4
4
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
5
5
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
6
6
  import { SubmitLoginForFlow } from "../blocks/saucedemo-web/methods/submit-login-for-flow.js";
7
7
  import { AddToCartBlock } from "../blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.js";
8
8
 
9
- const engine = new Engine();
10
-
11
- // The QA case: a smoke test only cares that it was able to navigate this far -
12
- // it doesn't need the same DOM confirmation the real checkout.flow.ts wants.
13
- // Same Blocks, same act/resolve, zero duplication - only verify differs.
14
- // .withVerify([]) reads from the Block itself, discoverable by typing
15
- // "NavLoginBlock."/"SubmitLoginForFlow." in an editor - not a free function
16
- // you have to already know exists.
17
- //
18
- // Explicit <LoginPage, LoginPage, LoginPage, LoggedIn, ItemInCart> here -
19
- // AddToCartBlock's In is now the wildcard Checkpoint<string> (it's reused as
20
- // shopFlow's own entry block too), and inferring the chain purely from
21
- // several chained .withVerify([]) calls in one array trips TS's overload
22
- // resolution into unifying the wrong Out type partway through; pinning the
23
- // type args sidesteps it rather than fighting it. The two middle `LoginPage`
24
- // entries are fill-username / fill-password (self-loop Methods).
25
- export const smokeFlow = engine.defineFlow<LoginPage, LoginPage, LoginPage, LoggedIn, ItemInCart>([
26
- start,
27
- NavLoginBlock.withVerify([]),
28
- FillUsernameBlock,
29
- FillPasswordBlock,
30
- SubmitLoginForFlow.withVerify([]),
31
- AddToCartBlock.withVerify([]),
32
- end,
33
- ]);
9
+ /** Smoke: the happy path with the Blocks' own verify lists switched off where a later step already proves the outcome. */
10
+ export const smokeFlow = engine
11
+ .map()
12
+ .start()
13
+ .gotoPage(NavLoginBlock.withVerify([]))
14
+ .method(FillUsernameBlock)
15
+ .method(FillPasswordBlock)
16
+ .method(SubmitLoginForFlow.withVerify([]))
17
+ .method(AddToCartBlock.withVerify([]))
18
+ .end();
@@ -1,50 +1,31 @@
1
- import {
2
- Engine,
3
- start,
4
- end,
5
- withTitle,
6
- withSessionReset,
7
- withExpectedFailure,
8
- withHighlightFixtures,
9
- Trait,
10
- } from "waygraph";
1
+ import { engine } from "../../config/waygraph.config.js";
2
+ import "../states/checkout.mem-stubs.js";
3
+ import { Trait } from "waygraph";
11
4
  import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
12
5
  import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
13
6
  import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
14
7
  import { SubmitLoginBlock } from "../blocks/saucedemo-web/methods/submit-login.method.block.js";
15
-
16
- const engine = new Engine();
8
+ import { loginFailed } from "../stubs/login.js";
17
9
 
18
10
  /**
19
- * Prove stubOnError (waygraph 0.12.4+): force verify to demand /inventory.html
20
- * while mem is locked_out_user — step throws, demo rings the error banner
21
- * before the error panel, then expected-failure styling.
22
- *
23
- * waygraph demo --blocks stubOnErrorFlow --auto-next --fast \\
24
- * --data '{"saucedemo.credentials":{"username":"locked_out_user","password":"secret_sauce"}}'
11
+ * Forces a verify failure (locked_out_user is refused, but the verify demands the inventory page) to show `stubOnError` ringing
12
+ * the error banner before the failure panel. Needs locked_out_user credentials: `--data` or mem.
25
13
  */
26
- const forcedInventoryVerify = withSessionReset(
27
- engine
28
- .defineFlow([start, NavLoginBlock, FillUsernameBlock, FillPasswordBlock, SubmitLoginBlock, end])
29
- .withBlockVerify("submit-login", [Trait.url({ pathname: "/inventory.html" })]),
30
- );
31
-
32
- export const stubOnErrorFlow = withHighlightFixtures(
33
- withExpectedFailure(
34
- withTitle(forcedInventoryVerify, "stubOnError: locked_out fail rings"),
35
- "Intentional verify fail - stubOnError rings the error banner before the panel",
36
- ),
37
- {
38
- "submit-login": {
39
- stubOnError: {
40
- error: {
41
- label: "BUG · locked out still on login",
42
- detail: "Verify demanded inventory; banner is the proof point.",
43
- tag: "FAIL",
44
- duration: true,
45
- fastMode: 500,
46
- },
47
- },
48
- },
49
- },
50
- );
14
+ export const stubOnErrorFlow = engine
15
+ .map({
16
+ expectedFailure:
17
+ "Intentional verify fail - stubOnError rings the error banner before the panel",
18
+ })
19
+ .start()
20
+ .gotoPage(
21
+ NavLoginBlock.stubBefore((ctx) =>
22
+ ctx.title("stubOnError: locked_out fail rings"),
23
+ ),
24
+ )
25
+ .method(FillUsernameBlock)
26
+ .method(FillPasswordBlock)
27
+ .method(SubmitLoginBlock.stubOnError(loginFailed))
28
+ .end()
29
+ .withBlockVerify("submit-login", [
30
+ Trait.url({ pathname: "/inventory.html" }),
31
+ ]);