waygraph 0.15.19 → 0.15.21
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 +72 -1309
- package/dist/auto-session.d.ts +10 -1
- package/dist/auto-session.js +27 -7
- package/dist/cli.js +98 -31
- package/dist/engine.d.ts +20 -0
- package/dist/engine.js +18 -0
- package/dist/highlight-shorthand.d.ts +24 -0
- package/dist/highlight-shorthand.js +30 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/mem-stub.d.ts +41 -0
- package/dist/mem-stub.js +36 -0
- package/examples/saucedemo/.waygraph-auto/11c497cd.log +44 -0
- package/examples/saucedemo/.waygraph-auto/29d11a49.log +44 -0
- package/examples/saucedemo/.waygraph-auto/2c9a4003.log +44 -0
- package/examples/saucedemo/.waygraph-auto/32ef32a8.log +44 -0
- package/examples/saucedemo/.waygraph-auto/36ba01f7.log +44 -0
- package/examples/saucedemo/.waygraph-auto/537af83d.log +44 -0
- package/examples/saucedemo/.waygraph-auto/5adfacd5.log +44 -0
- package/examples/saucedemo/.waygraph-auto/76c7d418.log +44 -0
- package/examples/saucedemo/.waygraph-auto/78197960.log +44 -0
- package/examples/saucedemo/.waygraph-auto/7c2acbc2.log +44 -0
- package/examples/saucedemo/.waygraph-auto/844b63ff.log +44 -0
- package/examples/saucedemo/.waygraph-auto/88a4200b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b0eed995.log +44 -0
- package/examples/saucedemo/.waygraph-auto/bb69dc1a.log +44 -0
- package/examples/saucedemo/.waygraph-auto/bc4ae56f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c17253b0.log +44 -0
- package/examples/saucedemo/.waygraph-auto/c31a9465.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c5ac2393.log +44 -0
- package/examples/saucedemo/.waygraph-auto/c701e3c2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d207a000.log +44 -0
- package/examples/saucedemo/.waygraph-auto/fa3c5655.log +44 -0
- package/examples/saucedemo/package-lock.json +20 -532
- package/examples/saucedemo/package.json +0 -1
- package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +23 -0
- package/package.json +1 -1
- package/templates/scaffold/README.md +21 -19
- package/templates/scaffold/STRUCTURE.md +37 -70
- package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +1 -1
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +1 -1
- package/templates/skills/waygraph-convention.skill.md +5 -1
- package/templates/skills/waygraph-pilot.skill.md +1 -1
- package/examples/saucedemo/.waygraph-auto/4adfbe91.json +0 -8
- package/examples/saucedemo/.waygraph-auto/9f0287e6.json +0 -8
- /package/examples/saucedemo/.waygraph-auto/{4adfbe91.log → 32e2c26f.log} +0 -0
- /package/examples/saucedemo/.waygraph-auto/{9f0287e6.log → 4c6b9e15.log} +0 -0
package/dist/auto-session.d.ts
CHANGED
|
@@ -31,8 +31,17 @@ export type ParsedPick = PickResult | {
|
|
|
31
31
|
/**
|
|
32
32
|
* Same number/`q`/range rules `cliPick` already applies, but returning a
|
|
33
33
|
* result instead of looping to re-prompt - one request gets one answer.
|
|
34
|
+
* Also accepts a Block name (exact, case-sensitive) as a shorthand for its
|
|
35
|
+
* menu index - `send <id> "submit-login"` instead of hunting the number.
|
|
36
|
+
* Ambiguous (the same Block name appearing more than once in one menu)
|
|
37
|
+
* refuses rather than guessing which occurrence was meant - a pick runs a
|
|
38
|
+
* real browser action, not something to silently get wrong.
|
|
34
39
|
*/
|
|
35
|
-
export declare function parsePick(raw: string,
|
|
40
|
+
export declare function parsePick(raw: string, menu: {
|
|
41
|
+
readonly flat: readonly {
|
|
42
|
+
readonly block: string;
|
|
43
|
+
}[];
|
|
44
|
+
}): ParsedPick;
|
|
36
45
|
export interface DomSnapshot {
|
|
37
46
|
mode: "aria" | "full";
|
|
38
47
|
selector?: string;
|
package/dist/auto-session.js
CHANGED
|
@@ -37,18 +37,38 @@ export function buildSessionSnapshot(menu, library, here, lastRunNote) {
|
|
|
37
37
|
/**
|
|
38
38
|
* Same number/`q`/range rules `cliPick` already applies, but returning a
|
|
39
39
|
* result instead of looping to re-prompt - one request gets one answer.
|
|
40
|
+
* Also accepts a Block name (exact, case-sensitive) as a shorthand for its
|
|
41
|
+
* menu index - `send <id> "submit-login"` instead of hunting the number.
|
|
42
|
+
* Ambiguous (the same Block name appearing more than once in one menu)
|
|
43
|
+
* refuses rather than guessing which occurrence was meant - a pick runs a
|
|
44
|
+
* real browser action, not something to silently get wrong.
|
|
40
45
|
*/
|
|
41
|
-
export function parsePick(raw,
|
|
42
|
-
const ans = raw.trim()
|
|
43
|
-
|
|
46
|
+
export function parsePick(raw, menu) {
|
|
47
|
+
const ans = raw.trim();
|
|
48
|
+
const lower = ans.toLowerCase();
|
|
49
|
+
if (lower === "q" || lower === "quit")
|
|
44
50
|
return { type: "quit" };
|
|
45
|
-
const n = Number(
|
|
46
|
-
if (Number.isInteger(n) && n >= 1 && n <=
|
|
51
|
+
const n = Number(lower);
|
|
52
|
+
if (Number.isInteger(n) && n >= 1 && n <= menu.flat.length) {
|
|
47
53
|
return { type: "pick", index: n - 1 };
|
|
48
54
|
}
|
|
55
|
+
const matches = [];
|
|
56
|
+
menu.flat.forEach((edge, i) => {
|
|
57
|
+
if (edge.block === ans)
|
|
58
|
+
matches.push(i);
|
|
59
|
+
});
|
|
60
|
+
if (matches.length === 1) {
|
|
61
|
+
return { type: "pick", index: matches[0] };
|
|
62
|
+
}
|
|
63
|
+
if (matches.length > 1) {
|
|
64
|
+
return {
|
|
65
|
+
type: "invalid",
|
|
66
|
+
reason: `"${raw}" matches ${matches.length} menu entries - use the numeric index instead of the Block name`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
49
69
|
return {
|
|
50
70
|
type: "invalid",
|
|
51
|
-
reason: `"${raw}" is not a valid pick - enter a number from 1 to ${
|
|
71
|
+
reason: `"${raw}" is not a valid pick - enter a number from 1 to ${menu.flat.length}, a Block name, or "q" to quit`,
|
|
52
72
|
};
|
|
53
73
|
}
|
|
54
74
|
const FULL_MODE_DEFAULT_DEPTH = 12;
|
|
@@ -499,7 +519,7 @@ export class AutoSession {
|
|
|
499
519
|
/** Applies exactly one pick: runs at most one Block, returns the resulting state. */
|
|
500
520
|
async applyPick(raw) {
|
|
501
521
|
const menu = await this.currentMenu();
|
|
502
|
-
const pick = parsePick(raw, menu
|
|
522
|
+
const pick = parsePick(raw, menu);
|
|
503
523
|
if (pick.type === "invalid")
|
|
504
524
|
return { ok: false, error: pick.reason };
|
|
505
525
|
if (pick.type === "quit") {
|
package/dist/cli.js
CHANGED
|
@@ -31,6 +31,7 @@ import { runAgentDive, printSkillIndex, readSkillMarkdown, SKILL_FLAG_MAP, } fro
|
|
|
31
31
|
import { runTraverse } from "./traverse-run.js";
|
|
32
32
|
import { parseMinEdgeCoverage } from "./traverse-coverage.js";
|
|
33
33
|
import { isFileSelectToken, parseBlocksSelect, } from "./blocks-select.js";
|
|
34
|
+
import { parseHighlightShorthand } from "./highlight-shorthand.js";
|
|
34
35
|
// ---------------------------------------------------------------------------
|
|
35
36
|
// Filesystem
|
|
36
37
|
// ---------------------------------------------------------------------------
|
|
@@ -242,6 +243,7 @@ import {
|
|
|
242
243
|
resolveDeviceState,
|
|
243
244
|
resolveTodoDockUi,
|
|
244
245
|
WAYGRAPH_RING_CSS,
|
|
246
|
+
getMemStub,
|
|
245
247
|
} from "waygraph";
|
|
246
248
|
|
|
247
249
|
function walkDir(dir, pattern) {
|
|
@@ -341,7 +343,7 @@ function parseChainSpec(spec) {
|
|
|
341
343
|
});
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
function seedMemFromRequires(mem, requires, json, label) {
|
|
346
|
+
function seedMemFromRequires(mem, requires, json, label, stubActive) {
|
|
345
347
|
if (requires.length === 0) {
|
|
346
348
|
if (json !== undefined) {
|
|
347
349
|
throw new Error(
|
|
@@ -353,21 +355,34 @@ function seedMemFromRequires(mem, requires, json, label) {
|
|
|
353
355
|
if (json === undefined) {
|
|
354
356
|
// --data / WAYGRAPH_DATA supplies the same payload shape as blockName({...}).
|
|
355
357
|
const fromEnv = process.env.WAYGRAPH_DATA;
|
|
356
|
-
if (fromEnv && fromEnv.trim())
|
|
357
|
-
|
|
358
|
-
|
|
358
|
+
if (fromEnv && fromEnv.trim()) json = fromEnv;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
let parsed;
|
|
362
|
+
let haveParsed = false;
|
|
363
|
+
if (json !== undefined) {
|
|
364
|
+
try {
|
|
365
|
+
parsed = JSON.parse(json);
|
|
366
|
+
haveParsed = true;
|
|
367
|
+
} catch (err) {
|
|
368
|
+
throw new Error("waygraph chain: \\"" + label + "\\" payload is not valid JSON - " + String(err));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (!haveParsed) {
|
|
373
|
+
// No payload at all - only a hard failure when memStub isn't active for
|
|
374
|
+
// this flow; when it is, fall through with an empty object so the
|
|
375
|
+
// per-key loop below gets a chance to fill each one from the registry.
|
|
376
|
+
if (!stubActive) {
|
|
359
377
|
throw new Error(
|
|
360
378
|
"waygraph chain: \\"" + label + "\\" requires " + requires.map((k) => k.name).join(", ") +
|
|
361
|
-
" - give a JSON payload (inline blockName({...}) or --data '{...}')"
|
|
379
|
+
" - give a JSON payload (inline blockName({...}) or --data '{...}'), or enable --mem-stub" +
|
|
380
|
+
" with registerMemStub for these keys",
|
|
362
381
|
);
|
|
363
382
|
}
|
|
383
|
+
parsed = {};
|
|
364
384
|
}
|
|
365
|
-
|
|
366
|
-
try {
|
|
367
|
-
parsed = JSON.parse(json);
|
|
368
|
-
} catch (err) {
|
|
369
|
-
throw new Error("waygraph chain: \\"" + label + "\\" payload is not valid JSON - " + String(err));
|
|
370
|
-
}
|
|
385
|
+
|
|
371
386
|
// Keyed-by-name when every require name is a top-level key (preferred for
|
|
372
387
|
// --data and for {"saucedemo.credentials":{...}} even with one require).
|
|
373
388
|
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -377,26 +392,42 @@ function seedMemFromRequires(mem, requires, json, label) {
|
|
|
377
392
|
return;
|
|
378
393
|
}
|
|
379
394
|
}
|
|
380
|
-
|
|
395
|
+
// Single-key shorthand: the whole payload IS that one key's value - only
|
|
396
|
+
// when a real payload was actually given (the stub-only "{}" fallback
|
|
397
|
+
// above must fall through to per-key stub resolution instead).
|
|
398
|
+
if (haveParsed && requires.length === 1) {
|
|
381
399
|
mem.set(requires[0], parsed);
|
|
382
400
|
return;
|
|
383
401
|
}
|
|
384
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
402
|
+
if (haveParsed && (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))) {
|
|
385
403
|
throw new Error(
|
|
386
404
|
"waygraph chain: \\"" + label + "\\" requires " + requires.length + " keys (" +
|
|
387
405
|
requires.map((k) => k.name).join(", ") + ") - payload must be an object keyed by each key's name",
|
|
388
406
|
);
|
|
389
407
|
}
|
|
408
|
+
const stillMissing = [];
|
|
390
409
|
for (const k of requires) {
|
|
391
|
-
if (
|
|
392
|
-
|
|
410
|
+
if (k.name in parsed) {
|
|
411
|
+
mem.set(k, parsed[k.name]);
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
const fake = stubActive ? getMemStub(k) : undefined;
|
|
415
|
+
if (fake) {
|
|
416
|
+
mem.set(k, fake());
|
|
417
|
+
continue;
|
|
393
418
|
}
|
|
394
|
-
|
|
419
|
+
stillMissing.push(k);
|
|
420
|
+
}
|
|
421
|
+
if (stillMissing.length > 0) {
|
|
422
|
+
throw new Error(
|
|
423
|
+
"waygraph chain: \\"" + label + "\\" payload is missing required key(s): " +
|
|
424
|
+
stillMissing.map((k) => "\\"" + k.name + "\\"").join(", "),
|
|
425
|
+
);
|
|
395
426
|
}
|
|
396
427
|
}
|
|
397
428
|
|
|
398
|
-
function seedMemForBlock(mem, resolved, json) {
|
|
399
|
-
seedMemFromRequires(mem, resolved.block.requires ?? [], json, resolved.exportName);
|
|
429
|
+
function seedMemForBlock(mem, resolved, json, stubActive) {
|
|
430
|
+
seedMemFromRequires(mem, resolved.block.requires ?? [], json, resolved.exportName, stubActive);
|
|
400
431
|
}
|
|
401
432
|
|
|
402
433
|
/**
|
|
@@ -406,14 +437,14 @@ function seedMemForBlock(mem, resolved, json) {
|
|
|
406
437
|
* name) and seeds them all from one JSON payload, same keyed-by-name shape
|
|
407
438
|
* as a multi-key Block payload already uses.
|
|
408
439
|
*/
|
|
409
|
-
function seedMemForFlow(mem, flowBlocks, json, label) {
|
|
440
|
+
function seedMemForFlow(mem, flowBlocks, json, label, stubActive) {
|
|
410
441
|
const seen = new Map();
|
|
411
442
|
for (const bi of flowBlocks) {
|
|
412
443
|
for (const k of bi.block.requires ?? []) {
|
|
413
444
|
if (!seen.has(k.name)) seen.set(k.name, k);
|
|
414
445
|
}
|
|
415
446
|
}
|
|
416
|
-
seedMemFromRequires(mem, Array.from(seen.values()), json, label);
|
|
447
|
+
seedMemFromRequires(mem, Array.from(seen.values()), json, label, stubActive);
|
|
417
448
|
}
|
|
418
449
|
|
|
419
450
|
// ---------------------------------------------------------------------------
|
|
@@ -5898,7 +5929,8 @@ async function main() {
|
|
|
5898
5929
|
// Same --data / WAYGRAPH_DATA seeding as the multi-segment path.
|
|
5899
5930
|
// Without this, \`waygraph run shop.flow.ts --data '{...}'\` (and bare
|
|
5900
5931
|
// export names) hit preflight with an empty MemPage.
|
|
5901
|
-
const
|
|
5932
|
+
const stubActive = flow.memStub === true || process.env.WAYGRAPH_MEM_STUB === "1";
|
|
5933
|
+
const seedMem = () => seedMemForFlow(mem, blockInfos, undefined, bareRef, stubActive);
|
|
5902
5934
|
resolved = blockInfos.map((bi, idx) => ({
|
|
5903
5935
|
block: bi.block,
|
|
5904
5936
|
exportName: bi.name,
|
|
@@ -5969,6 +6001,7 @@ async function main() {
|
|
|
5969
6001
|
if (flow && typeof flow.blocks === "function") {
|
|
5970
6002
|
flows.push(flow);
|
|
5971
6003
|
episodeCounter += 1;
|
|
6004
|
+
const stubActive = flow.memStub === true || process.env.WAYGRAPH_MEM_STUB === "1";
|
|
5972
6005
|
flowMeta.push({
|
|
5973
6006
|
episodeNumber: episodeCounter,
|
|
5974
6007
|
episodeTitle: flow.title || seg.ref,
|
|
@@ -5976,18 +6009,21 @@ async function main() {
|
|
|
5976
6009
|
highlightFixtures: flow.highlightFixtures,
|
|
5977
6010
|
demoPace: flow.demoPace,
|
|
5978
6011
|
highlightStyle: flow.highlightStyle,
|
|
5979
|
-
seedMem: () => seedMemForFlow(mem, flow.blocks(), seg.json, seg.ref),
|
|
6012
|
+
seedMem: () => seedMemForFlow(mem, flow.blocks(), seg.json, seg.ref, stubActive),
|
|
5980
6013
|
});
|
|
5981
6014
|
} else {
|
|
5982
6015
|
const r = await findBlock(projectDir, seg.ref);
|
|
5983
6016
|
flows.push(wrapEngine.defineFlow([start, r.block, end]));
|
|
6017
|
+
// A bare Block segment (no Flow, no withMemStub to opt in) only gets
|
|
6018
|
+
// memStub via the global --mem-stub/WAYGRAPH_MEM_STUB override.
|
|
6019
|
+
const stubActive = process.env.WAYGRAPH_MEM_STUB === "1";
|
|
5984
6020
|
flowMeta.push({
|
|
5985
6021
|
episodeNumber: undefined,
|
|
5986
6022
|
episodeTitle: undefined,
|
|
5987
6023
|
highlightFixtures: undefined,
|
|
5988
6024
|
demoPace: undefined,
|
|
5989
6025
|
highlightStyle: undefined,
|
|
5990
|
-
seedMem: () => seedMemForBlock(mem, r, seg.json),
|
|
6026
|
+
seedMem: () => seedMemForBlock(mem, r, seg.json, stubActive),
|
|
5991
6027
|
});
|
|
5992
6028
|
}
|
|
5993
6029
|
}
|
|
@@ -6889,6 +6925,9 @@ function parseRunFlags(argv) {
|
|
|
6889
6925
|
out.data = t.value;
|
|
6890
6926
|
i = t.nextI;
|
|
6891
6927
|
}
|
|
6928
|
+
else if (a === "--mem-stub") {
|
|
6929
|
+
out.memStub = true;
|
|
6930
|
+
}
|
|
6892
6931
|
else if (a === "--video" || a.startsWith("--video=")) {
|
|
6893
6932
|
if (a.startsWith("--video=")) {
|
|
6894
6933
|
out.video = a.slice("--video=".length);
|
|
@@ -7016,6 +7055,9 @@ function applyRunFlags(flags, opts) {
|
|
|
7016
7055
|
if (flags.data !== undefined) {
|
|
7017
7056
|
process.env.WAYGRAPH_DATA = flags.data;
|
|
7018
7057
|
}
|
|
7058
|
+
if (flags.memStub) {
|
|
7059
|
+
process.env.WAYGRAPH_MEM_STUB = "1";
|
|
7060
|
+
}
|
|
7019
7061
|
if (flags.fast) {
|
|
7020
7062
|
process.env.WAYGRAPH_DEMO_FAST = "1";
|
|
7021
7063
|
}
|
|
@@ -7233,7 +7275,12 @@ Primary (less is more):
|
|
|
7233
7275
|
--cli --detach --non-headless Detached session with a real visible browser
|
|
7234
7276
|
(same --non-headless flag run/demo already use)
|
|
7235
7277
|
waygraph auto send <sessionId> "<pick>" Send one pick to a --detach session, print
|
|
7236
|
-
the resulting state as JSON (no TTY needed)
|
|
7278
|
+
the resulting state as JSON (no TTY needed).
|
|
7279
|
+
<pick> is a 1-based menu index, a Block name
|
|
7280
|
+
(exact match; ambiguous names refuse rather than
|
|
7281
|
+
guess), or "q"/"quit". Same command as
|
|
7282
|
+
browser send <sessionId> "<pick>" (prefer that
|
|
7283
|
+
prefix for a --detach/persistent session).
|
|
7237
7284
|
--timeout <ms> Override the 15s default wait for this one call -
|
|
7238
7285
|
a single Block can legitimately run a slow real
|
|
7239
7286
|
interaction (e.g. a multi-step mouse drag)
|
|
@@ -7297,6 +7344,15 @@ Primary (less is more):
|
|
|
7297
7344
|
label,tone?,size?,weight?}], todos[], todoIndex?,
|
|
7298
7345
|
todoTitle?, holdMs? (0=until next), clear:true.
|
|
7299
7346
|
Missing selectors listed in response, not fatal.
|
|
7347
|
+
Same command as browser highlight <sessionId>
|
|
7348
|
+
'<json>' (prefer that prefix for a --detach/
|
|
7349
|
+
persistent session).
|
|
7350
|
+
<selector>|<label>[|<tone>] Shorthand for 1-3 rings, no JSON braces/quotes
|
|
7351
|
+
to escape - rings separated by ";", e.g.
|
|
7352
|
+
"#x|Login button|warning; .err|Error banner|danger".
|
|
7353
|
+
Covers selector/label/tone only; anything else
|
|
7354
|
+
(size/weight/zoom/focus/todos/...) needs the JSON
|
|
7355
|
+
form above.
|
|
7300
7356
|
waygraph browser Show browser subcommands
|
|
7301
7357
|
waygraph browser start Open a new session (headful by default, about:blank)
|
|
7302
7358
|
--inject preset|path Merge an external Block library (e.g. saucedemo)
|
|
@@ -7316,6 +7372,10 @@ Primary (less is more):
|
|
|
7316
7372
|
layer; use browser/pilot for agent-driven sessions.
|
|
7317
7373
|
waygraph demo [--blocks <flow|file|spec>] Watch with step overlay (QA path)
|
|
7318
7374
|
--data '{...}' Mem seed JSON (or inline flow({...}))
|
|
7375
|
+
--mem-stub Fill any requires key --data didn't cover from
|
|
7376
|
+
registerMemStub's registry (needs the key
|
|
7377
|
+
registered, or the flow's own withMemStub - a
|
|
7378
|
+
key with neither still fails preflight)
|
|
7319
7379
|
--auto-next Auto-advance steps (alias: --autoplay)
|
|
7320
7380
|
--fast Shorter auto-next / Next gates (keeps smooth cursor)
|
|
7321
7381
|
--full Classic wrap-all block chips (default: carousel)
|
|
@@ -7332,6 +7392,7 @@ Primary (less is more):
|
|
|
7332
7392
|
--title / --base-url
|
|
7333
7393
|
waygraph run [--blocks <flow|file|spec>] Execute (no overlay unless --step)
|
|
7334
7394
|
--data '{...}'
|
|
7395
|
+
--mem-stub Same as demo's --mem-stub
|
|
7335
7396
|
--non-headless Show browser
|
|
7336
7397
|
--video [dir] Record .webm
|
|
7337
7398
|
--video-viewport WxH Recording size (default run: 1280x720)
|
|
@@ -7460,7 +7521,7 @@ async function main() {
|
|
|
7460
7521
|
" waygraph run src/flows/shop.flow.ts\n" +
|
|
7461
7522
|
" waygraph run --blocks shopFlow\n" +
|
|
7462
7523
|
" waygraph list # file → export map\n" +
|
|
7463
|
-
" Flags: --blocks --data --non-headless --video [dir] --step/--no-step");
|
|
7524
|
+
" Flags: --blocks --data --mem-stub --non-headless --video [dir] --step/--no-step");
|
|
7464
7525
|
process.exit(1);
|
|
7465
7526
|
}
|
|
7466
7527
|
const proj = flags.blocks
|
|
@@ -7779,7 +7840,7 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
7779
7840
|
console.error("waygraph demo: missing flow/spec — e.g.\n" +
|
|
7780
7841
|
" waygraph demo src/flows/shop.flow.ts\n" +
|
|
7781
7842
|
" waygraph demo --blocks shopFlow\n" +
|
|
7782
|
-
" Flags: --blocks --data --auto-next --fast --full --mini --ff-expand --ff-disabled --auto-play-video --title --base-url --video");
|
|
7843
|
+
" Flags: --blocks --data --mem-stub --auto-next --fast --full --mini --ff-expand --ff-disabled --auto-play-video --title --base-url --video");
|
|
7783
7844
|
process.exit(1);
|
|
7784
7845
|
}
|
|
7785
7846
|
const proj = flags.blocks
|
|
@@ -8223,19 +8284,25 @@ Agents shipped: waygraph-planner, waygraph-author, waygraph-healer.
|
|
|
8223
8284
|
if (sub === "highlight") {
|
|
8224
8285
|
const raw = args[3];
|
|
8225
8286
|
if (raw === undefined) {
|
|
8226
|
-
console.error(
|
|
8287
|
+
console.error(`waygraph ${command} highlight: usage:\n` +
|
|
8288
|
+
` waygraph ${command} highlight <sessionId> '{"rings":[{"selector":"#x","label":"X"}]}'\n` +
|
|
8289
|
+
` waygraph ${command} highlight <sessionId> "#x|X" (shorthand: <selector>|<label>[|<tone>], rings separated by ";")`);
|
|
8227
8290
|
process.exit(1);
|
|
8228
8291
|
}
|
|
8229
8292
|
let fixtures;
|
|
8230
8293
|
try {
|
|
8231
8294
|
fixtures = JSON.parse(raw);
|
|
8232
8295
|
}
|
|
8233
|
-
catch {
|
|
8234
|
-
|
|
8235
|
-
|
|
8296
|
+
catch (jsonErr) {
|
|
8297
|
+
const shorthand = parseHighlightShorthand(raw);
|
|
8298
|
+
if (shorthand.type === "error") {
|
|
8299
|
+
console.error(`waygraph ${command} highlight: body is neither valid JSON (${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}) nor valid shorthand (${shorthand.reason})`);
|
|
8300
|
+
process.exit(1);
|
|
8301
|
+
}
|
|
8302
|
+
fixtures = shorthand.fixtures;
|
|
8236
8303
|
}
|
|
8237
8304
|
if (fixtures.op !== undefined && fixtures.op !== "highlight") {
|
|
8238
|
-
console.error(
|
|
8305
|
+
console.error(`waygraph ${command} highlight: do not set "op" (or set it to "highlight")`);
|
|
8239
8306
|
process.exit(1);
|
|
8240
8307
|
}
|
|
8241
8308
|
const { op: _ignore, ...rest } = fixtures;
|
package/dist/engine.d.ts
CHANGED
|
@@ -251,6 +251,15 @@ export interface Flow<Out extends Checkpoint<string>> {
|
|
|
251
251
|
* Per-slot stub/fixture values win. `run()` ignores.
|
|
252
252
|
*/
|
|
253
253
|
readonly highlightStyle?: import("./highlights.js").HighlightStyleDefaults;
|
|
254
|
+
/**
|
|
255
|
+
* Set once this Flow has been wrapped in {@link withMemStub} - opts into
|
|
256
|
+
* auto-filling `requires` keys with registered fake values
|
|
257
|
+
* (`registerMemStub`, `src/mem-stub.ts`) instead of failing preflight when
|
|
258
|
+
* the caller didn't supply them. `run()` never reads this - the CLI's own
|
|
259
|
+
* `--data`/`--mem-stub` seeding, or a bare-library caller's own explicit
|
|
260
|
+
* `seedMemStub(mem, flow)` call, is what actually fills mem before `run()`.
|
|
261
|
+
*/
|
|
262
|
+
readonly memStub?: boolean;
|
|
254
263
|
/**
|
|
255
264
|
* This Flow's constituent Blocks, in order between `start`/`end`, as plain
|
|
256
265
|
* data - for introspection/visualization tools, without running anything.
|
|
@@ -318,6 +327,17 @@ export declare function withSessionReset<Out extends Checkpoint<string>>(flow: F
|
|
|
318
327
|
* @example const ticket123 = withTitle(loginFlow, "Ticket #123 - Sales rep signs in");
|
|
319
328
|
*/
|
|
320
329
|
export declare function withTitle<Out extends Checkpoint<string>>(flow: Flow<Out>, title: string): Flow<Out>;
|
|
330
|
+
/**
|
|
331
|
+
* Opts this Flow into memStub: `requires` keys the caller didn't supply get
|
|
332
|
+
* filled from `registerMemStub`'s registry (`src/mem-stub.ts`) instead of
|
|
333
|
+
* failing preflight, for any key that has a registered fake generator - a
|
|
334
|
+
* required key with no registration still fails exactly as before.
|
|
335
|
+
* Non-destructive, same pattern as {@link withTitle}. `run()` never reads
|
|
336
|
+
* this itself - the CLI's `--data`/`--mem-stub` seeding, or a bare-library
|
|
337
|
+
* caller's own explicit `seedMemStub(mem, flow)` call, does the filling.
|
|
338
|
+
* @example const demoLogin = withMemStub(loginFlow);
|
|
339
|
+
*/
|
|
340
|
+
export declare function withMemStub<Out extends Checkpoint<string>>(flow: Flow<Out>): Flow<Out>;
|
|
321
341
|
/**
|
|
322
342
|
* Demo pacing for a whole Flow episode (fast review vs slow gap/wrong walkthrough).
|
|
323
343
|
* Non-destructive. `fastForwardComposeBlock` is always blitz for its own step;
|
package/dist/engine.js
CHANGED
|
@@ -401,6 +401,24 @@ export function withTitle(flow, title) {
|
|
|
401
401
|
modBlockVerify: (block, nameOrIndex, newCheck) => withTitle(flow.modBlockVerify(block, nameOrIndex, newCheck), title),
|
|
402
402
|
};
|
|
403
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Opts this Flow into memStub: `requires` keys the caller didn't supply get
|
|
406
|
+
* filled from `registerMemStub`'s registry (`src/mem-stub.ts`) instead of
|
|
407
|
+
* failing preflight, for any key that has a registered fake generator - a
|
|
408
|
+
* required key with no registration still fails exactly as before.
|
|
409
|
+
* Non-destructive, same pattern as {@link withTitle}. `run()` never reads
|
|
410
|
+
* this itself - the CLI's `--data`/`--mem-stub` seeding, or a bare-library
|
|
411
|
+
* caller's own explicit `seedMemStub(mem, flow)` call, does the filling.
|
|
412
|
+
* @example const demoLogin = withMemStub(loginFlow);
|
|
413
|
+
*/
|
|
414
|
+
export function withMemStub(flow) {
|
|
415
|
+
return {
|
|
416
|
+
...flow,
|
|
417
|
+
memStub: true,
|
|
418
|
+
withBlockVerify: (block, verify) => withMemStub(flow.withBlockVerify(block, verify)),
|
|
419
|
+
modBlockVerify: (block, nameOrIndex, newCheck) => withMemStub(flow.modBlockVerify(block, nameOrIndex, newCheck)),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
404
422
|
/**
|
|
405
423
|
* Demo pacing for a whole Flow episode (fast review vs slow gap/wrong walkthrough).
|
|
406
424
|
* Non-destructive. `fastForwardComposeBlock` is always blitz for its own step;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact alternative to full-JSON `browser highlight` payloads, for the
|
|
3
|
+
* common case (a couple of rings, each just selector + label + maybe tone).
|
|
4
|
+
* Full JSON stays fully supported for anything needing size/weight/zoom/
|
|
5
|
+
* focus/detail/tag/todos - this only ever covers a subset.
|
|
6
|
+
*
|
|
7
|
+
* Grammar: `<selector>|<label>[|<tone>]` rings joined by `;`.
|
|
8
|
+
* "#submit|Login button|warning; .error|Error banner|danger"
|
|
9
|
+
*
|
|
10
|
+
* `;` and `|` were picked because neither is valid inside a CSS/Playwright
|
|
11
|
+
* selector or an ordinary label - unlike `,`/`:`, which real selectors use
|
|
12
|
+
* constantly (`:nth-child(2)`, `:not(.x)`, `[href*="mailto:"]`, compound
|
|
13
|
+
* `a, b` lists). A selector/label containing a literal `;` or `|` needs the
|
|
14
|
+
* full-JSON form instead - documented, not silently mishandled.
|
|
15
|
+
*/
|
|
16
|
+
import type { PilotHighlightFixtures } from "./pilot-overlay.js";
|
|
17
|
+
export type ParsedHighlightShorthand = {
|
|
18
|
+
type: "ok";
|
|
19
|
+
fixtures: PilotHighlightFixtures;
|
|
20
|
+
} | {
|
|
21
|
+
type: "error";
|
|
22
|
+
reason: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseHighlightShorthand(raw: string): ParsedHighlightShorthand;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function parseHighlightShorthand(raw) {
|
|
2
|
+
const tokens = raw
|
|
3
|
+
.split(";")
|
|
4
|
+
.map((t) => t.trim())
|
|
5
|
+
.filter((t) => t.length > 0);
|
|
6
|
+
if (tokens.length === 0) {
|
|
7
|
+
return { type: "error", reason: "empty highlight shorthand - give at least one <selector>|<label> ring" };
|
|
8
|
+
}
|
|
9
|
+
const rings = [];
|
|
10
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
11
|
+
const token = tokens[i];
|
|
12
|
+
const parts = token.split("|").map((p) => p.trim());
|
|
13
|
+
if (parts.length < 2 || parts.length > 3) {
|
|
14
|
+
return {
|
|
15
|
+
type: "error",
|
|
16
|
+
reason: `ring ${i + 1} ("${token}") must be <selector>|<label> or <selector>|<label>|<tone> ` +
|
|
17
|
+
`- got ${parts.length} part(s) separated by "|"`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const [selector, label, tone] = parts;
|
|
21
|
+
if (!selector) {
|
|
22
|
+
return { type: "error", reason: `ring ${i + 1} ("${token}") has an empty selector` };
|
|
23
|
+
}
|
|
24
|
+
if (!label) {
|
|
25
|
+
return { type: "error", reason: `ring ${i + 1} ("${token}") has an empty label` };
|
|
26
|
+
}
|
|
27
|
+
rings.push(tone ? { selector, label, tone } : { selector, label });
|
|
28
|
+
}
|
|
29
|
+
return { type: "ok", fixtures: { rings } };
|
|
30
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export type { Checkpoint, Instruction, Block, DefinedBlock, Start, WaygraphInstanceOption } from "./types.js";
|
|
2
2
|
export { connect, checkpoint } from "./types.js";
|
|
3
3
|
export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
|
|
4
|
+
export { registerMemStub, seedMemStub, getMemStub } from "./mem-stub.js";
|
|
4
5
|
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
|
|
5
|
-
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
6
|
+
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
6
7
|
export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
|
|
7
8
|
export type { WaygraphHighlightStub, WaygraphHighlightFixture, WaygraphSlide, WaygraphTodoItem, WaygraphTodoInput, WaygraphTodoGroup, WaygraphTodoGroupInput, WaygraphTodosOpts, TodoDockUiOpts, TodoDockUiResolved, TodoDockState, TodoListStyle, FixtureDurationFields, HighlightStubPhase, HighlightStubPhaseName, HighlightFixtureMap, ResolvedHighlight, WaygraphHighlight, HighlightTone, HighlightSize, HighlightWeight, HighlightStyleDefaults, DemoPace, DemoPaceName, StubCtx, StubLifecycleFn, StubPhaseResult, StubPhaseFixtures, DevicePreset, DeviceViewport, DeviceState, DeviceOrientation, } from "./highlights.js";
|
|
8
9
|
export type { Flow, EngineConfig, ComposedBlock, FastForwardComposedBlock, RunGraphOptions, BlockInfo, NavBlock, NavBlockOptions, NavClickBlock, NavClickBlockOptions, MethodBlock, ActionBlock, AssertBlock, AssertBlockOptions, PageBlock, PageBlockOptions, PageMethodEntry, EffectBlock, MemEffectBlock, MemNavBlock, Layout, LayoutOptions, MapBuilderOptions, } from "./engine.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { connect, checkpoint } from "./types.js";
|
|
2
2
|
export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
|
|
3
|
+
export { registerMemStub, seedMemStub, getMemStub } from "./mem-stub.js";
|
|
3
4
|
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
|
|
4
|
-
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
5
|
+
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withMemStub, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
5
6
|
export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
|
|
6
7
|
export { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./graph.js";
|
|
7
8
|
export { isFileSelectToken, parseBlocksSelect, matchBlocksSelect, globToRegExp, } from "./blocks-select.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memStub: a registry of caller-supplied FAKE VALUES for required MemKeys, so
|
|
3
|
+
* a Flow can run/demo without hand-seeding every credential/name/email every
|
|
4
|
+
* time. Bring your own generator (Faker.js or anything else) - waygraph takes
|
|
5
|
+
* no dependency on one, it only stores and invokes an opaque `() => T`.
|
|
6
|
+
*
|
|
7
|
+
* "Stub" here is unrelated to the other two meanings already in this
|
|
8
|
+
* codebase: `stubBefore`/`stubAfter`/`stubOnError` (demo narration fixtures,
|
|
9
|
+
* see highlights.ts's `runStubPhase`) and `upload`'s `stub: "image"|"pdf"|
|
|
10
|
+
* "video"` (a placeholder file). This is a third, separate "stub."
|
|
11
|
+
*
|
|
12
|
+
* Opt-in only, per Flow (`withMemStub`, engine.ts) or per-run (`--mem-stub` /
|
|
13
|
+
* WAYGRAPH_MEM_STUB=1) - a required key with no registered generator still
|
|
14
|
+
* fails preflight exactly as before. Registered per MemKey *instance*
|
|
15
|
+
* (identity, not `.name`), matching MemPage's own store - two keys sharing a
|
|
16
|
+
* debug name must never cross-contaminate here either.
|
|
17
|
+
*/
|
|
18
|
+
import type { MemKey } from "./mem-page.js";
|
|
19
|
+
import type { MemPage } from "./mem-page.js";
|
|
20
|
+
import type { Flow } from "./engine.js";
|
|
21
|
+
/**
|
|
22
|
+
* Registers a fake-value generator for one required MemKey.
|
|
23
|
+
* @example registerMemStub(LoginCreds.key, () => ({
|
|
24
|
+
* username: faker.internet.userName(),
|
|
25
|
+
* password: faker.internet.password(),
|
|
26
|
+
* }));
|
|
27
|
+
*/
|
|
28
|
+
export declare function registerMemStub<T>(key: MemKey<T>, fake: () => T): void;
|
|
29
|
+
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub}/{@link withMemStub} instead. */
|
|
30
|
+
export declare function getMemStub<T>(key: MemKey<T>): (() => T) | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* For a bare library `flow.run(mem, ...)` call outside the CLI (which has its
|
|
33
|
+
* own `--mem-stub`-aware seeding) - call this yourself before `run()` when
|
|
34
|
+
* `flow.memStub` is true, the same way external tooling already reads
|
|
35
|
+
* `flow.resetSession`/`flow.title`/etc. (`run()` itself never reads Flow
|
|
36
|
+
* flags - see the `with*` helpers in engine.ts).
|
|
37
|
+
* @example
|
|
38
|
+
* if (flow.memStub) seedMemStub(mem, flow);
|
|
39
|
+
* await flow.run(mem, config);
|
|
40
|
+
*/
|
|
41
|
+
export declare function seedMemStub(mem: MemPage, flow: Flow<any>): void;
|
package/dist/mem-stub.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const registry = new Map();
|
|
2
|
+
/**
|
|
3
|
+
* Registers a fake-value generator for one required MemKey.
|
|
4
|
+
* @example registerMemStub(LoginCreds.key, () => ({
|
|
5
|
+
* username: faker.internet.userName(),
|
|
6
|
+
* password: faker.internet.password(),
|
|
7
|
+
* }));
|
|
8
|
+
*/
|
|
9
|
+
export function registerMemStub(key, fake) {
|
|
10
|
+
registry.set(key, fake);
|
|
11
|
+
}
|
|
12
|
+
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub}/{@link withMemStub} instead. */
|
|
13
|
+
export function getMemStub(key) {
|
|
14
|
+
return registry.get(key);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* For a bare library `flow.run(mem, ...)` call outside the CLI (which has its
|
|
18
|
+
* own `--mem-stub`-aware seeding) - call this yourself before `run()` when
|
|
19
|
+
* `flow.memStub` is true, the same way external tooling already reads
|
|
20
|
+
* `flow.resetSession`/`flow.title`/etc. (`run()` itself never reads Flow
|
|
21
|
+
* flags - see the `with*` helpers in engine.ts).
|
|
22
|
+
* @example
|
|
23
|
+
* if (flow.memStub) seedMemStub(mem, flow);
|
|
24
|
+
* await flow.run(mem, config);
|
|
25
|
+
*/
|
|
26
|
+
export function seedMemStub(mem, flow) {
|
|
27
|
+
for (const bi of flow.blocks()) {
|
|
28
|
+
for (const k of bi.block.requires ?? []) {
|
|
29
|
+
if (mem.has(k))
|
|
30
|
+
continue;
|
|
31
|
+
const fake = registry.get(k);
|
|
32
|
+
if (fake)
|
|
33
|
+
mem.set(k, fake());
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -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,
|