waygraph 0.12.34 → 0.12.35
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 +17 -5
- package/dist/highlights.d.ts +15 -3
- package/dist/highlights.js +12 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +4 -1
- package/package.json +1 -1
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +4 -1
package/dist/cli.js
CHANGED
|
@@ -829,11 +829,15 @@ async function installOverlay(page, title) {
|
|
|
829
829
|
const el0 = document.querySelector(sel);
|
|
830
830
|
if (el0) {
|
|
831
831
|
const r0 = el0.getBoundingClientRect();
|
|
832
|
+
const already =
|
|
833
|
+
window.__wgCamera && window.__wgCamera.scale > 1.001;
|
|
834
|
+
// Already zoomed (zoomOut:false chain): short pan, not full zoom-in.
|
|
835
|
+
const dur = already ? Math.min(camMs, 420) : camMs;
|
|
832
836
|
window.__wgSetCamera(
|
|
833
837
|
r0.left + r0.width / 2,
|
|
834
838
|
r0.top + r0.height / 2,
|
|
835
839
|
zoom,
|
|
836
|
-
|
|
840
|
+
dur,
|
|
837
841
|
);
|
|
838
842
|
}
|
|
839
843
|
}
|
|
@@ -1590,7 +1594,11 @@ async function cycleHighlightRings(page, highlights, gatesFast, opts) {
|
|
|
1590
1594
|
},
|
|
1591
1595
|
)
|
|
1592
1596
|
.catch(() => {});
|
|
1593
|
-
|
|
1597
|
+
const alreadyZoomed = await page
|
|
1598
|
+
.evaluate(() => !!(window.__wgCamera && window.__wgCamera.scale > 1.001))
|
|
1599
|
+
.catch(() => false);
|
|
1600
|
+
const waitMs = alreadyZoomed ? Math.min(camMs, 420) : camMs;
|
|
1601
|
+
await new Promise((res) => setTimeout(res, waitMs));
|
|
1594
1602
|
|
|
1595
1603
|
// Appear settle
|
|
1596
1604
|
await new Promise((res) => setTimeout(res, fadeMs));
|
|
@@ -1599,11 +1607,12 @@ async function cycleHighlightRings(page, highlights, gatesFast, opts) {
|
|
|
1599
1607
|
const holdMs =
|
|
1600
1608
|
authored != null ? authored : defaultHoldMs != null ? defaultHoldMs : legacyMs;
|
|
1601
1609
|
await new Promise((res) => setTimeout(res, holdMs));
|
|
1602
|
-
// Disappear before next
|
|
1610
|
+
// Disappear before next. zoomOut:false keeps camera for the next ring.
|
|
1603
1611
|
await stopLiveFollow();
|
|
1604
1612
|
await hideRing(page);
|
|
1605
|
-
|
|
1606
|
-
|
|
1613
|
+
const doZoomOut = h.zoomOut !== false;
|
|
1614
|
+
if (doZoomOut) await resetCameraZoom(page);
|
|
1615
|
+
await new Promise((res) => setTimeout(res, doZoomOut ? fadeMs : 120));
|
|
1607
1616
|
} catch {
|
|
1608
1617
|
/* best-effort */
|
|
1609
1618
|
}
|
|
@@ -2939,6 +2948,7 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
|
|
|
2939
2948
|
focus: styled.focus,
|
|
2940
2949
|
color: styled.color,
|
|
2941
2950
|
cursor: styled.cursor,
|
|
2951
|
+
zoomOut: styled.zoomOut,
|
|
2942
2952
|
};
|
|
2943
2953
|
});
|
|
2944
2954
|
await cycleHighlightRings(page, beforeRings, !!pacing.gatesFast, {
|
|
@@ -3019,6 +3029,7 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
|
|
|
3019
3029
|
focus: styled.focus,
|
|
3020
3030
|
color: styled.color,
|
|
3021
3031
|
cursor: styled.cursor,
|
|
3032
|
+
zoomOut: styled.zoomOut,
|
|
3022
3033
|
};
|
|
3023
3034
|
});
|
|
3024
3035
|
await cycleHighlightRings(page, errHighlights, !!pacing.gatesFast, {
|
|
@@ -3113,6 +3124,7 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
|
|
|
3113
3124
|
focus: styled.focus,
|
|
3114
3125
|
color: styled.color,
|
|
3115
3126
|
cursor: styled.cursor,
|
|
3127
|
+
zoomOut: styled.zoomOut,
|
|
3116
3128
|
};
|
|
3117
3129
|
});
|
|
3118
3130
|
} else {
|
package/dist/highlights.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export type StubPhaseFixtures = {
|
|
|
50
50
|
* cursor. Not element CSS zoom. Typical `1.25` .. `2`.
|
|
51
51
|
*/
|
|
52
52
|
zoom?: number;
|
|
53
|
+
/** Default zoomOut for rings (false = keep camera between rings). */
|
|
54
|
+
zoomOut?: boolean;
|
|
53
55
|
/** Top demo banner title (the purple "waygraph demo" card). */
|
|
54
56
|
title?: string;
|
|
55
57
|
};
|
|
@@ -81,10 +83,15 @@ export interface WaygraphHighlightStub extends FixtureDurationFields {
|
|
|
81
83
|
weight?: HighlightWeight;
|
|
82
84
|
/**
|
|
83
85
|
* Camera zoom while this ring is up (Screen Studio style - page scales toward
|
|
84
|
-
* the target / cursor). Typical `1.25` .. `2`. Cleared when the ring hides
|
|
85
|
-
* Episode default: {@link StubCtx.zoom}.
|
|
86
|
+
* the target / cursor). Typical `1.25` .. `2`. Cleared when the ring hides
|
|
87
|
+
* unless `zoomOut: false`. Episode default: {@link StubCtx.zoom}.
|
|
86
88
|
*/
|
|
87
89
|
zoom?: number;
|
|
90
|
+
/**
|
|
91
|
+
* When false, keep the camera zoomed after this ring (pan to the next target
|
|
92
|
+
* instead of zooming out). Default true. Phase default: {@link StubCtx.zoomOut}.
|
|
93
|
+
*/
|
|
94
|
+
zoomOut?: boolean;
|
|
88
95
|
/**
|
|
89
96
|
* Spotlight: dim the rest of the page, keep this target as the focal point.
|
|
90
97
|
*/
|
|
@@ -109,7 +116,7 @@ export interface WaygraphHighlightStub extends FixtureDurationFields {
|
|
|
109
116
|
cursor?: boolean;
|
|
110
117
|
}
|
|
111
118
|
/** Flow fixture patch: label required; selector optional (inherits from stub). */
|
|
112
|
-
export type WaygraphHighlightFixture = Partial<Pick<WaygraphHighlightStub, "selector">> & Required<Pick<WaygraphHighlightStub, "label">> & Pick<WaygraphHighlightStub, "detail" | "tag" | "tone" | "size" | "weight" | "zoom" | "focus" | "followMouse" | "follow" | "color" | "cursor"> & FixtureDurationFields;
|
|
119
|
+
export type WaygraphHighlightFixture = Partial<Pick<WaygraphHighlightStub, "selector">> & Required<Pick<WaygraphHighlightStub, "label">> & Pick<WaygraphHighlightStub, "detail" | "tag" | "tone" | "size" | "weight" | "zoom" | "zoomOut" | "focus" | "followMouse" | "follow" | "color" | "cursor"> & FixtureDurationFields;
|
|
113
120
|
export type HighlightStubPhase = Record<string, WaygraphHighlightStub>;
|
|
114
121
|
/**
|
|
115
122
|
* Open stub lifecycle context. Authors set rings + episode fixtures freely —
|
|
@@ -147,6 +154,10 @@ export type StubCtx<Out extends Checkpoint<string> = Checkpoint<string>> = {
|
|
|
147
154
|
todoIndex(n: number): void;
|
|
148
155
|
/** Default camera zoom for rings without their own zoom. */
|
|
149
156
|
zoom(n: number): void;
|
|
157
|
+
/**
|
|
158
|
+
* Default zoomOut for rings in this phase. `false` = keep camera between rings.
|
|
159
|
+
*/
|
|
160
|
+
zoomOut(keep: boolean): void;
|
|
150
161
|
/** Top banner title (waygraph demo card). */
|
|
151
162
|
title(text: string): void;
|
|
152
163
|
/** Alias for {@link StubCtx.title}. */
|
|
@@ -170,6 +181,7 @@ export type StubPhaseResult = {
|
|
|
170
181
|
todos: WaygraphTodoItem[];
|
|
171
182
|
todoIndex?: number;
|
|
172
183
|
zoom?: number;
|
|
184
|
+
zoomOut?: boolean;
|
|
173
185
|
title?: string;
|
|
174
186
|
};
|
|
175
187
|
/**
|
package/dist/highlights.js
CHANGED
|
@@ -403,6 +403,9 @@ function createStubCtx(bag, opts) {
|
|
|
403
403
|
if (Number.isFinite(n) && n > 0)
|
|
404
404
|
bag.zoom = n;
|
|
405
405
|
},
|
|
406
|
+
zoomOut(keep) {
|
|
407
|
+
bag.zoomOut = !!keep;
|
|
408
|
+
},
|
|
406
409
|
title(text) {
|
|
407
410
|
bag.title = String(text ?? "");
|
|
408
411
|
},
|
|
@@ -419,6 +422,8 @@ function createStubCtx(bag, opts) {
|
|
|
419
422
|
if (partial.zoom !== undefined && Number.isFinite(partial.zoom) && partial.zoom > 0) {
|
|
420
423
|
bag.zoom = partial.zoom;
|
|
421
424
|
}
|
|
425
|
+
if (partial.zoomOut !== undefined)
|
|
426
|
+
bag.zoomOut = !!partial.zoomOut;
|
|
422
427
|
if (partial.title !== undefined)
|
|
423
428
|
bag.title = String(partial.title ?? "");
|
|
424
429
|
},
|
|
@@ -443,6 +448,11 @@ function applyDefaultZoom(slots, defaultZoom) {
|
|
|
443
448
|
return slots;
|
|
444
449
|
return slots.map((h) => (h.zoom !== undefined && h.zoom > 0 ? h : { ...h, zoom: defaultZoom }));
|
|
445
450
|
}
|
|
451
|
+
function applyDefaultZoomOut(slots, defaultZoomOut) {
|
|
452
|
+
if (defaultZoomOut === undefined)
|
|
453
|
+
return slots;
|
|
454
|
+
return slots.map((h) => h.zoomOut !== undefined ? h : { ...h, zoomOut: defaultZoomOut });
|
|
455
|
+
}
|
|
446
456
|
function mergePhaseMaps(phaseMap, fixturePhase) {
|
|
447
457
|
const slotIds = new Set([...Object.keys(phaseMap), ...Object.keys(fixturePhase || {})]);
|
|
448
458
|
const ordered = [...slotIds].sort((a, b) => {
|
|
@@ -546,12 +556,14 @@ export async function runStubPhase(block, phase, opts) {
|
|
|
546
556
|
const fixturePhase = opts?.fixtures?.[block.name]?.[phase];
|
|
547
557
|
let highlights = mergePhaseMaps(bag.highlights, fixturePhase);
|
|
548
558
|
highlights = applyDefaultZoom(highlights, bag.zoom);
|
|
559
|
+
highlights = applyDefaultZoomOut(highlights, bag.zoomOut);
|
|
549
560
|
const todos = normalizeTodos(bag.todos, bag.todoIndex);
|
|
550
561
|
return {
|
|
551
562
|
highlights,
|
|
552
563
|
todos,
|
|
553
564
|
...(bag.todoIndex !== undefined ? { todoIndex: bag.todoIndex } : {}),
|
|
554
565
|
...(bag.zoom !== undefined ? { zoom: bag.zoom } : {}),
|
|
566
|
+
...(bag.zoomOut !== undefined ? { zoomOut: bag.zoomOut } : {}),
|
|
555
567
|
...(bag.title !== undefined && bag.title !== "" ? { title: bag.title } : {}),
|
|
556
568
|
};
|
|
557
569
|
}
|
|
@@ -15,7 +15,6 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
15
15
|
checkpoint: "CartPage",
|
|
16
16
|
click: ".shopping_cart_link",
|
|
17
17
|
verify: [Trait.url({ pathname: "/cart.html" })],
|
|
18
|
-
// Demo: zoom cart chrome, then the cart line items after landing.
|
|
19
18
|
stubBefore: (ctx) => {
|
|
20
19
|
ctx.title("Open cart");
|
|
21
20
|
ctx.todos(["Find the product", "Add to cart", "Open cart"]);
|
|
@@ -29,6 +28,7 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
29
28
|
focus: true,
|
|
30
29
|
color: "#c9a6ff",
|
|
31
30
|
zoom: 1.55,
|
|
31
|
+
zoomOut: false,
|
|
32
32
|
followMouse: true,
|
|
33
33
|
weight: "bold",
|
|
34
34
|
},
|
|
@@ -36,6 +36,7 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
36
36
|
},
|
|
37
37
|
stubAfter: (ctx) => {
|
|
38
38
|
ctx.banner("Your cart");
|
|
39
|
+
ctx.zoomOut(false);
|
|
39
40
|
ctx.ring("items", {
|
|
40
41
|
selector: InventorySel.cartItem,
|
|
41
42
|
label: "Cart items",
|
package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts
CHANGED
|
@@ -33,12 +33,13 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
35
|
],
|
|
36
|
-
// Demo
|
|
36
|
+
// Demo: zoom product -> add (stay zoomed), then badge after act.
|
|
37
37
|
stubBefore: (ctx) => {
|
|
38
38
|
ctx.title("Pick a product");
|
|
39
39
|
ctx.todos(["Find the product", "Add to cart", "Open cart"]);
|
|
40
40
|
ctx.todoIndex(0);
|
|
41
41
|
ctx.zoom(1.35);
|
|
42
|
+
ctx.zoomOut(false);
|
|
42
43
|
ctx.highlights({
|
|
43
44
|
product: {
|
|
44
45
|
selector: InventorySel.title(DEMO_PRODUCT_ID),
|
|
@@ -47,6 +48,7 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
47
48
|
focus: true,
|
|
48
49
|
color: "#c9a6ff",
|
|
49
50
|
zoom: 1.45,
|
|
51
|
+
zoomOut: false,
|
|
50
52
|
followMouse: true,
|
|
51
53
|
},
|
|
52
54
|
add: {
|
|
@@ -55,6 +57,7 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
55
57
|
focus: true,
|
|
56
58
|
color: "#86efac",
|
|
57
59
|
zoom: 1.5,
|
|
60
|
+
zoomOut: false,
|
|
58
61
|
weight: "bold",
|
|
59
62
|
},
|
|
60
63
|
});
|
package/package.json
CHANGED
|
@@ -15,7 +15,6 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
15
15
|
checkpoint: "CartPage",
|
|
16
16
|
click: ".shopping_cart_link",
|
|
17
17
|
verify: [Trait.url({ pathname: "/cart.html" })],
|
|
18
|
-
// Demo: zoom cart chrome, then the cart line items after landing.
|
|
19
18
|
stubBefore: (ctx) => {
|
|
20
19
|
ctx.title("Open cart");
|
|
21
20
|
ctx.todos(["Find the product", "Add to cart", "Open cart"]);
|
|
@@ -29,6 +28,7 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
29
28
|
focus: true,
|
|
30
29
|
color: "#c9a6ff",
|
|
31
30
|
zoom: 1.55,
|
|
31
|
+
zoomOut: false,
|
|
32
32
|
followMouse: true,
|
|
33
33
|
weight: "bold",
|
|
34
34
|
},
|
|
@@ -36,6 +36,7 @@ export const NavCartBlock = defineNavClickBlock<CartPage>({
|
|
|
36
36
|
},
|
|
37
37
|
stubAfter: (ctx) => {
|
|
38
38
|
ctx.banner("Your cart");
|
|
39
|
+
ctx.zoomOut(false);
|
|
39
40
|
ctx.ring("items", {
|
|
40
41
|
selector: InventorySel.cartItem,
|
|
41
42
|
label: "Cart items",
|
package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts
CHANGED
|
@@ -33,12 +33,13 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
35
|
],
|
|
36
|
-
// Demo
|
|
36
|
+
// Demo: zoom product -> add (stay zoomed), then badge after act.
|
|
37
37
|
stubBefore: (ctx) => {
|
|
38
38
|
ctx.title("Pick a product");
|
|
39
39
|
ctx.todos(["Find the product", "Add to cart", "Open cart"]);
|
|
40
40
|
ctx.todoIndex(0);
|
|
41
41
|
ctx.zoom(1.35);
|
|
42
|
+
ctx.zoomOut(false);
|
|
42
43
|
ctx.highlights({
|
|
43
44
|
product: {
|
|
44
45
|
selector: InventorySel.title(DEMO_PRODUCT_ID),
|
|
@@ -47,6 +48,7 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
47
48
|
focus: true,
|
|
48
49
|
color: "#c9a6ff",
|
|
49
50
|
zoom: 1.45,
|
|
51
|
+
zoomOut: false,
|
|
50
52
|
followMouse: true,
|
|
51
53
|
},
|
|
52
54
|
add: {
|
|
@@ -55,6 +57,7 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
55
57
|
focus: true,
|
|
56
58
|
color: "#86efac",
|
|
57
59
|
zoom: 1.5,
|
|
60
|
+
zoomOut: false,
|
|
58
61
|
weight: "bold",
|
|
59
62
|
},
|
|
60
63
|
});
|