waygraph 0.16.1 → 0.16.2

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 (55) hide show
  1. package/dist/cli/commands/codemod-stubs.js +90 -2
  2. package/dist/cli/run-chain.js +2 -2
  3. package/dist/cli/util.js +1 -1
  4. package/dist/demo/narration/demo-pace.d.ts +1 -1
  5. package/dist/demo/narration/demo-pace.js +1 -1
  6. package/dist/demo/narration/merge.d.ts +1 -1
  7. package/dist/demo/narration/merge.js +1 -1
  8. package/dist/demo/narration/narration.d.ts +2 -6
  9. package/dist/demo/narration/narration.js +5 -17
  10. package/dist/demo/narration/stub-ctx.js +3 -3
  11. package/dist/demo/overlay/inpage/core.js +0 -6
  12. package/dist/demo/overlay/overlay-css.js +1 -55
  13. package/dist/demo/overlay/overlay.js +3 -2
  14. package/dist/demo/overlay/rings.d.ts +0 -8
  15. package/dist/demo/overlay/rings.js +0 -15
  16. package/dist/demo/overlay/ui/overlay.css +40 -0
  17. package/dist/demo/stepper/after.js +4 -17
  18. package/dist/demo/stepper/before.js +3 -1
  19. package/dist/demo/stepper/demo-log.js +1 -1
  20. package/dist/demo/stepper/interaction-patch.js +3 -15
  21. package/dist/demo/stepper/panel-after.js +1 -1
  22. package/dist/demo/stepper/slides.d.ts +3 -0
  23. package/dist/demo/stepper/slides.js +18 -2
  24. package/dist/demo/stepper/teardown.js +0 -1
  25. package/dist/demo/verbose-log.js +1 -1
  26. package/dist/engine/block/block.d.ts +1 -12
  27. package/dist/engine/block/kinds/method.d.ts +0 -2
  28. package/dist/engine/block/kinds/method.js +0 -1
  29. package/dist/engine/block/kinds/nav.js +1 -1
  30. package/dist/engine/run/run.d.ts +1 -19
  31. package/dist/engine/run/run.js +0 -88
  32. package/dist/engine/stub/ring.d.ts +2 -4
  33. package/dist/engine/stub/ring.js +1 -0
  34. package/dist/engine/stub/stub.d.ts +16 -8
  35. package/dist/index.d.ts +2 -3
  36. package/dist/index.js +2 -2
  37. package/dist/runner/plan/find.js +2 -2
  38. package/dist/runner/plan/plan.js +1 -1
  39. package/dist/runner/plan/seed-mem.js +5 -5
  40. package/dist/runner/plan/spec.js +1 -1
  41. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
  42. package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +2 -1
  43. package/examples/saucedemo/src/flows/checkout.flow.ts +2 -1
  44. package/examples/saucedemo/src/flows/shop.flow.ts +2 -1
  45. package/examples/saucedemo/src/stubs/device-showcase.ts +37 -43
  46. package/examples/saucedemo/src/stubs/finish-order.ts +38 -0
  47. package/package.json +1 -1
  48. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
  49. package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +2 -1
  50. package/templates/quickstart/src/flows/checkout.flow.ts +2 -1
  51. package/templates/quickstart/src/flows/shop.flow.ts +2 -1
  52. package/templates/quickstart/src/stubs/device-showcase.ts +37 -43
  53. package/templates/quickstart/src/stubs/finish-order.ts +38 -0
  54. package/templates/scaffold/src/flows/home/hello.flow.ts +3 -0
  55. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +1 -9
@@ -78,18 +78,16 @@ export const deviceShowcase = {
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.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) => {
@@ -115,26 +113,24 @@ export const deviceShowcase = {
115
113
  ctx.todos("saucedemo", ...checklist(3, 3));
116
114
  ctx.zoom(1.35);
117
115
  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
- },
116
+ ctx.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.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) => {
@@ -159,17 +155,15 @@ export const deviceShowcase = {
159
155
  ctx.todos("saucedemo", ...checklist(5, 5));
160
156
  ctx.zoom(1.4);
161
157
  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
- },
158
+ ctx.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) => {
@@ -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.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.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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -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
  });
@@ -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. */
@@ -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
@@ -80,5 +81,5 @@ export const checkoutFlow = engine
80
81
  }),
81
82
  )
82
83
  .method(SubmitCheckoutInfoBlock.stubBefore((ctx) => ctx.hideCaption()))
83
- .method(FinishOrderBlock)
84
+ .method(FinishOrderBlock.stubBefore(placingOrder).stubAfter(orderPlacedYap))
84
85
  .end();
@@ -8,6 +8,7 @@ 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
@@ -20,5 +21,5 @@ export const shopFlow = engine
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();
@@ -78,18 +78,16 @@ export const deviceShowcase = {
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.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) => {
@@ -115,26 +113,24 @@ export const deviceShowcase = {
115
113
  ctx.todos("saucedemo", ...checklist(3, 3));
116
114
  ctx.zoom(1.35);
117
115
  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
- },
116
+ ctx.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.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) => {
@@ -159,17 +155,15 @@ export const deviceShowcase = {
159
155
  ctx.todos("saucedemo", ...checklist(5, 5));
160
156
  ctx.zoom(1.4);
161
157
  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
- },
158
+ ctx.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) => {
@@ -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.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.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
+ }
@@ -33,6 +33,9 @@ export const homeHelloFlow = engine
33
33
  duration: true,
34
34
  });
35
35
  ctx.ring("sub", { selector: DemoSel.sub, label: "Subcopy", duration: 1500 });
36
+ ctx.slides([
37
+ { caption: "Scaffold covers auto + narration", detail: "Page hub, Effect instanceOptions, stubs, YAP.", tag: "YAP", duration: true },
38
+ ]);
36
39
  })
37
40
  .stubOnError((ctx) => {
38
41
  ctx.ring("title", { selector: DemoSel.title, label: "Heading at failure", tag: "FAIL" });
@@ -2,19 +2,11 @@ import { defineAssertBlock, Trait } from "waygraph";
2
2
  import { Home } from "../../../../states/demo.states.js";
3
3
  import { DemoSel } from "../_sel.js";
4
4
 
5
- /** Heading still shows after arrival; the slide is a YAP caption for the demo overlay. */
5
+ /** Heading still shows after arrival. */
6
6
  export const AssertHelloBlock = defineAssertBlock({
7
7
  name: "assert-hello",
8
8
  description: "Confirms the hello heading is still visible after arrival.",
9
9
  checkpoint: Home,
10
10
  waitForHeading: "Hello Waygraph",
11
11
  verify: [Trait.text(DemoSel.title, "Hello Waygraph"), Trait.visible(DemoSel.sub)],
12
- slides: [
13
- {
14
- caption: "Scaffold covers auto + narration",
15
- detail: "Page hub, Effect instanceOptions, stubs, fixtures, YAP.",
16
- tag: "YAP",
17
- duration: true,
18
- },
19
- ],
20
12
  });