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.
- package/dist/cli/commands/codemod-stubs.js +90 -2
- package/dist/cli/run-chain.js +2 -2
- package/dist/cli/util.js +1 -1
- package/dist/demo/narration/demo-pace.d.ts +1 -1
- package/dist/demo/narration/demo-pace.js +1 -1
- package/dist/demo/narration/merge.d.ts +1 -1
- package/dist/demo/narration/merge.js +1 -1
- package/dist/demo/narration/narration.d.ts +2 -6
- package/dist/demo/narration/narration.js +5 -17
- package/dist/demo/narration/stub-ctx.js +3 -3
- package/dist/demo/overlay/inpage/core.js +0 -6
- package/dist/demo/overlay/overlay-css.js +1 -55
- package/dist/demo/overlay/overlay.js +3 -2
- package/dist/demo/overlay/rings.d.ts +0 -8
- package/dist/demo/overlay/rings.js +0 -15
- package/dist/demo/overlay/ui/overlay.css +40 -0
- package/dist/demo/stepper/after.js +4 -17
- package/dist/demo/stepper/before.js +3 -1
- package/dist/demo/stepper/demo-log.js +1 -1
- package/dist/demo/stepper/interaction-patch.js +3 -15
- package/dist/demo/stepper/panel-after.js +1 -1
- package/dist/demo/stepper/slides.d.ts +3 -0
- package/dist/demo/stepper/slides.js +18 -2
- package/dist/demo/stepper/teardown.js +0 -1
- package/dist/demo/verbose-log.js +1 -1
- package/dist/engine/block/block.d.ts +1 -12
- package/dist/engine/block/kinds/method.d.ts +0 -2
- package/dist/engine/block/kinds/method.js +0 -1
- package/dist/engine/block/kinds/nav.js +1 -1
- package/dist/engine/run/run.d.ts +1 -19
- package/dist/engine/run/run.js +0 -88
- package/dist/engine/stub/ring.d.ts +2 -4
- package/dist/engine/stub/ring.js +1 -0
- package/dist/engine/stub/stub.d.ts +16 -8
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -2
- package/dist/runner/plan/find.js +2 -2
- package/dist/runner/plan/plan.js +1 -1
- package/dist/runner/plan/seed-mem.js +5 -5
- package/dist/runner/plan/spec.js +1 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/examples/saucedemo/src/flows/checkout.flow.ts +2 -1
- package/examples/saucedemo/src/flows/shop.flow.ts +2 -1
- package/examples/saucedemo/src/stubs/device-showcase.ts +37 -43
- package/examples/saucedemo/src/stubs/finish-order.ts +38 -0
- package/package.json +1 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/templates/quickstart/src/flows/checkout.flow.ts +2 -1
- package/templates/quickstart/src/flows/shop.flow.ts +2 -1
- package/templates/quickstart/src/stubs/device-showcase.ts +37 -43
- package/templates/quickstart/src/stubs/finish-order.ts +38 -0
- package/templates/scaffold/src/flows/home/hello.flow.ts +3 -0
- 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.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { defineMethodBlock, Trait
|
|
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
|
|
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.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
|
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
|
});
|