waygraph 0.15.0 → 0.15.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.
package/dist/cli.js CHANGED
@@ -3809,6 +3809,62 @@ async function hideRing(page) {
3809
3809
  .catch(() => {});
3810
3810
  }
3811
3811
 
3812
+ /**
3813
+ * Real navigation wipes document + overlay helpers. Reinstall and re-paint
3814
+ * carried todos / device / optional stubBefore ring so keep-dock and nav
3815
+ * highlights do not vanish until the next ctx.todos() / stubAfter (PIA #15).
3816
+ */
3817
+ async function restoreTheaterAfterNavigation(page, todoDockRef, deviceRef, stubBeforeRef) {
3818
+ const needs =
3819
+ (await page
3820
+ .evaluate(() => !window.__wgSyncTodos || !document.getElementById("wg-ring"))
3821
+ .catch(() => true)) || false;
3822
+ if (!needs) {
3823
+ // Overlay survived (SPA / no full document wipe) - still refresh dock
3824
+ // if Node has a carry and the DOM lost .wg-todo-dock.
3825
+ const hasDock = await page
3826
+ .evaluate(() => !!document.querySelector(".wg-todo-dock, #wg-todo-dock"))
3827
+ .catch(() => false);
3828
+ if (hasDock || !todoDockRef || !todoDockRef.current) return;
3829
+ }
3830
+ await installOverlay(page);
3831
+ const dock = todoDockRef && todoDockRef.current;
3832
+ if (dock) {
3833
+ await page
3834
+ .evaluate((d) => {
3835
+ if (window.__wgSyncTodos) window.__wgSyncTodos({ sync: "set", dock: d });
3836
+ }, dock)
3837
+ .catch(() => {});
3838
+ }
3839
+ if (deviceRef && deviceRef.current) {
3840
+ await applyDeviceToPage(page, deviceRef.current, "set").catch(() => {});
3841
+ }
3842
+ // Re-show first matching stubBefore ring if selector still exists (sidebar
3843
+ // nav targets often survive the route change).
3844
+ const stubs = (stubBeforeRef && stubBeforeRef.current) || [];
3845
+ for (const h of stubs) {
3846
+ if (!h || !h.selector) continue;
3847
+ const box = await page
3848
+ .evaluate((sel) => {
3849
+ const el = document.querySelector(sel);
3850
+ if (!el) return null;
3851
+ const r = el.getBoundingClientRect();
3852
+ if (r.width < 2 || r.height < 2) return null;
3853
+ return { x: r.x, y: r.y, width: r.width, height: r.height };
3854
+ }, h.selector)
3855
+ .catch(() => null);
3856
+ if (box) {
3857
+ await showRing(page, box, formatHighlightCaption(h), h.tone || "planned", {
3858
+ size: h.size,
3859
+ weight: h.weight,
3860
+ selector: h.selector,
3861
+ focus: !!h.focus,
3862
+ }).catch(() => {});
3863
+ break;
3864
+ }
3865
+ }
3866
+ }
3867
+
3812
3868
  /**
3813
3869
  * Removes every overlay element (panel, ring, ring-label, cursor,
3814
3870
  * click-pulse, banner) and stops the live resize/scroll ring tracker, once
@@ -4542,6 +4598,7 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
4542
4598
  // of leaving it lit until the next Block's own before-panel clears
4543
4599
  // it - it was sticking around through the whole rest of the step.
4544
4600
  await hideRing(page);
4601
+ await restoreTheaterAfterNavigation(page, todoDockRef, deviceRef, stubBeforeRef);
4545
4602
  return result;
4546
4603
  };
4547
4604
  }
@@ -4670,6 +4727,8 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
4670
4727
  }
4671
4728
  await new Promise((res) => setTimeout(res, clickPostPop()));
4672
4729
  await hideRing(page);
4730
+ // Full document navigation drops #wg-todo-dock + rings; restore carry.
4731
+ await restoreTheaterAfterNavigation(page, todoDockRef, deviceRef, stubBeforeRef);
4673
4732
  return result;
4674
4733
  };
4675
4734
  }
@@ -4921,17 +4980,21 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
4921
4980
  if (sync === "set" && dock) {
4922
4981
  if (!parallel) todoDockById.clear();
4923
4982
  todoDockById.set(dockRegistryKey(dock), dock);
4983
+ return;
4984
+ }
4985
+ // keep: refresh / re-seed so syncAllTodoDocks never sees an empty map
4986
+ // while lastTodoDock still carries (nav wipe + mid-act advance).
4987
+ if (sync === "keep" && dock) {
4988
+ todoDockById.set(dockRegistryKey(dock), dock);
4924
4989
  }
4925
4990
  };
4926
4991
  const syncAllTodoDocks = async (opts) => {
4927
4992
  const docks = [...todoDockById.values()];
4928
4993
  const parallel = !!(opts && opts.parallel);
4929
4994
  if (!docks.length) {
4930
- await page
4931
- .evaluate(() => {
4932
- if (window.__wgSyncTodos) window.__wgSyncTodos({ sync: "clear" });
4933
- })
4934
- .catch(() => {});
4995
+ // Empty registry: do NOT clear the DOM. renderBefore/After may have
4996
+ // just painted from lastTodoDock (keep). Clearing here made todos
4997
+ // vanish until the next ctx.todos() set (PIA #15).
4935
4998
  return;
4936
4999
  }
4937
5000
  await page
@@ -38,9 +38,9 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
38
38
  cart: {
39
39
  selector: CartSel.cartLink,
40
40
  label: "Cart",
41
- detail: "Open cart",
41
+ detail: "tone: planned (purple) - open cart",
42
+ tone: "planned",
42
43
  focus: true,
43
- color: "#c9a6ff",
44
44
  zoomOut: false,
45
45
  followMouse: false,
46
46
  weight: "bold",
@@ -56,9 +56,9 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
56
56
  ctx.ring("items", {
57
57
  selector: InventorySel.cartItem,
58
58
  label: "Cart items",
59
- detail: "Product landed in cart",
59
+ detail: "tone: success (green) - product in cart",
60
+ tone: "success",
60
61
  focus: true,
61
- color: "#86efac",
62
62
  zoomOut: true,
63
63
  followMouse: false,
64
64
  duration: true,
@@ -20,13 +20,20 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
20
20
  resolve: () => checkpoint("OrderComplete"),
21
21
  verify: [Trait.text(CheckoutOverviewSel.completeHeader, "Thank you for your order!")],
22
22
  stubBefore: {
23
- finish: { selector: CheckoutOverviewSel.finishBtn, label: "Finish" },
23
+ finish: {
24
+ selector: CheckoutOverviewSel.finishBtn,
25
+ label: "Finish",
26
+ detail: "tone: warning (yellow) - place order",
27
+ tone: "warning",
28
+ weight: "bold",
29
+ },
24
30
  },
25
31
  stubAfter: {
26
32
  thanks: {
27
33
  selector: CheckoutOverviewSel.completeHeader,
28
34
  label: "Order confirmed",
29
- detail: "Thank you for your order!",
35
+ detail: "tone: success (green) - thank you!",
36
+ tone: "success",
30
37
  duration: true,
31
38
  },
32
39
  },
@@ -37,12 +44,14 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
37
44
  caption: "Checkout is a short pipeline",
38
45
  detail: "Cart -> info -> overview -> done. You just placed the order.",
39
46
  tag: "YAP",
47
+ tone: "info",
40
48
  duration: true,
41
49
  },
42
50
  {
43
51
  caption: "Completion page is the durable proof",
44
- detail: "The thank-you header is what verify asserts on.",
52
+ detail: "tone: success - the thank-you header is what verify asserts on.",
45
53
  tag: "YAP",
54
+ tone: "success",
46
55
  selector: CheckoutOverviewSel.completeHeader,
47
56
  duration: 2500,
48
57
  fastMode: 700,
@@ -51,6 +60,7 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
51
60
  caption: "Episode continues after this yap",
52
61
  detail: "Next step rings the same banner, then you move on.",
53
62
  tag: "YAP",
63
+ tone: "planned",
54
64
  selector: CheckoutOverviewSel.completeHeader,
55
65
  duration: true,
56
66
  fastMode: 500,
@@ -57,17 +57,18 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
57
57
  product: {
58
58
  selector: InventorySel.title(DEMO_PRODUCT_ID),
59
59
  label: "Sauce Labs Backpack",
60
- detail: "Zoom the product",
60
+ detail: "tone: info (blue)",
61
+ tone: "info",
61
62
  focus: true,
62
- color: "#c9a6ff",
63
63
  zoom: 1.45,
64
64
  zoomOut: false,
65
65
  },
66
66
  add: {
67
67
  selector: InventorySel.addBtn(DEMO_PRODUCT_ID),
68
68
  label: "Add to cart",
69
+ detail: "tone: success (green)",
70
+ tone: "success",
69
71
  focus: true,
70
- color: "#86efac",
71
72
  zoom: 1.5,
72
73
  zoomOut: false,
73
74
  weight: "bold",
@@ -92,9 +93,9 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
92
93
  ctx.ring("badge", {
93
94
  selector: InventorySel.cartBadge,
94
95
  label: "Cart badge",
95
- detail: "Item count updated",
96
+ detail: "tone: success (green) - count updated",
97
+ tone: "success",
96
98
  focus: true,
97
- color: "#86efac",
98
99
  zoomOut: false,
99
100
  duration: true,
100
101
  });
@@ -26,9 +26,10 @@ export const FillPasswordBlock = defineMethodBlock<LoginPage, LoginPage>({
26
26
  password: {
27
27
  selector: LoginSel.password,
28
28
  label: "Password",
29
+ detail: "tone: planned (purple)",
29
30
  todo: "login-pass",
31
+ tone: "planned",
30
32
  focus: true,
31
- color: "#c9a6ff",
32
33
  zoom: 1.4,
33
34
  },
34
35
  });
@@ -44,9 +44,10 @@ export const FillUsernameBlock = defineMethodBlock<LoginPage, LoginPage>({
44
44
  username: {
45
45
  selector: LoginSel.username,
46
46
  label: "Username",
47
+ detail: "tone: info (blue)",
47
48
  todo: "login-user",
49
+ tone: "info",
48
50
  focus: true,
49
- color: "#c9a6ff",
50
51
  zoom: 1.4,
51
52
  },
52
53
  });
@@ -48,9 +48,10 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
48
48
  submit: {
49
49
  selector: LoginSel.loginButton,
50
50
  label: "Login",
51
+ detail: "tone: warning (yellow)",
51
52
  todo: "login-submit",
53
+ tone: "warning",
52
54
  focus: true,
53
- color: "#86efac",
54
55
  zoom: 1.55,
55
56
  weight: "bold",
56
57
  gesture: "tap",
@@ -72,9 +73,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
72
73
  ctx.ring("error", {
73
74
  selector: LoginSel.errorBanner,
74
75
  label: "Login error banner",
76
+ detail: "tone: danger (red)",
75
77
  tone: "danger",
76
78
  focus: true,
77
- color: "#f87171",
78
79
  duration: true,
79
80
  });
80
81
  return;
@@ -96,9 +97,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
96
97
  ctx.ring("shelf", {
97
98
  selector: ".inventory_list",
98
99
  label: "Product shelf",
99
- detail: "Ready to shop",
100
+ detail: "tone: success (green) - ready to shop",
101
+ tone: "success",
100
102
  focus: true,
101
- color: "#c9a6ff",
102
103
  zoom: 1.25,
103
104
  duration: true,
104
105
  });
@@ -108,9 +109,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
108
109
  ctx.ring("error", {
109
110
  selector: LoginSel.errorBanner,
110
111
  label: "Login error banner",
112
+ detail: "tone: danger (red)",
111
113
  tone: "danger",
112
114
  focus: true,
113
- color: "#f87171",
114
115
  duration: true,
115
116
  });
116
117
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",
@@ -38,9 +38,9 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
38
38
  cart: {
39
39
  selector: CartSel.cartLink,
40
40
  label: "Cart",
41
- detail: "Open cart",
41
+ detail: "tone: planned (purple) - open cart",
42
+ tone: "planned",
42
43
  focus: true,
43
- color: "#c9a6ff",
44
44
  zoomOut: false,
45
45
  followMouse: false,
46
46
  weight: "bold",
@@ -56,9 +56,9 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
56
56
  ctx.ring("items", {
57
57
  selector: InventorySel.cartItem,
58
58
  label: "Cart items",
59
- detail: "Product landed in cart",
59
+ detail: "tone: success (green) - product in cart",
60
+ tone: "success",
60
61
  focus: true,
61
- color: "#86efac",
62
62
  zoomOut: true,
63
63
  followMouse: false,
64
64
  duration: true,
@@ -20,13 +20,20 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
20
20
  resolve: () => checkpoint("OrderComplete"),
21
21
  verify: [Trait.text(CheckoutOverviewSel.completeHeader, "Thank you for your order!")],
22
22
  stubBefore: {
23
- finish: { selector: CheckoutOverviewSel.finishBtn, label: "Finish" },
23
+ finish: {
24
+ selector: CheckoutOverviewSel.finishBtn,
25
+ label: "Finish",
26
+ detail: "tone: warning (yellow) - place order",
27
+ tone: "warning",
28
+ weight: "bold",
29
+ },
24
30
  },
25
31
  stubAfter: {
26
32
  thanks: {
27
33
  selector: CheckoutOverviewSel.completeHeader,
28
34
  label: "Order confirmed",
29
- detail: "Thank you for your order!",
35
+ detail: "tone: success (green) - thank you!",
36
+ tone: "success",
30
37
  duration: true,
31
38
  },
32
39
  },
@@ -37,12 +44,14 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
37
44
  caption: "Checkout is a short pipeline",
38
45
  detail: "Cart -> info -> overview -> done. You just placed the order.",
39
46
  tag: "YAP",
47
+ tone: "info",
40
48
  duration: true,
41
49
  },
42
50
  {
43
51
  caption: "Completion page is the durable proof",
44
- detail: "The thank-you header is what verify asserts on.",
52
+ detail: "tone: success - the thank-you header is what verify asserts on.",
45
53
  tag: "YAP",
54
+ tone: "success",
46
55
  selector: CheckoutOverviewSel.completeHeader,
47
56
  duration: 2500,
48
57
  fastMode: 700,
@@ -51,6 +60,7 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
51
60
  caption: "Episode continues after this yap",
52
61
  detail: "Next step rings the same banner, then you move on.",
53
62
  tag: "YAP",
63
+ tone: "planned",
54
64
  selector: CheckoutOverviewSel.completeHeader,
55
65
  duration: true,
56
66
  fastMode: 500,
@@ -57,17 +57,18 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
57
57
  product: {
58
58
  selector: InventorySel.title(DEMO_PRODUCT_ID),
59
59
  label: "Sauce Labs Backpack",
60
- detail: "Zoom the product",
60
+ detail: "tone: info (blue)",
61
+ tone: "info",
61
62
  focus: true,
62
- color: "#c9a6ff",
63
63
  zoom: 1.45,
64
64
  zoomOut: false,
65
65
  },
66
66
  add: {
67
67
  selector: InventorySel.addBtn(DEMO_PRODUCT_ID),
68
68
  label: "Add to cart",
69
+ detail: "tone: success (green)",
70
+ tone: "success",
69
71
  focus: true,
70
- color: "#86efac",
71
72
  zoom: 1.5,
72
73
  zoomOut: false,
73
74
  weight: "bold",
@@ -92,9 +93,9 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
92
93
  ctx.ring("badge", {
93
94
  selector: InventorySel.cartBadge,
94
95
  label: "Cart badge",
95
- detail: "Item count updated",
96
+ detail: "tone: success (green) - count updated",
97
+ tone: "success",
96
98
  focus: true,
97
- color: "#86efac",
98
99
  zoomOut: false,
99
100
  duration: true,
100
101
  });
@@ -26,9 +26,10 @@ export const FillPasswordBlock = defineMethodBlock<LoginPage, LoginPage>({
26
26
  password: {
27
27
  selector: LoginSel.password,
28
28
  label: "Password",
29
+ detail: "tone: planned (purple)",
29
30
  todo: "login-pass",
31
+ tone: "planned",
30
32
  focus: true,
31
- color: "#c9a6ff",
32
33
  zoom: 1.4,
33
34
  },
34
35
  });
@@ -44,9 +44,10 @@ export const FillUsernameBlock = defineMethodBlock<LoginPage, LoginPage>({
44
44
  username: {
45
45
  selector: LoginSel.username,
46
46
  label: "Username",
47
+ detail: "tone: info (blue)",
47
48
  todo: "login-user",
49
+ tone: "info",
48
50
  focus: true,
49
- color: "#c9a6ff",
50
51
  zoom: 1.4,
51
52
  },
52
53
  });
@@ -48,9 +48,10 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
48
48
  submit: {
49
49
  selector: LoginSel.loginButton,
50
50
  label: "Login",
51
+ detail: "tone: warning (yellow)",
51
52
  todo: "login-submit",
53
+ tone: "warning",
52
54
  focus: true,
53
- color: "#86efac",
54
55
  zoom: 1.55,
55
56
  weight: "bold",
56
57
  gesture: "tap",
@@ -72,9 +73,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
72
73
  ctx.ring("error", {
73
74
  selector: LoginSel.errorBanner,
74
75
  label: "Login error banner",
76
+ detail: "tone: danger (red)",
75
77
  tone: "danger",
76
78
  focus: true,
77
- color: "#f87171",
78
79
  duration: true,
79
80
  });
80
81
  return;
@@ -96,9 +97,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
96
97
  ctx.ring("shelf", {
97
98
  selector: ".inventory_list",
98
99
  label: "Product shelf",
99
- detail: "Ready to shop",
100
+ detail: "tone: success (green) - ready to shop",
101
+ tone: "success",
100
102
  focus: true,
101
- color: "#c9a6ff",
102
103
  zoom: 1.25,
103
104
  duration: true,
104
105
  });
@@ -108,9 +109,9 @@ export const SubmitLoginBlock = defineMethodBlock<LoginPage, LoginSubmitOutcome>
108
109
  ctx.ring("error", {
109
110
  selector: LoginSel.errorBanner,
110
111
  label: "Login error banner",
112
+ detail: "tone: danger (red)",
111
113
  tone: "danger",
112
114
  focus: true,
113
- color: "#f87171",
114
115
  duration: true,
115
116
  });
116
117
  },