@pcamarajr/scout 0.9.0 → 0.11.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/dist/cli.js +139 -52
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +26 -2
- package/dist/config.js +28 -1
- package/dist/config.js.map +1 -1
- package/dist/cookies.d.ts +14 -0
- package/dist/cookies.js +121 -0
- package/dist/cookies.js.map +1 -0
- package/dist/engine.d.ts +22 -9
- package/dist/engine.js +68 -44
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/init.js +3 -0
- package/dist/init.js.map +1 -1
- package/dist/mcp/server.js +51 -29
- package/dist/mcp/server.js.map +1 -1
- package/dist/report.d.ts +10 -4
- package/dist/report.js +33 -26
- package/dist/report.js.map +1 -1
- package/dist/runner/ai-runner.d.ts +3 -2
- package/dist/runner/ai-runner.js +12 -1
- package/dist/runner/ai-runner.js.map +1 -1
- package/dist/runner/browser.d.ts +58 -4
- package/dist/runner/browser.js +146 -3
- package/dist/runner/browser.js.map +1 -1
- package/dist/runner/script-runner.d.ts +9 -5
- package/dist/runner/script-runner.js +29 -7
- package/dist/runner/script-runner.js.map +1 -1
- package/dist/runner/video.d.ts +38 -8
- package/dist/runner/video.js +51 -13
- package/dist/runner/video.js.map +1 -1
- package/dist/specs.d.ts +14 -0
- package/dist/specs.js +59 -1
- package/dist/specs.js.map +1 -1
- package/dist/store.d.ts +14 -9
- package/dist/store.js +25 -16
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +54 -1
- package/dist/viewports.d.ts +54 -0
- package/dist/viewports.js +83 -0
- package/dist/viewports.js.map +1 -0
- package/package.json +1 -1
- package/templates/AGENTS.md +40 -3
|
@@ -9,23 +9,45 @@ const ASSERTION_KINDS = new Set([
|
|
|
9
9
|
"assertConsoleMessage",
|
|
10
10
|
]);
|
|
11
11
|
/**
|
|
12
|
-
* Replay dedicated to producing the
|
|
12
|
+
* Replay dedicated to producing the demo video: identical step execution to
|
|
13
13
|
* {@link replaySteps}, but it records each step's wall-clock offset (for burned
|
|
14
|
-
* captions)
|
|
14
|
+
* captions), drives the synthetic cursor to each target and pulses on the
|
|
15
|
+
* action, and dwells after assertions / at the end so a human can read the
|
|
15
16
|
* verified state. It is decoupled from the verdict — this run is never the
|
|
16
|
-
* source of truth, so the pacing pauses cannot affect a pass/fail
|
|
17
|
+
* source of truth, so the pacing pauses and overlay cannot affect a pass/fail
|
|
18
|
+
* decision (the cursor calls are best-effort and swallow their own errors).
|
|
17
19
|
*/
|
|
18
|
-
export async function
|
|
20
|
+
export async function replayForDemo(session, steps, assertDwellMs, cursorTravelMs, endDwellMs) {
|
|
19
21
|
const timeline = [];
|
|
20
22
|
const epoch = session.videoEpoch ?? Date.now();
|
|
21
23
|
for (let i = 0; i < steps.length; i++) {
|
|
22
24
|
const step = steps[i];
|
|
23
|
-
|
|
25
|
+
// tMs is taken before the cursor travels, so the caption shows during travel.
|
|
26
|
+
const entry = {
|
|
27
|
+
label: `${i + 1}/${steps.length} · ${describeStep(step)}`,
|
|
28
|
+
tMs: Date.now() - epoch,
|
|
29
|
+
};
|
|
30
|
+
timeline.push(entry);
|
|
31
|
+
// Demo overlay: move the cursor to the target, let the eye follow, then pulse.
|
|
32
|
+
const center = await session.pointToStep(step, cursorTravelMs);
|
|
33
|
+
if (center) {
|
|
34
|
+
entry.x = center.x;
|
|
35
|
+
entry.y = center.y;
|
|
36
|
+
if (cursorTravelMs)
|
|
37
|
+
await session.page.waitForTimeout(cursorTravelMs);
|
|
38
|
+
await session.pulseCursor();
|
|
39
|
+
}
|
|
24
40
|
try {
|
|
25
41
|
await session.executeStep(step);
|
|
26
42
|
}
|
|
27
|
-
catch {
|
|
28
|
-
|
|
43
|
+
catch (error) {
|
|
44
|
+
const reason = error instanceof Error ? error.message.split("\n")[0] : String(error);
|
|
45
|
+
return {
|
|
46
|
+
passed: false,
|
|
47
|
+
timeline,
|
|
48
|
+
failedIndex: i,
|
|
49
|
+
failure: `step ${i + 1} (${describeStep(step)}): ${reason}`,
|
|
50
|
+
};
|
|
29
51
|
}
|
|
30
52
|
if (ASSERTION_KINDS.has(step.kind))
|
|
31
53
|
await session.page.waitForTimeout(assertDwellMs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-runner.js","sourceRoot":"","sources":["../../src/runner/script-runner.ts"],"names":[],"mappings":"AAWA,MAAM,eAAe,GAAG,IAAI,GAAG,CAAe;IAC5C,aAAa;IACb,YAAY;IACZ,eAAe;IACf,kBAAkB;IAClB,WAAW;IACX,eAAe;IACf,uBAAuB;IACvB,sBAAsB;CACvB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"script-runner.js","sourceRoot":"","sources":["../../src/runner/script-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner/video.d.ts
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
import type { Verdict } from "../types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* (never the messy AI run)
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* Demo-video pipeline. The video is sourced from a dedicated, paced replay
|
|
4
|
+
* (never the messy AI run) — a synthetic cursor + click pulse are injected into
|
|
5
|
+
* the page (see demoCursorStub) and captured natively by the recording — then
|
|
6
|
+
* post-processed by ffmpeg into a GitHub-ready MP4 with baked-in step labels and
|
|
7
|
+
* a verdict card. ffmpeg is an *optional* system dependency — when it is missing
|
|
8
|
+
* we keep the raw WebM and warn with an install hint instead of bundling a
|
|
9
|
+
* binary into the base install.
|
|
8
10
|
*/
|
|
9
11
|
export interface TimelineEntry {
|
|
10
12
|
/** Caption burned onto the frame while this step runs (e.g. "2/5 · clicar em ...") */
|
|
11
13
|
label: string;
|
|
12
14
|
/** Milliseconds from video start (context creation) to the step's execution */
|
|
13
15
|
tMs: number;
|
|
16
|
+
/** Target center (viewport px) the cursor moved to — only for target-bearing steps. */
|
|
17
|
+
x?: number;
|
|
18
|
+
y?: number;
|
|
14
19
|
}
|
|
15
20
|
export interface VideoPacing {
|
|
16
21
|
/** Playwright slowMo (ms added per action) — slows the replay for human viewing */
|
|
17
22
|
slowMoMs: number;
|
|
18
23
|
/** Extra pause after each assertion so the verified state is readable */
|
|
19
24
|
assertDwellMs: number;
|
|
25
|
+
/**
|
|
26
|
+
* Dwell after the synthetic cursor starts travelling to a target, before the
|
|
27
|
+
* step acts — lets the eye follow cursor → target → click. Zeroed in the
|
|
28
|
+
* non-paced fallback so it mirrors the authoritative run.
|
|
29
|
+
*/
|
|
30
|
+
cursorTravelMs: number;
|
|
20
31
|
/** Opening card (scenario name) duration */
|
|
21
32
|
titleCardMs: number;
|
|
22
33
|
/** Closing verdict card duration — also the final-frame dwell it overlays */
|
|
@@ -24,13 +35,32 @@ export interface VideoPacing {
|
|
|
24
35
|
}
|
|
25
36
|
/**
|
|
26
37
|
* Maps the single `videoSpeed` knob (0,1] to concrete pacing. <1 = slower.
|
|
27
|
-
* At 1.0 the replay runs at natural speed; the default 0.
|
|
28
|
-
* human can actually follow.
|
|
38
|
+
* At 1.0 the replay runs at natural speed; the default 0.35 yields a demo a
|
|
39
|
+
* human can actually follow, with enough cursor-travel dwell to read each move.
|
|
29
40
|
*/
|
|
30
41
|
export declare function pacingFor(videoSpeed?: number): VideoPacing;
|
|
31
42
|
/** First usable font: SCOUT_VIDEO_FONT override, then common system paths. */
|
|
32
43
|
export declare function resolveFont(): string | undefined;
|
|
33
|
-
|
|
44
|
+
export interface FfmpegDiagnosis {
|
|
45
|
+
ok: boolean;
|
|
46
|
+
/** The binary we probed (FFMPEG_PATH or "ffmpeg"). */
|
|
47
|
+
bin: string;
|
|
48
|
+
/** Why it's unusable, when ok is false. */
|
|
49
|
+
reason?: "missing" | "broken";
|
|
50
|
+
/** Human-readable detail — the spawn error, exit signal, or first stderr line. */
|
|
51
|
+
detail?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Probes ffmpeg and classifies the outcome. "missing" = not on PATH /
|
|
55
|
+
* FFMPEG_PATH points nowhere (spawn errored). "broken" = the binary exists but
|
|
56
|
+
* won't run — typically aborts (e.g. SIGABRT from a missing shared library on a
|
|
57
|
+
* half-removed Homebrew install). The two need different remediation, so we
|
|
58
|
+
* tell them apart instead of collapsing both to "not found".
|
|
59
|
+
*/
|
|
60
|
+
export declare function diagnoseFfmpeg(): FfmpegDiagnosis;
|
|
61
|
+
/** Install/repair hint tailored to a missing vs a broken ffmpeg. */
|
|
62
|
+
export declare function ffmpegRemediation(d: FfmpegDiagnosis): string;
|
|
63
|
+
/** Resolves the ffmpeg binary (FFMPEG_PATH or PATH), or undefined if absent/broken. */
|
|
34
64
|
export declare function findFfmpeg(): string | undefined;
|
|
35
65
|
export interface OverlaySpec {
|
|
36
66
|
font: string;
|
package/dist/runner/video.js
CHANGED
|
@@ -6,14 +6,15 @@ function clamp(n, lo, hi) {
|
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Maps the single `videoSpeed` knob (0,1] to concrete pacing. <1 = slower.
|
|
9
|
-
* At 1.0 the replay runs at natural speed; the default 0.
|
|
10
|
-
* human can actually follow.
|
|
9
|
+
* At 1.0 the replay runs at natural speed; the default 0.35 yields a demo a
|
|
10
|
+
* human can actually follow, with enough cursor-travel dwell to read each move.
|
|
11
11
|
*/
|
|
12
|
-
export function pacingFor(videoSpeed = 0.
|
|
12
|
+
export function pacingFor(videoSpeed = 0.35) {
|
|
13
13
|
const speed = clamp(videoSpeed, 0.1, 1);
|
|
14
14
|
return {
|
|
15
15
|
slowMoMs: Math.round(BASE_SLOWMO * (1 / speed - 1)),
|
|
16
16
|
assertDwellMs: Math.round(500 / speed),
|
|
17
|
+
cursorTravelMs: clamp(Math.round(250 / speed), 250, 900),
|
|
17
18
|
titleCardMs: 1500,
|
|
18
19
|
verdictCardMs: 1800,
|
|
19
20
|
};
|
|
@@ -33,11 +34,39 @@ export function resolveFont() {
|
|
|
33
34
|
return override;
|
|
34
35
|
return FONT_CANDIDATES.find((f) => fs.existsSync(f));
|
|
35
36
|
}
|
|
36
|
-
/**
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Probes ffmpeg and classifies the outcome. "missing" = not on PATH /
|
|
39
|
+
* FFMPEG_PATH points nowhere (spawn errored). "broken" = the binary exists but
|
|
40
|
+
* won't run — typically aborts (e.g. SIGABRT from a missing shared library on a
|
|
41
|
+
* half-removed Homebrew install). The two need different remediation, so we
|
|
42
|
+
* tell them apart instead of collapsing both to "not found".
|
|
43
|
+
*/
|
|
44
|
+
export function diagnoseFfmpeg() {
|
|
38
45
|
const bin = process.env.FFMPEG_PATH || "ffmpeg";
|
|
39
|
-
const probe = spawnSync(bin, ["-version"], {
|
|
40
|
-
|
|
46
|
+
const probe = spawnSync(bin, ["-version"], { encoding: "utf8" });
|
|
47
|
+
if (probe.error) {
|
|
48
|
+
return { ok: false, bin, reason: "missing", detail: probe.error.message };
|
|
49
|
+
}
|
|
50
|
+
if (probe.status === 0)
|
|
51
|
+
return { ok: true, bin };
|
|
52
|
+
const stderr = (probe.stderr || "").trim();
|
|
53
|
+
const firstLine = stderr.split("\n").find((l) => l.trim().length > 0);
|
|
54
|
+
const detail = probe.signal
|
|
55
|
+
? `aborted with ${probe.signal}${firstLine ? ` — ${firstLine}` : ""}`
|
|
56
|
+
: firstLine || `exited with status ${probe.status}`;
|
|
57
|
+
return { ok: false, bin, reason: "broken", detail };
|
|
58
|
+
}
|
|
59
|
+
/** Install/repair hint tailored to a missing vs a broken ffmpeg. */
|
|
60
|
+
export function ffmpegRemediation(d) {
|
|
61
|
+
if (d.reason === "broken") {
|
|
62
|
+
return `ffmpeg is installed (${d.bin}) but won't run: ${d.detail}. Repair it — 'brew reinstall ffmpeg' (macOS), reinstall via your package manager (Linux), or point FFMPEG_PATH at a working binary.`;
|
|
63
|
+
}
|
|
64
|
+
return "ffmpeg not found. Install it — 'brew install ffmpeg' (macOS) / 'apt-get install ffmpeg' (Debian/Ubuntu) — or set FFMPEG_PATH to its location.";
|
|
65
|
+
}
|
|
66
|
+
/** Resolves the ffmpeg binary (FFMPEG_PATH or PATH), or undefined if absent/broken. */
|
|
67
|
+
export function findFfmpeg() {
|
|
68
|
+
const d = diagnoseFfmpeg();
|
|
69
|
+
return d.ok ? d.bin : undefined;
|
|
41
70
|
}
|
|
42
71
|
function probeDurationMs(ffmpegBin, file) {
|
|
43
72
|
const ffprobe = process.env.FFPROBE_PATH ||
|
|
@@ -62,9 +91,17 @@ const VERDICT_LABEL = {
|
|
|
62
91
|
partial: "PARCIAL",
|
|
63
92
|
blocked: "BLOQUEADO",
|
|
64
93
|
};
|
|
65
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Sanitizes a value for an ffmpeg `drawtext` field. Strips the quote/backslash
|
|
96
|
+
* that would break out of the `text='…'` wrapper, then escapes `:` — ffmpeg's
|
|
97
|
+
* filter-option separator — which otherwise truncates any caption containing a
|
|
98
|
+
* URL (e.g. a `navigate` step's `https://…`) and fails the whole filtergraph.
|
|
99
|
+
*/
|
|
66
100
|
function safeText(s) {
|
|
67
|
-
return s
|
|
101
|
+
return s
|
|
102
|
+
.replace(/['\\]/g, "")
|
|
103
|
+
.replace(/:/g, "\\:")
|
|
104
|
+
.trim();
|
|
68
105
|
}
|
|
69
106
|
/** Approx Arial glyph advance as a fraction of font size — for width fitting. */
|
|
70
107
|
const GLYPH_RATIO = 0.56;
|
|
@@ -127,7 +164,7 @@ export function buildOverlayFilter(spec) {
|
|
|
127
164
|
const title = fitText(spec.scenarioName, width - 40, 40, 18);
|
|
128
165
|
filters.push(fullBox(0, titleSec));
|
|
129
166
|
filters.push(text(title.text, { size: title.size, color: "white", y: "(h/2)-70", a: 0, b: titleSec }));
|
|
130
|
-
filters.push(text("scout
|
|
167
|
+
filters.push(text("scout demo", { size: 22, color: "0xBDC3C7", y: "(h/2)+10", a: 0, b: titleSec }));
|
|
131
168
|
// Closing verdict card.
|
|
132
169
|
const verdict = fitText(VERDICT_LABEL[spec.verdict], width - 40, 52, 24);
|
|
133
170
|
filters.push(fullBox(verdictStart, dur));
|
|
@@ -146,13 +183,14 @@ export function buildOverlayFilter(spec) {
|
|
|
146
183
|
* `--record-video` always yields a playable file.
|
|
147
184
|
*/
|
|
148
185
|
export function generateVideo(input) {
|
|
149
|
-
const
|
|
150
|
-
if (!
|
|
186
|
+
const diag = diagnoseFfmpeg();
|
|
187
|
+
if (!diag.ok) {
|
|
151
188
|
return {
|
|
152
189
|
output: input.webmPath,
|
|
153
|
-
warning:
|
|
190
|
+
warning: `MP4 overlay not generated, kept the raw WebM. ${ffmpegRemediation(diag)}`,
|
|
154
191
|
};
|
|
155
192
|
}
|
|
193
|
+
const ffmpeg = diag.bin;
|
|
156
194
|
const font = resolveFont();
|
|
157
195
|
const durationMs = probeDurationMs(ffmpeg, input.webmPath) ??
|
|
158
196
|
(input.timeline.at(-1)?.tMs ?? 0) + input.pacing.verdictCardMs;
|
package/dist/runner/video.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/runner/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/runner/video.ts"],"names":[],"mappings":"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"}
|
package/dist/specs.d.ts
CHANGED
|
@@ -18,6 +18,20 @@ export declare function slugToToken(slug: string): string;
|
|
|
18
18
|
export declare function parseSpec(specFile: string, root: string, cwd: string): Scenario[];
|
|
19
19
|
/** Load every scenario across all spec files, validating slug uniqueness. */
|
|
20
20
|
export declare function loadScenarios(cwd?: string): Scenario[];
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a `go` selector against the loaded scenarios.
|
|
23
|
+
*
|
|
24
|
+
* A scenario slug is `<file>/<scenario>` (nested spec dirs add more segments).
|
|
25
|
+
* The selector may name:
|
|
26
|
+
* - a single scenario, by exact slug (`auth/login/success`) or heading name;
|
|
27
|
+
* - a whole spec file / directory, by its slug prefix (`auth`, `auth/login`),
|
|
28
|
+
* which matches every scenario whose slug starts with `<selector>/`.
|
|
29
|
+
*
|
|
30
|
+
* The result is the de-duplicated union of those matches, preserving the input
|
|
31
|
+
* order, so `scout go auth` runs all of `auth` while `scout go auth/login`
|
|
32
|
+
* still targets the lone scenario when one exists.
|
|
33
|
+
*/
|
|
34
|
+
export declare function selectScenarios(all: Scenario[], selector: string): Scenario[];
|
|
21
35
|
export interface NewScenarioInput {
|
|
22
36
|
feature: string;
|
|
23
37
|
name: string;
|
package/dist/specs.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import matter from "gray-matter";
|
|
4
4
|
import { SCOUT_DIR } from "./config.js";
|
|
5
|
+
import { mergeCookiesByName, parseCookieList, parseInlineCookies } from "./cookies.js";
|
|
5
6
|
/**
|
|
6
7
|
* Scenario specs live as markdown files under `.scout/specs/**\/*.scout.md`.
|
|
7
8
|
* One file per feature/component; each `## heading` is one scenario. The
|
|
@@ -20,10 +21,15 @@ const OVERRIDE_KEYS = new Set([
|
|
|
20
21
|
"profile",
|
|
21
22
|
"notes",
|
|
22
23
|
"tags",
|
|
24
|
+
"viewports",
|
|
23
25
|
"grantPermissions",
|
|
24
26
|
"denyPermissions",
|
|
25
27
|
"geolocation",
|
|
28
|
+
"cookies",
|
|
26
29
|
]);
|
|
30
|
+
/** Filesystem/report-safe viewport names (mirrors viewports.ts, kept inline so
|
|
31
|
+
* spec parsing has no Playwright dependency). */
|
|
32
|
+
const VIEWPORT_NAME_RE = /^[a-z0-9-]+$/;
|
|
27
33
|
/**
|
|
28
34
|
* Browser permissions Scout can grant/deny per scenario. Curated (not a
|
|
29
35
|
* pass-through to Playwright) so a typo fails loudly at load time instead of
|
|
@@ -179,6 +185,28 @@ function parseTags(raw) {
|
|
|
179
185
|
}
|
|
180
186
|
return undefined;
|
|
181
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Parse a viewport-name list from YAML (array/string) or a comma-separated
|
|
190
|
+
* override line, validating each name's charset (fail-loud, like permissions).
|
|
191
|
+
* Existence against the registry is checked later at resolution time.
|
|
192
|
+
*/
|
|
193
|
+
function parseViewportList(raw, ctx) {
|
|
194
|
+
let items;
|
|
195
|
+
if (Array.isArray(raw))
|
|
196
|
+
items = raw.map(String);
|
|
197
|
+
else if (typeof raw === "string") {
|
|
198
|
+
const inner = raw.trim().replace(/^\[|\]$/g, "");
|
|
199
|
+
items = inner.split(",").map((t) => t.trim()).filter(Boolean);
|
|
200
|
+
}
|
|
201
|
+
if (!items?.length)
|
|
202
|
+
return undefined;
|
|
203
|
+
for (const name of items) {
|
|
204
|
+
if (!VIEWPORT_NAME_RE.test(name)) {
|
|
205
|
+
throw new Error(`Invalid viewport name "${name}" in ${ctx}. Use lowercase letters, digits and hyphens.`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return [...new Set(items)];
|
|
209
|
+
}
|
|
182
210
|
/**
|
|
183
211
|
* Split markdown body into `## ` sections (h1/h3+ and preamble are ignored).
|
|
184
212
|
* Fenced code blocks (``` ... ```) are skipped so a documented `## ` inside a
|
|
@@ -210,7 +238,9 @@ export function parseSpec(specFile, root, cwd) {
|
|
|
210
238
|
const fileFeature = typeof data.feature === "string" ? data.feature : path.basename(specFile).replace(SPEC_EXT, "");
|
|
211
239
|
const fileProfile = typeof data.profile === "string" ? data.profile : undefined;
|
|
212
240
|
const fileTags = parseTags(data.tags);
|
|
241
|
+
const fileViewports = parseViewportList(data.viewports, `${path.relative(cwd, specFile)} frontmatter`);
|
|
213
242
|
const relFile = path.relative(cwd, specFile);
|
|
243
|
+
const fileCookies = parseCookieList(data.cookies, relFile);
|
|
214
244
|
const sections = splitSections(content);
|
|
215
245
|
const scenarios = [];
|
|
216
246
|
const seen = new Set();
|
|
@@ -240,7 +270,16 @@ export function parseSpec(specFile, root, cwd) {
|
|
|
240
270
|
}
|
|
241
271
|
seen.add(scenarioSlug);
|
|
242
272
|
const tags = parseTags(overrides.tags) ?? fileTags;
|
|
243
|
-
const
|
|
273
|
+
const ctx = `${relFile} → "${section.name}"`;
|
|
274
|
+
// A per-section `viewports:` REPLACES the file-level list (it does not merge
|
|
275
|
+
// like tags) — a scenario explicitly chooses the sizes it runs in.
|
|
276
|
+
const viewports = "viewports" in overrides ? parseViewportList(overrides.viewports, ctx) : fileViewports;
|
|
277
|
+
const permissions = resolvePermissions(data, overrides, ctx);
|
|
278
|
+
// Per-section override (inline name=value) wins over the file frontmatter,
|
|
279
|
+
// by cookie name; the profile's cookies merge under both at launch.
|
|
280
|
+
const sectionCookies = "cookies" in overrides ? parseInlineCookies(overrides.cookies, ctx) : [];
|
|
281
|
+
const merged = mergeCookiesByName(fileCookies, sectionCookies);
|
|
282
|
+
const cookies = merged.length ? merged : undefined;
|
|
244
283
|
scenarios.push({
|
|
245
284
|
slug: `${fileSlug}/${scenarioSlug}`,
|
|
246
285
|
name: section.name,
|
|
@@ -249,7 +288,9 @@ export function parseSpec(specFile, root, cwd) {
|
|
|
249
288
|
profile: overrides.profile ?? fileProfile,
|
|
250
289
|
notes: overrides.notes,
|
|
251
290
|
tags,
|
|
291
|
+
viewports,
|
|
252
292
|
permissions,
|
|
293
|
+
cookies,
|
|
253
294
|
file: relFile,
|
|
254
295
|
});
|
|
255
296
|
}
|
|
@@ -272,6 +313,23 @@ export function loadScenarios(cwd = process.cwd()) {
|
|
|
272
313
|
}
|
|
273
314
|
return all;
|
|
274
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Resolve a `go` selector against the loaded scenarios.
|
|
318
|
+
*
|
|
319
|
+
* A scenario slug is `<file>/<scenario>` (nested spec dirs add more segments).
|
|
320
|
+
* The selector may name:
|
|
321
|
+
* - a single scenario, by exact slug (`auth/login/success`) or heading name;
|
|
322
|
+
* - a whole spec file / directory, by its slug prefix (`auth`, `auth/login`),
|
|
323
|
+
* which matches every scenario whose slug starts with `<selector>/`.
|
|
324
|
+
*
|
|
325
|
+
* The result is the de-duplicated union of those matches, preserving the input
|
|
326
|
+
* order, so `scout go auth` runs all of `auth` while `scout go auth/login`
|
|
327
|
+
* still targets the lone scenario when one exists.
|
|
328
|
+
*/
|
|
329
|
+
export function selectScenarios(all, selector) {
|
|
330
|
+
const prefix = `${selector}/`;
|
|
331
|
+
return all.filter((s) => s.slug === selector || s.name === selector || s.slug.startsWith(prefix));
|
|
332
|
+
}
|
|
275
333
|
/** Render a `## ` section (with optional overrides) for appending to a spec. */
|
|
276
334
|
function renderSection(input) {
|
|
277
335
|
const overrides = [];
|
package/dist/specs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specs.js","sourceRoot":"","sources":["../src/specs.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"specs.js","sourceRoot":"","sources":["../src/specs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvF;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AACjC,MAAM,QAAQ,GAAG,WAAW,CAAC;AAC7B,0DAA0D;AAC1D,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,SAAS;IACT,OAAO;IACP,MAAM;IACN,WAAW;IACX,kBAAkB;IAClB,iBAAiB;IACjB,aAAa;IACb,SAAS;CACV,CAAC,CAAC;AAEH;kDACkD;AAClD,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,aAAa;IACb,eAAe;IACf,QAAQ;IACR,YAAY;IACZ,gBAAgB;IAChB,iBAAiB;IACjB,MAAM;CACP,CAAC,CAAC;AAEH,2FAA2F;AAC3F,SAAS,mBAAmB,CAAC,GAAY,EAAE,GAAW;IACpD,IAAI,KAA2B,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACjD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,uBAAuB,CAAC,QAAQ,GAAG,cAAc,CAAC,GAAG,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,qFAAqF;AACrF,SAAS,gBAAgB,CAAC,GAAY,EAAE,GAAW;IACjD,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,GAAW,CAAC;IAChB,IAAI,GAAW,CAAC;IAChB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACzB,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;SAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,QAAQ,GAAG,uCAAuC,CAAC,CAAC;QACjG,CAAC;QACD,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,uCAAuC,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,2CAA2C,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,IAA6B,EAC7B,SAAiC,EACjC,GAAW;IAEX,MAAM,KAAK,GACT,kBAAkB,IAAI,SAAS;QAC7B,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,gBAAgB,EAAE,GAAG,CAAC;QACtD,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,IAAI,GACR,iBAAiB,IAAI,SAAS;QAC5B,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC;QACrD,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,WAAW,GACf,aAAa,IAAI,SAAS;QACxB,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC;QAC9C,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAE9C,wEAAwE;IACxE,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,WAAW,EAAE,CAAC;QAChB,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,SAAS,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,2EAA2E,CAC1G,CAAC;IACJ,CAAC;IACD,+EAA+E;IAC/E,8EAA8E;IAC9E,+EAA+E;IAC/E,oDAAoD;IACpD,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC1B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,QAAQ,GAAG,SAAS,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,IAAI,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC;IACxC,IAAI,QAAQ;QAAE,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACrC,IAAI,WAAW;QAAE,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IAClD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,mFAAmF;AACnF,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;aACrD,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,kFAAkF;AAClF,SAAS,gBAAgB,CAAC,QAAgB,EAAE,IAAY;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACtG,OAAO,GAAG;SACP,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SACf,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;SAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,GAAY,EAAE,GAAW;IAClD,IAAI,KAA2B,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACjD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,QAAQ,GAAG,8CAA8C,CACxF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7B,CAAC;AAOD;;;;GAIG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,GAAG,GAAmB,IAAI,CAAC;IAC/B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC;QAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC;YACN,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,IAAY,EAAE,GAAW;IACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEtC,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACpH,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACvG,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE3D,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,mEAAmE;QACnE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,CAAC,EAAE,CAAC;QACvD,MAAM,SAAS,GAA2B,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,MAAM,CAAC,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAE,MAAM;YAC1C,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAE9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,aAAa,OAAO,CAAC,IAAI,QAAQ,OAAO,2BAA2B,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,CAAC,IAAI,YAAY,YAAY,SAAS,OAAO,GAAG,CAAC,CAAC;QAClG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEvB,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,OAAO,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC;QAC7C,6EAA6E;QAC7E,mEAAmE;QACnE,MAAM,SAAS,GAAG,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QACzG,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC7D,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,cAAc,GAClB,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAiC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACjF,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,GAAG,QAAQ,IAAI,YAAY,EAAE;YACnC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,WAAW;YACzC,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,IAAI;YACJ,SAAS;YACT,WAAW;YACX,OAAO;YACP,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,IAAI,QAAQ,QAAQ,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,CAAC;YACvG,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,GAAe,EAAE,QAAgB;IAC/D,MAAM,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC;IAC9B,OAAO,GAAG,CAAC,MAAM,CACf,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAC/E,CAAC;AACJ,CAAC;AAWD,gFAAgF;AAChF,SAAS,aAAa,CAAC,KAAuB;IAC5C,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,KAAK,CAAC,OAAO;QAAE,SAAS,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/D,IAAI,KAAK,CAAC,KAAK;QAAE,SAAS,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACtE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC;IAC3D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,iBAAiB,KAAK,CAAC,OAAO,WAAW,CAAC;QAC9D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,YAAY,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,CAAC,IAAI,UAAU,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/store.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { RunResult, Scenario, Step } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Filesystem store inside the target project:
|
|
4
|
-
* .scout/specs/<feature>.scout.md
|
|
5
|
-
* .scout/scripts/<slug>.json
|
|
6
|
-
* .scout/runs/<runId>/
|
|
7
|
-
* .scout/state/<profile>.json
|
|
4
|
+
* .scout/specs/<feature>.scout.md — committed (the suite; markdown source of truth)
|
|
5
|
+
* .scout/scripts/<slug>@<viewport>.json — committed (cached deterministic steps per viewport; `<slug>` is `<file>/<scenario>`)
|
|
6
|
+
* .scout/runs/<runId>/ — gitignored (artifacts per run)
|
|
7
|
+
* .scout/state/<profile>.json — gitignored (auth storageState)
|
|
8
8
|
*/
|
|
9
9
|
export declare class Store {
|
|
10
10
|
readonly root: string;
|
|
@@ -14,11 +14,16 @@ export declare class Store {
|
|
|
14
14
|
exists(): boolean;
|
|
15
15
|
listScenarios(): Scenario[];
|
|
16
16
|
getScenario(slug: string): Scenario | undefined;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
/** Committed script for one (scenario × viewport): `scripts/<slug>@<viewport>.json`. */
|
|
18
|
+
scriptPath(slug: string, viewport: string): string;
|
|
19
|
+
loadSteps(slug: string, viewport: string): Step[] | undefined;
|
|
20
|
+
saveSteps(slug: string, viewport: string, steps: Step[]): void;
|
|
21
|
+
newRunDir(slug: string, viewport: string): string;
|
|
21
22
|
saveRunResult(result: RunResult): void;
|
|
22
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Latest run result per (scenario × viewport), keyed `<slug>@<viewport>` (for
|
|
25
|
+
* `scout report`). Each viewport is an independent verification unit, so two
|
|
26
|
+
* viewports of the same scenario never overwrite each other.
|
|
27
|
+
*/
|
|
23
28
|
latestRuns(): Map<string, RunResult>;
|
|
24
29
|
}
|
package/dist/store.js
CHANGED
|
@@ -4,10 +4,10 @@ import { SCOUT_DIR } from "./config.js";
|
|
|
4
4
|
import { SPECS_DIR, loadScenarios, slugToToken } from "./specs.js";
|
|
5
5
|
/**
|
|
6
6
|
* Filesystem store inside the target project:
|
|
7
|
-
* .scout/specs/<feature>.scout.md
|
|
8
|
-
* .scout/scripts/<slug>.json
|
|
9
|
-
* .scout/runs/<runId>/
|
|
10
|
-
* .scout/state/<profile>.json
|
|
7
|
+
* .scout/specs/<feature>.scout.md — committed (the suite; markdown source of truth)
|
|
8
|
+
* .scout/scripts/<slug>@<viewport>.json — committed (cached deterministic steps per viewport; `<slug>` is `<file>/<scenario>`)
|
|
9
|
+
* .scout/runs/<runId>/ — gitignored (artifacts per run)
|
|
10
|
+
* .scout/state/<profile>.json — gitignored (auth storageState)
|
|
11
11
|
*/
|
|
12
12
|
export class Store {
|
|
13
13
|
root;
|
|
@@ -40,31 +40,36 @@ export class Store {
|
|
|
40
40
|
return this.listScenarios().find((s) => s.slug === slug);
|
|
41
41
|
}
|
|
42
42
|
// ---- cached deterministic scripts ----
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
/** Committed script for one (scenario × viewport): `scripts/<slug>@<viewport>.json`. */
|
|
44
|
+
scriptPath(slug, viewport) {
|
|
45
|
+
return path.join(this.root, "scripts", `${slug}@${viewport}.json`);
|
|
45
46
|
}
|
|
46
|
-
loadSteps(slug) {
|
|
47
|
-
const file = this.scriptPath(slug);
|
|
47
|
+
loadSteps(slug, viewport) {
|
|
48
|
+
const file = this.scriptPath(slug, viewport);
|
|
48
49
|
if (!fs.existsSync(file))
|
|
49
50
|
return undefined;
|
|
50
51
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
51
52
|
}
|
|
52
|
-
saveSteps(slug, steps) {
|
|
53
|
-
const file = this.scriptPath(slug);
|
|
53
|
+
saveSteps(slug, viewport, steps) {
|
|
54
|
+
const file = this.scriptPath(slug, viewport);
|
|
54
55
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
55
56
|
fs.writeFileSync(file, JSON.stringify(steps, null, 2) + "\n");
|
|
56
57
|
}
|
|
57
58
|
// ---- runs ----
|
|
58
|
-
newRunDir(slug) {
|
|
59
|
+
newRunDir(slug, viewport) {
|
|
59
60
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
60
|
-
const dir = path.join(this.root, "runs", `${stamp}-${slugToToken(slug)}`);
|
|
61
|
+
const dir = path.join(this.root, "runs", `${stamp}-${slugToToken(slug)}@${viewport}`);
|
|
61
62
|
fs.mkdirSync(dir, { recursive: true });
|
|
62
63
|
return dir;
|
|
63
64
|
}
|
|
64
65
|
saveRunResult(result) {
|
|
65
66
|
fs.writeFileSync(path.join(result.runDir, "result.json"), JSON.stringify(result, null, 2) + "\n");
|
|
66
67
|
}
|
|
67
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Latest run result per (scenario × viewport), keyed `<slug>@<viewport>` (for
|
|
70
|
+
* `scout report`). Each viewport is an independent verification unit, so two
|
|
71
|
+
* viewports of the same scenario never overwrite each other.
|
|
72
|
+
*/
|
|
68
73
|
latestRuns() {
|
|
69
74
|
const runsDir = path.join(this.root, "runs");
|
|
70
75
|
const map = new Map();
|
|
@@ -76,7 +81,7 @@ export class Store {
|
|
|
76
81
|
if (!fs.existsSync(file))
|
|
77
82
|
continue;
|
|
78
83
|
const result = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
79
|
-
map.set(result.slug
|
|
84
|
+
map.set(`${result.slug}@${result.viewport}`, result); // later overwrites earlier
|
|
80
85
|
}
|
|
81
86
|
return map;
|
|
82
87
|
}
|
|
@@ -90,8 +95,10 @@ feature: Example
|
|
|
90
95
|
# How to write a scout spec
|
|
91
96
|
|
|
92
97
|
One file per feature/component. File-level frontmatter sets defaults
|
|
93
|
-
(\`feature\`, \`profile\`, \`tags\`). Each \`##\` heading is one scenario;
|
|
94
|
-
\`profile\`/\`notes\`/\`tags\` override lines may follow a heading
|
|
98
|
+
(\`feature\`, \`profile\`, \`tags\`, \`viewports\`). Each \`##\` heading is one scenario;
|
|
99
|
+
optional \`profile\`/\`notes\`/\`tags\`/\`viewports\` override lines may follow a heading
|
|
100
|
+
before the prose. A scenario's \`viewports\` list (built-ins: mobile/desktop/tablet)
|
|
101
|
+
REPLACES the file-level one and fans the scenario out into one run per viewport.
|
|
95
102
|
Write the flow + expected behavior in plain language — no selectors, no code.
|
|
96
103
|
|
|
97
104
|
Copy the block below into a new \`*.scout.md\` file (outside the fence) to start:
|
|
@@ -101,6 +108,7 @@ Copy the block below into a new \`*.scout.md\` file (outside the fence) to start
|
|
|
101
108
|
feature: Paywall
|
|
102
109
|
profile: anon
|
|
103
110
|
tags: [monetization]
|
|
111
|
+
viewports: [mobile]
|
|
104
112
|
---
|
|
105
113
|
|
|
106
114
|
## Free user hits paywall on ep 3
|
|
@@ -108,6 +116,7 @@ Open ep 3 of series X without login; paywall appears with a signup CTA.
|
|
|
108
116
|
|
|
109
117
|
## Subscriber bypasses paywall
|
|
110
118
|
profile: qa
|
|
119
|
+
viewports: [mobile, desktop]
|
|
111
120
|
|
|
112
121
|
Logged-in subscriber opens ep 3; plays with no paywall.
|
|
113
122
|
\`\`\`
|