waygraph 0.15.23 → 0.15.24

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.
Files changed (41) hide show
  1. package/dist/cli/discover.d.ts +40 -0
  2. package/dist/cli/discover.js +148 -0
  3. package/dist/cli/flags.d.ts +91 -0
  4. package/dist/cli/flags.js +442 -0
  5. package/dist/cli/run-chain.d.ts +8 -0
  6. package/dist/cli/run-chain.js +67 -0
  7. package/dist/cli/usage.d.ts +4 -0
  8. package/dist/cli/usage.js +236 -0
  9. package/dist/cli/util.d.ts +4 -0
  10. package/dist/cli/util.js +24 -0
  11. package/dist/cli.js +45 -2448
  12. package/dist/commands/agent-dive.d.ts +1 -0
  13. package/dist/commands/agent-dive.js +52 -0
  14. package/dist/commands/check.d.ts +4 -0
  15. package/dist/commands/check.js +192 -0
  16. package/dist/commands/init.d.ts +1 -0
  17. package/dist/commands/init.js +54 -0
  18. package/dist/commands/list.d.ts +2 -0
  19. package/dist/commands/list.js +67 -0
  20. package/dist/commands/map.d.ts +1 -0
  21. package/dist/commands/map.js +29 -0
  22. package/dist/commands/run.d.ts +3 -0
  23. package/dist/commands/run.js +104 -0
  24. package/dist/commands/session.d.ts +2 -0
  25. package/dist/commands/session.js +600 -0
  26. package/dist/commands/test.d.ts +1 -0
  27. package/dist/commands/test.js +33 -0
  28. package/dist/commands/traverse.d.ts +1 -0
  29. package/dist/commands/traverse.js +177 -0
  30. package/dist/commands/try.d.ts +1 -0
  31. package/dist/commands/try.js +298 -0
  32. package/examples/saucedemo/.waygraph-auto/0ac58118.log +0 -0
  33. package/examples/saucedemo/.waygraph-auto/309c107f.log +0 -0
  34. package/examples/saucedemo/.waygraph-auto/3ab7c7bd.log +44 -0
  35. package/examples/saucedemo/.waygraph-auto/45864828.log +0 -0
  36. package/examples/saucedemo/.waygraph-auto/95bd8371.log +0 -0
  37. package/examples/saucedemo/.waygraph-auto/bcb9e31a.log +0 -0
  38. package/examples/saucedemo/.waygraph-auto/cd3e528c.log +0 -0
  39. package/examples/saucedemo/.waygraph-auto/dce1535d.log +0 -0
  40. package/examples/saucedemo/.waygraph-auto/e280bf20.log +0 -0
  41. package/package.json +1 -1
@@ -0,0 +1,177 @@
1
+ // Split out of the former 8,700-line cli.ts (see src/ARCHITECTURE.md). Behavior unchanged.
2
+ import { resolve } from "node:path";
3
+ import { existsSync, statSync } from "node:fs";
4
+ import { parseBlocksSelect } from "../blocks-select.js";
5
+ import { parseMinEdgeCoverage } from "../traverse-coverage.js";
6
+ import { runTraverse } from "../traverse-run.js";
7
+ export async function traverseCase(args) {
8
+ if (args.includes("--step") || args.includes("--auto-next") || args.includes("--autoplay")) {
9
+ console.error("waygraph traverse: --step / --auto-next not supported (not a demo)");
10
+ process.exit(1);
11
+ }
12
+ const rest = args.slice(1);
13
+ let from;
14
+ let data;
15
+ let maxSteps;
16
+ let maxVisits;
17
+ let maxEdge;
18
+ let headed = false;
19
+ let baseUrl;
20
+ let blocksFilter;
21
+ let parallel;
22
+ let session;
23
+ let minEdgeCoverageRaw;
24
+ let coverageOut;
25
+ let noCoverageReport = false;
26
+ let projectDir = process.cwd();
27
+ for (let i = 0; i < rest.length; i++) {
28
+ const a = rest[i];
29
+ if (a === "--from" || a.startsWith("--from=")) {
30
+ from = a.startsWith("--from=") ? a.slice(7) : rest[++i];
31
+ continue;
32
+ }
33
+ if (a === "--data" || a.startsWith("--data=")) {
34
+ data = a.startsWith("--data=") ? a.slice(7) : rest[++i];
35
+ continue;
36
+ }
37
+ if (a === "--blocks" || a.startsWith("--blocks=")) {
38
+ if (a.startsWith("--blocks=")) {
39
+ blocksFilter = a.slice("--blocks=".length);
40
+ }
41
+ else {
42
+ const v = rest[++i];
43
+ if (!v || v.startsWith("-")) {
44
+ console.error("waygraph traverse: --blocks needs a glob, /regex/, or path substring");
45
+ process.exit(1);
46
+ }
47
+ blocksFilter = v;
48
+ }
49
+ continue;
50
+ }
51
+ if (a === "--parallel" || a.startsWith("--parallel=")) {
52
+ const v = a.startsWith("--parallel=") ? a.slice("--parallel=".length) : rest[++i];
53
+ parallel = Number(v);
54
+ continue;
55
+ }
56
+ if (a === "--session" || a.startsWith("--session=")) {
57
+ const v = a.startsWith("--session=") ? a.slice("--session=".length) : rest[++i];
58
+ if (v !== "clone" && v !== "inherit") {
59
+ console.error('waygraph traverse: --session must be "clone" or "inherit"');
60
+ process.exit(1);
61
+ }
62
+ session = v;
63
+ continue;
64
+ }
65
+ if (a === "--min-edge-coverage" || a.startsWith("--min-edge-coverage=")) {
66
+ minEdgeCoverageRaw = a.startsWith("--min-edge-coverage=")
67
+ ? a.slice("--min-edge-coverage=".length)
68
+ : rest[++i];
69
+ continue;
70
+ }
71
+ if (a === "--coverage-out" || a.startsWith("--coverage-out=")) {
72
+ coverageOut = a.startsWith("--coverage-out=")
73
+ ? a.slice("--coverage-out=".length)
74
+ : rest[++i];
75
+ continue;
76
+ }
77
+ if (a === "--no-coverage-report") {
78
+ noCoverageReport = true;
79
+ continue;
80
+ }
81
+ if (a === "--max-steps" || a.startsWith("--max-steps=")) {
82
+ const v = a.startsWith("--max-steps=") ? a.slice(12) : rest[++i];
83
+ maxSteps = Number(v);
84
+ continue;
85
+ }
86
+ if (a === "--max-visits" || a.startsWith("--max-visits=")) {
87
+ const v = a.startsWith("--max-visits=") ? a.slice(13) : rest[++i];
88
+ maxVisits = Number(v);
89
+ continue;
90
+ }
91
+ if (a === "--max-visits-per-edge" || a.startsWith("--max-visits-per-edge=")) {
92
+ const v = a.startsWith("--max-visits-per-edge=")
93
+ ? a.slice("--max-visits-per-edge=".length)
94
+ : rest[++i];
95
+ maxEdge = Number(v);
96
+ continue;
97
+ }
98
+ if (a === "--non-headless" || a === "--headed") {
99
+ headed = true;
100
+ continue;
101
+ }
102
+ if (a === "--base-url" || a.startsWith("--base-url=")) {
103
+ baseUrl = a.startsWith("--base-url=") ? a.slice(11) : rest[++i];
104
+ continue;
105
+ }
106
+ if (a === "--help" || a === "-h") {
107
+ console.log(`waygraph traverse [project] [flags]
108
+
109
+ Graph crawl (RFC Phase B-E). Walks unused legal edges until a leaf,
110
+ budget kill, or first broken edge. --parallel N uses session clone + edge leases.
111
+
112
+ --blocks <glob|/regex/|substr> Phase C: filter *.block.ts discovery
113
+ --parallel N Phase D: N clone workers (default 1, max 4)
114
+ --session clone|inherit Phase D: default clone; inherit refused if parallel>1
115
+ --min-edge-coverage X Phase E: suite gate 0.8 | 80% | 80 (exit 2 if below)
116
+ --coverage-out PATH Phase E: write JSON (default .waygraph-traverse/coverage.json)
117
+ --no-coverage-report Phase E: print Coverage line only (no JSON file)
118
+ --from <Checkpoint> start checkpoint (optional)
119
+ --data '{...}' Mem seed JSON
120
+ --max-steps N default 50 (per worker)
121
+ --max-visits N per-node visit cap (default 2)
122
+ --max-visits-per-edge N default 1
123
+ --non-headless show browser
124
+ --base-url URL
125
+
126
+ Examples:
127
+ waygraph traverse --blocks '**/mailpit/**/*.block.ts'
128
+ waygraph traverse --parallel 2 --session clone --max-steps 20
129
+ waygraph traverse --min-edge-coverage 80% --coverage-out ./cov.json
130
+
131
+ PASS: [Reached Leaf Node[traverse-1] at=... steps=N]
132
+ FAIL: [Broke at edge[traverse-1] block=... from=... to=...]
133
+ COVER: [Coverage edges=H/T ratio=R% min=M% PASS|FAIL]
134
+ `);
135
+ process.exit(0);
136
+ }
137
+ if (!a.startsWith("-")) {
138
+ projectDir = resolve(a);
139
+ }
140
+ }
141
+ if (!existsSync(projectDir) || !statSync(projectDir).isDirectory()) {
142
+ console.error(`waygraph traverse: no such directory: ${projectDir}`);
143
+ process.exit(1);
144
+ }
145
+ const blocksSelect = blocksFilter
146
+ ? parseBlocksSelect(blocksFilter)
147
+ : undefined;
148
+ let minEdgeCoverage;
149
+ if (minEdgeCoverageRaw !== undefined) {
150
+ const parsed = parseMinEdgeCoverage(minEdgeCoverageRaw);
151
+ if (parsed === null) {
152
+ console.error(`waygraph traverse: --min-edge-coverage expects 0.8, 80%, or 80 (got ${JSON.stringify(minEdgeCoverageRaw)})`);
153
+ process.exit(1);
154
+ }
155
+ minEdgeCoverage = parsed;
156
+ }
157
+ const code = await runTraverse(projectDir, {
158
+ ...(from ? { from } : {}),
159
+ ...(data ? { data } : {}),
160
+ ...(maxSteps !== undefined && Number.isFinite(maxSteps) ? { maxSteps } : {}),
161
+ ...(maxVisits !== undefined && Number.isFinite(maxVisits)
162
+ ? { maxVisitsPerNode: maxVisits }
163
+ : {}),
164
+ ...(maxEdge !== undefined && Number.isFinite(maxEdge)
165
+ ? { maxVisitsPerEdge: maxEdge }
166
+ : {}),
167
+ headed,
168
+ ...(baseUrl ? { baseURL: baseUrl } : {}),
169
+ ...(blocksSelect ? { blocksSelect } : {}),
170
+ ...(parallel !== undefined && Number.isFinite(parallel) ? { parallel } : {}),
171
+ ...(session ? { session } : {}),
172
+ ...(minEdgeCoverage !== undefined ? { minEdgeCoverage } : {}),
173
+ ...(coverageOut ? { coverageOut: resolve(coverageOut) } : {}),
174
+ ...(noCoverageReport ? { noCoverageReport: true } : {}),
175
+ });
176
+ process.exit(code);
177
+ }
@@ -0,0 +1 @@
1
+ export declare function tryCase(args: string[]): Promise<void>;
@@ -0,0 +1,298 @@
1
+ // Split out of the former 8,700-line cli.ts (see src/ARCHITECTURE.md). Behavior unchanged.
2
+ import { join } from "node:path";
3
+ import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { spawn } from "node:child_process";
5
+ import { packageRoot, runInherited } from "../cli/util.js";
6
+ import { tmpdir } from "node:os";
7
+ import { runChain } from "../cli/run-chain.js";
8
+ import { applyRunFlags, parseRunFlags } from "../cli/flags.js";
9
+ /**
10
+ * Runs a throwaway probe script rooted at `projectDir` - the exact same
11
+ * directory the real demo files get copied into, so it resolves "waygraph"
12
+ * and "@playwright/test" exactly as they will - and actually launches (then
13
+ * immediately closes) chromium, a real check rather than a guess at whether
14
+ * the browser's installed. Never leaves the probe script behind.
15
+ */
16
+ async function probeTryPrereqs(projectDir) {
17
+ const tsxEsm = import.meta.resolve("tsx/esm");
18
+ const probeScript = [
19
+ "try {",
20
+ ' await import("waygraph");',
21
+ "} catch {",
22
+ ' console.error("WAYGRAPH_TRY_MISSING_WAYGRAPH");',
23
+ " process.exit(1);",
24
+ "}",
25
+ "let mod;",
26
+ "try {",
27
+ ' mod = await import("@playwright/test");',
28
+ "} catch {",
29
+ ' console.error("WAYGRAPH_TRY_MISSING_PLAYWRIGHT_TEST");',
30
+ " process.exit(1);",
31
+ "}",
32
+ "try {",
33
+ " const browser = await mod.chromium.launch({ headless: true });",
34
+ " await browser.close();",
35
+ "} catch (err) {",
36
+ " if (String(err && err.message).includes(\"Executable doesn't exist\")) {",
37
+ ' console.error("WAYGRAPH_TRY_MISSING_BROWSER");',
38
+ " process.exit(1);",
39
+ " }",
40
+ " console.error(String((err && err.stack) || err));",
41
+ " process.exit(1);",
42
+ "}",
43
+ ].join("\n");
44
+ const probePath = join(projectDir, `.waygraph-try-probe-${process.pid}.mjs`);
45
+ writeFileSync(probePath, probeScript);
46
+ try {
47
+ const result = await new Promise((res, rej) => {
48
+ const child = spawn(process.execPath, ["--import", tsxEsm, probePath], {
49
+ cwd: projectDir,
50
+ stdio: ["ignore", "ignore", "pipe"],
51
+ env: process.env,
52
+ });
53
+ let stderrBuf = "";
54
+ child.stderr?.on("data", (d) => { stderrBuf += d.toString(); });
55
+ child.on("error", rej);
56
+ child.on("exit", (code) => res({ code: code ?? 1, stderr: stderrBuf }));
57
+ });
58
+ if (result.code === 0)
59
+ return { ok: true };
60
+ const stderr = result.stderr;
61
+ if (stderr.includes("WAYGRAPH_TRY_MISSING_WAYGRAPH"))
62
+ return { ok: false, missing: "waygraph" };
63
+ if (stderr.includes("WAYGRAPH_TRY_MISSING_PLAYWRIGHT_TEST"))
64
+ return { ok: false, missing: "playwright-test" };
65
+ if (stderr.includes("WAYGRAPH_TRY_MISSING_BROWSER"))
66
+ return { ok: false, missing: "browser" };
67
+ return { ok: false, missing: "unknown", detail: stderr.trim() || `probe exited with code ${result.code}` };
68
+ }
69
+ finally {
70
+ rmSync(probePath, { force: true });
71
+ }
72
+ }
73
+ /** Installs deps + chromium inside an already-copied quickstart folder. */
74
+ async function ensureDirPrereqs(dir, label) {
75
+ let status = await probeTryPrereqs(dir);
76
+ if (status.ok)
77
+ return null;
78
+ if (!existsSync(join(dir, "package.json"))) {
79
+ return `${label}: no package.json in ${dir}`;
80
+ }
81
+ if (status.missing === "waygraph" || status.missing === "playwright-test" || status.missing === "unknown") {
82
+ // Copied quickstart must not keep a workspace-tainted lockfile (breaks temp-dir npm install).
83
+ rmSync(join(dir, "package-lock.json"), { force: true });
84
+ console.log(`${label}: installing dependencies in ${dir} ...`);
85
+ const installCode = await runInherited("npm", ["install"], dir);
86
+ if (installCode !== 0) {
87
+ return `npm install exited with code ${installCode} - see the output above.`;
88
+ }
89
+ status = await probeTryPrereqs(dir);
90
+ if (status.ok)
91
+ return null;
92
+ if (status.missing === "unknown") {
93
+ return formatProbeFailure(status.detail ?? "probe failed");
94
+ }
95
+ }
96
+ console.log(`${label}: downloading Playwright's chromium browser ...`);
97
+ const localPlaywrightBin = join(dir, "node_modules", ".bin", "playwright");
98
+ const browserCode = existsSync(localPlaywrightBin)
99
+ ? await runInherited(localPlaywrightBin, ["install", "chromium"], dir)
100
+ : await runInherited("npx", ["--yes", "playwright", "install", "chromium"], dir);
101
+ if (browserCode !== 0) {
102
+ return `"playwright install chromium" exited with code ${browserCode} - see the output above.`;
103
+ }
104
+ status = await probeTryPrereqs(dir);
105
+ if (status.ok)
106
+ return null;
107
+ return formatProbeFailure(status.detail ?? "prerequisites still aren't ready after attempting to install them.");
108
+ }
109
+ /** Playwright browser binary present but OS libs missing (common in Docker/Codespaces). */
110
+ function formatProbeFailure(detail) {
111
+ const needsDeps = /shared libraries|libnspr4|libnss3|libatk|cannot open shared object file/i.test(detail);
112
+ const hint = needsDeps
113
+ ? "\n\nChromium needs OS packages too - try:\n sudo npx playwright install-deps chromium\n" +
114
+ "In cloud/CI without a display, record headless:\n npx waygraph try demo --video ./out --no-step"
115
+ : "";
116
+ return `couldn't verify prerequisites:\n${detail}${hint}`;
117
+ }
118
+ const TRY_DEMO_CHAIN = 'loginFlow({"saucedemo.credentials":{"username":"standard_user","password":"secret_sauce"}}) then ' +
119
+ 'shopFlow({"saucedemo.selectedItem":{"id":"sauce-labs-backpack","name":"Sauce Labs Backpack"}}) then ' +
120
+ 'viewerBlockedFlow({"saucedemo.credentials":{"username":"locked_out_user","password":"secret_sauce"}})';
121
+ /**
122
+ * Point a copied quickstart at this checkout's waygraph build (not npm registry).
123
+ * Uses `npm pack` into destDir - a file: symlink to the dev tree can double-load
124
+ * @playwright/test when sibling projects also install Playwright.
125
+ */
126
+ async function wireQuickstartToPackageRoot(destDir) {
127
+ const root = packageRoot();
128
+ const version = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).version;
129
+ const packCode = await runInherited("npm", ["pack", "--pack-destination", destDir, "--silent"], root);
130
+ if (packCode !== 0) {
131
+ throw new Error(`waygraph try demo: npm pack failed with exit code ${packCode}`);
132
+ }
133
+ const tgz = join(destDir, `waygraph-${version}.tgz`);
134
+ const pkgPath = join(destDir, "package.json");
135
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
136
+ if (!pkg.dependencies)
137
+ pkg.dependencies = {};
138
+ pkg.dependencies.waygraph = `file:${tgz}`;
139
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
140
+ }
141
+ /**
142
+ * Copy templates/quickstart into a fresh OS temp dir and wire it to this
143
+ * package build. Returns destDir, or null after setting exitCode on failure.
144
+ */
145
+ async function prepareTryQuickstart(label) {
146
+ const destDir = mkdtempSync(join(tmpdir(), `${label}-`));
147
+ cpSync(join(packageRoot(), "templates", "quickstart"), destDir, { recursive: true });
148
+ rmSync(join(destDir, "node_modules"), { recursive: true, force: true });
149
+ rmSync(join(destDir, "test-results"), { recursive: true, force: true });
150
+ rmSync(join(destDir, "package-lock.json"), { force: true });
151
+ try {
152
+ await wireQuickstartToPackageRoot(destDir);
153
+ }
154
+ catch (err) {
155
+ console.error(err instanceof Error ? err.message : String(err));
156
+ process.exitCode = 1;
157
+ return null;
158
+ }
159
+ const problem = await ensureDirPrereqs(destDir, label);
160
+ if (problem) {
161
+ console.error(`${label}: couldn't get ready.\n${problem}`);
162
+ process.exitCode = 1;
163
+ return null;
164
+ }
165
+ return destDir;
166
+ }
167
+ /**
168
+ * `waygraph try demo` - copy a self-contained saucedemo project into a temp
169
+ * dir (never the caller's cwd), run a chainFlow step demo (Sign In + Shop +
170
+ * blocked Viewer), then run the headless Playwright test, and print where
171
+ * everything lives.
172
+ */
173
+ async function runTryDemo() {
174
+ const destDir = await prepareTryQuickstart("waygraph-try-demo");
175
+ if (!destDir)
176
+ return;
177
+ process.env.WAYGRAPH_BASE_URL ??= "https://www.saucedemo.com";
178
+ process.env.WAYGRAPH_STEP ??= "1";
179
+ process.env.WAYGRAPH_AUTOPLAY ??= "0";
180
+ // Explicit --no-step --video = unattended headless .webm only (the
181
+ // documented cloud/CI recipe above) - nobody needs to watch a live
182
+ // window for Playwright's own recordVideo to capture the right thing.
183
+ // This must be decided BEFORE the headed default below, or the
184
+ // unconditional "??=" there always wins and the documented recipe never
185
+ // actually runs headless.
186
+ const unattendedVideo = Boolean(process.env.WAYGRAPH_VIDEO) && process.env.WAYGRAPH_STEP === "0";
187
+ if (unattendedVideo) {
188
+ process.env.WAYGRAPH_AUTOPLAY ??= "1";
189
+ process.env.WAYGRAPH_HEADED ??= "0";
190
+ }
191
+ else {
192
+ // Default: headed stepper, manual Next. --video records that session
193
+ // too (not a headless rush) as long as --step is still on.
194
+ process.env.WAYGRAPH_HEADED ??= "1";
195
+ }
196
+ const videoTo = process.env.WAYGRAPH_VIDEO;
197
+ console.log(videoTo
198
+ ? "waygraph try demo: step-through + record (Sign In -> Shop & Checkout -> blocked Viewer login) - click Next; video -> " +
199
+ (videoTo === "1" ? ".waygraph-videos/" : videoTo)
200
+ : "waygraph try demo: step-through (Sign In -> Shop & Checkout -> blocked Viewer login) - click Next for each step ...");
201
+ await runChain(destDir, TRY_DEMO_CHAIN);
202
+ if (process.exitCode)
203
+ return;
204
+ console.log("\nwaygraph try demo: running headless chainFlow test ...");
205
+ const testCode = await runInherited("npm", ["test"], destDir);
206
+ if (testCode !== 0) {
207
+ process.exitCode = testCode;
208
+ return;
209
+ }
210
+ const testFile = join(destDir, "tests", "chain-flow.spec.ts");
211
+ const loginFlowFile = join(destDir, "src", "flows", "login.flow.ts");
212
+ const shopFlowFile = join(destDir, "src", "flows", "shop.flow.ts");
213
+ const viewerBlockedFlowFile = join(destDir, "src", "flows", "viewer-blocked.flow.ts");
214
+ console.log("\nwaygraph try demo: done.\n\n" +
215
+ "Temp project (does not touch your cwd - lives under the OS temp dir):\n" +
216
+ ` ${destDir}\n\n` +
217
+ "Episodes you just watched (same Flow objects the test imports):\n" +
218
+ ` ${loginFlowFile}\n` +
219
+ ` ${shopFlowFile}\n` +
220
+ ` ${viewerBlockedFlowFile}\n\n` +
221
+ "Headless chainFlow test (automated - no clicking):\n" +
222
+ ` ${testFile}\n\n` +
223
+ "Run again in that temp folder:\n" +
224
+ ` cd ${destDir}\n` +
225
+ " npm run demo # step-through, manual Next (--step --no-autoplay)\n" +
226
+ " npm run auto # interactive explore (Effect Add/Remove, MemNav Open details)\n" +
227
+ " npm test # playwright chainFlow test\n\n" +
228
+ "Permanent full example in this package: examples/saucedemo\n" +
229
+ "Keep a permanent scaffold in your tree: waygraph init my-app\n");
230
+ }
231
+ const TRY_AUTO_DATA = '{"saucedemo.credentials":{"username":"standard_user","password":"secret_sauce"}}';
232
+ /**
233
+ * `waygraph try auto` / `try auto:cli` - temp Sauce Demo explore.
234
+ * Default is the **headed** browser panel. Pass `auto:cli` or `--cli` for the
235
+ * terminal menu (same rows).
236
+ *
237
+ * Runs as a child in the temp project so Block imports share that install's
238
+ * `@playwright/test`. In-process explore from the outer CLI against a packed
239
+ * `file:*.tgz` copy double-loads Playwright and silently yields 0 graph edges
240
+ * ("LoginPage / No moves").
241
+ */
242
+ async function runTryAuto(opts = { cli: false }) {
243
+ const destDir = await prepareTryQuickstart("waygraph-try-auto");
244
+ if (!destDir)
245
+ return;
246
+ process.env.WAYGRAPH_BASE_URL ??= "https://www.saucedemo.com";
247
+ const cli = opts.cli === true;
248
+ console.log(cli
249
+ ? "waygraph try auto: CLI explore on Sauce Demo (temp dir).\n" +
250
+ " Creds pre-seeded (saucedemo.credentials).\n" +
251
+ " Pick [1] submit-login, then inventory Add/Remove / Open details.\n" +
252
+ " Type q to quit. Headed panel: waygraph try auto\n"
253
+ : "waygraph try auto: headed explore on Sauce Demo (temp dir).\n" +
254
+ " Creds pre-seeded. CLI menu: waygraph try auto:cli\n" +
255
+ " Pick submit-login, then inventory menus. Quit from the panel.\n");
256
+ const bin = join(destDir, "node_modules", ".bin", "waygraph");
257
+ const args = ["auto"];
258
+ if (cli)
259
+ args.push("--cli");
260
+ args.push("--data", TRY_AUTO_DATA);
261
+ const code = await runInherited(bin, args, destDir);
262
+ if (code !== 0)
263
+ process.exitCode = code;
264
+ console.log("\nwaygraph try auto: explorer closed.\n\n" +
265
+ `Temp project:\n ${destDir}\n\n` +
266
+ "Run again:\n" +
267
+ ` cd ${destDir} && npm run auto\n` +
268
+ ` cd ${destDir} && npm run auto:cli\n\n` +
269
+ "In-package: examples/saucedemo\n" +
270
+ "Docs: https://deviate-dv8.github.io/waygraph/auto.html\n");
271
+ }
272
+ export async function tryCase(args) {
273
+ const flags = parseRunFlags(args.slice(1));
274
+ applyRunFlags(flags);
275
+ const modeRaw = (flags.positionals[0] ?? "demo").toLowerCase();
276
+ // auto:cli / --cli = CLI; bare try auto = headed panel
277
+ const mode = modeRaw === "auto:cli" || modeRaw === "auto-cli"
278
+ ? "auto:cli"
279
+ : modeRaw === "auto"
280
+ ? "auto"
281
+ : modeRaw;
282
+ if (mode === "auto" || mode === "auto:cli") {
283
+ const cli = mode === "auto:cli" || flags.cli === true
284
+ ? true
285
+ : flags.headed === true || flags.nonHeadless === true
286
+ ? false
287
+ : false; // try auto default = headed
288
+ await runTryAuto({ cli });
289
+ }
290
+ else if (mode === "demo" || mode === "") {
291
+ await runTryDemo();
292
+ }
293
+ else {
294
+ console.error(`waygraph try: unknown mode "${modeRaw}" - use "demo", "auto", or "auto:cli"`);
295
+ process.exitCode = 1;
296
+ }
297
+ return;
298
+ }
File without changes
File without changes
@@ -0,0 +1,44 @@
1
+ waygraph auto: skip src/blocks/saucedemo-web/cart/nav-cart.block.ts: Requiring @playwright/test second time,
2
+ waygraph auto: skip src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts: Requiring @playwright/test second time,
3
+ waygraph auto: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts: Requiring @playwright/test second time,
4
+ waygraph auto: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts: Requiring @playwright/test second time,
5
+ waygraph auto: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts: Requiring @playwright/test second time,
6
+ waygraph auto: skip src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts: Requiring @playwright/test second time,
7
+ waygraph auto: skip src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts: Requiring @playwright/test second time,
8
+ waygraph auto: skip src/blocks/saucedemo-web/ff-owner-auth.block.ts: Requiring @playwright/test second time,
9
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/inventory.page.block.ts: Requiring @playwright/test second time,
10
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts: Requiring @playwright/test second time,
11
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts: Requiring @playwright/test second time,
12
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts: Requiring @playwright/test second time,
13
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts: Requiring @playwright/test second time,
14
+ waygraph auto: skip src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts: Requiring @playwright/test second time,
15
+ waygraph auto: skip src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts: Requiring @playwright/test second time,
16
+ waygraph auto: skip src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts: Requiring @playwright/test second time,
17
+ waygraph auto: skip src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts: Requiring @playwright/test second time,
18
+ waygraph auto: skip src/blocks/saucedemo-web/methods/fill-password.method.block.ts: Requiring @playwright/test second time,
19
+ waygraph auto: skip src/blocks/saucedemo-web/methods/fill-username.method.block.ts: Requiring @playwright/test second time,
20
+ waygraph auto: skip src/blocks/saucedemo-web/methods/submit-login.method.block.ts: Requiring @playwright/test second time,
21
+ waygraph auto: skip src/blocks/saucedemo-web/methods/submit-logout.method.block.ts: Requiring @playwright/test second time,
22
+ waygraph auto: skip src/blocks/saucedemo-web/nav-login.block.ts: Requiring @playwright/test second time,
23
+ waygraph graph: skip src/blocks/saucedemo-web/cart/nav-cart.block.ts: Requiring @playwright/test second time,
24
+ waygraph graph: skip src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts: Requiring @playwright/test second time,
25
+ waygraph graph: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts: Requiring @playwright/test second time,
26
+ waygraph graph: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts: Requiring @playwright/test second time,
27
+ waygraph graph: skip src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts: Requiring @playwright/test second time,
28
+ waygraph graph: skip src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts: Requiring @playwright/test second time,
29
+ waygraph graph: skip src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts: Requiring @playwright/test second time,
30
+ waygraph graph: skip src/blocks/saucedemo-web/ff-owner-auth.block.ts: Requiring @playwright/test second time,
31
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/inventory.page.block.ts: Requiring @playwright/test second time,
32
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts: Requiring @playwright/test second time,
33
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts: Requiring @playwright/test second time,
34
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts: Requiring @playwright/test second time,
35
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts: Requiring @playwright/test second time,
36
+ waygraph graph: skip src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts: Requiring @playwright/test second time,
37
+ waygraph graph: skip src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts: Requiring @playwright/test second time,
38
+ waygraph graph: skip src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts: Requiring @playwright/test second time,
39
+ waygraph graph: skip src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts: Requiring @playwright/test second time,
40
+ waygraph graph: skip src/blocks/saucedemo-web/methods/fill-password.method.block.ts: Requiring @playwright/test second time,
41
+ waygraph graph: skip src/blocks/saucedemo-web/methods/fill-username.method.block.ts: Requiring @playwright/test second time,
42
+ waygraph graph: skip src/blocks/saucedemo-web/methods/submit-login.method.block.ts: Requiring @playwright/test second time,
43
+ waygraph graph: skip src/blocks/saucedemo-web/methods/submit-logout.method.block.ts: Requiring @playwright/test second time,
44
+ waygraph graph: skip src/blocks/saucedemo-web/nav-login.block.ts: Requiring @playwright/test second time,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.23",
3
+ "version": "0.15.24",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",