@pcamarajr/scout 0.9.0 → 0.10.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 +85 -25
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +18 -2
- package/dist/config.js +18 -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 +11 -9
- package/dist/engine.js +44 -35
- package/dist/engine.js.map +1 -1
- package/dist/report.js +1 -1
- package/dist/report.js.map +1 -1
- package/dist/runner/ai-runner.d.ts +1 -1
- package/dist/runner/ai-runner.js +9 -0
- package/dist/runner/ai-runner.js.map +1 -1
- package/dist/runner/browser.d.ts +52 -4
- package/dist/runner/browser.js +138 -0
- 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 +28 -1
- package/dist/specs.js.map +1 -1
- package/dist/types.d.ts +27 -1
- package/package.json +1 -1
package/dist/engine.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { loadConfig, resolveStorageState } from "./config.js";
|
|
3
|
+
import { loadConfig, resolveCookies, resolveStorageState } from "./config.js";
|
|
4
4
|
import { detectAiCredentials, inferProvider } from "./credentials.js";
|
|
5
5
|
import { renderRunReport } from "./report.js";
|
|
6
6
|
import { BrowserSession } from "./runner/browser.js";
|
|
7
7
|
import { runWithAgent } from "./runner/ai-runner.js";
|
|
8
|
-
import { describeStep,
|
|
8
|
+
import { describeStep, replayForDemo, replaySteps } from "./runner/script-runner.js";
|
|
9
9
|
import { generateVideo, pacingFor } from "./runner/video.js";
|
|
10
10
|
/**
|
|
11
11
|
* Core run logic shared by CLI and MCP server:
|
|
@@ -20,6 +20,7 @@ export async function runScenario(store, scenario, config = loadConfig(), opts =
|
|
|
20
20
|
const start = Date.now();
|
|
21
21
|
const runDir = store.newRunDir(scenario.slug);
|
|
22
22
|
const storageState = resolveStorageState(scenario.profile, config);
|
|
23
|
+
const cookies = resolveCookies(scenario, config);
|
|
23
24
|
const cached = opts.forceAi ? undefined : store.loadSteps(scenario.slug);
|
|
24
25
|
const aiCreds = detectAiCredentials(inferProvider(config.model), { engine: config.engine });
|
|
25
26
|
const launch = () => BrowserSession.launch({
|
|
@@ -29,6 +30,7 @@ export async function runScenario(store, scenario, config = loadConfig(), opts =
|
|
|
29
30
|
locale: config.locale,
|
|
30
31
|
runDir,
|
|
31
32
|
permissions: scenario.permissions,
|
|
33
|
+
cookies,
|
|
32
34
|
extraHeaders: config.headers,
|
|
33
35
|
});
|
|
34
36
|
let result;
|
|
@@ -52,7 +54,7 @@ export async function runScenario(store, scenario, config = loadConfig(), opts =
|
|
|
52
54
|
}
|
|
53
55
|
else if (heal && aiCreds.ok) {
|
|
54
56
|
// cached script broke — re-verify with the agent and re-record
|
|
55
|
-
const aiResult = await runAi(scenario, config, store, runDir, storageState, opts);
|
|
57
|
+
const aiResult = await runAi(scenario, config, store, runDir, storageState, cookies, opts);
|
|
56
58
|
result = {
|
|
57
59
|
...aiResult,
|
|
58
60
|
healed: true,
|
|
@@ -81,15 +83,15 @@ export async function runScenario(store, scenario, config = loadConfig(), opts =
|
|
|
81
83
|
if (!aiCreds.ok) {
|
|
82
84
|
throw new Error(aiCreds.remediation);
|
|
83
85
|
}
|
|
84
|
-
const aiResult = await runAi(scenario, config, store, runDir, storageState, opts);
|
|
86
|
+
const aiResult = await runAi(scenario, config, store, runDir, storageState, cookies, opts);
|
|
85
87
|
result = { ...aiResult, startedAt, durationMs: Date.now() - start };
|
|
86
88
|
}
|
|
87
|
-
//
|
|
89
|
+
// Demo video: always sourced from a dedicated clean replay of the
|
|
88
90
|
// recorded script (never the AI run), only when verified and opted-in.
|
|
89
91
|
if (config.recordVideo && result.verdict === "verified") {
|
|
90
92
|
const steps = store.loadSteps(scenario.slug);
|
|
91
93
|
if (steps?.length) {
|
|
92
|
-
result.video = await
|
|
94
|
+
result.video = await recordDemoVideo(scenario, steps, config, storageState, cookies, runDir);
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
store.saveRunResult(result);
|
|
@@ -97,29 +99,29 @@ export async function runScenario(store, scenario, config = loadConfig(), opts =
|
|
|
97
99
|
return result;
|
|
98
100
|
}
|
|
99
101
|
/**
|
|
100
|
-
* Builds the pacing for the non-paced fallback replay: zero slowMo and
|
|
101
|
-
*
|
|
102
|
-
* title/verdict card durations are kept so the rendered MP4 still bookends
|
|
103
|
-
* the scenario name and the VERIFIED card.
|
|
102
|
+
* Builds the pacing for the non-paced fallback replay: zero slowMo, dwell and
|
|
103
|
+
* cursor-travel so it mirrors the authoritative `ai+heal` replay (which passed).
|
|
104
|
+
* The title/verdict card durations are kept so the rendered MP4 still bookends
|
|
105
|
+
* with the scenario name and the VERIFIED card.
|
|
104
106
|
*/
|
|
105
107
|
export function nonPacedPacing(paced) {
|
|
106
|
-
return { ...paced, slowMoMs: 0, assertDwellMs: 0 };
|
|
108
|
+
return { ...paced, slowMoMs: 0, assertDwellMs: 0, cursorTravelMs: 0 };
|
|
107
109
|
}
|
|
108
110
|
/**
|
|
109
111
|
* Renders an MP4 from a recorded WebM, persisting the timeline and degrading to
|
|
110
112
|
* the raw WebM under a stable name when ffmpeg is missing or fails. Returns the
|
|
111
113
|
* artifact path, or undefined when no WebM was produced at all.
|
|
112
114
|
*/
|
|
113
|
-
function
|
|
115
|
+
function renderDemo(recorded, scenario, runDir, pacing) {
|
|
114
116
|
const webm = recorded.webm;
|
|
115
117
|
if (!webm || !fs.existsSync(webm)) {
|
|
116
118
|
console.warn("[scout] video: replay produced no WebM file.");
|
|
117
119
|
return undefined;
|
|
118
120
|
}
|
|
119
|
-
fs.writeFileSync(path.join(runDir, "
|
|
121
|
+
fs.writeFileSync(path.join(runDir, "demo.timeline.json"), JSON.stringify(recorded.timeline, null, 2) + "\n");
|
|
120
122
|
const result = generateVideo({
|
|
121
123
|
webmPath: webm,
|
|
122
|
-
outPath: path.join(runDir, "
|
|
124
|
+
outPath: path.join(runDir, "demo.mp4"),
|
|
123
125
|
width: 390,
|
|
124
126
|
height: 844,
|
|
125
127
|
scenarioName: scenario.name,
|
|
@@ -134,7 +136,7 @@ function renderPreview(recorded, scenario, runDir, pacing) {
|
|
|
134
136
|
return result.output;
|
|
135
137
|
}
|
|
136
138
|
// Fallback (no/failed ffmpeg): keep the raw WebM under a stable name.
|
|
137
|
-
const dest = path.join(runDir, "
|
|
139
|
+
const dest = path.join(runDir, "demo.webm");
|
|
138
140
|
try {
|
|
139
141
|
fs.renameSync(webm, dest);
|
|
140
142
|
return dest;
|
|
@@ -144,40 +146,44 @@ function renderPreview(recorded, scenario, runDir, pacing) {
|
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
148
|
/**
|
|
147
|
-
* Orchestrates
|
|
149
|
+
* Orchestrates demo-video generation, decoupled from the browser so it can be
|
|
148
150
|
* tested: `attempt` performs one recorded replay at a given pacing and returns
|
|
149
151
|
* its outcome + WebM. Best-effort and post-verdict — never touches the verdict.
|
|
150
152
|
*
|
|
151
153
|
* The verified scenario must NEVER yield zero video. The first attempt is paced
|
|
152
|
-
* (slowMo + dwell) for human viewing. If that paced replay fails — the
|
|
153
|
-
* sometimes perturbs timing on flows the authoritative run handled fine
|
|
154
|
-
* cookie banner) — we fall back to a non-paced replay that mirrors the
|
|
154
|
+
* (slowMo + dwell + cursor) for human viewing. If that paced replay fails — the
|
|
155
|
+
* pacing sometimes perturbs timing on flows the authoritative run handled fine
|
|
156
|
+
* (e.g. a cookie banner) — we fall back to a non-paced replay that mirrors the
|
|
155
157
|
* authoritative run, which passed, so a usable clip is still produced. Only if
|
|
156
158
|
* the fallback ALSO fails do we warn and yield no video.
|
|
157
159
|
*/
|
|
158
|
-
export async function
|
|
160
|
+
export async function recordDemoVideoFrom(attempt, scenario, runDir, pacing) {
|
|
159
161
|
const paced = await attempt(pacing);
|
|
160
162
|
if (paced.passed)
|
|
161
|
-
return
|
|
163
|
+
return renderDemo(paced, scenario, runDir, pacing);
|
|
162
164
|
if (paced.webm)
|
|
163
165
|
fs.rmSync(paced.webm, { force: true }); // discard the failed paced take
|
|
164
|
-
console.warn("[scout] video: paced
|
|
166
|
+
console.warn("[scout] video: paced demo replay failed; recorded a non-paced fallback clip (verdict unaffected)." +
|
|
167
|
+
(paced.failure ? ` Paced replay tripped on ${paced.failure}.` : ""));
|
|
165
168
|
const fallbackPacing = nonPacedPacing(pacing);
|
|
166
169
|
const fallback = await attempt(fallbackPacing);
|
|
167
170
|
if (fallback.passed)
|
|
168
|
-
return
|
|
171
|
+
return renderDemo(fallback, scenario, runDir, fallbackPacing);
|
|
169
172
|
if (fallback.webm)
|
|
170
173
|
fs.rmSync(fallback.webm, { force: true });
|
|
171
|
-
console.warn("[scout] video: non-paced fallback replay also failed — no video generated (verdict unaffected)."
|
|
174
|
+
console.warn("[scout] video: non-paced fallback replay also failed — no video generated (verdict unaffected)." +
|
|
175
|
+
(fallback.failure ? ` Replay tripped on ${fallback.failure}.` : "") +
|
|
176
|
+
" This usually means the scenario doesn't replay deterministically (it heals via AI each run), so there is no clean replay to film.");
|
|
172
177
|
return undefined;
|
|
173
178
|
}
|
|
174
179
|
/**
|
|
175
|
-
* Runs one extra, paced replay of the verified script with video recording on
|
|
176
|
-
* then renders it to a GitHub-ready
|
|
177
|
-
*
|
|
178
|
-
* still yields a clip; the verdict
|
|
180
|
+
* Runs one extra, paced replay of the verified script with video recording on
|
|
181
|
+
* (and the synthetic demo cursor injected), then renders it to a GitHub-ready
|
|
182
|
+
* MP4 with baked step labels + verdict card. On a paced-replay failure it
|
|
183
|
+
* retries without pacing so a verified scenario still yields a clip; the verdict
|
|
184
|
+
* is never affected.
|
|
179
185
|
*/
|
|
180
|
-
async function
|
|
186
|
+
async function recordDemoVideo(scenario, steps, config, storageState, cookies, runDir) {
|
|
181
187
|
const attempt = async (pacing) => {
|
|
182
188
|
let session;
|
|
183
189
|
try {
|
|
@@ -188,20 +194,22 @@ async function recordPreviewVideo(scenario, steps, config, storageState, runDir)
|
|
|
188
194
|
locale: config.locale,
|
|
189
195
|
runDir,
|
|
190
196
|
recordVideo: true,
|
|
197
|
+
demoCursor: true,
|
|
191
198
|
slowMoMs: pacing.slowMoMs,
|
|
192
199
|
permissions: scenario.permissions,
|
|
200
|
+
cookies,
|
|
193
201
|
extraHeaders: config.headers,
|
|
194
202
|
});
|
|
195
203
|
}
|
|
196
204
|
catch {
|
|
197
|
-
console.warn("[scout] video: could not open the browser for the
|
|
198
|
-
return { passed: false, timeline: [] };
|
|
205
|
+
console.warn("[scout] video: could not open the browser for the demo replay.");
|
|
206
|
+
return { passed: false, timeline: [], failure: "could not open the browser" };
|
|
199
207
|
}
|
|
200
|
-
const
|
|
208
|
+
const demo = await replayForDemo(session, steps, pacing.assertDwellMs, pacing.cursorTravelMs, pacing.verdictCardMs);
|
|
201
209
|
const { video: webm } = await session.close();
|
|
202
|
-
return { passed:
|
|
210
|
+
return { passed: demo.passed, webm, timeline: demo.timeline, failure: demo.failure };
|
|
203
211
|
};
|
|
204
|
-
return
|
|
212
|
+
return recordDemoVideoFrom(attempt, scenario, runDir, pacingFor(config.videoSpeed));
|
|
205
213
|
}
|
|
206
214
|
/**
|
|
207
215
|
* Runs `attempt` until it produces a real verdict, retrying runner failures
|
|
@@ -217,7 +225,7 @@ export async function runAiWithRetry(attempt, maxAttempts = 2) {
|
|
|
217
225
|
}
|
|
218
226
|
return { outcome, attempts: maxAttempts };
|
|
219
227
|
}
|
|
220
|
-
async function runAi(scenario, config, store, runDir, storageState, opts) {
|
|
228
|
+
async function runAi(scenario, config, store, runDir, storageState, cookies, opts) {
|
|
221
229
|
const startedAt = new Date().toISOString();
|
|
222
230
|
const start = Date.now();
|
|
223
231
|
const transcript = [];
|
|
@@ -233,6 +241,7 @@ async function runAi(scenario, config, store, runDir, storageState, opts) {
|
|
|
233
241
|
locale: config.locale,
|
|
234
242
|
runDir,
|
|
235
243
|
permissions: scenario.permissions,
|
|
244
|
+
cookies,
|
|
236
245
|
extraHeaders: config.headers,
|
|
237
246
|
});
|
|
238
247
|
let result;
|
package/dist/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/report.js
CHANGED
|
@@ -37,7 +37,7 @@ export function renderRunReport(result, scenario, steps) {
|
|
|
37
37
|
}
|
|
38
38
|
if (result.video) {
|
|
39
39
|
const name = path.basename(result.video);
|
|
40
|
-
lines.push(``, `##
|
|
40
|
+
lines.push(``, `## Demo`, ``, `<video src="./${name}" controls></video>`, ``, `[▶ ${name}](./${name}) — demo of the verified flow.`);
|
|
41
41
|
}
|
|
42
42
|
if (result.trace) {
|
|
43
43
|
lines.push(``, `## Trace`, ``, `\`npx playwright show-trace ${result.trace}\` — screenshots, DOM snapshots, network and console for the entire session.`);
|
package/dist/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,MAAM,IAAI,GAAmC;IAC3C,QAAQ,EAAE,GAAG;IACb,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,GAAG;CACb,CAAC;AAEF,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,QAAkB,EAAE,KAAc;IACnF,MAAM,KAAK,GAAG;QACZ,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE;QAC5C,EAAE;QACF,OAAO;QACP,WAAW;QACX,iBAAiB,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,EAAE,IAAI;QAC5G,YAAY,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI;QAClH,eAAe,QAAQ,CAAC,OAAO,IAAI,WAAW,IAAI;QAClD,gBAAgB,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;QAC1D,eAAe,MAAM,CAAC,SAAS,IAAI;QACnC,EAAE;QACF,iBAAiB,QAAQ,CAAC,QAAQ,EAAE;QACpC,EAAE;QACF,kBAAkB,MAAM,CAAC,MAAM,EAAE;KAClC,CAAC;IAEF,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,uBAAuB,KAAK,CAAC,MAAM,SAAS,EAAE,EAAE,CAAC,CAAC;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ScoutConfig } from "../config.js";
|
|
2
2
|
import type { Scenario } from "../types.js";
|
|
3
3
|
import { describeNoVerdict, relativizeUrl, type AiRunOutcome, type QueryEndInfo } from "./engines/types.js";
|
|
4
4
|
import { BrowserSession } from "./browser.js";
|
package/dist/runner/ai-runner.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveCookies } from "../config.js";
|
|
1
2
|
import { inferProvider } from "../credentials.js";
|
|
2
3
|
import { createScoutTools } from "./agent-tools.js";
|
|
3
4
|
import { selectEngine } from "./engines/index.js";
|
|
@@ -33,11 +34,19 @@ export async function runWithAgent(session, scenario, config) {
|
|
|
33
34
|
const envInfo = envVars.length
|
|
34
35
|
? `Env vars disponíveis via placeholder $ENV:VAR (em browser_fill e em URLs de browser_navigate): ${envVars.map((v) => `$ENV:${v}`).join(", ")}.`
|
|
35
36
|
: "";
|
|
37
|
+
// Cookies are seeded into the context by the runner before the flow. Announce
|
|
38
|
+
// only the NAMES so the agent treats the precondition as satisfied — values
|
|
39
|
+
// may be secrets ($ENV) and must never reach the LLM.
|
|
40
|
+
const presetCookies = resolveCookies(scenario, config);
|
|
41
|
+
const cookieInfo = presetCookies?.length
|
|
42
|
+
? `Cookies já setados no browser antes do fluxo (pré-condição satisfeita — NÃO tente setá-los, você não tem ferramenta pra isso): ${presetCookies.map((c) => c.name).join(", ")}.`
|
|
43
|
+
: "";
|
|
36
44
|
const systemPrompt = `Você é Scout, um agente de QA que verifica cenários em um browser real.
|
|
37
45
|
|
|
38
46
|
App alvo: ${config.baseUrl}
|
|
39
47
|
${profileInfo}
|
|
40
48
|
${envInfo}
|
|
49
|
+
${cookieInfo}
|
|
41
50
|
|
|
42
51
|
Método de trabalho:
|
|
43
52
|
1. Comece com browser_navigate para a página inicial do fluxo (ou browser_snapshot se já estiver lá).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-runner.js","sourceRoot":"","sources":["../../src/runner/ai-runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai-runner.js","sourceRoot":"","sources":["../../src/runner/ai-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Page } from "playwright";
|
|
2
|
-
import type { NetworkMatcher, PermissionPolicy, Step, Target } from "../types.js";
|
|
1
|
+
import { type BrowserContext, type Page } from "playwright";
|
|
2
|
+
import type { NetworkMatcher, PermissionPolicy, ScenarioCookie, Step, Target } from "../types.js";
|
|
3
3
|
export interface ElementInfo {
|
|
4
4
|
ref: number;
|
|
5
5
|
role: string;
|
|
@@ -21,12 +21,24 @@ export interface LaunchOptions {
|
|
|
21
21
|
storageState?: string;
|
|
22
22
|
locale?: string;
|
|
23
23
|
runDir: string;
|
|
24
|
-
/** Record a WebM of the context (used only by the
|
|
24
|
+
/** Record a WebM of the context (used only by the demo-video replay) */
|
|
25
25
|
recordVideo?: boolean;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Inject a synthetic cursor + click pulse (used only by the demo-video replay)
|
|
28
|
+
* so a viewer can see what each step acts on. Best-effort overlay, captured
|
|
29
|
+
* natively by recordVideo — never affects the verdict.
|
|
30
|
+
*/
|
|
31
|
+
demoCursor?: boolean;
|
|
32
|
+
/** Playwright slowMo (ms/action) — paces the demo replay for human viewing */
|
|
27
33
|
slowMoMs?: number;
|
|
28
34
|
/** Browser permission policy resolved from the scenario spec (grant/deny/geo). */
|
|
29
35
|
permissions?: PermissionPolicy;
|
|
36
|
+
/**
|
|
37
|
+
* Cookies to seed into the context before the first navigation (profile +
|
|
38
|
+
* scenario, already merged). `value` may carry a `$ENV:VAR` placeholder,
|
|
39
|
+
* resolved here at launch — never persisted resolved.
|
|
40
|
+
*/
|
|
41
|
+
cookies?: ScenarioCookie[];
|
|
30
42
|
/**
|
|
31
43
|
* Extra HTTP headers sent on every request in the context. Set from
|
|
32
44
|
* `scout.config.json` `headers` or `SCOUT_EXTRA_HEADERS`. The canonical use is
|
|
@@ -42,6 +54,19 @@ export interface LaunchOptions {
|
|
|
42
54
|
* in headed runs — headless already denies silently.
|
|
43
55
|
*/
|
|
44
56
|
export declare function denyPermissionsStub(deny: string[]): string;
|
|
57
|
+
/**
|
|
58
|
+
* Builds the init-script that injects a synthetic cursor + click pulse for the
|
|
59
|
+
* demo video. Playwright's recorded video never captures the OS pointer, so the
|
|
60
|
+
* UI would otherwise change with no visible cause; this paints a session-replay
|
|
61
|
+
* style cursor (Clarity/Sentry feel) that the recording captures natively.
|
|
62
|
+
*
|
|
63
|
+
* Injected at the context level so `window.__scoutCursor` re-exists after every
|
|
64
|
+
* navigation; the DOM element is (re)created lazily on the first `move()` since
|
|
65
|
+
* a `goto` wipes the previous document. `pointer-events:none` + a very high
|
|
66
|
+
* z-index guarantee it sits on top yet can never intercept the real click, so
|
|
67
|
+
* the overlay cannot perturb the flow it is filming.
|
|
68
|
+
*/
|
|
69
|
+
export declare function demoCursorStub(): string;
|
|
45
70
|
/**
|
|
46
71
|
* Thin Playwright wrapper shared by the AI runner and the replay runner.
|
|
47
72
|
* Owns ref→element resolution, tracing and screenshots.
|
|
@@ -148,10 +173,33 @@ export declare class BrowserSession {
|
|
|
148
173
|
/** Replays one recorded step (used by the deterministic runner). */
|
|
149
174
|
executeStep(step: Step): Promise<void>;
|
|
150
175
|
private targetLocator;
|
|
176
|
+
/**
|
|
177
|
+
* Demo overlay: animates the synthetic cursor to a target-bearing step's
|
|
178
|
+
* bounding-box center and returns that center (for the timeline). Returns null
|
|
179
|
+
* for steps without a target or when the element has no box. Best-effort — any
|
|
180
|
+
* failure is swallowed so it can never break the demo replay (or the verdict).
|
|
181
|
+
*/
|
|
182
|
+
pointToStep(step: Step, travelMs?: number): Promise<{
|
|
183
|
+
x: number;
|
|
184
|
+
y: number;
|
|
185
|
+
} | null>;
|
|
186
|
+
/** Demo overlay: emits a click pulse at the cursor's current position. Best-effort. */
|
|
187
|
+
pulseCursor(): Promise<void>;
|
|
151
188
|
close(): Promise<{
|
|
152
189
|
trace?: string;
|
|
153
190
|
video?: string;
|
|
154
191
|
}>;
|
|
155
192
|
}
|
|
193
|
+
/** The cookie shape Playwright's `context.addCookies()` accepts. */
|
|
194
|
+
type AddCookieParam = Parameters<BrowserContext["addCookies"]>[0][number];
|
|
195
|
+
/**
|
|
196
|
+
* Maps a declared ScenarioCookie to Playwright's addCookies shape, resolving
|
|
197
|
+
* `$ENV:VAR` in the value. Playwright needs either `url` or `domain`+`path`:
|
|
198
|
+
* with an explicit `domain` we pass it plus `path` (default `/`); otherwise we
|
|
199
|
+
* derive from `baseUrl` — `url: baseUrl` when no `path`, or the baseUrl host +
|
|
200
|
+
* the given `path` when a path is set.
|
|
201
|
+
*/
|
|
202
|
+
export declare function toPlaywrightCookie(c: ScenarioCookie, baseUrl: string): AddCookieParam;
|
|
156
203
|
/** Replaces $ENV:VAR_NAME placeholders so secrets never live in committed scripts. */
|
|
157
204
|
export declare function resolveEnvValue(value: string): string;
|
|
205
|
+
export {};
|
package/dist/runner/browser.js
CHANGED
|
@@ -25,6 +25,69 @@ export function denyPermissionsStub(deny) {
|
|
|
25
25
|
}
|
|
26
26
|
})();`;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds the init-script that injects a synthetic cursor + click pulse for the
|
|
30
|
+
* demo video. Playwright's recorded video never captures the OS pointer, so the
|
|
31
|
+
* UI would otherwise change with no visible cause; this paints a session-replay
|
|
32
|
+
* style cursor (Clarity/Sentry feel) that the recording captures natively.
|
|
33
|
+
*
|
|
34
|
+
* Injected at the context level so `window.__scoutCursor` re-exists after every
|
|
35
|
+
* navigation; the DOM element is (re)created lazily on the first `move()` since
|
|
36
|
+
* a `goto` wipes the previous document. `pointer-events:none` + a very high
|
|
37
|
+
* z-index guarantee it sits on top yet can never intercept the real click, so
|
|
38
|
+
* the overlay cannot perturb the flow it is filming.
|
|
39
|
+
*/
|
|
40
|
+
export function demoCursorStub() {
|
|
41
|
+
return `(() => {
|
|
42
|
+
if (window.top !== window.self) return; // top frame only — skip iframes
|
|
43
|
+
const CURSOR_ID = "__scout-cursor";
|
|
44
|
+
const STYLE_ID = "__scout-cursor-style";
|
|
45
|
+
let x = window.innerWidth / 2, y = window.innerHeight / 2;
|
|
46
|
+
function ensure() {
|
|
47
|
+
if (!document.body) return null;
|
|
48
|
+
if (!document.getElementById(STYLE_ID)) {
|
|
49
|
+
const style = document.createElement("style");
|
|
50
|
+
style.id = STYLE_ID;
|
|
51
|
+
style.textContent =
|
|
52
|
+
"#" + CURSOR_ID + "{position:fixed;top:0;left:0;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;background:rgba(0,0,0,.35);border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.45);z-index:2147483647;pointer-events:none;will-change:transform;}" +
|
|
53
|
+
// Positioned via left/top (NOT transform) so the scale keyframe, which
|
|
54
|
+
// owns the transform property, can't clobber its placement to (0,0).
|
|
55
|
+
".__scout-ripple{position:fixed;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;border:2px solid #2ECC71;z-index:2147483646;pointer-events:none;animation:__scout-ripple .55s ease-out forwards;}" +
|
|
56
|
+
"@keyframes __scout-ripple{from{transform:scale(1);opacity:.9;}to{transform:scale(3.6);opacity:0;}}";
|
|
57
|
+
(document.head || document.documentElement).appendChild(style);
|
|
58
|
+
}
|
|
59
|
+
let el = document.getElementById(CURSOR_ID);
|
|
60
|
+
if (!el) {
|
|
61
|
+
el = document.createElement("div");
|
|
62
|
+
el.id = CURSOR_ID;
|
|
63
|
+
el.style.transform = "translate(" + x + "px," + y + "px)";
|
|
64
|
+
document.body.appendChild(el);
|
|
65
|
+
}
|
|
66
|
+
return el;
|
|
67
|
+
}
|
|
68
|
+
window.__scoutCursor = {
|
|
69
|
+
move(nx, ny, durMs) {
|
|
70
|
+
const el = ensure();
|
|
71
|
+
if (!el) return;
|
|
72
|
+
el.style.transition = "transform " + (durMs || 0) + "ms cubic-bezier(.4,0,.2,1)";
|
|
73
|
+
x = nx; y = ny;
|
|
74
|
+
el.style.transform = "translate(" + nx + "px," + ny + "px)";
|
|
75
|
+
},
|
|
76
|
+
pulse() {
|
|
77
|
+
const el = ensure();
|
|
78
|
+
if (!el || !document.body) return;
|
|
79
|
+
const r = document.createElement("div");
|
|
80
|
+
r.className = "__scout-ripple";
|
|
81
|
+
r.style.left = x + "px";
|
|
82
|
+
r.style.top = y + "px";
|
|
83
|
+
document.body.appendChild(r);
|
|
84
|
+
setTimeout(() => r.remove(), 700);
|
|
85
|
+
el.style.background = "rgba(46,204,113,.5)";
|
|
86
|
+
setTimeout(() => { el.style.background = "rgba(0,0,0,.35)"; }, 240);
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
})();`;
|
|
90
|
+
}
|
|
28
91
|
const VIDEO_SIZE = { width: 390, height: 844 };
|
|
29
92
|
const STEP_TIMEOUT = 10_000;
|
|
30
93
|
/** Cap the ring buffers so a long-running session can't grow them unbounded. */
|
|
@@ -83,6 +146,16 @@ export class BrowserSession {
|
|
|
83
146
|
// Deny stub must run before any page script and in every page (incl. popups).
|
|
84
147
|
if (perm?.deny?.length)
|
|
85
148
|
await context.addInitScript(denyPermissionsStub(perm.deny));
|
|
149
|
+
// Seed declared cookies before any navigation, so the server reads them on
|
|
150
|
+
// the very first request (e.g. a server-side experiment variant). After
|
|
151
|
+
// storageState load → declared cookies win over the auth session by name.
|
|
152
|
+
if (opts.cookies?.length) {
|
|
153
|
+
await context.addCookies(opts.cookies.map((c) => toPlaywrightCookie(c, opts.baseUrl)));
|
|
154
|
+
}
|
|
155
|
+
// Demo cursor stub: a context init-script so the cursor API re-exists after
|
|
156
|
+
// every navigation (the element itself is re-created lazily on first move).
|
|
157
|
+
if (opts.demoCursor)
|
|
158
|
+
await context.addInitScript(demoCursorStub());
|
|
86
159
|
const videoEpoch = opts.recordVideo ? Date.now() : undefined;
|
|
87
160
|
await context.tracing.start({ screenshots: true, snapshots: true, sources: false });
|
|
88
161
|
const page = await context.newPage();
|
|
@@ -428,6 +501,41 @@ export class BrowserSession {
|
|
|
428
501
|
return this.page.locator(target.css);
|
|
429
502
|
throw new Error(`Target sem estratégia de localização: ${target.description}`);
|
|
430
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Demo overlay: animates the synthetic cursor to a target-bearing step's
|
|
506
|
+
* bounding-box center and returns that center (for the timeline). Returns null
|
|
507
|
+
* for steps without a target or when the element has no box. Best-effort — any
|
|
508
|
+
* failure is swallowed so it can never break the demo replay (or the verdict).
|
|
509
|
+
*/
|
|
510
|
+
async pointToStep(step, travelMs = 0) {
|
|
511
|
+
if (step.kind !== "click" && step.kind !== "fill" && step.kind !== "select")
|
|
512
|
+
return null;
|
|
513
|
+
try {
|
|
514
|
+
const box = await this.targetLocator(step.target).boundingBox();
|
|
515
|
+
if (!box)
|
|
516
|
+
return null;
|
|
517
|
+
const x = Math.round(box.x + box.width / 2);
|
|
518
|
+
const y = Math.round(box.y + box.height / 2);
|
|
519
|
+
await this.page.evaluate(([px, py, dur]) => {
|
|
520
|
+
window.__scoutCursor?.move(px, py, dur);
|
|
521
|
+
}, [x, y, travelMs]);
|
|
522
|
+
return { x, y };
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
return null; // overlay is best-effort; never disturb the replay
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/** Demo overlay: emits a click pulse at the cursor's current position. Best-effort. */
|
|
529
|
+
async pulseCursor() {
|
|
530
|
+
try {
|
|
531
|
+
await this.page.evaluate(() => {
|
|
532
|
+
window.__scoutCursor?.pulse();
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
// best-effort overlay — never disturb the replay
|
|
537
|
+
}
|
|
538
|
+
}
|
|
431
539
|
async close() {
|
|
432
540
|
let trace;
|
|
433
541
|
try {
|
|
@@ -455,6 +563,36 @@ export class BrowserSession {
|
|
|
455
563
|
return { trace, video: videoPath };
|
|
456
564
|
}
|
|
457
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Maps a declared ScenarioCookie to Playwright's addCookies shape, resolving
|
|
568
|
+
* `$ENV:VAR` in the value. Playwright needs either `url` or `domain`+`path`:
|
|
569
|
+
* with an explicit `domain` we pass it plus `path` (default `/`); otherwise we
|
|
570
|
+
* derive from `baseUrl` — `url: baseUrl` when no `path`, or the baseUrl host +
|
|
571
|
+
* the given `path` when a path is set.
|
|
572
|
+
*/
|
|
573
|
+
export function toPlaywrightCookie(c, baseUrl) {
|
|
574
|
+
const cookie = { name: c.name, value: resolveEnvValue(c.value) };
|
|
575
|
+
if (c.expires !== undefined)
|
|
576
|
+
cookie.expires = c.expires;
|
|
577
|
+
if (c.httpOnly !== undefined)
|
|
578
|
+
cookie.httpOnly = c.httpOnly;
|
|
579
|
+
if (c.secure !== undefined)
|
|
580
|
+
cookie.secure = c.secure;
|
|
581
|
+
if (c.sameSite !== undefined)
|
|
582
|
+
cookie.sameSite = c.sameSite;
|
|
583
|
+
if (c.domain) {
|
|
584
|
+
cookie.domain = c.domain;
|
|
585
|
+
cookie.path = c.path ?? "/";
|
|
586
|
+
}
|
|
587
|
+
else if (c.path) {
|
|
588
|
+
cookie.domain = new URL(baseUrl).hostname;
|
|
589
|
+
cookie.path = c.path;
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
cookie.url = baseUrl;
|
|
593
|
+
}
|
|
594
|
+
return cookie;
|
|
595
|
+
}
|
|
458
596
|
/** Replaces $ENV:VAR_NAME placeholders so secrets never live in committed scripts. */
|
|
459
597
|
export function resolveEnvValue(value) {
|
|
460
598
|
return value.replace(/\$ENV:([A-Z0-9_]+)/g, (_, name) => {
|