waygraph 0.15.2 → 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/checkout-step-two/methods/finish-order.method.block.ts +8 -7
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +8 -10
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +11 -10
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +5 -4
- 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/checkout-step-two/methods/finish-order.method.block.ts +8 -7
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +8 -10
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +11 -10
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +5 -4
- 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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineMethodBlock, checkpoint, Trait, narrate } from "waygraph";
|
|
1
|
+
import { defineMethodBlock, checkpoint, Trait, narrate, type StubCtx } from "waygraph";
|
|
2
2
|
import type { CheckoutOverviewPage, OrderComplete } from "../../../../states/checkout.states.js";
|
|
3
3
|
import { CheckoutOverviewSel } from "./checkout-overview.sel.js";
|
|
4
4
|
|
|
@@ -8,6 +8,7 @@ import { CheckoutOverviewSel } from "./checkout-overview.sel.js";
|
|
|
8
8
|
* Route: saucedemo-web/checkout-step-two/methods/ (= /checkout-step-two.html)
|
|
9
9
|
*
|
|
10
10
|
* Places the order on the overview page - form/finish click, not a NavBlock.
|
|
11
|
+
* Stubs use open ctx lifecycles (preferred) - not static slot maps.
|
|
11
12
|
*/
|
|
12
13
|
export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderComplete>({
|
|
13
14
|
name: "finish-order",
|
|
@@ -19,23 +20,23 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
|
|
|
19
20
|
},
|
|
20
21
|
resolve: () => checkpoint("OrderComplete"),
|
|
21
22
|
verify: [Trait.text(CheckoutOverviewSel.completeHeader, "Thank you for your order!")],
|
|
22
|
-
stubBefore: {
|
|
23
|
-
finish
|
|
23
|
+
stubBefore: (ctx: StubCtx) => {
|
|
24
|
+
ctx.ring("finish", {
|
|
24
25
|
selector: CheckoutOverviewSel.finishBtn,
|
|
25
26
|
label: "Finish",
|
|
26
27
|
detail: "tone: warning (yellow) - place order",
|
|
27
28
|
tone: "warning",
|
|
28
29
|
weight: "bold",
|
|
29
|
-
}
|
|
30
|
+
});
|
|
30
31
|
},
|
|
31
|
-
stubAfter: {
|
|
32
|
-
thanks
|
|
32
|
+
stubAfter: (ctx: StubCtx) => {
|
|
33
|
+
ctx.ring("thanks", {
|
|
33
34
|
selector: CheckoutOverviewSel.completeHeader,
|
|
34
35
|
label: "Order confirmed",
|
|
35
36
|
detail: "tone: success (green) - thank you!",
|
|
36
37
|
tone: "success",
|
|
37
38
|
duration: true,
|
|
38
|
-
}
|
|
39
|
+
});
|
|
39
40
|
},
|
|
40
41
|
// Shown AFTER act (order already placed) - selectors must match the
|
|
41
42
|
// completion page, not #finish on the overview.
|
|
@@ -22,16 +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
|
-
zoom: 1.4,
|
|
34
|
-
},
|
|
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,
|
|
35
33
|
});
|
|
36
34
|
},
|
|
37
35
|
stubAfter: (ctx: StubCtx) => {
|
|
@@ -40,16 +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
|
-
tone:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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,
|
|
53
54
|
});
|
|
54
55
|
},
|
|
55
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>;
|
|
@@ -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
|
),
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineMethodBlock, checkpoint, Trait, narrate } from "waygraph";
|
|
1
|
+
import { defineMethodBlock, checkpoint, Trait, narrate, type StubCtx } from "waygraph";
|
|
2
2
|
import type { CheckoutOverviewPage, OrderComplete } from "../../../../states/checkout.states.js";
|
|
3
3
|
import { CheckoutOverviewSel } from "./checkout-overview.sel.js";
|
|
4
4
|
|
|
@@ -8,6 +8,7 @@ import { CheckoutOverviewSel } from "./checkout-overview.sel.js";
|
|
|
8
8
|
* Route: saucedemo-web/checkout-step-two/methods/ (= /checkout-step-two.html)
|
|
9
9
|
*
|
|
10
10
|
* Places the order on the overview page - form/finish click, not a NavBlock.
|
|
11
|
+
* Stubs use open ctx lifecycles (preferred) - not static slot maps.
|
|
11
12
|
*/
|
|
12
13
|
export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderComplete>({
|
|
13
14
|
name: "finish-order",
|
|
@@ -19,23 +20,23 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
|
|
|
19
20
|
},
|
|
20
21
|
resolve: () => checkpoint("OrderComplete"),
|
|
21
22
|
verify: [Trait.text(CheckoutOverviewSel.completeHeader, "Thank you for your order!")],
|
|
22
|
-
stubBefore: {
|
|
23
|
-
finish
|
|
23
|
+
stubBefore: (ctx: StubCtx) => {
|
|
24
|
+
ctx.ring("finish", {
|
|
24
25
|
selector: CheckoutOverviewSel.finishBtn,
|
|
25
26
|
label: "Finish",
|
|
26
27
|
detail: "tone: warning (yellow) - place order",
|
|
27
28
|
tone: "warning",
|
|
28
29
|
weight: "bold",
|
|
29
|
-
}
|
|
30
|
+
});
|
|
30
31
|
},
|
|
31
|
-
stubAfter: {
|
|
32
|
-
thanks
|
|
32
|
+
stubAfter: (ctx: StubCtx) => {
|
|
33
|
+
ctx.ring("thanks", {
|
|
33
34
|
selector: CheckoutOverviewSel.completeHeader,
|
|
34
35
|
label: "Order confirmed",
|
|
35
36
|
detail: "tone: success (green) - thank you!",
|
|
36
37
|
tone: "success",
|
|
37
38
|
duration: true,
|
|
38
|
-
}
|
|
39
|
+
});
|
|
39
40
|
},
|
|
40
41
|
// Shown AFTER act (order already placed) - selectors must match the
|
|
41
42
|
// completion page, not #finish on the overview.
|
|
@@ -22,16 +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
|
-
zoom: 1.4,
|
|
34
|
-
},
|
|
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,
|
|
35
33
|
});
|
|
36
34
|
},
|
|
37
35
|
stubAfter: (ctx: StubCtx) => {
|
|
@@ -40,16 +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
|
-
tone:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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,
|
|
53
54
|
});
|
|
54
55
|
},
|
|
55
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>;
|