waygraph 0.16.1 → 0.16.4

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 (154) hide show
  1. package/README.md +12 -0
  2. package/dist/analysis/practices-check.d.ts +1 -1
  3. package/dist/analysis/practices-check.js +36 -0
  4. package/dist/beta.d.ts +6 -0
  5. package/dist/beta.js +5 -0
  6. package/dist/cli/commands/codemod-flows.js +2 -2
  7. package/dist/cli/commands/codemod-stubs.js +132 -2
  8. package/dist/cli/commands/pilot.js +3 -16
  9. package/dist/cli/commands/session-ops.js +26 -1
  10. package/dist/cli/flags.d.ts +1 -1
  11. package/dist/cli/flags.js +1 -1
  12. package/dist/cli/run-chain.js +2 -2
  13. package/dist/cli/usage.js +6 -0
  14. package/dist/cli/util.js +1 -1
  15. package/dist/demo/narration/demo-pace.d.ts +1 -1
  16. package/dist/demo/narration/demo-pace.js +1 -1
  17. package/dist/demo/narration/merge.d.ts +1 -1
  18. package/dist/demo/narration/merge.js +1 -1
  19. package/dist/demo/narration/narration.d.ts +2 -6
  20. package/dist/demo/narration/narration.js +5 -17
  21. package/dist/demo/narration/stub-ctx.js +126 -124
  22. package/dist/demo/overlay/cursor.js +1 -1
  23. package/dist/demo/overlay/inpage/banner.js +5 -0
  24. package/dist/demo/overlay/inpage/core.js +1 -6
  25. package/dist/demo/overlay/inpage/network.js +1 -1
  26. package/dist/demo/overlay/inpage/todos.js +0 -15
  27. package/dist/demo/overlay/network-capture.js +2 -2
  28. package/dist/demo/overlay/overlay-css.js +19 -76
  29. package/dist/demo/overlay/overlay-stage.js +1 -1
  30. package/dist/demo/overlay/overlay.js +3 -2
  31. package/dist/demo/overlay/phase-fixtures.js +5 -5
  32. package/dist/demo/overlay/pilot/shell.js +7 -5
  33. package/dist/demo/overlay/rings.d.ts +0 -8
  34. package/dist/demo/overlay/rings.js +0 -15
  35. package/dist/demo/overlay/ui/components/ring.js +2 -2
  36. package/dist/demo/overlay/ui/overlay.css +136 -33
  37. package/dist/demo/overlay/ui/shadow.js +69 -2
  38. package/dist/demo/stepper/after.js +4 -17
  39. package/dist/demo/stepper/before.js +3 -1
  40. package/dist/demo/stepper/demo-log.js +8 -8
  41. package/dist/demo/stepper/interaction-patch.js +3 -15
  42. package/dist/demo/stepper/panel-after.js +1 -1
  43. package/dist/demo/stepper/slides.d.ts +3 -0
  44. package/dist/demo/stepper/slides.js +18 -2
  45. package/dist/demo/stepper/stepper.js +1 -1
  46. package/dist/demo/stepper/teardown.js +0 -1
  47. package/dist/demo/verbose-log.js +1 -1
  48. package/dist/engine/block/block.d.ts +1 -12
  49. package/dist/engine/block/kind.d.ts +3 -0
  50. package/dist/engine/block/kind.js +11 -0
  51. package/dist/engine/block/kinds/method.d.ts +0 -2
  52. package/dist/engine/block/kinds/method.js +0 -1
  53. package/dist/engine/block/kinds/nav.js +1 -1
  54. package/dist/engine/errors.d.ts +12 -0
  55. package/dist/engine/errors.js +12 -0
  56. package/dist/engine/read/read-block.d.ts +61 -0
  57. package/dist/engine/read/read-block.js +94 -0
  58. package/dist/engine/read/read-key.d.ts +32 -0
  59. package/dist/engine/read/read-key.js +34 -0
  60. package/dist/engine/read/read-page.d.ts +19 -0
  61. package/dist/engine/read/read-page.js +50 -0
  62. package/dist/engine/read/readers.d.ts +82 -0
  63. package/dist/engine/read/readers.js +43 -0
  64. package/dist/engine/read/run-read.d.ts +17 -0
  65. package/dist/engine/read/run-read.js +156 -0
  66. package/dist/engine/run/connect.js +3 -2
  67. package/dist/engine/run/events.d.ts +28 -10
  68. package/dist/engine/run/events.js +52 -38
  69. package/dist/engine/run/run.d.ts +1 -19
  70. package/dist/engine/run/run.js +21 -97
  71. package/dist/engine/stub/ring.d.ts +2 -4
  72. package/dist/engine/stub/ring.js +1 -0
  73. package/dist/engine/stub/stub.d.ts +38 -25
  74. package/dist/index.d.ts +9 -7
  75. package/dist/index.js +11 -6
  76. package/dist/live/auto/auto.js +2 -3
  77. package/dist/live/auto/menu.js +3 -2
  78. package/dist/live/auto-session/auto-session.d.ts +9 -2
  79. package/dist/live/auto-session/auto-session.js +23 -20
  80. package/dist/live/auto-session/feed.d.ts +16 -0
  81. package/dist/live/auto-session/feed.js +71 -0
  82. package/dist/live/auto-session/helpers.d.ts +7 -0
  83. package/dist/live/auto-session/helpers.js +9 -0
  84. package/dist/live/auto-session/ipc.d.ts +15 -47
  85. package/dist/live/auto-session/ipc.js +34 -4
  86. package/dist/live/auto-session/protocol.d.ts +127 -0
  87. package/dist/live/auto-session/protocol.js +6 -0
  88. package/dist/live/auto-session/read.d.ts +25 -0
  89. package/dist/live/auto-session/read.js +50 -0
  90. package/dist/live/traverse/worker.d.ts +1 -0
  91. package/dist/live/traverse/worker.js +6 -1
  92. package/dist/manifest/manifest.d.ts +22 -2
  93. package/dist/manifest/manifest.js +27 -1
  94. package/dist/manifest/project.d.ts +10 -1
  95. package/dist/manifest/project.js +9 -12
  96. package/dist/manifest/read-blocks.d.ts +2 -0
  97. package/dist/manifest/read-blocks.js +23 -0
  98. package/dist/manifest/scan.d.ts +3 -2
  99. package/dist/manifest/scan.js +8 -4
  100. package/dist/runner/plan/find.js +2 -2
  101. package/dist/runner/plan/plan.js +1 -1
  102. package/dist/runner/plan/seed-mem.js +5 -5
  103. package/dist/runner/plan/spec.js +1 -1
  104. package/dist/runner/runner.d.ts +0 -1
  105. package/dist/runner/runner.js +6 -6
  106. package/dist/runtime/full-launch.d.ts +2 -1
  107. package/dist/runtime/full-launch.js +29 -27
  108. package/dist/runtime/run-log.d.ts +2 -0
  109. package/dist/runtime/run-log.js +13 -6
  110. package/examples/saucedemo/README.md +2 -2
  111. package/examples/saucedemo/src/blocks/SITE-MAP.md +3 -0
  112. package/examples/saucedemo/src/blocks/saucedemo-web/cart/cart.read.block.ts +26 -0
  113. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
  114. package/examples/saucedemo/src/blocks/saucedemo-web/header.read.block.ts +25 -0
  115. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.read.block.ts +28 -0
  116. package/examples/saucedemo/src/flows/api-demo.flow.ts +1 -1
  117. package/examples/saucedemo/src/flows/cart-bulk.flow.ts +1 -1
  118. package/examples/saucedemo/src/flows/cart-continue.flow.ts +1 -1
  119. package/examples/saucedemo/src/flows/catalog-logout.flow.ts +1 -1
  120. package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +3 -2
  121. package/examples/saucedemo/src/flows/checkout.flow.ts +13 -12
  122. package/examples/saucedemo/src/flows/login.flow.ts +1 -1
  123. package/examples/saucedemo/src/flows/shop.flow.ts +3 -2
  124. package/examples/saucedemo/src/flows/stub-on-error.flow.ts +1 -1
  125. package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +1 -1
  126. package/examples/saucedemo/src/states/checkout.reads.ts +9 -0
  127. package/examples/saucedemo/src/stubs/device-showcase.ts +70 -76
  128. package/examples/saucedemo/src/stubs/finish-order.ts +38 -0
  129. package/examples/saucedemo/src/stubs/login.ts +5 -5
  130. package/package.json +5 -1
  131. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
  132. package/templates/quickstart/src/flows/api-demo.flow.ts +1 -1
  133. package/templates/quickstart/src/flows/cart-bulk.flow.ts +1 -1
  134. package/templates/quickstart/src/flows/cart-continue.flow.ts +1 -1
  135. package/templates/quickstart/src/flows/catalog-logout.flow.ts +1 -1
  136. package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +3 -2
  137. package/templates/quickstart/src/flows/checkout.flow.ts +13 -12
  138. package/templates/quickstart/src/flows/login.flow.ts +1 -1
  139. package/templates/quickstart/src/flows/shop.flow.ts +3 -2
  140. package/templates/quickstart/src/flows/stub-on-error.flow.ts +1 -1
  141. package/templates/quickstart/src/flows/viewer-blocked.flow.ts +1 -1
  142. package/templates/quickstart/src/stubs/device-showcase.ts +70 -76
  143. package/templates/quickstart/src/stubs/finish-order.ts +38 -0
  144. package/templates/quickstart/src/stubs/login.ts +5 -5
  145. package/templates/scaffold/src/flows/(external)/hoppscotch/auth.flow.ts +1 -1
  146. package/templates/scaffold/src/flows/(external)/hoppscotch/get.flow.ts +1 -1
  147. package/templates/scaffold/src/flows/(external)/hoppscotch/post.flow.ts +1 -1
  148. package/templates/scaffold/src/flows/(user-stories)/email-verification.flow.ts +4 -4
  149. package/templates/scaffold/src/flows/README.md +1 -1
  150. package/templates/scaffold/src/flows/home/cart.flow.ts +7 -7
  151. package/templates/scaffold/src/flows/home/hello.flow.ts +10 -7
  152. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +1 -9
  153. package/templates/skills/waygraph-convention.skill.md +10 -2
  154. package/templates/skills/waygraph-pilot.skill.md +7 -0
@@ -38,13 +38,13 @@ function checklist(done: number, index: number) {
38
38
  export const deviceShowcase = {
39
39
  username: {
40
40
  before: (ctx: StubCtx) => {
41
- ctx.title("Signing in · mobile");
42
- ctx.device("mobile");
43
- ctx.orientation("portrait");
44
- ctx.todos("saucedemo", ...checklist(0, 0));
45
- ctx.zoom(1.35);
41
+ ctx.ui.title("Signing in · mobile");
42
+ ctx.ui.device("mobile");
43
+ ctx.ui.orientation("portrait");
44
+ ctx.ui.todos("saucedemo", ...checklist(0, 0));
45
+ ctx.ui.zoom(1.35);
46
46
  const fromMem = ctx.mem?.get(LoginCreds.key)?.username;
47
- ctx.ring("username", {
47
+ ctx.ui.ring("username", {
48
48
  selector: LoginSel.username,
49
49
  label: "Username",
50
50
  detail: fromMem
@@ -57,12 +57,12 @@ export const deviceShowcase = {
57
57
  });
58
58
  },
59
59
  after: (ctx: StubCtx) => {
60
- ctx.todos("saucedemo", ...checklist(1, 1));
60
+ ctx.ui.todos("saucedemo", ...checklist(1, 1));
61
61
  },
62
62
  },
63
63
  password: {
64
64
  before: (ctx: StubCtx) => {
65
- ctx.ring("password", {
65
+ ctx.ui.ring("password", {
66
66
  selector: LoginSel.password,
67
67
  label: "Password",
68
68
  detail: "tone: planned (purple)",
@@ -73,30 +73,28 @@ export const deviceShowcase = {
73
73
  });
74
74
  },
75
75
  after: (ctx: StubCtx) => {
76
- ctx.todos("saucedemo", ...checklist(2, 2));
76
+ ctx.ui.todos("saucedemo", ...checklist(2, 2));
77
77
  },
78
78
  },
79
79
  submit: {
80
80
  before: (ctx: StubCtx) => {
81
- ctx.highlights({
82
- submit: {
83
- selector: LoginSel.loginButton,
84
- label: "Login",
85
- detail: "tone: warning (yellow)",
86
- todo: "login-submit",
87
- tone: "warning",
88
- focus: true,
89
- zoom: 1.55,
90
- weight: "bold",
91
- gesture: "tap",
92
- },
81
+ ctx.ui.ring("submit", {
82
+ selector: LoginSel.loginButton,
83
+ label: "Login",
84
+ detail: "tone: warning (yellow)",
85
+ todo: "login-submit",
86
+ tone: "warning",
87
+ focus: true,
88
+ zoom: 1.55,
89
+ weight: "bold",
90
+ gesture: "tap",
93
91
  });
94
92
  },
95
93
  after: (ctx: StubCtx) => {
96
- ctx.title("Inventory · landscape");
97
- ctx.orientation("landscape");
98
- ctx.todos("saucedemo", ...checklist(3, 3));
99
- ctx.ring("shelf", {
94
+ ctx.ui.title("Inventory · landscape");
95
+ ctx.ui.orientation("landscape");
96
+ ctx.ui.todos("saucedemo", ...checklist(3, 3));
97
+ ctx.ui.ring("shelf", {
100
98
  selector: ".inventory_list",
101
99
  label: "Product shelf",
102
100
  detail: "tone: success (green) - ready to shop",
@@ -109,39 +107,37 @@ export const deviceShowcase = {
109
107
  },
110
108
  addToCart: {
111
109
  before: (ctx: StubCtx) => {
112
- ctx.title("Pick a product · tablet");
113
- ctx.device("tablet");
114
- ctx.orientation("portrait");
115
- ctx.todos("saucedemo", ...checklist(3, 3));
116
- ctx.zoom(1.35);
117
- ctx.zoomOut(false);
118
- ctx.highlights({
119
- product: {
120
- selector: InventorySel.title(PRODUCT_ID),
121
- label: "Sauce Labs Backpack",
122
- detail: "tone: info (blue)",
123
- tone: "info",
124
- focus: true,
125
- zoom: 1.45,
126
- zoomOut: false,
127
- },
128
- add: {
129
- selector: InventorySel.addBtn(PRODUCT_ID),
130
- label: "Add to cart",
131
- detail: "tone: success (green)",
132
- tone: "success",
133
- focus: true,
134
- zoom: 1.5,
135
- zoomOut: false,
136
- weight: "bold",
137
- },
110
+ ctx.ui.title("Pick a product · tablet");
111
+ ctx.ui.device("tablet");
112
+ ctx.ui.orientation("portrait");
113
+ ctx.ui.todos("saucedemo", ...checklist(3, 3));
114
+ ctx.ui.zoom(1.35);
115
+ ctx.ui.zoomOut(false);
116
+ ctx.ui.ring("product", {
117
+ selector: InventorySel.title(PRODUCT_ID),
118
+ label: "Sauce Labs Backpack",
119
+ detail: "tone: info (blue)",
120
+ tone: "info",
121
+ focus: true,
122
+ zoom: 1.45,
123
+ zoomOut: false,
124
+ });
125
+ ctx.ui.ring("add", {
126
+ selector: InventorySel.addBtn(PRODUCT_ID),
127
+ label: "Add to cart",
128
+ detail: "tone: success (green)",
129
+ tone: "success",
130
+ focus: true,
131
+ zoom: 1.5,
132
+ zoomOut: false,
133
+ weight: "bold",
138
134
  });
139
135
  },
140
136
  after: (ctx: StubCtx) => {
141
- ctx.title("In the cart");
142
- ctx.todos("saucedemo", ...checklist(4, 4));
143
- ctx.zoomOut(false);
144
- ctx.ring("badge", {
137
+ ctx.ui.title("In the cart");
138
+ ctx.ui.todos("saucedemo", ...checklist(4, 4));
139
+ ctx.ui.zoomOut(false);
140
+ ctx.ui.ring("badge", {
145
141
  selector: InventorySel.cartBadge,
146
142
  label: "Cart badge",
147
143
  detail: "tone: success (green) - count updated",
@@ -154,30 +150,28 @@ export const deviceShowcase = {
154
150
  },
155
151
  openCart: {
156
152
  before: (ctx: StubCtx) => {
157
- ctx.title("Open cart · landscape");
158
- ctx.orientation("landscape");
159
- ctx.todos("saucedemo", ...checklist(5, 5));
160
- ctx.zoom(1.4);
161
- ctx.zoomOut(false);
162
- ctx.highlights({
163
- cart: {
164
- selector: CartSel.cartLink,
165
- label: "Cart",
166
- detail: "tone: planned (purple) - open cart",
167
- tone: "planned",
168
- focus: true,
169
- zoomOut: false,
170
- weight: "bold",
171
- gesture: "tap",
172
- },
153
+ ctx.ui.title("Open cart · landscape");
154
+ ctx.ui.orientation("landscape");
155
+ ctx.ui.todos("saucedemo", ...checklist(5, 5));
156
+ ctx.ui.zoom(1.4);
157
+ ctx.ui.zoomOut(false);
158
+ ctx.ui.ring("cart", {
159
+ selector: CartSel.cartLink,
160
+ label: "Cart",
161
+ detail: "tone: planned (purple) - open cart",
162
+ tone: "planned",
163
+ focus: true,
164
+ zoomOut: false,
165
+ weight: "bold",
166
+ gesture: "tap",
173
167
  });
174
168
  },
175
169
  after: (ctx: StubCtx) => {
176
- ctx.title("Your cart · desktop");
177
- ctx.hideDevice();
178
- ctx.hideTodos();
179
- ctx.zoomOut(true);
180
- ctx.ring("items", {
170
+ ctx.ui.title("Your cart · desktop");
171
+ ctx.ui.hideDevice();
172
+ ctx.ui.hideTodos();
173
+ ctx.ui.zoomOut(true);
174
+ ctx.ui.ring("items", {
181
175
  selector: InventorySel.cartItem,
182
176
  label: "Cart items",
183
177
  detail: "tone: success (green) - product in cart",
@@ -0,0 +1,38 @@
1
+ import type { StubCtx } from "waygraph";
2
+ import { CheckoutOverviewSel } from "../blocks/saucedemo-web/checkout-step-two/methods/checkout-overview.sel.js";
3
+
4
+ /** Rings Finish while the order is placed. */
5
+ export function placingOrder(ctx: StubCtx): void {
6
+ ctx.ui.ring("finish", { selector: CheckoutOverviewSel.finishBtn, label: "Placing the order" });
7
+ }
8
+
9
+ /** Yap slides after the order is placed. They play on the completion page, so they ring its header, not #finish. */
10
+ export function orderPlacedYap(ctx: StubCtx): void {
11
+ ctx.ui.slides([
12
+ {
13
+ caption: "Checkout is a short pipeline",
14
+ detail: "Cart -> info -> overview -> done. You just placed the order.",
15
+ tag: "YAP",
16
+ tone: "info",
17
+ duration: true,
18
+ },
19
+ {
20
+ caption: "Completion page is the durable proof",
21
+ detail: "tone: success - the thank-you header is what verify asserts on.",
22
+ tag: "YAP",
23
+ tone: "success",
24
+ selector: CheckoutOverviewSel.completeHeader,
25
+ duration: 2500,
26
+ fastMode: 700,
27
+ },
28
+ {
29
+ caption: "Episode continues after this yap",
30
+ detail: "Next step rings the same banner, then you move on.",
31
+ tag: "YAP",
32
+ tone: "planned",
33
+ selector: CheckoutOverviewSel.completeHeader,
34
+ duration: true,
35
+ fastMode: 500,
36
+ },
37
+ ]);
38
+ }
@@ -3,8 +3,8 @@ import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
3
3
 
4
4
  /** What a refused login looks like on screen: the title, a finished checklist and the error banner. */
5
5
  export function loginRefused(ctx: StubCtx): void {
6
- ctx.title("Login blocked");
7
- ctx.todos(
6
+ ctx.ui.title("Login blocked");
7
+ ctx.ui.todos(
8
8
  "saucedemo",
9
9
  [
10
10
  { id: "login-user", text: "Enter username", done: true },
@@ -13,7 +13,7 @@ export function loginRefused(ctx: StubCtx): void {
13
13
  ],
14
14
  { title: "Sign in", style: "checklist" },
15
15
  );
16
- ctx.ring("error", {
16
+ ctx.ui.ring("error", {
17
17
  selector: LoginSel.errorBanner,
18
18
  label: "Login error banner",
19
19
  detail: "tone: danger (red)",
@@ -25,8 +25,8 @@ export function loginRefused(ctx: StubCtx): void {
25
25
 
26
26
  /** Rings the error banner when the login step itself throws. */
27
27
  export function loginFailed(ctx: StubCtx): void {
28
- ctx.title("Login failed");
29
- ctx.ring("error", {
28
+ ctx.ui.title("Login failed");
29
+ ctx.ui.ring("error", {
30
30
  selector: LoginSel.errorBanner,
31
31
  label: "Login error banner",
32
32
  detail: "tone: danger (red)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.16.1",
3
+ "version": "0.16.4",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -14,6 +14,10 @@
14
14
  "types": "./dist/index.d.ts",
15
15
  "default": "./dist/index.js"
16
16
  },
17
+ "./beta": {
18
+ "types": "./dist/beta.d.ts",
19
+ "default": "./dist/beta.js"
20
+ },
17
21
  "./runner": {
18
22
  "default": "./dist/runner/runner.js"
19
23
  }
@@ -1,4 +1,4 @@
1
- import { defineMethodBlock, Trait, narrate } from "waygraph";
1
+ import { defineMethodBlock, Trait } from "waygraph";
2
2
  import {
3
3
  CheckoutOverviewPage,
4
4
  OrderComplete,
@@ -21,9 +21,7 @@ export const FinishOrderBlock = defineMethodBlock({
21
21
  instruction: {
22
22
  async act(page) {
23
23
  const finishButton = page.locator(CheckoutOverviewSel.finishBtn);
24
- await narrate(finishButton, "Placing the order", () =>
25
- finishButton.click(),
26
- );
24
+ await finishButton.click();
27
25
  },
28
26
  verify: [
29
27
  Trait.text(
@@ -31,35 +29,5 @@ export const FinishOrderBlock = defineMethodBlock({
31
29
  "Thank you for your order!",
32
30
  ),
33
31
  ],
34
- // Shown AFTER act (order already placed) - selectors must match the
35
- // completion page, not #finish on the overview.
36
- slides: [
37
- {
38
- caption: "Checkout is a short pipeline",
39
- detail: "Cart -> info -> overview -> done. You just placed the order.",
40
- tag: "YAP",
41
- tone: "info",
42
- duration: true,
43
- },
44
- {
45
- caption: "Completion page is the durable proof",
46
- detail:
47
- "tone: success - the thank-you header is what verify asserts on.",
48
- tag: "YAP",
49
- tone: "success",
50
- selector: CheckoutOverviewSel.completeHeader,
51
- duration: 2500,
52
- fastMode: 700,
53
- },
54
- {
55
- caption: "Episode continues after this yap",
56
- detail: "Next step rings the same banner, then you move on.",
57
- tag: "YAP",
58
- tone: "planned",
59
- selector: CheckoutOverviewSel.completeHeader,
60
- duration: true,
61
- fastMode: 500,
62
- },
63
- ],
64
32
  },
65
33
  });
@@ -32,7 +32,7 @@ export const apiDemoEpisode = engine
32
32
  .start()
33
33
  .method(
34
34
  CheckBackendHealth.stubBefore((ctx) => {
35
- ctx.title("Checking backend health · real HTTP request, no browser");
35
+ ctx.ui.title("Checking backend health · real HTTP request, no browser");
36
36
  }),
37
37
  )
38
38
  .end();
@@ -10,7 +10,7 @@ export const cartBulkEpisode = engine
10
10
  .start()
11
11
  .method(
12
12
  AddAllToCartBlock.stubBefore((ctx) =>
13
- ctx.title("Cart bulk add/remove all"),
13
+ ctx.ui.title("Cart bulk add/remove all"),
14
14
  ),
15
15
  )
16
16
  .method(RemoveAllFromCartBlock)
@@ -7,7 +7,7 @@ export const cartContinueFlow = engine
7
7
  .map()
8
8
  .start()
9
9
  .gotoPage(
10
- NavCartBlock.stubBefore((ctx) => ctx.title("Cart then continue shopping")),
10
+ NavCartBlock.stubBefore((ctx) => ctx.ui.title("Cart then continue shopping")),
11
11
  )
12
12
  .gotoPage(NavContinueShoppingBlock)
13
13
  .end();
@@ -9,7 +9,7 @@ export const catalogLogoutFlow = engine
9
9
  .start()
10
10
  .gotoPage(
11
11
  NavItemDetailBlock.stubBefore((ctx) =>
12
- ctx.title("Catalog browse then logout"),
12
+ ctx.ui.title("Catalog browse then logout"),
13
13
  ),
14
14
  )
15
15
  .gotoPage(NavBackToInventoryBlock)
@@ -12,6 +12,7 @@ import { FillLastNameBlock } from "../blocks/saucedemo-web/checkout-step-one/met
12
12
  import { FillPostalCodeBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.js";
13
13
  import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.js";
14
14
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
15
+ import { orderPlacedYap, placingOrder } from "../stubs/finish-order.js";
15
16
  import { NavBackToProductsBlock } from "../blocks/saucedemo-web/inventory-item/nav-back-to-products.block.js";
16
17
 
17
18
  /** Full checkout, then the "Back Home" click-based Nav Block returns to the catalogue. */
@@ -20,7 +21,7 @@ export const checkoutThenBrowseAgainFlow = engine
20
21
  .start()
21
22
  .gotoPage(
22
23
  NavLoginBlock.stubBefore((ctx) =>
23
- ctx.title(
24
+ ctx.ui.title(
24
25
  "Owner: Checkout, then click Back Home (click-based NavBlock demo)",
25
26
  ),
26
27
  ),
@@ -35,6 +36,6 @@ export const checkoutThenBrowseAgainFlow = engine
35
36
  .method(FillLastNameBlock)
36
37
  .method(FillPostalCodeBlock)
37
38
  .method(SubmitCheckoutInfoBlock)
38
- .method(FinishOrderBlock)
39
+ .method(FinishOrderBlock.stubBefore(placingOrder).stubAfter(orderPlacedYap))
39
40
  .gotoPage(NavBackToProductsBlock)
40
41
  .end();
@@ -12,6 +12,7 @@ import { FillLastNameBlock } from "../blocks/saucedemo-web/checkout-step-one/met
12
12
  import { FillPostalCodeBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.js";
13
13
  import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.js";
14
14
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
15
+ import { orderPlacedYap, placingOrder } from "../stubs/finish-order.js";
15
16
  import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
16
17
 
17
18
  export const checkoutFlow = engine
@@ -20,7 +21,7 @@ export const checkoutFlow = engine
20
21
  .gotoPage(NavLoginBlock, { ff: true })
21
22
  .method(
22
23
  FillUsernameBlock.stubBefore((ctx) => {
23
- ctx.ring("username", {
24
+ ctx.ui.ring("username", {
24
25
  selector: LoginSel.username,
25
26
  label: "Demo user",
26
27
  detail:
@@ -34,7 +35,7 @@ export const checkoutFlow = engine
34
35
  )
35
36
  .method(
36
37
  FillPasswordBlock.stubBefore((ctx) => {
37
- ctx.ring("password", {
38
+ ctx.ui.ring("password", {
38
39
  selector: LoginSel.password,
39
40
  label: "Password",
40
41
  detail: "Filled from Mem credentials.",
@@ -46,7 +47,7 @@ export const checkoutFlow = engine
46
47
  )
47
48
  .method(
48
49
  SubmitLoginForFlow.stubBefore((ctx) => {
49
- ctx.ring("submit", {
50
+ ctx.ui.ring("submit", {
50
51
  selector: LoginSel.loginButton,
51
52
  label: "Sign in",
52
53
  tag: "GATE",
@@ -58,27 +59,27 @@ export const checkoutFlow = engine
58
59
  }),
59
60
  { ff: true },
60
61
  )
61
- .method(AddToCartBlock.stubBefore((ctx) => ctx.title("Owner: Full Checkout")))
62
+ .method(AddToCartBlock.stubBefore((ctx) => ctx.ui.title("Owner: Full Checkout")))
62
63
  .gotoPage(NavCartBlock)
63
64
  .gotoPage(NavCheckoutInfoBlock)
64
65
  .method(
65
66
  FillFirstNameBlock.stubBefore((ctx) => {
66
- ctx.caption("Enter the first name on the order");
67
- ctx.titlePos("left");
67
+ ctx.ui.caption("Enter the first name on the order");
68
+ ctx.ui.titlePos("left");
68
69
  }),
69
70
  )
70
71
  .method(
71
72
  FillLastNameBlock.stubBefore((ctx) => {
72
- ctx.caption("Enter the last name on the order");
73
- ctx.titlePos("center");
73
+ ctx.ui.caption("Enter the last name on the order");
74
+ ctx.ui.titlePos("center");
74
75
  }),
75
76
  )
76
77
  .method(
77
78
  FillPostalCodeBlock.stubBefore((ctx) => {
78
- ctx.caption("Enter a postal code to calculate shipping");
79
- ctx.titlePos("right");
79
+ ctx.ui.caption("Enter a postal code to calculate shipping");
80
+ ctx.ui.titlePos("right");
80
81
  }),
81
82
  )
82
- .method(SubmitCheckoutInfoBlock.stubBefore((ctx) => ctx.hideCaption()))
83
- .method(FinishOrderBlock)
83
+ .method(SubmitCheckoutInfoBlock.stubBefore((ctx) => ctx.ui.hideCaption()))
84
+ .method(FinishOrderBlock.stubBefore(placingOrder).stubAfter(orderPlacedYap))
84
85
  .end();
@@ -9,7 +9,7 @@ import { SubmitLoginForFlow } from "../blocks/saucedemo-web/methods/submit-login
9
9
  export const loginFlow = engine
10
10
  .map({ memStub: true })
11
11
  .start()
12
- .gotoPage(NavLoginBlock.stubBefore((ctx) => ctx.title("Sign In")))
12
+ .gotoPage(NavLoginBlock.stubBefore((ctx) => ctx.ui.title("Sign In")))
13
13
  .method(FillUsernameBlock)
14
14
  .method(FillPasswordBlock)
15
15
  .method(SubmitLoginForFlow)
@@ -8,17 +8,18 @@ import { FillLastNameBlock } from "../blocks/saucedemo-web/checkout-step-one/met
8
8
  import { FillPostalCodeBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.js";
9
9
  import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.js";
10
10
  import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
11
+ import { orderPlacedYap, placingOrder } from "../stubs/finish-order.js";
11
12
 
12
13
  /** Add the selected item, check out and place the order. Starts signed in (run it after loginFlow). */
13
14
  export const shopFlow = engine
14
15
  .map({ memStub: true })
15
16
  .start()
16
- .method(AddToCartBlock.stubBefore((ctx) => ctx.title("Shop & Checkout")))
17
+ .method(AddToCartBlock.stubBefore((ctx) => ctx.ui.title("Shop & Checkout")))
17
18
  .gotoPage(NavCartBlock)
18
19
  .gotoPage(NavCheckoutInfoBlock)
19
20
  .method(FillFirstNameBlock)
20
21
  .method(FillLastNameBlock)
21
22
  .method(FillPostalCodeBlock)
22
23
  .method(SubmitCheckoutInfoBlock)
23
- .method(FinishOrderBlock)
24
+ .method(FinishOrderBlock.stubBefore(placingOrder).stubAfter(orderPlacedYap))
24
25
  .end();
@@ -19,7 +19,7 @@ export const stubOnErrorFlow = engine
19
19
  .start()
20
20
  .gotoPage(
21
21
  NavLoginBlock.stubBefore((ctx) =>
22
- ctx.title("stubOnError: locked_out fail rings"),
22
+ ctx.ui.title("stubOnError: locked_out fail rings"),
23
23
  ),
24
24
  )
25
25
  .method(FillUsernameBlock)
@@ -19,7 +19,7 @@ export const viewerBlockedFlow = engine
19
19
  .start()
20
20
  .gotoPage(
21
21
  NavLoginBlock.stubBefore((ctx) =>
22
- ctx.title("Viewer: Blocked Login Attempt"),
22
+ ctx.ui.title("Viewer: Blocked Login Attempt"),
23
23
  ),
24
24
  )
25
25
  .method(FillUsernameBlock)