waygraph 0.15.1 → 0.15.3
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 +6 -1
- package/dist/engine.d.ts +124 -12
- package/dist/engine.js +170 -13
- package/dist/highlights.d.ts +8 -0
- package/dist/highlights.js +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/types.d.ts +17 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +4 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +19 -8
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +6 -5
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +8 -9
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +11 -9
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +6 -5
- package/examples/saucedemo/src/flows/checkout.flow.ts +61 -97
- package/examples/saucedemo/src/flows/login.flow.ts +11 -2
- package/examples/saucedemo/src/flows/shop.flow.ts +13 -13
- package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +9 -2
- package/package.json +1 -1
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +4 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +19 -8
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +6 -5
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +8 -9
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +11 -9
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +6 -5
- package/templates/quickstart/src/flows/checkout.flow.ts +61 -97
- package/templates/quickstart/src/flows/login.flow.ts +11 -2
- package/templates/quickstart/src/flows/shop.flow.ts +13 -13
- package/templates/quickstart/src/flows/viewer-blocked.flow.ts +9 -2
|
@@ -22,15 +22,14 @@ export const FillPasswordBlock = defineMethodBlock<LoginPage, LoginPage>({
|
|
|
22
22
|
},
|
|
23
23
|
resolve: () => checkpoint("LoginPage"),
|
|
24
24
|
stubBefore: (ctx: StubCtx) => {
|
|
25
|
-
ctx.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
25
|
+
ctx.ring("password", {
|
|
26
|
+
selector: LoginSel.password,
|
|
27
|
+
label: "Password",
|
|
28
|
+
detail: "tone: planned (purple)",
|
|
29
|
+
todo: "login-pass",
|
|
30
|
+
tone: "planned",
|
|
31
|
+
focus: true,
|
|
32
|
+
zoom: 1.4,
|
|
34
33
|
});
|
|
35
34
|
},
|
|
36
35
|
stubAfter: (ctx: StubCtx) => {
|
|
@@ -40,15 +40,17 @@ export const FillUsernameBlock = defineMethodBlock<LoginPage, LoginPage>({
|
|
|
40
40
|
{ title: "Device showcase", index: 0 },
|
|
41
41
|
);
|
|
42
42
|
ctx.zoom(1.35);
|
|
43
|
-
ctx.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
const fromMem = ctx.mem?.get(LoginCreds.key)?.username;
|
|
44
|
+
ctx.ring("username", {
|
|
45
|
+
selector: LoginSel.username,
|
|
46
|
+
label: "Username",
|
|
47
|
+
detail: fromMem
|
|
48
|
+
? `tone: info (blue) - mem ${fromMem}`
|
|
49
|
+
: "tone: info (blue)",
|
|
50
|
+
tone: "info",
|
|
51
|
+
todo: "login-user",
|
|
52
|
+
focus: true,
|
|
53
|
+
zoom: 1.4,
|
|
52
54
|
});
|
|
53
55
|
},
|
|
54
56
|
stubAfter: (ctx: StubCtx) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MethodBlock } from "waygraph";
|
|
2
2
|
import type { LoginPage, LoggedIn } from "../../../states/checkout.states.js";
|
|
3
3
|
import { SubmitLoginBlock } from "./submit-login.method.block.js";
|
|
4
4
|
|
|
@@ -7,7 +7,8 @@ import { SubmitLoginBlock } from "./submit-login.method.block.js";
|
|
|
7
7
|
* Helper: typed alias over SubmitLoginBlock
|
|
8
8
|
* Route: saucedemo-web/methods/ (page URL /)
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* runtime still branches on bad credentials via
|
|
10
|
+
* MethodBlock cast so map().method() keeps the factory brand while Flows can
|
|
11
|
+
* treat Out as LoggedIn; runtime still branches on bad credentials via
|
|
12
|
+
* SubmitLoginBlock.
|
|
12
13
|
*/
|
|
13
|
-
export const SubmitLoginForFlow = SubmitLoginBlock as unknown as
|
|
14
|
+
export const SubmitLoginForFlow = SubmitLoginBlock as unknown as MethodBlock<LoginPage, LoggedIn>;
|
|
@@ -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: "
|
|
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
|
},
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { Engine,
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
CheckoutInfoPage,
|
|
7
|
-
CheckoutOverviewPage,
|
|
8
|
-
OrderComplete,
|
|
9
|
-
} from "../states/checkout.states.js";
|
|
10
|
-
import { FfOwnerAuthBlock } from "../blocks/saucedemo-web/ff-owner-auth.block.js";
|
|
1
|
+
import { Engine, withTitle } from "waygraph";
|
|
2
|
+
import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
|
|
3
|
+
import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
|
|
4
|
+
import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
|
|
5
|
+
import { SubmitLoginForFlow } from "../blocks/saucedemo-web/methods/submit-login-for-flow.js";
|
|
11
6
|
import { AddToCartBlock } from "../blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.js";
|
|
12
7
|
import { NavCartBlock } from "../blocks/saucedemo-web/cart/nav-cart.block.js";
|
|
13
8
|
import { NavCheckoutInfoBlock } from "../blocks/saucedemo-web/cart/nav-checkout-info.block.js";
|
|
@@ -16,98 +11,67 @@ import { FillLastNameBlock } from "../blocks/saucedemo-web/checkout-step-one/met
|
|
|
16
11
|
import { FillPostalCodeBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.js";
|
|
17
12
|
import { SubmitCheckoutInfoBlock } from "../blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.js";
|
|
18
13
|
import { FinishOrderBlock } from "../blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.js";
|
|
14
|
+
import { LoginSel } from "../blocks/saucedemo-web/methods/login.sel.js";
|
|
19
15
|
|
|
20
16
|
const engine = new Engine({ headless: false, slowMo: 250 });
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
CheckoutInfoPage,
|
|
39
|
-
CheckoutInfoPage,
|
|
40
|
-
CheckoutInfoPage,
|
|
41
|
-
CheckoutOverviewPage,
|
|
42
|
-
OrderComplete
|
|
43
|
-
>([
|
|
44
|
-
start,
|
|
45
|
-
FfOwnerAuthBlock,
|
|
46
|
-
AddToCartBlock,
|
|
47
|
-
NavCartBlock,
|
|
48
|
-
NavCheckoutInfoBlock,
|
|
49
|
-
FillFirstNameBlock,
|
|
50
|
-
FillLastNameBlock,
|
|
51
|
-
FillPostalCodeBlock,
|
|
52
|
-
SubmitCheckoutInfoBlock,
|
|
53
|
-
FinishOrderBlock,
|
|
54
|
-
end,
|
|
55
|
-
]),
|
|
56
|
-
"Owner: Full Checkout",
|
|
57
|
-
),
|
|
58
|
-
{
|
|
59
|
-
"ff-owner-auth": {
|
|
60
|
-
stubAfter: {
|
|
61
|
-
inventory: {
|
|
62
|
-
label: "Signed in (fast-forward)",
|
|
63
|
-
detail: "Auth collapsed via FFCompose - interesting work starts here.",
|
|
64
|
-
tag: "AC",
|
|
65
|
-
duration: true,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
// Kept for --ff-expand (inners become separate steps again: nav-login,
|
|
70
|
-
// fill-username, fill-password, submit-login).
|
|
71
|
-
"fill-username": {
|
|
72
|
-
stubBefore: {
|
|
73
|
-
username: {
|
|
18
|
+
/**
|
|
19
|
+
* Owner checkout via map() + .ffStart/.ffEnd (no separate FfOwnerAuthBlock,
|
|
20
|
+
* no HighlightFixtureMap). Auth collapses to one blitz step; post-login
|
|
21
|
+
* blocks keep their own ctx stubBefore/stubAfter. Call-site decorate example
|
|
22
|
+
* on fill-username when --ff-expand shows inners again.
|
|
23
|
+
*/
|
|
24
|
+
export const checkoutFlow = withTitle(
|
|
25
|
+
engine
|
|
26
|
+
.map()
|
|
27
|
+
.start()
|
|
28
|
+
.ffStart("ff-owner-auth")
|
|
29
|
+
.gotoPage(NavLoginBlock)
|
|
30
|
+
.method(
|
|
31
|
+
FillUsernameBlock.stubBefore((ctx) => {
|
|
32
|
+
ctx.ring("username", {
|
|
33
|
+
selector: LoginSel.username,
|
|
74
34
|
label: "Demo user",
|
|
75
|
-
detail: "standard_user from Mem - library block stays neutral
|
|
35
|
+
detail: "standard_user from Mem - library block stays neutral underneath",
|
|
76
36
|
tag: "AC",
|
|
77
37
|
duration: true,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
"finish-order": {
|
|
102
|
-
stubAfter: {
|
|
103
|
-
thanks: {
|
|
104
|
-
label: "Order placed",
|
|
105
|
-
detail: "Completion header is the durable proof.",
|
|
38
|
+
focus: true,
|
|
39
|
+
});
|
|
40
|
+
}),
|
|
41
|
+
)
|
|
42
|
+
.method(
|
|
43
|
+
FillPasswordBlock.stubBefore((ctx) => {
|
|
44
|
+
ctx.ring("password", {
|
|
45
|
+
selector: LoginSel.password,
|
|
46
|
+
label: "Password",
|
|
47
|
+
detail: "Filled from Mem credentials.",
|
|
48
|
+
duration: 1500,
|
|
49
|
+
focus: true,
|
|
50
|
+
});
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
.method(
|
|
54
|
+
SubmitLoginForFlow.stubBefore((ctx) => {
|
|
55
|
+
ctx.ring("submit", {
|
|
56
|
+
selector: LoginSel.loginButton,
|
|
57
|
+
label: "Sign in",
|
|
106
58
|
tag: "GATE",
|
|
107
|
-
duration:
|
|
108
|
-
fastMode:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
59
|
+
duration: true,
|
|
60
|
+
fastMode: 500,
|
|
61
|
+
focus: true,
|
|
62
|
+
weight: "bold",
|
|
63
|
+
});
|
|
64
|
+
}),
|
|
65
|
+
)
|
|
66
|
+
.ffEnd()
|
|
67
|
+
.method(AddToCartBlock)
|
|
68
|
+
.gotoPage(NavCartBlock)
|
|
69
|
+
.gotoPage(NavCheckoutInfoBlock)
|
|
70
|
+
.method(FillFirstNameBlock)
|
|
71
|
+
.method(FillLastNameBlock)
|
|
72
|
+
.method(FillPostalCodeBlock)
|
|
73
|
+
.method(SubmitCheckoutInfoBlock)
|
|
74
|
+
.method(FinishOrderBlock)
|
|
75
|
+
.end(),
|
|
76
|
+
"Owner: Full Checkout",
|
|
113
77
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Engine,
|
|
1
|
+
import { Engine, withTitle } from "waygraph";
|
|
2
2
|
import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
|
|
3
3
|
import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
|
|
4
4
|
import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
|
|
@@ -8,7 +8,16 @@ const engine = new Engine();
|
|
|
8
8
|
|
|
9
9
|
// The step-mode overlay prepends "Episode N: " itself - the title here is
|
|
10
10
|
// just the label, not the full heading.
|
|
11
|
+
// map() + ctx stubs on the Method blocks (see fill-username / fill-password /
|
|
12
|
+
// submit-login) - no HighlightFixtureMap.
|
|
11
13
|
export const loginFlow = withTitle(
|
|
12
|
-
engine
|
|
14
|
+
engine
|
|
15
|
+
.map()
|
|
16
|
+
.start()
|
|
17
|
+
.gotoPage(NavLoginBlock)
|
|
18
|
+
.method(FillUsernameBlock)
|
|
19
|
+
.method(FillPasswordBlock)
|
|
20
|
+
.method(SubmitLoginForFlow)
|
|
21
|
+
.end(),
|
|
13
22
|
"Sign In",
|
|
14
23
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Engine,
|
|
1
|
+
import { Engine, withTitle } from "waygraph";
|
|
2
2
|
import { AddToCartBlock } from "../blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.js";
|
|
3
3
|
import { NavCartBlock } from "../blocks/saucedemo-web/cart/nav-cart.block.js";
|
|
4
4
|
import { NavCheckoutInfoBlock } from "../blocks/saucedemo-web/cart/nav-checkout-info.block.js";
|
|
@@ -13,17 +13,17 @@ const engine = new Engine();
|
|
|
13
13
|
// Episode-2 half of chainFlow(loginFlow, shopFlow) - assumes already LoggedIn
|
|
14
14
|
// (AddToCartBlock's In is the Checkpoint<string> wildcard).
|
|
15
15
|
export const shopFlow = withTitle(
|
|
16
|
-
engine
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
engine
|
|
17
|
+
.map()
|
|
18
|
+
.start()
|
|
19
|
+
.method(AddToCartBlock)
|
|
20
|
+
.gotoPage(NavCartBlock)
|
|
21
|
+
.gotoPage(NavCheckoutInfoBlock)
|
|
22
|
+
.method(FillFirstNameBlock)
|
|
23
|
+
.method(FillLastNameBlock)
|
|
24
|
+
.method(FillPostalCodeBlock)
|
|
25
|
+
.method(SubmitCheckoutInfoBlock)
|
|
26
|
+
.method(FinishOrderBlock)
|
|
27
|
+
.end(),
|
|
28
28
|
"Shop & Checkout",
|
|
29
29
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Engine,
|
|
1
|
+
import { Engine, withTitle, withSessionReset, withExpectedFailure } from "waygraph";
|
|
2
2
|
import { NavLoginBlock } from "../blocks/saucedemo-web/nav-login.block.js";
|
|
3
3
|
import { FillUsernameBlock } from "../blocks/saucedemo-web/methods/fill-username.method.block.js";
|
|
4
4
|
import { FillPasswordBlock } from "../blocks/saucedemo-web/methods/fill-password.method.block.js";
|
|
@@ -25,7 +25,14 @@ const engine = new Engine();
|
|
|
25
25
|
export const viewerBlockedFlow = withExpectedFailure(
|
|
26
26
|
withTitle(
|
|
27
27
|
withSessionReset(
|
|
28
|
-
engine
|
|
28
|
+
engine
|
|
29
|
+
.map()
|
|
30
|
+
.start()
|
|
31
|
+
.gotoPage(NavLoginBlock)
|
|
32
|
+
.method(FillUsernameBlock)
|
|
33
|
+
.method(FillPasswordBlock)
|
|
34
|
+
.method(SubmitLoginBlock)
|
|
35
|
+
.end(),
|
|
29
36
|
),
|
|
30
37
|
"Viewer: Blocked Login Attempt",
|
|
31
38
|
),
|