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
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "waygraph-example-routed-demo",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Waygraph Map folder convention proof - (group)/<page>/page.block.ts + nav.block.ts + methods/*.block.ts, offline fixture, zero new engine code.",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"typecheck": "tsc --noEmit",
|
|
9
|
+
"test": "npm run fixture:test",
|
|
10
|
+
"fixture": "node scripts/fixture-server.mjs",
|
|
11
|
+
"fixture:test": "node scripts/with-fixture.mjs npx playwright test",
|
|
12
|
+
"graph": "waygraph graph",
|
|
13
|
+
"auto:cli": "node scripts/with-fixture.mjs waygraph auto --cli"
|
|
14
|
+
},
|
|
15
|
+
"waygraph": {
|
|
16
|
+
"baseUrl": "http://127.0.0.1:4277"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"waygraph": "file:../.."
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@playwright/test": "^1.55.0",
|
|
23
|
+
"@types/node": "^26.0.0",
|
|
24
|
+
"typescript": "^5.6.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from "@playwright/test";
|
|
2
|
+
|
|
3
|
+
const PORT = process.env.WAYGRAPH_FIXTURE_PORT || "4277";
|
|
4
|
+
const HOST = process.env.WAYGRAPH_FIXTURE_HOST || "127.0.0.1";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
testDir: "./tests",
|
|
8
|
+
fullyParallel: false,
|
|
9
|
+
workers: 1,
|
|
10
|
+
timeout: 30_000,
|
|
11
|
+
reporter: "list",
|
|
12
|
+
use: {
|
|
13
|
+
headless: true,
|
|
14
|
+
baseURL: process.env.WAYGRAPH_BASE_URL || `http://${HOST}:${PORT}`,
|
|
15
|
+
launchOptions: {
|
|
16
|
+
executablePath: process.env.CHROME_PATH || process.env.CHROMIUM_PATH,
|
|
17
|
+
args: ["--no-sandbox", "--disable-dev-shm-usage"],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tiny static server for this example's offline fixture pages.
|
|
4
|
+
* Mirrors templates/scaffold's own scripts/fixture-server.mjs exactly.
|
|
5
|
+
*/
|
|
6
|
+
import { createServer } from "node:http";
|
|
7
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
8
|
+
import { join, dirname, extname, normalize } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "../src/pages");
|
|
12
|
+
const PORT = Number(process.env.WAYGRAPH_FIXTURE_PORT || 4277);
|
|
13
|
+
const HOST = process.env.WAYGRAPH_FIXTURE_HOST || "127.0.0.1";
|
|
14
|
+
|
|
15
|
+
const TYPES = {
|
|
16
|
+
".html": "text/html; charset=utf-8",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const server = createServer((req, res) => {
|
|
20
|
+
const raw = (req.url || "/").split("?")[0] || "/";
|
|
21
|
+
const rel = raw === "/" ? "dashboard.html" : raw.replace(/^\//, "");
|
|
22
|
+
const full = normalize(join(ROOT, rel));
|
|
23
|
+
if (!full.startsWith(ROOT) || !existsSync(full)) {
|
|
24
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
25
|
+
res.end("not found");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const type = TYPES[extname(full)] || "application/octet-stream";
|
|
29
|
+
res.writeHead(200, { "content-type": type });
|
|
30
|
+
res.end(readFileSync(full));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
server.listen(PORT, HOST, () => {
|
|
34
|
+
if (process.env.WAYGRAPH_FIXTURE_QUIET !== "1") {
|
|
35
|
+
console.error(`waygraph fixture: http://${HOST}:${PORT}/dashboard.html`);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Start fixture-server, run a child command, tear down on exit.
|
|
4
|
+
* Usage: node scripts/with-fixture.mjs [--] <cmd> [args...]
|
|
5
|
+
* Mirrors templates/scaffold's own scripts/with-fixture.mjs exactly.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const PORT = process.env.WAYGRAPH_FIXTURE_PORT || "4277";
|
|
13
|
+
const HOST = process.env.WAYGRAPH_FIXTURE_HOST || "127.0.0.1";
|
|
14
|
+
|
|
15
|
+
const argv = process.argv.slice(2).filter((a) => a !== "--");
|
|
16
|
+
if (argv.length === 0) {
|
|
17
|
+
console.error("usage: node scripts/with-fixture.mjs <cmd> [args...]");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const env = {
|
|
22
|
+
...process.env,
|
|
23
|
+
WAYGRAPH_FIXTURE_PORT: PORT,
|
|
24
|
+
WAYGRAPH_FIXTURE_HOST: HOST,
|
|
25
|
+
WAYGRAPH_FIXTURE_QUIET: "1",
|
|
26
|
+
WAYGRAPH_BASE_URL: process.env.WAYGRAPH_BASE_URL || `http://${HOST}:${PORT}`,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const server = spawn(process.execPath, [join(HERE, "fixture-server.mjs")], {
|
|
30
|
+
env,
|
|
31
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
function killServer() {
|
|
35
|
+
try {
|
|
36
|
+
server.kill("SIGTERM");
|
|
37
|
+
} catch {
|
|
38
|
+
/* ignore */
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function waitReady(ms = 5000) {
|
|
43
|
+
const url = `http://${HOST}:${PORT}/dashboard.html`;
|
|
44
|
+
const start = Date.now();
|
|
45
|
+
while (Date.now() - start < ms) {
|
|
46
|
+
try {
|
|
47
|
+
const res = await fetch(url);
|
|
48
|
+
if (res.ok) return;
|
|
49
|
+
} catch {
|
|
50
|
+
/* retry */
|
|
51
|
+
}
|
|
52
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`fixture server not ready at ${url}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let code = 1;
|
|
58
|
+
try {
|
|
59
|
+
await waitReady();
|
|
60
|
+
const child = spawn(argv[0], argv.slice(1), { env, stdio: "inherit", shell: false });
|
|
61
|
+
code = await new Promise((resolve) => {
|
|
62
|
+
child.on("exit", (c, signal) => resolve(signal ? 1 : (c ?? 1)));
|
|
63
|
+
});
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error(e instanceof Error ? e.message : String(e));
|
|
66
|
+
code = 1;
|
|
67
|
+
} finally {
|
|
68
|
+
killServer();
|
|
69
|
+
}
|
|
70
|
+
process.exit(code);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Engine } from "waygraph";
|
|
2
|
+
import { NavDashboardBlock } from "../map/(app_base)/dashboard/_nav.block.js";
|
|
3
|
+
import { ClickWidgetBlock } from "../map/(app_base)/dashboard/_methods/click-widget.block.js";
|
|
4
|
+
import { NavDocsBlock } from "../map/(external)/docs/_nav.block.js";
|
|
5
|
+
// Page hubs registered for auto/docs grouping (arrival-only after nav).
|
|
6
|
+
import "../map/(app_base)/dashboard/_page.block.js";
|
|
7
|
+
import "../map/(external)/docs/_page.block.js";
|
|
8
|
+
|
|
9
|
+
const engine = new Engine();
|
|
10
|
+
|
|
11
|
+
const homeOrigin = process.env.WAYGRAPH_BASE_URL || "http://127.0.0.1:4277";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Same real Blocks, same real Checkpoints, same real fixture server as
|
|
15
|
+
* routed-demo.flow.ts - built with `engine.map()` instead of
|
|
16
|
+
* `engine.defineFlow([start, ..., end])` to prove the fluent builder
|
|
17
|
+
* against a real browser/DOM, not just the in-memory fakes
|
|
18
|
+
* tests/nav/map-builder.spec.ts already covers in the main package.
|
|
19
|
+
*
|
|
20
|
+
* Both nav steps use `.gotoPage()`, not `.gotoExternal()` - even though
|
|
21
|
+
* NavDocsBlock's file lives under the `(external)/` group. That group name
|
|
22
|
+
* is organizational intent (docs.sel.ts's own `WAYGRAPH_DOCS_URL` env
|
|
23
|
+
* override exists for genuinely pointing it at a different origin), but
|
|
24
|
+
* this fixture server happens to serve docs.html from the exact same
|
|
25
|
+
* origin as dashboard.html - the same real inconsistency this session
|
|
26
|
+
* found and fixed in templates/scaffold's own (external)/docs -> (app_base)
|
|
27
|
+
* rename, left as-is here since routed-demo is the one place a reader
|
|
28
|
+
* benefits from seeing it: passing a real `homeOrigin` below means
|
|
29
|
+
* `.gotoExternal(NavDocsBlock)` would actually THROW (same-origin, not
|
|
30
|
+
* cross-origin) - `.gotoPage()` is the one that's honest about what this
|
|
31
|
+
* fixture really does, regardless of the folder it's grouped under.
|
|
32
|
+
*/
|
|
33
|
+
export const routedDemoMapFlow = engine
|
|
34
|
+
.map({ homeOrigin })
|
|
35
|
+
.start()
|
|
36
|
+
.gotoPage(NavDashboardBlock)
|
|
37
|
+
.method(ClickWidgetBlock)
|
|
38
|
+
.gotoPage(NavDocsBlock)
|
|
39
|
+
.end();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Engine, start, end } from "waygraph";
|
|
2
|
+
import { NavDashboardBlock } from "../map/(app_base)/dashboard/_nav.block.js";
|
|
3
|
+
import { ClickWidgetBlock } from "../map/(app_base)/dashboard/_methods/click-widget.block.js";
|
|
4
|
+
import { NavDocsBlock } from "../map/(external)/docs/_nav.block.js";
|
|
5
|
+
// Page hubs registered for auto/docs grouping (arrival-only after nav).
|
|
6
|
+
import "../map/(app_base)/dashboard/_page.block.js";
|
|
7
|
+
import "../map/(external)/docs/_page.block.js";
|
|
8
|
+
|
|
9
|
+
const engine = new Engine();
|
|
10
|
+
|
|
11
|
+
/** Smoke: dashboard -> click widget -> docs, all Blocks under the Waygraph Map folder convention. */
|
|
12
|
+
export const routedDemoFlow = engine.defineFlow([start, NavDashboardBlock, ClickWidgetBlock, NavDocsBlock, end]);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint, Trait } from "waygraph";
|
|
2
|
+
import type { Dashboard } from "../../../../states/routed-demo.states.js";
|
|
3
|
+
import { DashboardSel } from "../_sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Method
|
|
7
|
+
* Route: (app_base)/dashboard/_methods/
|
|
8
|
+
*
|
|
9
|
+
* Fixed folder name under the Waygraph Map convention - every page-slug
|
|
10
|
+
* folder's own actions live under methods/, same as today's freeform
|
|
11
|
+
* convention's own methods/ subfolder.
|
|
12
|
+
*/
|
|
13
|
+
export const ClickWidgetBlock = defineMethodBlock<Dashboard, Dashboard>({
|
|
14
|
+
name: "click-widget",
|
|
15
|
+
description: "Clicks the dashboard's demo widget button.",
|
|
16
|
+
instruction: {
|
|
17
|
+
async act(page) {
|
|
18
|
+
await page.locator(DashboardSel.widgetBtn).click();
|
|
19
|
+
},
|
|
20
|
+
resolve: () => checkpoint("Dashboard"),
|
|
21
|
+
verify: [Trait.text(DashboardSel.widgetOut, "clicked")],
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineNavBlock, Trait } from "waygraph";
|
|
2
|
+
import type { Dashboard } from "../../../states/routed-demo.states.js";
|
|
3
|
+
import { DashboardSel, DASHBOARD_URL } from "./_sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Nav
|
|
7
|
+
* Route: (app_base)/dashboard/
|
|
8
|
+
*
|
|
9
|
+
* Fixed file name under the Waygraph Map convention - every page-slug
|
|
10
|
+
* folder's own navigation Block is always nav.block.ts.
|
|
11
|
+
*/
|
|
12
|
+
export const NavDashboardBlock = defineNavBlock<Dashboard>({
|
|
13
|
+
name: "nav-dashboard",
|
|
14
|
+
description: "Opens the dashboard page.",
|
|
15
|
+
checkpoint: "Dashboard",
|
|
16
|
+
url: DASHBOARD_URL,
|
|
17
|
+
verify: [Trait.visible(DashboardSel.heading)],
|
|
18
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { definePageBlock, Trait } from "waygraph";
|
|
2
|
+
import type { Dashboard } from "../../../states/routed-demo.states.js";
|
|
3
|
+
import { DashboardSel } from "./_sel.js";
|
|
4
|
+
import { ClickWidgetBlock } from "./_methods/click-widget.block.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Kind: Page
|
|
8
|
+
* Route: (app_base)/dashboard/
|
|
9
|
+
*
|
|
10
|
+
* Fixed file name under the Waygraph Map convention - every page-slug
|
|
11
|
+
* folder's own arrival hub is always page.block.ts. Arrival-only
|
|
12
|
+
* (nav.block.ts already landed on Dashboard).
|
|
13
|
+
*/
|
|
14
|
+
export const DashboardPageBlock = definePageBlock<Dashboard>({
|
|
15
|
+
name: "page-dashboard",
|
|
16
|
+
description: "Dashboard hub - the routed-demo example's (app_base) group.",
|
|
17
|
+
checkpoint: "Dashboard",
|
|
18
|
+
verify: [Trait.visible(DashboardSel.heading)],
|
|
19
|
+
methods: {
|
|
20
|
+
clickWidget: () => ClickWidgetBlock,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const DASHBOARD_URL =
|
|
2
|
+
process.env.WAYGRAPH_DASHBOARD_URL ??
|
|
3
|
+
`http://${process.env.WAYGRAPH_FIXTURE_HOST || "127.0.0.1"}:${process.env.WAYGRAPH_FIXTURE_PORT || "4277"}/dashboard.html`;
|
|
4
|
+
|
|
5
|
+
export const DashboardSel = {
|
|
6
|
+
heading: "#dashboard-heading",
|
|
7
|
+
widgetBtn: "#widget-btn",
|
|
8
|
+
widgetOut: "#widget-out",
|
|
9
|
+
goDocs: "#go-docs",
|
|
10
|
+
} as const;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineNavBlock, Trait } from "waygraph";
|
|
2
|
+
import type { Docs } from "../../../states/routed-demo.states.js";
|
|
3
|
+
import { DocsSel, DOCS_URL } from "./_sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Nav
|
|
7
|
+
* Route: (external)/docs/
|
|
8
|
+
*
|
|
9
|
+
* `(external)` is a purely organizational group folder (Next.js route-group
|
|
10
|
+
* style, parens never affect the Checkpoint tag) - separates cross-origin/
|
|
11
|
+
* external tooling from the app's own `(app_base)` pages, matching the
|
|
12
|
+
* already-established `*-external/` namespacing precedent from
|
|
13
|
+
* waygraph-mail-adapters.
|
|
14
|
+
*/
|
|
15
|
+
export const NavDocsBlock = defineNavBlock<Docs>({
|
|
16
|
+
name: "nav-docs",
|
|
17
|
+
description: "Opens the docs page.",
|
|
18
|
+
checkpoint: "Docs",
|
|
19
|
+
url: DOCS_URL,
|
|
20
|
+
verify: [Trait.visible(DocsSel.heading)],
|
|
21
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { definePageBlock, Trait } from "waygraph";
|
|
2
|
+
import type { Docs } from "../../../states/routed-demo.states.js";
|
|
3
|
+
import { DocsSel } from "./_sel.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Kind: Page
|
|
7
|
+
* Route: (external)/docs/
|
|
8
|
+
* Arrival-only (nav.block.ts already landed on Docs).
|
|
9
|
+
*/
|
|
10
|
+
export const DocsPageBlock = definePageBlock<Docs>({
|
|
11
|
+
name: "page-docs",
|
|
12
|
+
description: "Docs hub - the routed-demo example's (external) group.",
|
|
13
|
+
checkpoint: "Docs",
|
|
14
|
+
verify: [Trait.visible(DocsSel.heading)],
|
|
15
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head><title>Routed demo - dashboard</title></head>
|
|
4
|
+
<body>
|
|
5
|
+
<h1 id="dashboard-heading">Dashboard</h1>
|
|
6
|
+
<button id="widget-btn" onclick="document.getElementById('widget-out').textContent = 'clicked'">Click widget</button>
|
|
7
|
+
<div id="widget-out"></div>
|
|
8
|
+
<a id="go-docs" href="/docs.html">Docs</a>
|
|
9
|
+
</body>
|
|
10
|
+
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Checkpoint } from "waygraph";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checkpoint names match their own folder's page-slug (PascalCase) under the
|
|
5
|
+
* Waygraph Map convention - `dashboard/` -> `Dashboard`, `docs/` -> `Docs`.
|
|
6
|
+
* See openspec/changes/waygraph-map for why this is a naming convention, not
|
|
7
|
+
* something any tool enforces.
|
|
8
|
+
*/
|
|
9
|
+
export type Dashboard = Checkpoint<"Dashboard">;
|
|
10
|
+
export type Docs = Checkpoint<"Docs">;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
import { MemPage, checkpoint } from "waygraph";
|
|
3
|
+
import { routedDemoMapFlow } from "../src/flows/routed-demo-map.flow.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Proof that `engine.map()` (the fluent, kind-checked flow builder) works
|
|
7
|
+
* end to end against a real browser/DOM, not just the in-memory fakes
|
|
8
|
+
* tests/nav/map-builder.spec.ts already covers in the main waygraph
|
|
9
|
+
* package - same real fixture server and real Blocks routed-demo.spec.ts
|
|
10
|
+
* already proves work via defineFlow/the CLI, this time built with
|
|
11
|
+
* .start().gotoPage(...).method(...).gotoPage(...).end() instead.
|
|
12
|
+
*/
|
|
13
|
+
test("engine.map()-built flow runs for real: Dashboard -> click widget -> Docs", async ({ context }) => {
|
|
14
|
+
const mem = new MemPage();
|
|
15
|
+
const result = await routedDemoMapFlow.run(context, mem);
|
|
16
|
+
expect(result).toEqual(checkpoint("Docs"));
|
|
17
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Proof for openspec/changes/waygraph-map: every existing command works
|
|
8
|
+
* against a project organized under the Waygraph Map folder convention
|
|
9
|
+
* ((group)/<page-slug>/page.block.ts + nav.block.ts + methods/*.block.ts)
|
|
10
|
+
* with ZERO new engine code - discoverGraph/loadBlockLibrary already walk
|
|
11
|
+
* any folder structure, matching only the .block.ts filename pattern.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const exec = promisify(execFile);
|
|
15
|
+
const node = process.execPath;
|
|
16
|
+
const CLI = join(import.meta.dirname, "..", "..", "..", "bin", "waygraph");
|
|
17
|
+
const root = join(import.meta.dirname, "..");
|
|
18
|
+
|
|
19
|
+
async function runCli(args: string[]): Promise<{ stdout: string; code: number }> {
|
|
20
|
+
try {
|
|
21
|
+
const { stdout } = (await exec(node, [CLI, ...args], { cwd: root })) as { stdout: string };
|
|
22
|
+
return { stdout, code: 0 };
|
|
23
|
+
} catch (err) {
|
|
24
|
+
const e = err as { stdout?: string; code?: number };
|
|
25
|
+
if (e.stdout !== undefined) return { stdout: e.stdout, code: e.code ?? 1 };
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test("waygraph graph discovers both Checkpoints via the exact same discoverGraph path a freeform project uses", async () => {
|
|
31
|
+
const { stdout, code } = await runCli(["graph"]);
|
|
32
|
+
expect(code).toBe(0);
|
|
33
|
+
const graph = JSON.parse(stdout.trim());
|
|
34
|
+
const checkpoints = graph.nodes.map((n: { checkpoint: string }) => n.checkpoint);
|
|
35
|
+
expect(checkpoints).toEqual(expect.arrayContaining(["Dashboard", "Docs"]));
|
|
36
|
+
expect(graph.edges.some((e: { block: string }) => e.block === "nav-dashboard")).toBe(true);
|
|
37
|
+
expect(graph.edges.some((e: { block: string }) => e.block === "nav-docs")).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("a real detached session navigates the convention-organized site for real, including a real click", async () => {
|
|
41
|
+
test.setTimeout(30_000);
|
|
42
|
+
const { stdout } = await exec(node, [
|
|
43
|
+
CLI,
|
|
44
|
+
"auto",
|
|
45
|
+
"--cli",
|
|
46
|
+
"--detach",
|
|
47
|
+
"--base-url",
|
|
48
|
+
process.env.WAYGRAPH_BASE_URL || "http://127.0.0.1:4277",
|
|
49
|
+
root,
|
|
50
|
+
]).then((r) => r);
|
|
51
|
+
const { sessionId } = JSON.parse(stdout.trim());
|
|
52
|
+
try {
|
|
53
|
+
const status = await exec(node, [CLI, "auto", "status", sessionId], { cwd: root });
|
|
54
|
+
const statusRes = JSON.parse(status.stdout.trim());
|
|
55
|
+
expect(statusRes.snapshot.here).toBe("Dashboard");
|
|
56
|
+
|
|
57
|
+
const clickEdge = statusRes.snapshot.sections
|
|
58
|
+
.flatMap((s: { edges: { block: string; index: number }[] }) => s.edges)
|
|
59
|
+
.find((e: { block: string }) => e.block === "click-widget");
|
|
60
|
+
expect(clickEdge).toBeTruthy();
|
|
61
|
+
const clickRes = await exec(node, [CLI, "auto", "send", sessionId, String(clickEdge.index)], { cwd: root });
|
|
62
|
+
const clickJson = JSON.parse(clickRes.stdout.trim());
|
|
63
|
+
expect(clickJson.ok).toBe(true);
|
|
64
|
+
expect(clickJson.snapshot.here).toBe("Dashboard");
|
|
65
|
+
|
|
66
|
+
// auto reach: one call, real multi-step route (Dashboard -> Docs via nav-docs).
|
|
67
|
+
const reachRes = await exec(node, [CLI, "auto", "reach", sessionId, "Docs"], { cwd: root });
|
|
68
|
+
const reachJson = JSON.parse(reachRes.stdout.trim());
|
|
69
|
+
expect(reachJson.ok).toBe(true);
|
|
70
|
+
expect(reachJson.path).toEqual(["nav-docs"]);
|
|
71
|
+
expect(reachJson.snapshot.here).toBe("Docs");
|
|
72
|
+
} finally {
|
|
73
|
+
await exec(node, [CLI, "auto", "send", sessionId, "q"], { cwd: root }).catch(() => {});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noImplicitAny": true,
|
|
9
|
+
"noUncheckedIndexedAccess": true,
|
|
10
|
+
"exactOptionalPropertyTypes": true,
|
|
11
|
+
"noUnusedLocals": true,
|
|
12
|
+
"noUnusedParameters": false,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts", "tests/**/*.ts"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "waygraph-example-routed-demo-consumer",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Waygraph Map 'waypack' loading proof - depends on routed-demo as a plain file: dependency, no separate manifest, waygraph graph understands it via the loaded package's own node_modules path.",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"graph:own": "waygraph graph",
|
|
9
|
+
"graph:loaded": "waygraph graph node_modules/waygraph-example-routed-demo"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"waygraph": "file:../..",
|
|
13
|
+
"waygraph-example-routed-demo": "file:../routed-demo"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.6.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|