waygraph 0.13.7 → 0.15.0
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/README.md +970 -232
- package/assets/stubs/stub.mp4 +0 -0
- package/assets/stubs/stub.pdf +32 -0
- package/assets/stubs/stub.png +0 -0
- package/dist/agent-dive.d.ts +9 -0
- package/dist/agent-dive.js +32 -0
- package/dist/auto-explore-run.d.ts +20 -2
- package/dist/auto-explore-run.js +9 -8
- package/dist/auto-explore.js +22 -2
- package/dist/auto-session-ipc.d.ts +123 -0
- package/dist/auto-session-ipc.js +381 -0
- package/dist/auto-session.d.ts +342 -0
- package/dist/auto-session.js +760 -0
- package/dist/cli.js +450 -51
- package/dist/engine.d.ts +201 -1
- package/dist/engine.js +312 -2
- package/dist/graph.d.ts +18 -0
- package/dist/graph.js +65 -2
- package/dist/highlights.d.ts +20 -1
- package/dist/highlights.js +60 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -3
- package/dist/map-check.d.ts +18 -0
- package/dist/map-check.js +140 -0
- package/dist/pilot-overlay.d.ts +88 -0
- package/dist/pilot-overlay.js +363 -0
- package/dist/pilot.d.ts +49 -0
- package/dist/pilot.js +53 -0
- package/dist/trait.d.ts +22 -0
- package/dist/trait.js +60 -3
- package/dist/types.d.ts +21 -1
- package/dist/types.js +17 -1
- package/examples/routed-demo/.waygraph-auto/4d4902b7.log +0 -0
- package/examples/routed-demo/.waygraph-auto/51ef462e.log +0 -0
- package/examples/routed-demo/.waygraph-auto/71527ad9.log +0 -0
- package/examples/routed-demo/.waygraph-auto/ca16778e.log +0 -0
- package/examples/routed-demo/package.json +26 -0
- package/examples/routed-demo/playwright.config.ts +20 -0
- package/examples/routed-demo/scripts/fixture-server.mjs +37 -0
- package/examples/routed-demo/scripts/with-fixture.mjs +70 -0
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +39 -0
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +12 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +23 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +18 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +22 -0
- package/examples/routed-demo/src/map/(app_base)/dashboard/_sel.ts +10 -0
- package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +21 -0
- package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +15 -0
- package/examples/routed-demo/src/map/(external)/docs/_sel.ts +7 -0
- package/examples/routed-demo/src/pages/dashboard.html +10 -0
- package/examples/routed-demo/src/pages/docs.html +8 -0
- package/examples/routed-demo/src/states/routed-demo.states.ts +10 -0
- package/examples/routed-demo/test-results/.last-run.json +4 -0
- package/examples/routed-demo/tests/routed-demo-map.spec.ts +17 -0
- package/examples/routed-demo/tests/routed-demo.spec.ts +75 -0
- package/examples/routed-demo/tsconfig.json +18 -0
- package/examples/routed-demo-consumer/package.json +18 -0
- package/examples/saucedemo/.waygraph-auto/00d5336e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/010dd92b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/011ad671.log +0 -0
- package/examples/saucedemo/.waygraph-auto/01b45645.log +0 -0
- package/examples/saucedemo/.waygraph-auto/03764153.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0593587e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/06d12823.log +0 -0
- package/examples/saucedemo/.waygraph-auto/083cc5b9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0b1f5b26.json +8 -0
- package/examples/saucedemo/.waygraph-auto/0c00f25f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/0e480591.log +0 -0
- package/examples/saucedemo/.waygraph-auto/104751ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/110958b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/138107c1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/159d541b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/16aa2c01.log +0 -0
- package/examples/saucedemo/.waygraph-auto/16c35dd5.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1706547d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/17537e42.log +0 -0
- package/examples/saucedemo/.waygraph-auto/175655f7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/17ede493.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1fe2414f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/1fe2e3b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2219f00b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/23e62571.log +0 -0
- package/examples/saucedemo/.waygraph-auto/25f68ada.log +0 -0
- package/examples/saucedemo/.waygraph-auto/26ca9cd8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2bb6c4e8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2d425004.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2f5b3ea6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/31bb303d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/31f2042f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/36551ec1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/36a1c274.log +0 -0
- package/examples/saucedemo/.waygraph-auto/381aa338.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3882bce1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/38acd1dc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/3b8b77b9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4028d2a2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4168b208.log +0 -0
- package/examples/saucedemo/.waygraph-auto/42cc9113.log +0 -0
- package/examples/saucedemo/.waygraph-auto/439d30aa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/43ab66ce.log +0 -0
- package/examples/saucedemo/.waygraph-auto/43f66838.log +0 -0
- package/examples/saucedemo/.waygraph-auto/442171d4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/453b1ce1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/457322bd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/46197027.log +0 -0
- package/examples/saucedemo/.waygraph-auto/46889468.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4890da1c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4893a63b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4a85f496.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4af71440.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4f7496d1.log +0 -0
- package/examples/saucedemo/.waygraph-auto/50e8baaa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/52b3a455.log +0 -0
- package/examples/saucedemo/.waygraph-auto/532dd9b8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5391ce40.log +0 -0
- package/examples/saucedemo/.waygraph-auto/57dbddb3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5897f501.log +0 -0
- package/examples/saucedemo/.waygraph-auto/59c0b57d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5b511794.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5c0eef7f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5c47910f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5d60da77.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5eda8273.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5fc3a33b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/61b6546d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/621518ad.log +0 -0
- package/examples/saucedemo/.waygraph-auto/632b7118.log +0 -0
- package/examples/saucedemo/.waygraph-auto/64314c2b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/650ed066.log +0 -0
- package/examples/saucedemo/.waygraph-auto/66516213.log +0 -0
- package/examples/saucedemo/.waygraph-auto/66c17079.log +0 -0
- package/examples/saucedemo/.waygraph-auto/69bf0b80.log +0 -0
- package/examples/saucedemo/.waygraph-auto/69c2347a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d22bdb0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d9aaad3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7103bebb.log +0 -0
- package/examples/saucedemo/.waygraph-auto/740c9faa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/74872fc5.log +0 -0
- package/examples/saucedemo/.waygraph-auto/75846ca9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7626c85b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/76308eec.log +0 -0
- package/examples/saucedemo/.waygraph-auto/76c1650e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7861f38f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/78b21219.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7af224ed.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7c3be585.log +0 -0
- package/examples/saucedemo/.waygraph-auto/7ed55a2c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80086ba2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/80206369.log +0 -0
- package/examples/saucedemo/.waygraph-auto/847f1092.log +0 -0
- package/examples/saucedemo/.waygraph-auto/84d6d293.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8581abfa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/87b7e0fd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/87c79256.log +0 -0
- package/examples/saucedemo/.waygraph-auto/88af2495.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8a3eb088.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8c04a403.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8c9ab09e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8cc5db51.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8ea3a69c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/9150f913.log +0 -0
- package/examples/saucedemo/.waygraph-auto/929a4313.log +0 -0
- package/examples/saucedemo/.waygraph-auto/95a599e4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/96c45350.log +0 -0
- package/examples/saucedemo/.waygraph-auto/986030e6.log +0 -0
- package/examples/saucedemo/.waygraph-auto/99787abb.log +0 -0
- package/examples/saucedemo/.waygraph-auto/99ddb62c.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a2dd30dd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a63a2d20.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a78befb7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a84d9b79.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a87bb3ee.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a9270890.log +0 -0
- package/examples/saucedemo/.waygraph-auto/aa440153.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ab7561e0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ac19ae60.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ae21ad8e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/af09042f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b1684126.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b21e9d12.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b5a838be.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b603549d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b81e074f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b83e6259.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b9cb2796.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ba58abb7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb0a0018.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb9fd384.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bc0bdd0e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bc7d4a83.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bd8e082a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bea0c93e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bf35201a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bffa3a7a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c02ea583.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c2caf0a8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c3bdc714.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c4afb8bc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c916a654.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c9b8d69e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cd68bbc4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cdc6db50.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d01906a7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d02e5e7e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d09aff71.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d0e41396.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d1370d76.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d3714ae4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d9e5f8a4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/da0685dc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/da894ad8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/daa2f922.log +0 -0
- package/examples/saucedemo/.waygraph-auto/daefb614.log +0 -0
- package/examples/saucedemo/.waygraph-auto/db97e833.log +0 -0
- package/examples/saucedemo/.waygraph-auto/dec3076e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e101d19a.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e1973991.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e207c989.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e633e545.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e69aec68.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e70e2d06.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e8306a4b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ebad3410.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ec88b3ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ecbb0966.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ecdee753.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ed888783.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ed931dac.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ef655a3f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f34c9a26.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f3c29b21.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f53f7cfc.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5525d53.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5ad5830.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f90035b3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fa687bc2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/faed36dd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fb66fba0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fc48fd76.log +0 -0
- package/examples/saucedemo/docs/CONVENTION.md +25 -5
- package/examples/saucedemo/docs/HELPERS.md +15 -4
- package/examples/saucedemo/scripts/capture-wrong-login.mjs +8 -2
- package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +8 -2
- package/examples/saucedemo/src/blocks/SITE-MAP.md +14 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +15 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/NAV.md +1 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/cart.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -2
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/NAV.md +6 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/checkout-info.sel.ts +11 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +22 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +21 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +21 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +6 -7
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/NAV.md +2 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/checkout-overview.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +7 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +7 -2
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/NAV.md +1 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/item-detail.sel.ts +9 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +2 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +51 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +69 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/login.sel.ts +13 -0
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +4 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -51
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +4 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +14 -6
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +15 -0
- package/examples/saucedemo/src/flows/checkout.flow.ts +20 -2
- package/examples/saucedemo/src/flows/device-showcase.flow.ts +4 -0
- package/examples/saucedemo/src/flows/login.flow.ts +3 -1
- package/examples/saucedemo/src/flows/shop.flow.ts +6 -0
- package/examples/saucedemo/src/flows/smoke.flow.ts +13 -7
- package/examples/saucedemo/src/flows/stub-on-error.flow.ts +4 -2
- package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +6 -2
- package/examples/saucedemo/tests/flow-block-verify.spec.ts +3 -3
- package/examples/saucedemo/tests/submit-login-branch.spec.ts +5 -3
- package/package.json +2 -1
- package/templates/agents/waygraph-author.agent.md +43 -5
- package/templates/agents/waygraph-planner.agent.md +33 -2
- package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +15 -1
- package/templates/quickstart/src/blocks/saucedemo-web/cart/NAV.md +1 -0
- package/templates/quickstart/src/blocks/saucedemo-web/cart/cart.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +19 -15
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/NAV.md +6 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/checkout-info.sel.ts +11 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +22 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +21 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +21 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +6 -7
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/NAV.md +2 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/checkout-overview.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +7 -6
- package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +7 -2
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +24 -16
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/NAV.md +1 -0
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/item-detail.sel.ts +9 -0
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +2 -1
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +51 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +69 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/login.sel.ts +13 -0
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login-for-flow.ts +4 -4
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +35 -63
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +4 -3
- package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +14 -6
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +15 -0
- package/templates/quickstart/src/flows/checkout.flow.ts +29 -2
- package/templates/quickstart/src/flows/device-showcase.flow.ts +4 -0
- package/templates/quickstart/src/flows/login.flow.ts +3 -1
- package/templates/quickstart/src/flows/shop.flow.ts +6 -0
- package/templates/quickstart/src/flows/smoke.flow.ts +13 -7
- package/templates/quickstart/src/flows/viewer-blocked.flow.ts +6 -2
- package/templates/quickstart/tests/chain-flow.spec.ts +8 -1
- package/templates/scaffold/STRUCTURE.md +23 -3
- package/templates/scaffold/scripts/fixture-server.mjs +11 -2
- package/templates/scaffold/src/flows/example.flow.ts +8 -6
- package/templates/scaffold/src/flows/mail-verify.flow.ts +85 -0
- package/templates/scaffold/src/flows/shop.flow.ts +23 -6
- package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +20 -0
- package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +15 -0
- package/templates/scaffold/src/map/(app_base)/docs/_sel.ts +7 -0
- package/templates/scaffold/src/map/(app_base)/docs/docs.html +8 -0
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/add-item.effect.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +46 -0
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +38 -0
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/clear-cart.method.block.ts +9 -3
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/remove-item.effect.block.ts +3 -3
- package/templates/scaffold/src/{blocks/demo-web/nav-home.block.ts → map/(app_base)/home/_nav.block.ts} +2 -2
- package/templates/scaffold/src/{blocks/demo-web/home.page.block.ts → map/(app_base)/home/_page.block.ts} +7 -7
- package/templates/scaffold/src/{blocks/demo-web/demo-sel.ts → map/(app_base)/home/_sel.ts} +1 -0
- package/templates/scaffold/src/{blocks/demo-web → map/(app_base)/home}/home.html +4 -0
- package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +34 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +48 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +49 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +41 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +39 -0
- package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +20 -0
- package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +30 -0
- package/templates/scaffold/src/map/(external)/mailpit/_sel.ts +5 -0
- package/templates/scaffold/src/states/demo.mem-keys.ts +25 -1
- package/templates/scaffold/src/states/demo.states.ts +11 -0
- package/templates/scaffold/test-results/.last-run.json +4 -0
- package/templates/scaffold/tests/example.spec.ts +2 -2
- package/templates/scaffold/tests/mail-verify.spec.ts +191 -0
- package/templates/skills/waygraph-blind-pilot.skill.md +61 -0
- package/templates/skills/waygraph-pilot.skill.md +108 -0
- package/templates/quickstart/README-saucedemo-commands.md +0 -72
- package/templates/scaffold/src/blocks/SITE-MAP.md +0 -12
- package/templates/scaffold/src/blocks/demo-web/NAV.md +0 -29
- package/templates/scaffold/src/blocks/demo-web/methods/assert-hello.method.block.ts +0 -50
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint } from "waygraph";
|
|
2
|
+
import type { CheckoutInfoPage } from "../../../../states/checkout.states.js";
|
|
3
|
+
import { CheckoutInfoSel } from "./checkout-info.sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Method
|
|
7
|
+
* Helper: defineMethodBlock
|
|
8
|
+
* Route: saucedemo-web/checkout-step-one/methods/ (= /checkout-step-one.html)
|
|
9
|
+
*
|
|
10
|
+
* Fills the first name field only - self-loop on CheckoutInfoPage. Continue
|
|
11
|
+
* is its own Block (submit-checkout-info.method.block.ts).
|
|
12
|
+
*/
|
|
13
|
+
export const FillFirstNameBlock = defineMethodBlock<CheckoutInfoPage, CheckoutInfoPage>({
|
|
14
|
+
name: "fill-first-name",
|
|
15
|
+
description: "Fills the first name field on the shipping info form.",
|
|
16
|
+
instruction: {
|
|
17
|
+
async act(page) {
|
|
18
|
+
await page.locator(CheckoutInfoSel.firstName).fill("Ada");
|
|
19
|
+
},
|
|
20
|
+
resolve: () => checkpoint("CheckoutInfoPage"),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint } from "waygraph";
|
|
2
|
+
import type { CheckoutInfoPage } from "../../../../states/checkout.states.js";
|
|
3
|
+
import { CheckoutInfoSel } from "./checkout-info.sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Method
|
|
7
|
+
* Helper: defineMethodBlock
|
|
8
|
+
* Route: saucedemo-web/checkout-step-one/methods/ (= /checkout-step-one.html)
|
|
9
|
+
*
|
|
10
|
+
* Fills the last name field only - self-loop on CheckoutInfoPage.
|
|
11
|
+
*/
|
|
12
|
+
export const FillLastNameBlock = defineMethodBlock<CheckoutInfoPage, CheckoutInfoPage>({
|
|
13
|
+
name: "fill-last-name",
|
|
14
|
+
description: "Fills the last name field on the shipping info form.",
|
|
15
|
+
instruction: {
|
|
16
|
+
async act(page) {
|
|
17
|
+
await page.locator(CheckoutInfoSel.lastName).fill("Lovelace");
|
|
18
|
+
},
|
|
19
|
+
resolve: () => checkpoint("CheckoutInfoPage"),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint } from "waygraph";
|
|
2
|
+
import type { CheckoutInfoPage } from "../../../../states/checkout.states.js";
|
|
3
|
+
import { CheckoutInfoSel } from "./checkout-info.sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Method
|
|
7
|
+
* Helper: defineMethodBlock
|
|
8
|
+
* Route: saucedemo-web/checkout-step-one/methods/ (= /checkout-step-one.html)
|
|
9
|
+
*
|
|
10
|
+
* Fills the postal code field only - self-loop on CheckoutInfoPage.
|
|
11
|
+
*/
|
|
12
|
+
export const FillPostalCodeBlock = defineMethodBlock<CheckoutInfoPage, CheckoutInfoPage>({
|
|
13
|
+
name: "fill-postal-code",
|
|
14
|
+
description: "Fills the postal code field on the shipping info form.",
|
|
15
|
+
instruction: {
|
|
16
|
+
async act(page) {
|
|
17
|
+
await page.locator(CheckoutInfoSel.postalCode).fill("1000");
|
|
18
|
+
},
|
|
19
|
+
resolve: () => checkpoint("CheckoutInfoPage"),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { defineMethodBlock, checkpoint, Trait } from "waygraph";
|
|
2
2
|
import type { CheckoutInfoPage, CheckoutOverviewPage } from "../../../../states/checkout.states.js";
|
|
3
|
+
import { CheckoutInfoSel } from "./checkout-info.sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Method
|
|
6
7
|
* Helper: defineMethodBlock
|
|
7
8
|
* Route: saucedemo-web/checkout-step-one/methods/ (= /checkout-step-one.html)
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Clicks Continue only - fields are filled by fill-first-name /
|
|
11
|
+
* fill-last-name / fill-postal-code (each its own Block). One Block, one
|
|
12
|
+
* action: submit.
|
|
11
13
|
*/
|
|
12
14
|
export const SubmitCheckoutInfoBlock = defineMethodBlock<CheckoutInfoPage, CheckoutOverviewPage>({
|
|
13
15
|
name: "submit-checkout-info",
|
|
14
|
-
description: "
|
|
16
|
+
description: "Continues from the shipping info form to the order overview.",
|
|
15
17
|
instruction: {
|
|
16
18
|
async act(page) {
|
|
17
|
-
await page.locator(
|
|
18
|
-
await page.locator("#last-name").fill("Lovelace");
|
|
19
|
-
await page.locator("#postal-code").fill("1000");
|
|
20
|
-
await page.locator("#continue").click();
|
|
19
|
+
await page.locator(CheckoutInfoSel.continueBtn).click();
|
|
21
20
|
},
|
|
22
21
|
resolve: () => checkpoint("CheckoutOverviewPage"),
|
|
23
22
|
verify: [Trait.url({ pathname: "/checkout-step-two.html" })],
|
|
@@ -15,7 +15,9 @@ Order overview / finish page.
|
|
|
15
15
|
| File | Kind | Notes |
|
|
16
16
|
|------|------|-------|
|
|
17
17
|
| `methods/finish-order.method.block.ts` | Method | Finish -> thank-you / OrderComplete |
|
|
18
|
+
| `methods/checkout-overview.sel.ts` | helper | `CheckoutOverviewSel` (not a Block) |
|
|
18
19
|
|
|
19
20
|
## Related mem keys / checkpoints
|
|
20
21
|
|
|
21
22
|
- Checkpoints: `CheckoutOverviewPage`, `OrderComplete`
|
|
23
|
+
- Sel: `CheckoutOverviewSel` (`methods/checkout-overview.sel.ts`) - DOM only, not mem
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM selectors for the order overview / completion page
|
|
3
|
+
* (`/checkout-step-two.html`). Convention: DOM strings live in `*Sel` next
|
|
4
|
+
* to the page, not inlined in each Block.
|
|
5
|
+
*/
|
|
6
|
+
export const CheckoutOverviewSel = {
|
|
7
|
+
finishBtn: "#finish",
|
|
8
|
+
completeHeader: ".complete-header",
|
|
9
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineMethodBlock, checkpoint, Trait, narrate } from "waygraph";
|
|
2
2
|
import type { CheckoutOverviewPage, OrderComplete } from "../../../../states/checkout.states.js";
|
|
3
|
+
import { CheckoutOverviewSel } from "./checkout-overview.sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Method
|
|
@@ -13,17 +14,17 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
|
|
|
13
14
|
description: "Places the order and confirms the 'Thank you for your order!' completion page.",
|
|
14
15
|
instruction: {
|
|
15
16
|
async act(page) {
|
|
16
|
-
const finishButton = page.locator(
|
|
17
|
+
const finishButton = page.locator(CheckoutOverviewSel.finishBtn);
|
|
17
18
|
await narrate(finishButton, "Placing the order", () => finishButton.click());
|
|
18
19
|
},
|
|
19
20
|
resolve: () => checkpoint("OrderComplete"),
|
|
20
|
-
verify: [Trait.text(
|
|
21
|
+
verify: [Trait.text(CheckoutOverviewSel.completeHeader, "Thank you for your order!")],
|
|
21
22
|
stubBefore: {
|
|
22
|
-
finish: { selector:
|
|
23
|
+
finish: { selector: CheckoutOverviewSel.finishBtn, label: "Finish" },
|
|
23
24
|
},
|
|
24
25
|
stubAfter: {
|
|
25
26
|
thanks: {
|
|
26
|
-
selector:
|
|
27
|
+
selector: CheckoutOverviewSel.completeHeader,
|
|
27
28
|
label: "Order confirmed",
|
|
28
29
|
detail: "Thank you for your order!",
|
|
29
30
|
duration: true,
|
|
@@ -42,7 +43,7 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
|
|
|
42
43
|
caption: "Completion page is the durable proof",
|
|
43
44
|
detail: "The thank-you header is what verify asserts on.",
|
|
44
45
|
tag: "YAP",
|
|
45
|
-
selector:
|
|
46
|
+
selector: CheckoutOverviewSel.completeHeader,
|
|
46
47
|
duration: 2500,
|
|
47
48
|
fastMode: 700,
|
|
48
49
|
},
|
|
@@ -50,7 +51,7 @@ export const FinishOrderBlock = defineMethodBlock<CheckoutOverviewPage, OrderCom
|
|
|
50
51
|
caption: "Episode continues after this yap",
|
|
51
52
|
detail: "Next step rings the same banner, then you move on.",
|
|
52
53
|
tag: "YAP",
|
|
53
|
-
selector:
|
|
54
|
+
selector: CheckoutOverviewSel.completeHeader,
|
|
54
55
|
duration: true,
|
|
55
56
|
fastMode: 500,
|
|
56
57
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { fastForwardComposeBlock } from "waygraph";
|
|
2
2
|
import { NavLoginBlock } from "./nav-login.block.js";
|
|
3
|
+
import { FillUsernameBlock } from "./methods/fill-username.method.block.js";
|
|
4
|
+
import { FillPasswordBlock } from "./methods/fill-password.method.block.js";
|
|
3
5
|
import { SubmitLoginForFlow } from "./methods/submit-login-for-flow.js";
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -7,11 +9,14 @@ import { SubmitLoginForFlow } from "./methods/submit-login-for-flow.js";
|
|
|
7
9
|
* Helper: fastForwardComposeBlock
|
|
8
10
|
* Route: saucedemo-web/ (auth prefix)
|
|
9
11
|
*
|
|
10
|
-
* Collapses nav-login +
|
|
11
|
-
* checkout demos skip watching auth. Use
|
|
12
|
+
* Collapses nav-login + fill-username + fill-password + submit-login into
|
|
13
|
+
* one opaque demo/run step so checkout demos skip watching auth. Use
|
|
14
|
+
* --ff-expand to gate inners again (they show as 4 separate steps).
|
|
12
15
|
* loginFlow stays expanded for Sign In episode narration.
|
|
13
16
|
*/
|
|
14
17
|
export const FfOwnerAuthBlock = fastForwardComposeBlock("ff-owner-auth", [
|
|
15
18
|
NavLoginBlock,
|
|
19
|
+
FillUsernameBlock,
|
|
20
|
+
FillPasswordBlock,
|
|
16
21
|
SubmitLoginForFlow,
|
|
17
22
|
]);
|
package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts
CHANGED
|
@@ -37,16 +37,20 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
37
37
|
// Demo: zoom product -> add (stay zoomed), then badge after act.
|
|
38
38
|
stubBefore: (ctx: StubCtx) => {
|
|
39
39
|
ctx.title("Pick a product · tablet");
|
|
40
|
-
// Device showcase: tablet portrait (toast + lerp from mobile landscape).
|
|
41
40
|
ctx.device("tablet");
|
|
42
41
|
ctx.portrait();
|
|
43
|
-
ctx.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
ctx.todos(
|
|
43
|
+
"saucedemo",
|
|
44
|
+
[
|
|
45
|
+
{ id: "login-user", text: "Enter username", done: true },
|
|
46
|
+
{ id: "login-pass", text: "Enter password", done: true },
|
|
47
|
+
{ id: "login-submit", text: "Tap Login", done: true },
|
|
48
|
+
{ id: "cart-find", text: "Find the product" },
|
|
49
|
+
{ id: "cart-add", text: "Add to cart" },
|
|
50
|
+
{ id: "cart-open", text: "Open cart" },
|
|
51
|
+
],
|
|
52
|
+
{ title: "Device showcase", index: 3 },
|
|
53
|
+
);
|
|
50
54
|
ctx.zoom(1.35);
|
|
51
55
|
ctx.zoomOut(false);
|
|
52
56
|
ctx.highlights({
|
|
@@ -72,13 +76,18 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
72
76
|
},
|
|
73
77
|
stubAfter: (ctx: StubCtx) => {
|
|
74
78
|
ctx.banner("In the cart");
|
|
75
|
-
ctx.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
ctx.todos(
|
|
80
|
+
"saucedemo",
|
|
81
|
+
[
|
|
82
|
+
{ id: "login-user", text: "Enter username", done: true },
|
|
83
|
+
{ id: "login-pass", text: "Enter password", done: true },
|
|
84
|
+
{ id: "login-submit", text: "Tap Login", done: true },
|
|
85
|
+
{ id: "cart-find", text: "Find the product", done: true },
|
|
86
|
+
{ id: "cart-add", text: "Add to cart" },
|
|
87
|
+
{ id: "cart-open", text: "Open cart" },
|
|
88
|
+
],
|
|
89
|
+
{ title: "Device showcase", index: 4 },
|
|
90
|
+
);
|
|
82
91
|
ctx.zoomOut(false);
|
|
83
92
|
ctx.ring("badge", {
|
|
84
93
|
selector: InventorySel.cartBadge,
|
|
@@ -86,7 +95,6 @@ export const AddToCartBlock = defineEffectBlock<Checkpoint<string>, ItemInCart>(
|
|
|
86
95
|
detail: "Item count updated",
|
|
87
96
|
focus: true,
|
|
88
97
|
color: "#86efac",
|
|
89
|
-
zoom: 1.6,
|
|
90
98
|
zoomOut: false,
|
|
91
99
|
duration: true,
|
|
92
100
|
});
|
|
@@ -3,7 +3,7 @@ import type { ItemDetailPage } from "../../../states/checkout.states.js";
|
|
|
3
3
|
import { SelectedItem } from "../../../states/checkout.mem-keys.js";
|
|
4
4
|
import {
|
|
5
5
|
collectInventoryItems,
|
|
6
|
-
|
|
6
|
+
InventorySel,
|
|
7
7
|
} from "./methods/inventory-items.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -19,7 +19,7 @@ export const NavItemDetailBlock = defineMemNavBlock<ItemDetailPage>({
|
|
|
19
19
|
description: "Opens the product named by mem (saucedemo.selectedItem) on its detail page.",
|
|
20
20
|
checkpoint: "ItemDetailPage",
|
|
21
21
|
requires: [SelectedItem.key],
|
|
22
|
-
click: (mem) =>
|
|
22
|
+
click: (mem) => InventorySel.title(mem.get(SelectedItem.key).id),
|
|
23
23
|
verify: [Trait.url({ pathname: "/inventory-item.html" })],
|
|
24
24
|
async instanceOptions(page): Promise<readonly WaygraphInstanceOption[]> {
|
|
25
25
|
const items = await collectInventoryItems(page);
|
|
@@ -28,7 +28,7 @@ export const NavItemDetailBlock = defineMemNavBlock<ItemDetailPage>({
|
|
|
28
28
|
label: `Open "${item.name}" details`,
|
|
29
29
|
key: SelectedItem.key,
|
|
30
30
|
value: item,
|
|
31
|
-
highlight:
|
|
31
|
+
highlight: InventorySel.title(item.id),
|
|
32
32
|
}));
|
|
33
33
|
},
|
|
34
34
|
});
|
|
@@ -23,3 +23,4 @@ Single product detail page, plus nav edges that return to catalog
|
|
|
23
23
|
## Related mem keys / checkpoints
|
|
24
24
|
|
|
25
25
|
- Checkpoints: `ItemDetailPage`, `LoggedIn` (after back / continue), `OrderComplete` (from for back-to-products)
|
|
26
|
+
- Sel: `ItemDetailSel` (`item-detail.sel.ts`) - DOM only, not mem
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM selectors for the item detail page (`/inventory-item.html`) and the
|
|
3
|
+
* order-complete page's equivalent nav control. Convention: DOM strings
|
|
4
|
+
* live in `*Sel` next to the page, not inlined in each Block.
|
|
5
|
+
*/
|
|
6
|
+
export const ItemDetailSel = {
|
|
7
|
+
continueShoppingBtn: "#continue-shopping",
|
|
8
|
+
backToProductsBtn: "#back-to-products",
|
|
9
|
+
};
|
package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineNavClickBlock, Trait } from "waygraph";
|
|
2
2
|
import type { LoggedIn } from "../../../states/checkout.states.js";
|
|
3
|
+
import { ItemDetailSel } from "./item-detail.sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Nav
|
|
@@ -13,6 +14,6 @@ export const NavBackToInventoryBlock = defineNavClickBlock<LoggedIn>({
|
|
|
13
14
|
name: "nav-back-to-inventory",
|
|
14
15
|
description: "Clicks 'Back to products' on the item detail page.",
|
|
15
16
|
checkpoint: "LoggedIn",
|
|
16
|
-
click:
|
|
17
|
+
click: ItemDetailSel.backToProductsBtn,
|
|
17
18
|
verify: [Trait.url({ pathname: "/inventory.html" })],
|
|
18
19
|
});
|
package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineNavClickBlock, Trait } from "waygraph";
|
|
2
2
|
import type { LoggedIn } from "../../../states/checkout.states.js";
|
|
3
|
+
import { ItemDetailSel } from "./item-detail.sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Nav
|
|
@@ -13,6 +14,6 @@ export const NavBackToProductsBlock = defineNavClickBlock<LoggedIn>({
|
|
|
13
14
|
name: "nav-back-to-products",
|
|
14
15
|
description: "Clicks 'Back Home' on the order confirmation page.",
|
|
15
16
|
checkpoint: "LoggedIn",
|
|
16
|
-
click:
|
|
17
|
+
click: ItemDetailSel.backToProductsBtn,
|
|
17
18
|
verify: [Trait.url({ pathname: "/inventory.html" })],
|
|
18
19
|
});
|
package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineNavClickBlock, Trait } from "waygraph";
|
|
2
2
|
import type { LoggedIn } from "../../../states/checkout.states.js";
|
|
3
|
+
import { ItemDetailSel } from "./item-detail.sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Nav
|
|
@@ -12,6 +13,6 @@ export const NavContinueShoppingBlock = defineNavClickBlock<LoggedIn>({
|
|
|
12
13
|
name: "nav-continue-shopping",
|
|
13
14
|
description: "Clicks 'Continue Shopping' on the cart page.",
|
|
14
15
|
checkpoint: "LoggedIn",
|
|
15
|
-
click:
|
|
16
|
+
click: ItemDetailSel.continueShoppingBtn,
|
|
16
17
|
verify: [Trait.url({ pathname: "/inventory.html" })],
|
|
17
18
|
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint, type StubCtx } from "waygraph";
|
|
2
|
+
import type { LoginPage } from "../../../states/checkout.states.js";
|
|
3
|
+
import { LoginCreds } from "../../../states/checkout.mem-keys.js";
|
|
4
|
+
import { LoginSel } from "./login.sel.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Kind: Method
|
|
8
|
+
* Helper: defineMethodBlock
|
|
9
|
+
* Route: saucedemo-web/methods/ (page URL /)
|
|
10
|
+
*
|
|
11
|
+
* Fills the password field only - self-loop on LoginPage. See
|
|
12
|
+
* fill-username.method.block.ts for why this is split from submit.
|
|
13
|
+
*/
|
|
14
|
+
export const FillPasswordBlock = defineMethodBlock<LoginPage, LoginPage>({
|
|
15
|
+
name: "fill-password",
|
|
16
|
+
description: "Fills the password field on the login form.",
|
|
17
|
+
requires: [LoginCreds.key],
|
|
18
|
+
instruction: {
|
|
19
|
+
async act(page, _input, mem) {
|
|
20
|
+
const { password } = mem.get(LoginCreds.key);
|
|
21
|
+
await page.locator(LoginSel.password).fill(password);
|
|
22
|
+
},
|
|
23
|
+
resolve: () => checkpoint("LoginPage"),
|
|
24
|
+
stubBefore: (ctx: StubCtx) => {
|
|
25
|
+
ctx.highlights({
|
|
26
|
+
password: {
|
|
27
|
+
selector: LoginSel.password,
|
|
28
|
+
label: "Password",
|
|
29
|
+
todo: "login-pass",
|
|
30
|
+
focus: true,
|
|
31
|
+
color: "#c9a6ff",
|
|
32
|
+
zoom: 1.4,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
stubAfter: (ctx: StubCtx) => {
|
|
37
|
+
ctx.todos(
|
|
38
|
+
"saucedemo",
|
|
39
|
+
[
|
|
40
|
+
{ id: "login-user", text: "Enter username", done: true },
|
|
41
|
+
{ id: "login-pass", text: "Enter password", done: true },
|
|
42
|
+
{ id: "login-submit", text: "Tap Login" },
|
|
43
|
+
{ id: "cart-find", text: "Find the product" },
|
|
44
|
+
{ id: "cart-add", text: "Add to cart" },
|
|
45
|
+
{ id: "cart-open", text: "Open cart" },
|
|
46
|
+
],
|
|
47
|
+
{ title: "Device showcase", index: 2 },
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint, type StubCtx } from "waygraph";
|
|
2
|
+
import type { LoginPage } from "../../../states/checkout.states.js";
|
|
3
|
+
import { LoginCreds } from "../../../states/checkout.mem-keys.js";
|
|
4
|
+
import { LoginSel } from "./login.sel.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Kind: Method
|
|
8
|
+
* Helper: defineMethodBlock
|
|
9
|
+
* Route: saucedemo-web/methods/ (page URL /)
|
|
10
|
+
*
|
|
11
|
+
* Fills the username field only - self-loop on LoginPage, no submit, no
|
|
12
|
+
* page.goto. Submit is its own Block (submit-login.method.block.ts) so the
|
|
13
|
+
* graph/demo show fill vs submit as real, distinct steps instead of one
|
|
14
|
+
* Block doing "input username and password and login at the same time".
|
|
15
|
+
*/
|
|
16
|
+
export const FillUsernameBlock = defineMethodBlock<LoginPage, LoginPage>({
|
|
17
|
+
name: "fill-username",
|
|
18
|
+
description: "Fills the username field on the login form.",
|
|
19
|
+
requires: [LoginCreds.key],
|
|
20
|
+
instruction: {
|
|
21
|
+
async act(page, _input, mem) {
|
|
22
|
+
const { username } = mem.get(LoginCreds.key);
|
|
23
|
+
await page.locator(LoginSel.username).fill(username);
|
|
24
|
+
},
|
|
25
|
+
resolve: () => checkpoint("LoginPage"),
|
|
26
|
+
stubBefore: (ctx: StubCtx) => {
|
|
27
|
+
ctx.title("Signing in · mobile");
|
|
28
|
+
ctx.device("mobile");
|
|
29
|
+
ctx.portrait();
|
|
30
|
+
ctx.todos(
|
|
31
|
+
"saucedemo",
|
|
32
|
+
[
|
|
33
|
+
{ id: "login-user", text: "Enter username" },
|
|
34
|
+
{ id: "login-pass", text: "Enter password" },
|
|
35
|
+
{ id: "login-submit", text: "Tap Login" },
|
|
36
|
+
{ id: "cart-find", text: "Find the product" },
|
|
37
|
+
{ id: "cart-add", text: "Add to cart" },
|
|
38
|
+
{ id: "cart-open", text: "Open cart" },
|
|
39
|
+
],
|
|
40
|
+
{ title: "Device showcase", index: 0 },
|
|
41
|
+
);
|
|
42
|
+
ctx.zoom(1.35);
|
|
43
|
+
ctx.highlights({
|
|
44
|
+
username: {
|
|
45
|
+
selector: LoginSel.username,
|
|
46
|
+
label: "Username",
|
|
47
|
+
todo: "login-user",
|
|
48
|
+
focus: true,
|
|
49
|
+
color: "#c9a6ff",
|
|
50
|
+
zoom: 1.4,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
stubAfter: (ctx: StubCtx) => {
|
|
55
|
+
ctx.todos(
|
|
56
|
+
"saucedemo",
|
|
57
|
+
[
|
|
58
|
+
{ id: "login-user", text: "Enter username", done: true },
|
|
59
|
+
{ id: "login-pass", text: "Enter password" },
|
|
60
|
+
{ id: "login-submit", text: "Tap Login" },
|
|
61
|
+
{ id: "cart-find", text: "Find the product" },
|
|
62
|
+
{ id: "cart-add", text: "Add to cart" },
|
|
63
|
+
{ id: "cart-open", text: "Open cart" },
|
|
64
|
+
],
|
|
65
|
+
{ title: "Device showcase", index: 1 },
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM selectors for the login route (`/`) and its logout burger menu.
|
|
3
|
+
* Convention: DOM strings live in `*Sel` next to the page, not inlined in
|
|
4
|
+
* each Block.
|
|
5
|
+
*/
|
|
6
|
+
export const LoginSel = {
|
|
7
|
+
username: "#user-name",
|
|
8
|
+
password: "#password",
|
|
9
|
+
loginButton: "#login-button",
|
|
10
|
+
errorBanner: '[data-test="error"]',
|
|
11
|
+
burgerMenuButton: "#react-burger-menu-btn",
|
|
12
|
+
logoutLink: "#logout_sidebar_link",
|
|
13
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { DefinedBlock } from "waygraph";
|
|
2
2
|
import type { LoginPage, LoggedIn } from "../../../states/checkout.states.js";
|
|
3
|
-
import {
|
|
3
|
+
import { SubmitLoginBlock } from "./submit-login.method.block.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Kind: helper (not a discoverable Block file)
|
|
7
|
-
* Helper: typed alias over
|
|
7
|
+
* Helper: typed alias over SubmitLoginBlock
|
|
8
8
|
* Route: saucedemo-web/methods/ (page URL /)
|
|
9
9
|
*
|
|
10
10
|
* DefinedBlock cast so linear Flows can chain .withVerify on Out=LoggedIn;
|
|
11
|
-
* runtime still branches on bad credentials via
|
|
11
|
+
* runtime still branches on bad credentials via SubmitLoginBlock.
|
|
12
12
|
*/
|
|
13
|
-
export const SubmitLoginForFlow =
|
|
13
|
+
export const SubmitLoginForFlow = SubmitLoginBlock as unknown as DefinedBlock<LoginPage, LoggedIn>;
|