create-waygraph 0.0.1 → 0.0.4
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 +37 -17
- package/bin/create-waygraph.js +9 -2
- package/package.json +2 -1
- package/templates/README.md +25 -0
- package/templates/STRUCTURE.md +36 -0
- package/templates/gitignore +1 -0
- package/templates/package.json +12 -3
- package/templates/playwright.config.ts +0 -3
- package/templates/src/blocks/SITE-MAP.md +13 -0
- package/templates/src/blocks/demo-web/NAV.md +20 -0
- package/templates/src/blocks/demo-web/methods/assert-hello.method.block.ts +51 -0
- package/templates/src/blocks/demo-web/nav-home.block.ts +25 -0
- package/templates/src/flows/example.flow.ts +25 -3
- package/templates/src/states/demo.states.ts +4 -0
- package/templates/tests/example.spec.ts +2 -2
- package/templates/src/blocks/load-page.block.ts +0 -18
package/README.md
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# create-waygraph
|
|
2
2
|
|
|
3
|
-
Scaffolds a new [waygraph](https://github.com/deviate-dv8/waygraph) project -
|
|
4
|
-
shape, no prompts, no template picker.
|
|
3
|
+
Scaffolds a new [waygraph](https://github.com/deviate-dv8/waygraph) **offline** project -
|
|
4
|
+
one fixed shape, no prompts, no template picker.
|
|
5
|
+
|
|
6
|
+
This is the scaffold command linked from
|
|
7
|
+
[waygraph GitHub Pages](https://deviate-dv8.github.io/waygraph/) (`npx create-waygraph`).
|
|
8
|
+
Same template as `npx waygraph init` (waygraph >= 0.12.6). For a live saucedemo walkthrough
|
|
9
|
+
without creating a folder in your cwd, use `npx waygraph try demo` instead.
|
|
10
|
+
|
|
11
|
+
**Scaffold tree (authoritative):** https://deviate-dv8.github.io/waygraph/scaffold.html
|
|
5
12
|
|
|
6
13
|
```bash
|
|
7
14
|
npx create-waygraph my-project
|
|
@@ -9,26 +16,39 @@ cd my-project
|
|
|
9
16
|
npm install
|
|
10
17
|
npx playwright install chromium
|
|
11
18
|
npm test
|
|
19
|
+
npm run demo
|
|
12
20
|
```
|
|
13
21
|
|
|
14
|
-
Generates:
|
|
22
|
+
Generates (0.12+):
|
|
15
23
|
|
|
16
|
-
```
|
|
24
|
+
```text
|
|
17
25
|
my-project/
|
|
18
|
-
package.json
|
|
19
|
-
|
|
20
|
-
playwright.config.ts
|
|
21
|
-
.gitignore
|
|
26
|
+
package.json
|
|
27
|
+
STRUCTURE.md
|
|
22
28
|
src/
|
|
23
|
-
blocks/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
blocks/
|
|
30
|
+
SITE-MAP.md
|
|
31
|
+
demo-web/ # synthetic "/" (data: URL)
|
|
32
|
+
NAV.md
|
|
33
|
+
nav-home.block.ts
|
|
34
|
+
methods/
|
|
35
|
+
assert-hello.method.block.ts
|
|
36
|
+
states/demo.states.ts
|
|
37
|
+
flows/example.flow.ts # withTitle + withHighlightFixtures
|
|
38
|
+
tests/example.spec.ts
|
|
27
39
|
```
|
|
28
40
|
|
|
29
|
-
`npm test` goes green
|
|
30
|
-
|
|
41
|
+
`npm test` goes green offline - nav uses a `data:` URL. Stubs / fixtures / one YAP
|
|
42
|
+
slide are already wired so `npm run demo` shows narration.
|
|
43
|
+
|
|
44
|
+
## Consumer layout (App Router projects)
|
|
45
|
+
|
|
46
|
+
When the target app has real Next.js routes, **block folders mirror `app/` page routes**:
|
|
47
|
+
|
|
48
|
+
- URL `/` -> nav at namespace root (`zsign-web/` or `pia-web/`), not `landing/` or `root/`
|
|
49
|
+
- Route groups `(auth)` / `(app)` vanish from folder names
|
|
50
|
+
- Folders with no `page.tsx` are grouping only - no NAV.md, no nav block
|
|
51
|
+
- Sidebar / layout chrome -> `shared/chrome/`, not a parallel `shell/nav/*` family
|
|
31
52
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
adding anything to your own `node_modules`.
|
|
53
|
+
Full contract: waygraph [Consumer layout](https://deviate-dv8.github.io/waygraph/consumer.html)
|
|
54
|
+
and mesh handout `WAYGRAPH-CONSUMER-CONVENTION.md`.
|
package/bin/create-waygraph.js
CHANGED
|
@@ -27,12 +27,19 @@ fs.cpSync(templatesDir, targetDir, { recursive: true });
|
|
|
27
27
|
fs.renameSync(path.join(targetDir, "gitignore"), path.join(targetDir, ".gitignore"));
|
|
28
28
|
|
|
29
29
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
30
|
-
const packageJson = fs.readFileSync(packageJsonPath, "utf8").
|
|
30
|
+
const packageJson = fs.readFileSync(packageJsonPath, "utf8").replaceAll("__PROJECT_NAME__", path.basename(targetDir));
|
|
31
31
|
fs.writeFileSync(packageJsonPath, packageJson);
|
|
32
32
|
|
|
33
|
-
console.log(`Scaffolded ${
|
|
33
|
+
console.log(`Scaffolded ${path.basename(targetDir)}/`);
|
|
34
34
|
console.log("");
|
|
35
35
|
console.log(` cd ${projectName}`);
|
|
36
36
|
console.log(" npm install");
|
|
37
37
|
console.log(" npx playwright install chromium");
|
|
38
38
|
console.log(" npm test");
|
|
39
|
+
console.log(" npx waygraph list");
|
|
40
|
+
console.log(" npx waygraph check");
|
|
41
|
+
console.log(" npx waygraph auto # headed panel");
|
|
42
|
+
console.log(" npx waygraph demo src/flows/example.flow.ts");
|
|
43
|
+
console.log("");
|
|
44
|
+
console.log("(Same offline scaffold as: npx waygraph init <name> - waygraph >= 0.10.6.)");
|
|
45
|
+
console.log("(Live saucedemo: npx waygraph try auto | try demo - temp dir, not a scaffold.)");
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-waygraph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Scaffold a new waygraph project - package.json, tsconfig, playwright.config, and one working example flow.",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
8
|
"create-waygraph": "bin/create-waygraph.js"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
Offline waygraph scaffold (`data:` URL - no network for `npm test`).
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
See [STRUCTURE.md](./STRUCTURE.md). Package docs:
|
|
8
|
+
https://deviate-dv8.github.io/waygraph/scaffold.html
|
|
9
|
+
|
|
10
|
+
## Commands
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install
|
|
14
|
+
npx playwright install chromium
|
|
15
|
+
npm test
|
|
16
|
+
npm run list
|
|
17
|
+
npm run check
|
|
18
|
+
npm run demo # headed step (manual Next)
|
|
19
|
+
npm run demo:auto-next
|
|
20
|
+
npm run auto
|
|
21
|
+
npm run auto:cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Point `package.json` `waygraph.baseUrl` at your real app when you leave the
|
|
25
|
+
`data:` demo. Keep route folders = app URLs (consumer layout).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Offline scaffold layout (`waygraph init` / `create-waygraph`)
|
|
2
|
+
|
|
3
|
+
Shipped under `templates/scaffold/` in the **waygraph** package.
|
|
4
|
+
Same tree is what `npx waygraph init my-app` copies.
|
|
5
|
+
|
|
6
|
+
Docs (readable in the package site): [docs/scaffold.html](../../docs/scaffold.html)
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
.
|
|
10
|
+
├── package.json # waygraph ^0.12.6, demo/run/auto scripts
|
|
11
|
+
├── playwright.config.ts
|
|
12
|
+
├── tsconfig.json
|
|
13
|
+
├── STRUCTURE.md # this file
|
|
14
|
+
├── README.md
|
|
15
|
+
├── src/
|
|
16
|
+
│ ├── blocks/
|
|
17
|
+
│ │ ├── SITE-MAP.md # namespace map (consumer convention)
|
|
18
|
+
│ │ └── demo-web/ # synthetic site (data: URL) - mirrors app "/"
|
|
19
|
+
│ │ ├── NAV.md
|
|
20
|
+
│ │ ├── nav-home.block.ts
|
|
21
|
+
│ │ └── methods/
|
|
22
|
+
│ │ └── assert-hello.method.block.ts
|
|
23
|
+
│ ├── states/
|
|
24
|
+
│ │ └── demo.states.ts
|
|
25
|
+
│ └── flows/
|
|
26
|
+
│ └── example.flow.ts # withTitle + withHighlightFixtures
|
|
27
|
+
└── tests/
|
|
28
|
+
└── example.spec.ts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Rule of thumb:** route folders = app URL folders; `/` lives at the namespace
|
|
32
|
+
root (`demo-web/`). Methods hang under `methods/`. Chrome/shared UI would be
|
|
33
|
+
`shared/chrome/` (not invented for this offline hello).
|
|
34
|
+
|
|
35
|
+
Grow this into a real app by renaming `demo-web/` to your FE origin namespace
|
|
36
|
+
and adding one folder per `page.tsx` URL. See package docs **Consumer layout**.
|
package/templates/gitignore
CHANGED
package/templates/package.json
CHANGED
|
@@ -6,11 +6,20 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"typecheck": "tsc --noEmit",
|
|
8
8
|
"test": "playwright test",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"list": "waygraph list",
|
|
10
|
+
"check": "waygraph check",
|
|
11
|
+
"auto": "waygraph auto",
|
|
12
|
+
"auto:cli": "waygraph auto --cli",
|
|
13
|
+
"demo": "waygraph demo --blocks exampleFlow",
|
|
14
|
+
"demo:auto-next": "waygraph demo --blocks exampleFlow --auto-next --title \"Scaffold demo\"",
|
|
15
|
+
"run": "waygraph run --blocks exampleFlow",
|
|
16
|
+
"graph": "waygraph graph"
|
|
17
|
+
},
|
|
18
|
+
"waygraph": {
|
|
19
|
+
"baseUrl": "about:blank"
|
|
11
20
|
},
|
|
12
21
|
"dependencies": {
|
|
13
|
-
"waygraph": "^0.
|
|
22
|
+
"waygraph": "^0.12.6"
|
|
14
23
|
},
|
|
15
24
|
"devDependencies": {
|
|
16
25
|
"@playwright/test": "^1.55.0",
|
|
@@ -6,9 +6,6 @@ export default defineConfig({
|
|
|
6
6
|
reporter: "list",
|
|
7
7
|
use: {
|
|
8
8
|
launchOptions: {
|
|
9
|
-
// If CHROME_PATH/CHROMIUM_PATH is set (e.g. a Flatpak/system Chromium),
|
|
10
|
-
// use it instead of downloading Playwright's own bundled binary.
|
|
11
|
-
// Falls through to Playwright's default when unset - safe either way.
|
|
12
9
|
executablePath: process.env.CHROME_PATH || process.env.CHROMIUM_PATH,
|
|
13
10
|
},
|
|
14
11
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Site map (scaffold)
|
|
2
|
+
|
|
3
|
+
Offline hello uses one synthetic namespace (`demo-web/`) and a `data:` home URL
|
|
4
|
+
so `npm test` stays green without the network.
|
|
5
|
+
|
|
6
|
+
| Folder | URL | Notes |
|
|
7
|
+
|--------|-----|-------|
|
|
8
|
+
| `demo-web/` | `/` (synthetic) | Nav + methods for the hello page |
|
|
9
|
+
| `demo-web/methods/` | same URL | On-page asserts / future form acts |
|
|
10
|
+
|
|
11
|
+
When you wire a real app, rename `demo-web/` to your FE origin namespace and
|
|
12
|
+
add one folder per real `page.tsx` route. Grouping dirs without a page get no
|
|
13
|
+
`NAV.md`. Full contract: waygraph **Consumer layout** docs.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# demo-web / (synthetic home)
|
|
2
|
+
|
|
3
|
+
**URL:** `data:text/html,…` (offline hello - replace with your real `/`)
|
|
4
|
+
|
|
5
|
+
## Nav-to
|
|
6
|
+
|
|
7
|
+
| From | Block | How |
|
|
8
|
+
|------|-------|-----|
|
|
9
|
+
| start | `nav-home` | `defineNavBlock` `url` → data HTML |
|
|
10
|
+
|
|
11
|
+
## Methods
|
|
12
|
+
|
|
13
|
+
| Block | Kind | Notes |
|
|
14
|
+
|-------|------|-------|
|
|
15
|
+
| `assert-hello` | Method | Verify heading; demo stubs + fixtures |
|
|
16
|
+
|
|
17
|
+
## States / mem-keys
|
|
18
|
+
|
|
19
|
+
- Checkpoint `Home` after nav
|
|
20
|
+
- Checkpoint `HomeVerified` after assert-hello
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { defineMethodBlock, checkpoint, Trait } from "waygraph";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Kind: Method
|
|
5
|
+
* Helper: defineMethodBlock
|
|
6
|
+
* Route: demo-web/methods/
|
|
7
|
+
*
|
|
8
|
+
* Same-URL assert after nav - shows stubBefore / stubAfter / stubOnError shape.
|
|
9
|
+
*/
|
|
10
|
+
export const AssertHelloBlock = defineMethodBlock({
|
|
11
|
+
name: "assert-hello",
|
|
12
|
+
description: "Confirms the hello heading is still visible after arrival.",
|
|
13
|
+
instruction: {
|
|
14
|
+
async act(_page) {
|
|
15
|
+
// No DOM mutation - observe/verify own the proof.
|
|
16
|
+
},
|
|
17
|
+
async observe(page) {
|
|
18
|
+
await page.locator("h1").first().waitFor({ state: "visible", timeout: 5_000 });
|
|
19
|
+
return "ok" as const;
|
|
20
|
+
},
|
|
21
|
+
resolve: () => checkpoint("HomeVerified"),
|
|
22
|
+
verify: [Trait.text("h1", "Hello Waygraph"), Trait.visible("#sub")],
|
|
23
|
+
stubBefore: {
|
|
24
|
+
title: { selector: "h1", label: "Heading about to check" },
|
|
25
|
+
},
|
|
26
|
+
stubAfter: {
|
|
27
|
+
title: {
|
|
28
|
+
selector: "h1",
|
|
29
|
+
label: "Hello confirmed",
|
|
30
|
+
detail: "Offline scaffold proof point.",
|
|
31
|
+
duration: true,
|
|
32
|
+
},
|
|
33
|
+
sub: { selector: "#sub", label: "Subcopy", duration: 1500 },
|
|
34
|
+
},
|
|
35
|
+
stubOnError: {
|
|
36
|
+
title: {
|
|
37
|
+
selector: "h1",
|
|
38
|
+
label: "Heading at failure",
|
|
39
|
+
tag: "FAIL",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
slides: [
|
|
43
|
+
{
|
|
44
|
+
caption: "Scaffold is route-shaped",
|
|
45
|
+
detail: "demo-web/ = synthetic /. Grow folders per real page.tsx.",
|
|
46
|
+
tag: "YAP",
|
|
47
|
+
duration: true,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineNavBlock, Trait } from "waygraph";
|
|
2
|
+
|
|
3
|
+
/** Offline hello page - swap `url` for a real app route when you graduate. */
|
|
4
|
+
export const HOME_URL =
|
|
5
|
+
'data:text/html,<!doctype html><html><body><h1>Hello Waygraph</h1><p id="sub">Scaffold demo</p></body></html>';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Kind: Nav
|
|
9
|
+
* Helper: defineNavBlock
|
|
10
|
+
* Route: demo-web/ (synthetic "/")
|
|
11
|
+
*/
|
|
12
|
+
export const NavHomeBlock = defineNavBlock({
|
|
13
|
+
name: "nav-home",
|
|
14
|
+
description: "Opens the offline hello page (data: URL).",
|
|
15
|
+
checkpoint: "Home",
|
|
16
|
+
url: HOME_URL,
|
|
17
|
+
verify: [Trait.text("h1", "Hello Waygraph")],
|
|
18
|
+
stubBefore: {},
|
|
19
|
+
stubAfter: {
|
|
20
|
+
title: { selector: "h1", label: "Home heading", duration: true },
|
|
21
|
+
},
|
|
22
|
+
stubOnError: {
|
|
23
|
+
title: { selector: "h1", label: "Home heading at failure" },
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -1,6 +1,28 @@
|
|
|
1
|
-
import { Engine, start, end } from "waygraph";
|
|
2
|
-
import {
|
|
1
|
+
import { Engine, start, end, withTitle, withHighlightFixtures } from "waygraph";
|
|
2
|
+
import { NavHomeBlock } from "../blocks/demo-web/nav-home.block.js";
|
|
3
|
+
import { AssertHelloBlock } from "../blocks/demo-web/methods/assert-hello.method.block.js";
|
|
3
4
|
|
|
4
5
|
const engine = new Engine();
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Offline example: nav to data: hello page, then assert heading.
|
|
9
|
+
* Flow fixtures override ticket-style copy on stubs (demo narration).
|
|
10
|
+
*/
|
|
11
|
+
export const exampleFlow = withHighlightFixtures(
|
|
12
|
+
withTitle(
|
|
13
|
+
engine.defineFlow([start, NavHomeBlock, AssertHelloBlock, end]),
|
|
14
|
+
"Scaffold: Hello Waygraph",
|
|
15
|
+
),
|
|
16
|
+
{
|
|
17
|
+
"assert-hello": {
|
|
18
|
+
stubAfter: {
|
|
19
|
+
title: {
|
|
20
|
+
label: "AC · Hello visible",
|
|
21
|
+
detail: "Replace this fixture copy with your ticket lines.",
|
|
22
|
+
tag: "AC",
|
|
23
|
+
duration: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
@@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test";
|
|
|
2
2
|
import { MemPage, checkpoint } from "waygraph";
|
|
3
3
|
import { exampleFlow } from "../src/flows/example.flow.js";
|
|
4
4
|
|
|
5
|
-
test("example flow reaches
|
|
5
|
+
test("example flow reaches HomeVerified", async ({ context }) => {
|
|
6
6
|
const result = await exampleFlow.run(context, new MemPage());
|
|
7
|
-
expect(result).toEqual(checkpoint("
|
|
7
|
+
expect(result).toEqual(checkpoint("HomeVerified"));
|
|
8
8
|
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { defineBlock, checkpoint, Trait } from "waygraph";
|
|
2
|
-
import type { Checkpoint } from "waygraph";
|
|
3
|
-
|
|
4
|
-
export type Start = Checkpoint<"__start__">;
|
|
5
|
-
export type Loaded = Checkpoint<"Loaded">;
|
|
6
|
-
|
|
7
|
-
const PAGE_URL = "data:text/html,<h1>Hello Waygraph</h1>";
|
|
8
|
-
|
|
9
|
-
export const LoadPageBlock = defineBlock<Start, Loaded>({
|
|
10
|
-
name: "load-page",
|
|
11
|
-
instruction: {
|
|
12
|
-
async act(page) {
|
|
13
|
-
await page.goto(PAGE_URL);
|
|
14
|
-
},
|
|
15
|
-
resolve: () => checkpoint("Loaded"),
|
|
16
|
-
verify: [Trait.text("h1", "Hello Waygraph")],
|
|
17
|
-
},
|
|
18
|
-
});
|