ptywright 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.mjs +1 -1
- package/dist/bin/ptywright.mjs +1 -1
- package/dist/{cli-CRGGdNy8.mjs → cli-DVDqUtha.mjs} +8 -2
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/mcp.mjs +1 -1
- package/dist/{runner-CF2ieCkx.mjs → runner-1gYMz8D5.mjs} +246 -104
- package/dist/{server-DpsZDVu2.mjs → server-OujH4CEo.mjs} +1 -1
- package/package.json +1 -1
- package/schemas/ptywright-agent-manifest.schema.json +1 -0
- package/schemas/ptywright-agent-replay-summary.schema.json +1 -1
- package/schemas/ptywright-agent-run.schema.json +1 -1
- package/schemas/ptywright-agent.schema.json +1 -1
package/dist/agent.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatAgentLaunchPlan, i as runAgentSpecPath, n as replayAgentRecordPath, r as runAgentSpec, t as defaultSpecNameForPath } from "./runner-
|
|
1
|
+
import { a as formatAgentLaunchPlan, i as runAgentSpecPath, n as replayAgentRecordPath, r as runAgentSpec, t as defaultSpecNameForPath } from "./runner-1gYMz8D5.mjs";
|
|
2
2
|
export { defaultSpecNameForPath, formatAgentLaunchPlan, replayAgentRecordPath, runAgentSpec, runAgentSpecPath };
|
package/dist/bin/ptywright.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as loadPtywrightConfig } from "./config-bGg636EW.mjs";
|
|
2
|
-
import { C as writeAgentManifestPath, D as escapeHtml, E as escapeAttribute, O as normalizeAgentFlowSpec, S as validateAgentManifestFiles, T as readAgentCassettePath, _ as formatArgv, b as isAgentManifestLike, c as launchAgentBrowser, d as AGENT_RUN_RECORD_SCHEMA_URL, f as agentRunModeSchema, g as writeAgentRunRecordPath, h as readAgentRunRecordPath, i as runAgentSpecPath, k as sanitizeArtifactName, l as createAgentTemplateSpec, m as isAgentRunRecordLike, n as replayAgentRecordPath, o as resolveAgentLaunchTarget, p as formatAgentArgv, s as normalizeAgentFlowSpecWithConfig, u as loadAgentSpec, v as AGENT_MANIFEST_FILE_NAME, w as isAgentCassetteLike, x as readAgentManifestPath, y as agentManifestPath } from "./runner-
|
|
2
|
+
import { C as writeAgentManifestPath, D as escapeHtml, E as escapeAttribute, O as normalizeAgentFlowSpec, S as validateAgentManifestFiles, T as readAgentCassettePath, _ as formatArgv, b as isAgentManifestLike, c as launchAgentBrowser, d as AGENT_RUN_RECORD_SCHEMA_URL, f as agentRunModeSchema, g as writeAgentRunRecordPath, h as readAgentRunRecordPath, i as runAgentSpecPath, k as sanitizeArtifactName, l as createAgentTemplateSpec, m as isAgentRunRecordLike, n as replayAgentRecordPath, o as resolveAgentLaunchTarget, p as formatAgentArgv, s as normalizeAgentFlowSpecWithConfig, u as loadAgentSpec, v as AGENT_MANIFEST_FILE_NAME, w as isAgentCassetteLike, x as readAgentManifestPath, y as agentManifestPath } from "./runner-1gYMz8D5.mjs";
|
|
3
3
|
import { a as sameArgv, i as diffCommandMaps, r as formatZodIssues } from "./manifest_files-DW80c1H7.mjs";
|
|
4
4
|
import { i as portableCliPath, n as mergeProcessEnv, o as relativeHref, s as samePath } from "./env-DPYHo-zH.mjs";
|
|
5
5
|
import { d as resolvePtyBackend, u as createDefaultPtyAdapter } from "./runner-BHXXwxYp.mjs";
|
|
6
|
-
import { a as resolveScriptManifestPath, c as relocateScriptManifestCommands, d as resolveScriptRunSummaryPath, f as runScriptPath, i as readScriptManifestPath, l as resolveManifestPrimaryPath$1, n as runAllScripts, o as validateScriptManifest, r as findScriptSummaryManifest, t as createPtywrightServer, u as readScriptRunSummaryPath } from "./server-
|
|
6
|
+
import { a as resolveScriptManifestPath, c as relocateScriptManifestCommands, d as resolveScriptRunSummaryPath, f as runScriptPath, i as readScriptManifestPath, l as resolveManifestPrimaryPath$1, n as runAllScripts, o as validateScriptManifest, r as findScriptSummaryManifest, t as createPtywrightServer, u as readScriptRunSummaryPath } from "./server-OujH4CEo.mjs";
|
|
7
7
|
import { c as createPtyCassetteReplay, i as formatPtyCassetteInspectLines, l as readPtyCassettePath, o as inspectPtyCassettePath, r as createPtyCassetteRecorder, t as wrapPtyLike, v as validatePtyCassette } from "./pty_like-DWIlWGgA.mjs";
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -418,6 +418,7 @@ const agentReplayFailedArtifactSchema = z.object({
|
|
|
418
418
|
kind: z.enum([
|
|
419
419
|
"terminal",
|
|
420
420
|
"dom",
|
|
421
|
+
"layout",
|
|
421
422
|
"screenshot"
|
|
422
423
|
]),
|
|
423
424
|
path: z.string().min(1),
|
|
@@ -1808,6 +1809,7 @@ async function replayRecordEntry(filePath, artifactsDir, options) {
|
|
|
1808
1809
|
try {
|
|
1809
1810
|
return await replayAgentRecordPath(filePath, {
|
|
1810
1811
|
artifactsDir,
|
|
1812
|
+
config: options.config,
|
|
1811
1813
|
headless: options.headless,
|
|
1812
1814
|
updateSnapshots: options.updateSnapshots
|
|
1813
1815
|
});
|
|
@@ -2023,6 +2025,7 @@ async function replayAllAgentRecords(options = {}) {
|
|
|
2023
2025
|
const artifactsDir = join(suiteDir, "tests", safeArtifactsDirName(relative(dir, filePath)));
|
|
2024
2026
|
const entryStartedAt = Date.now();
|
|
2025
2027
|
const result = await replayRecordEntry(filePath, artifactsDir, {
|
|
2028
|
+
config: options.config,
|
|
2026
2029
|
headless: options.headless ?? true,
|
|
2027
2030
|
updateSnapshots
|
|
2028
2031
|
});
|
|
@@ -2089,6 +2092,7 @@ async function checkAgentRegression(options = {}) {
|
|
|
2089
2092
|
validationAfter: emptyValidationResult(artifactsRoot)
|
|
2090
2093
|
});
|
|
2091
2094
|
const replay = await replayAllAgentRecords({
|
|
2095
|
+
config: options.config,
|
|
2092
2096
|
dir: cassetteDir,
|
|
2093
2097
|
artifactsRoot,
|
|
2094
2098
|
headless: options.headless ?? true,
|
|
@@ -2721,6 +2725,7 @@ async function runAgentRecord(args, context) {
|
|
|
2721
2725
|
}
|
|
2722
2726
|
async function runAgentCheck(args, context) {
|
|
2723
2727
|
return printAgentCheckResult(await checkAgentRegression({
|
|
2728
|
+
config: context.config,
|
|
2724
2729
|
cassetteDir: args.path ?? args.cassetteDir ?? resolveAgentConfigPath(context.config, context.config?.agent?.cassetteDir),
|
|
2725
2730
|
artifactsRoot: args.artifactsRoot ?? resolveAgentConfigPath(context.config, context.config?.agent?.artifactsRoot),
|
|
2726
2731
|
headless: context.headless,
|
|
@@ -2748,6 +2753,7 @@ async function runAgentRerun(args, context) {
|
|
|
2748
2753
|
}
|
|
2749
2754
|
async function runAgentReplayAll(args, context) {
|
|
2750
2755
|
return printAgentReplayAllResult(await replayAllAgentRecords({
|
|
2756
|
+
config: context.config,
|
|
2751
2757
|
dir: args.path ?? resolveAgentConfigPath(context.config, context.config?.agent?.cassetteDir),
|
|
2752
2758
|
artifactsRoot: args.artifactsRoot ?? resolveAgentConfigPath(context.config, context.config?.agent?.artifactsRoot),
|
|
2753
2759
|
headless: context.headless,
|
package/dist/cli.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as main } from "./cli-
|
|
1
|
+
import { t as main } from "./cli-DVDqUtha.mjs";
|
|
2
2
|
export { main };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createPtywrightServer } from "./server-
|
|
1
|
+
import { t as createPtywrightServer } from "./server-OujH4CEo.mjs";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
const { server, sessions } = createPtywrightServer();
|
package/dist/mcp.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createPtywrightServer } from "./server-
|
|
1
|
+
import { t as createPtywrightServer } from "./server-OujH4CEo.mjs";
|
|
2
2
|
export { createPtywrightServer };
|
|
@@ -36,6 +36,9 @@ function normalizeTerminalText(input, rules = []) {
|
|
|
36
36
|
function normalizeDomSnapshot(input, rules = []) {
|
|
37
37
|
return applyAgentMasks(input.replace(/\sdata-v-[a-z0-9-]+="[^"]*"/g, "").replace(/\sstyle="[^"]*--term-(?:cell-width|row-height):[^"]*"/g, "").replace(/\s+/g, " ").replace(/>\s+</g, "><").replace(/<div class="[^"]*\bterm-row\b[^"]*\bterm-scrollback-row\b[^"]*"[^>]*><span[^>]*><\/span><\/div>/g, "").trim(), rules, { replacement: escapeHtmlText });
|
|
38
38
|
}
|
|
39
|
+
function normalizeReplayDom(input, rules = []) {
|
|
40
|
+
return applyAgentMasks(input.replace(/\r\n?/g, "\n"), rules, { replacement: escapeHtmlText });
|
|
41
|
+
}
|
|
39
42
|
function sanitizeArtifactName(input) {
|
|
40
43
|
return input.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "artifact";
|
|
41
44
|
}
|
|
@@ -144,6 +147,7 @@ const snapshotStepSchema = z.object({
|
|
|
144
147
|
targets: z.array(z.enum([
|
|
145
148
|
"terminal",
|
|
146
149
|
"dom",
|
|
150
|
+
"layout",
|
|
147
151
|
"screenshot"
|
|
148
152
|
])).optional(),
|
|
149
153
|
fullPage: z.boolean().optional()
|
|
@@ -468,6 +472,7 @@ const agentManifestFileKindSchema = z.enum([
|
|
|
468
472
|
"report",
|
|
469
473
|
"terminal",
|
|
470
474
|
"dom",
|
|
475
|
+
"layout",
|
|
471
476
|
"screenshot",
|
|
472
477
|
"diff"
|
|
473
478
|
]);
|
|
@@ -595,6 +600,7 @@ const agentRunArtifactSchema = z.object({
|
|
|
595
600
|
kind: z.enum([
|
|
596
601
|
"terminal",
|
|
597
602
|
"dom",
|
|
603
|
+
"layout",
|
|
598
604
|
"screenshot"
|
|
599
605
|
]),
|
|
600
606
|
path: z.string().min(1),
|
|
@@ -879,8 +885,8 @@ function errorFields(error) {
|
|
|
879
885
|
//#endregion
|
|
880
886
|
//#region src/agent/aitty_report_assets.ts
|
|
881
887
|
function prepareAittyReportAssets(context) {
|
|
882
|
-
const sources = resolveAittyReportAssetSources(
|
|
883
|
-
if (!existsSync(sources.scriptSource) || !existsSync(sources.styleSource)) throw new Error("@aitty/snapshot report assets are missing.
|
|
888
|
+
const sources = resolveAittyReportAssetSources();
|
|
889
|
+
if (!existsSync(sources.scriptSource) || !existsSync(sources.styleSource)) throw new Error("@aitty/snapshot report assets are missing. Reinstall ptywright dependencies before generating reports.");
|
|
884
890
|
const assetDir = join(context.artifactsDir, "assets");
|
|
885
891
|
const scriptPath = join(assetDir, "aitty-web-component.js");
|
|
886
892
|
const stylePath = join(assetDir, "aitty-terminal.css");
|
|
@@ -889,63 +895,25 @@ function prepareAittyReportAssets(context) {
|
|
|
889
895
|
copyFileSync(sources.styleSource, stylePath);
|
|
890
896
|
return {
|
|
891
897
|
scriptPath,
|
|
892
|
-
scriptType: sources.scriptType,
|
|
893
898
|
stylePath
|
|
894
899
|
};
|
|
895
900
|
}
|
|
896
|
-
function resolveAittyReportAssetSources(
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
}
|
|
901
|
-
const fallback = tryResolveAittyReportAssetSources(createRequire(import.meta.url));
|
|
902
|
-
if (fallback) return fallback;
|
|
903
|
-
throw new Error("@aitty/snapshot report assets are missing. Install @aitty/snapshot or run the package build before generating reports.");
|
|
904
|
-
}
|
|
905
|
-
function resolveAittyReportResolverBases(context) {
|
|
906
|
-
const candidates = [
|
|
907
|
-
findNearestPackageJson(dirname(resolve(context.flowPath))),
|
|
908
|
-
findNearestPackageJson(dirname(resolve(context.reportPath))),
|
|
909
|
-
findNearestPackageJson(dirname(resolve(context.artifactsDir))),
|
|
910
|
-
findNearestPackageJson(process.cwd())
|
|
911
|
-
].filter((path) => Boolean(path));
|
|
912
|
-
return Array.from(new Set(candidates));
|
|
913
|
-
}
|
|
914
|
-
function findNearestPackageJson(startDir) {
|
|
915
|
-
let currentDir = resolve(startDir);
|
|
916
|
-
while (true) {
|
|
917
|
-
const packagePath = join(currentDir, "package.json");
|
|
918
|
-
if (existsSync(packagePath)) return packagePath;
|
|
919
|
-
const parentDir = dirname(currentDir);
|
|
920
|
-
if (parentDir === currentDir) return null;
|
|
921
|
-
currentDir = parentDir;
|
|
922
|
-
}
|
|
901
|
+
function resolveAittyReportAssetSources() {
|
|
902
|
+
const sources = tryResolveAittyReportAssetSources(createRequire(import.meta.url));
|
|
903
|
+
if (!sources) throw new Error("@aitty/snapshot report assets are missing. Install @aitty/snapshot before generating reports.");
|
|
904
|
+
return sources;
|
|
923
905
|
}
|
|
924
906
|
function tryResolveAittyReportAssetSources(resolver) {
|
|
925
|
-
return tryResolveAittyPackageAssetSources(resolver, "@aitty/snapshot") ?? tryResolveAittyPackageAssetSources(resolver, "@aitty/browser");
|
|
926
|
-
}
|
|
927
|
-
function tryResolveAittyPackageAssetSources(resolver, packageName) {
|
|
928
907
|
let scriptSource;
|
|
929
|
-
let scriptType = "classic";
|
|
930
908
|
let styleSource;
|
|
931
909
|
try {
|
|
932
|
-
scriptSource = resolver.resolve(
|
|
933
|
-
|
|
934
|
-
try {
|
|
935
|
-
scriptSource = resolver.resolve(`${packageName}/web-component.js`);
|
|
936
|
-
scriptType = "module";
|
|
937
|
-
} catch {
|
|
938
|
-
return null;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
try {
|
|
942
|
-
styleSource = resolver.resolve(`${packageName}/style.css`);
|
|
910
|
+
scriptSource = resolver.resolve("@aitty/snapshot/web-component.global.js");
|
|
911
|
+
styleSource = resolver.resolve("@aitty/snapshot/style.css");
|
|
943
912
|
} catch {
|
|
944
913
|
return null;
|
|
945
914
|
}
|
|
946
915
|
return {
|
|
947
916
|
scriptSource,
|
|
948
|
-
scriptType,
|
|
949
917
|
styleSource
|
|
950
918
|
};
|
|
951
919
|
}
|
|
@@ -960,13 +928,12 @@ function relativeHref(fromPath, targetPath, artifactsDir) {
|
|
|
960
928
|
function resolveAittyPreviewAssets(previewPath, assets, artifactsDir) {
|
|
961
929
|
return {
|
|
962
930
|
scriptHref: relativeHref(previewPath, assets.scriptPath, artifactsDir),
|
|
963
|
-
scriptType: assets.scriptType,
|
|
964
931
|
styleHref: relativeHref(previewPath, assets.stylePath, artifactsDir)
|
|
965
932
|
};
|
|
966
933
|
}
|
|
967
934
|
function renderAittyPreviewAssetTags(assets) {
|
|
968
935
|
return ` <link rel="stylesheet" href="${escapeAttribute(assets.styleHref)}" />
|
|
969
|
-
<script
|
|
936
|
+
<script src="${escapeAttribute(assets.scriptHref)}"><\/script>
|
|
970
937
|
`;
|
|
971
938
|
}
|
|
972
939
|
function renderAittyPreviewBody(args) {
|
|
@@ -1001,6 +968,7 @@ function renderAittyPreviewCss(viewOptions) {
|
|
|
1001
968
|
//#region src/agent/report_artifact_paths.ts
|
|
1002
969
|
function artifactViewerPath(artifact) {
|
|
1003
970
|
if (artifact.kind === "terminal") return artifact.path.endsWith(".terminal.txt") ? artifact.path.replace(/\.terminal\.txt$/, ".terminal.viewer.html") : `${artifact.path}.viewer.html`;
|
|
971
|
+
if (artifact.kind === "layout") return artifact.path.endsWith(".layout.txt") ? artifact.path.replace(/\.layout\.txt$/, ".layout.viewer.html") : `${artifact.path}.viewer.html`;
|
|
1004
972
|
if (artifact.kind === "dom") return artifact.path.endsWith(".dom.html") ? artifact.path.replace(/\.dom\.html$/, ".dom.viewer.html") : `${artifact.path}.viewer.html`;
|
|
1005
973
|
return null;
|
|
1006
974
|
}
|
|
@@ -1546,6 +1514,28 @@ function normalizeStringArray(value) {
|
|
|
1546
1514
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
1547
1515
|
}
|
|
1548
1516
|
//#endregion
|
|
1517
|
+
//#region src/agent/report_stable_frame_config.ts
|
|
1518
|
+
function resolveStableFrameConfig(config, flowName) {
|
|
1519
|
+
const stableFrames = config?.agent?.report?.stableFrames;
|
|
1520
|
+
const flowConfig = stableFrames?.flows?.[flowName];
|
|
1521
|
+
return {
|
|
1522
|
+
...stableFrames,
|
|
1523
|
+
...flowConfig,
|
|
1524
|
+
previewSource: flowConfig?.previewSource ?? stableFrames?.previewSource ?? "captured-dom",
|
|
1525
|
+
stableMs: flowConfig?.stableMs ?? stableFrames?.stableMs ?? 200,
|
|
1526
|
+
theme: flowConfig?.theme ?? stableFrames?.theme ?? "dark",
|
|
1527
|
+
viewportOnly: flowConfig?.viewportOnly ?? stableFrames?.viewportOnly ?? false,
|
|
1528
|
+
viewportTargets: {
|
|
1529
|
+
...stableFrames?.viewportTargets,
|
|
1530
|
+
...flowConfig?.viewportTargets
|
|
1531
|
+
}
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function shouldUsePtyReplayStableFrameDomPreview(args) {
|
|
1535
|
+
const config = resolveStableFrameConfig(args.config, args.flowName);
|
|
1536
|
+
return config.enabled !== false && !config.skip && config.previewSource === "pty-replay";
|
|
1537
|
+
}
|
|
1538
|
+
//#endregion
|
|
1549
1539
|
//#region src/agent/report_view_options.ts
|
|
1550
1540
|
function isMobileViewport(viewport) {
|
|
1551
1541
|
return Boolean(viewport?.isMobile || viewport?.hasTouch || (viewport?.width ?? 9999) <= 720);
|
|
@@ -1557,8 +1547,11 @@ function resolveReportViewOptions(result, config) {
|
|
|
1557
1547
|
const themeArg = readFlagValueFromArgSets(launchArgSets, "--theme");
|
|
1558
1548
|
const fontSizeArg = readFlagValueFromArgSets(launchArgSets, "--font-size");
|
|
1559
1549
|
const lineHeightArg = readFlagValueFromArgSets(launchArgSets, "--line-height");
|
|
1560
|
-
const stableFrameConfig = resolveStableFrameConfig
|
|
1561
|
-
const themeOverride = ptyReplayArg &&
|
|
1550
|
+
const stableFrameConfig = resolveStableFrameConfig(config, result.name);
|
|
1551
|
+
const themeOverride = ptyReplayArg && shouldUsePtyReplayStableFrameDomPreview({
|
|
1552
|
+
config,
|
|
1553
|
+
flowName: result.name
|
|
1554
|
+
}) ? stableFrameConfig.theme : void 0;
|
|
1562
1555
|
return {
|
|
1563
1556
|
fontSize: parsePositiveNumber(fontSizeArg) ?? 15,
|
|
1564
1557
|
lineHeight: parsePositiveNumber(lineHeightArg) ?? 1.6,
|
|
@@ -1571,15 +1564,6 @@ function parsePositiveNumber(value) {
|
|
|
1571
1564
|
const parsed = Number(value);
|
|
1572
1565
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1573
1566
|
}
|
|
1574
|
-
function resolveStableFrameConfig$1(config, flowName) {
|
|
1575
|
-
const stableFrames = config?.agent?.report?.stableFrames;
|
|
1576
|
-
const flowConfig = stableFrames?.flows?.[flowName];
|
|
1577
|
-
return {
|
|
1578
|
-
enabled: flowConfig?.enabled ?? stableFrames?.enabled,
|
|
1579
|
-
skip: flowConfig?.skip ?? stableFrames?.skip,
|
|
1580
|
-
theme: flowConfig?.theme ?? stableFrames?.theme ?? "dark"
|
|
1581
|
-
};
|
|
1582
|
-
}
|
|
1583
1567
|
//#endregion
|
|
1584
1568
|
//#region src/agent/report_artifact_viewer.ts
|
|
1585
1569
|
function renderArtifactViewerHtml(args) {
|
|
@@ -1667,21 +1651,6 @@ ${body}
|
|
|
1667
1651
|
</body>
|
|
1668
1652
|
</html>`;
|
|
1669
1653
|
}
|
|
1670
|
-
function resolveStableFrameConfig(config, flowName) {
|
|
1671
|
-
const stableFrames = config?.agent?.report?.stableFrames;
|
|
1672
|
-
const flowConfig = stableFrames?.flows?.[flowName];
|
|
1673
|
-
return {
|
|
1674
|
-
...stableFrames,
|
|
1675
|
-
...flowConfig,
|
|
1676
|
-
stableMs: flowConfig?.stableMs ?? stableFrames?.stableMs ?? 200,
|
|
1677
|
-
theme: flowConfig?.theme ?? stableFrames?.theme ?? "dark",
|
|
1678
|
-
viewportOnly: flowConfig?.viewportOnly ?? stableFrames?.viewportOnly ?? false,
|
|
1679
|
-
viewportTargets: {
|
|
1680
|
-
...stableFrames?.viewportTargets,
|
|
1681
|
-
...flowConfig?.viewportTargets
|
|
1682
|
-
}
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
1654
|
function resolvePtyReplayPath(replayPathArg, config) {
|
|
1686
1655
|
if (isAbsolute(replayPathArg)) return replayPathArg;
|
|
1687
1656
|
return resolve(config?.rootDir ?? process.cwd(), replayPathArg);
|
|
@@ -1922,27 +1891,61 @@ function isCodeLikeText(text) {
|
|
|
1922
1891
|
return /[{}()[\];=<>]/.test(text) || /\b(?:async|await|class|const|def|export|from|function|if|import|interface|let|return|type|var)\b/.test(text) || /(?:^|\s)(?:--?[a-z][\w-]*|#[\w-]+|\/[A-Za-z0-9._/-]+)(?:\s|$)/.test(text);
|
|
1923
1892
|
}
|
|
1924
1893
|
function wrapStableLogicalLine(line, targetCols) {
|
|
1925
|
-
|
|
1894
|
+
const cols = Math.max(1, targetCols);
|
|
1895
|
+
if (cellsDisplayWidth(line.cells) <= cols) return [line];
|
|
1926
1896
|
const rows = [];
|
|
1927
|
-
let
|
|
1928
|
-
|
|
1929
|
-
|
|
1897
|
+
let remaining = [...line.cells];
|
|
1898
|
+
while (remaining.length > 0) {
|
|
1899
|
+
const chunk = [];
|
|
1900
|
+
let usedCols = 0;
|
|
1901
|
+
let consumed = 0;
|
|
1902
|
+
for (const cell of remaining) {
|
|
1903
|
+
if (chunk.length > 0 && usedCols + cell.width > cols) break;
|
|
1904
|
+
chunk.push(cell);
|
|
1905
|
+
usedCols += cell.width;
|
|
1906
|
+
consumed += 1;
|
|
1907
|
+
if (usedCols >= cols) break;
|
|
1908
|
+
}
|
|
1909
|
+
if (chunk.length === 0) {
|
|
1910
|
+
chunk.push(remaining[0] ?? {
|
|
1911
|
+
style: DEFAULT_STYLE,
|
|
1912
|
+
text: "",
|
|
1913
|
+
width: 1
|
|
1914
|
+
});
|
|
1915
|
+
consumed = 1;
|
|
1916
|
+
}
|
|
1917
|
+
let rowCells = chunk;
|
|
1918
|
+
let nextRemaining = remaining.slice(consumed);
|
|
1919
|
+
const breakIndex = findStableLineBreakIndex(chunk);
|
|
1920
|
+
if (breakIndex > 0) {
|
|
1921
|
+
rowCells = chunk.slice(0, breakIndex);
|
|
1922
|
+
nextRemaining = [...chunk.slice(breakIndex + 1), ...nextRemaining];
|
|
1923
|
+
}
|
|
1930
1924
|
rows.push({
|
|
1931
|
-
cells,
|
|
1925
|
+
cells: trimTrailingStableCells(rowCells),
|
|
1932
1926
|
live: line.live,
|
|
1933
1927
|
physicalRows: 1
|
|
1934
1928
|
});
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
if (
|
|
1929
|
+
remaining = dropLeadingStableSpaces(nextRemaining);
|
|
1930
|
+
}
|
|
1931
|
+
return rows.length > 0 ? rows : [line];
|
|
1932
|
+
}
|
|
1933
|
+
function findStableLineBreakIndex(cells) {
|
|
1934
|
+
for (let index = cells.length - 2; index > 0; index -= 1) {
|
|
1935
|
+
const cell = cells[index];
|
|
1936
|
+
if (cell?.text === " " && cell.width === 1) return index;
|
|
1943
1937
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1938
|
+
return -1;
|
|
1939
|
+
}
|
|
1940
|
+
function trimTrailingStableCells(cells) {
|
|
1941
|
+
let end = cells.length;
|
|
1942
|
+
while (end > 0 && cells[end - 1]?.text === " " && cells[end - 1]?.width === 1) end -= 1;
|
|
1943
|
+
return cells.slice(0, end);
|
|
1944
|
+
}
|
|
1945
|
+
function dropLeadingStableSpaces(cells) {
|
|
1946
|
+
let start = 0;
|
|
1947
|
+
while (start < cells.length && cells[start]?.text === " " && cells[start]?.width === 1) start += 1;
|
|
1948
|
+
return cells.slice(start);
|
|
1946
1949
|
}
|
|
1947
1950
|
function renderStableFrameRow(line, lineCols, lineIndex) {
|
|
1948
1951
|
return `<div class="${line.live ? "term-row" : "term-row term-scrollback-row"}"${line.live ? ` data-aitty-live-grid-row="${lineIndex + 1}"` : ""} data-aitty-line-cols="${lineCols}">${renderStableFrameCells(line.cells, lineCols)}</div>`;
|
|
@@ -2110,13 +2113,13 @@ async function writeArtifactViewerPages(result, options = {}) {
|
|
|
2110
2113
|
});
|
|
2111
2114
|
}
|
|
2112
2115
|
const domPreviewPathsBySnapshot = new Map(readableArtifacts.filter(({ artifact }) => artifact.kind === "dom").map(({ artifact }) => [artifactSnapshotKey(artifact), artifactDomPreviewPath(artifact)]));
|
|
2113
|
-
const aittyAssets = domPreviewPathsBySnapshot.size > 0 ? prepareAittyReportAssets({
|
|
2114
|
-
artifactsDir: result.artifactsDir,
|
|
2115
|
-
flowPath: result.flowPath,
|
|
2116
|
-
reportPath: result.reportPath
|
|
2117
|
-
}) : null;
|
|
2116
|
+
const aittyAssets = domPreviewPathsBySnapshot.size > 0 ? prepareAittyReportAssets({ artifactsDir: result.artifactsDir }) : null;
|
|
2118
2117
|
const writtenDomPreviewPaths = /* @__PURE__ */ new Set();
|
|
2119
|
-
const
|
|
2118
|
+
const usePtyReplayStableFrameDomPreview = shouldUsePtyReplayStableFrameDomPreview({
|
|
2119
|
+
config: options.config,
|
|
2120
|
+
flowName: result.name
|
|
2121
|
+
});
|
|
2122
|
+
const ptyReplayStableFrame = aittyAssets && usePtyReplayStableFrameDomPreview ? await extractPtyReplayStableFrameForReport({
|
|
2120
2123
|
config: options.config,
|
|
2121
2124
|
result
|
|
2122
2125
|
}) : null;
|
|
@@ -2213,6 +2216,7 @@ function renderAgentReportArtifactsCss() {
|
|
|
2213
2216
|
return ` .artifacts {
|
|
2214
2217
|
display: grid;
|
|
2215
2218
|
gap: 14px;
|
|
2219
|
+
min-width: 0;
|
|
2216
2220
|
}
|
|
2217
2221
|
.artifact {
|
|
2218
2222
|
display: grid;
|
|
@@ -2221,12 +2225,14 @@ function renderAgentReportArtifactsCss() {
|
|
|
2221
2225
|
border-radius: 8px;
|
|
2222
2226
|
padding: 12px;
|
|
2223
2227
|
background: var(--panel);
|
|
2228
|
+
min-width: 0;
|
|
2224
2229
|
}
|
|
2225
2230
|
.artifact-summary {
|
|
2226
2231
|
display: grid;
|
|
2227
|
-
grid-template-columns: auto minmax(0, 1fr) minmax(
|
|
2232
|
+
grid-template-columns: auto minmax(0, 1fr) minmax(0, auto);
|
|
2228
2233
|
gap: 14px;
|
|
2229
2234
|
align-items: start;
|
|
2235
|
+
min-width: 0;
|
|
2230
2236
|
}
|
|
2231
2237
|
.artifact-meta {
|
|
2232
2238
|
display: grid;
|
|
@@ -2237,19 +2243,23 @@ function renderAgentReportArtifactsCss() {
|
|
|
2237
2243
|
display: flex;
|
|
2238
2244
|
flex-wrap: wrap;
|
|
2239
2245
|
gap: 8px 12px;
|
|
2246
|
+
min-width: 0;
|
|
2240
2247
|
}
|
|
2241
2248
|
.artifact a {
|
|
2242
2249
|
color: var(--focus);
|
|
2243
2250
|
font-weight: 700;
|
|
2244
2251
|
text-decoration: none;
|
|
2252
|
+
overflow-wrap: anywhere;
|
|
2245
2253
|
}
|
|
2246
2254
|
.artifact code {
|
|
2247
2255
|
color: var(--muted);
|
|
2248
2256
|
overflow-wrap: anywhere;
|
|
2257
|
+
min-width: 0;
|
|
2249
2258
|
}
|
|
2250
2259
|
.artifact-hash {
|
|
2251
2260
|
justify-self: end;
|
|
2252
2261
|
text-align: right;
|
|
2262
|
+
max-width: 100%;
|
|
2253
2263
|
}
|
|
2254
2264
|
.badge {
|
|
2255
2265
|
justify-self: start;
|
|
@@ -2304,6 +2314,7 @@ function renderAgentReportBaseCss() {
|
|
|
2304
2314
|
margin: 0;
|
|
2305
2315
|
background: var(--bg);
|
|
2306
2316
|
color: var(--ink);
|
|
2317
|
+
overflow-wrap: anywhere;
|
|
2307
2318
|
}
|
|
2308
2319
|
main {
|
|
2309
2320
|
display: grid;
|
|
@@ -2311,6 +2322,10 @@ function renderAgentReportBaseCss() {
|
|
|
2311
2322
|
width: min(1180px, calc(100vw - 32px));
|
|
2312
2323
|
margin: 0 auto;
|
|
2313
2324
|
padding: 32px 0 48px;
|
|
2325
|
+
min-width: 0;
|
|
2326
|
+
}
|
|
2327
|
+
main > * {
|
|
2328
|
+
min-width: 0;
|
|
2314
2329
|
}
|
|
2315
2330
|
header {
|
|
2316
2331
|
display: grid;
|
|
@@ -2319,27 +2334,37 @@ function renderAgentReportBaseCss() {
|
|
|
2319
2334
|
align-items: start;
|
|
2320
2335
|
border-bottom: 1px solid var(--line);
|
|
2321
2336
|
padding-bottom: 24px;
|
|
2337
|
+
min-width: 0;
|
|
2338
|
+
}
|
|
2339
|
+
header > * {
|
|
2340
|
+
min-width: 0;
|
|
2322
2341
|
}
|
|
2323
2342
|
h1 {
|
|
2324
2343
|
margin: 0;
|
|
2325
2344
|
font-size: 28px;
|
|
2326
2345
|
line-height: 1.15;
|
|
2327
2346
|
letter-spacing: 0;
|
|
2347
|
+
max-width: 100%;
|
|
2348
|
+
overflow-wrap: anywhere;
|
|
2328
2349
|
}
|
|
2329
2350
|
h2 {
|
|
2330
2351
|
margin: 0;
|
|
2331
2352
|
font-size: 18px;
|
|
2332
2353
|
line-height: 1.25;
|
|
2354
|
+
overflow-wrap: anywhere;
|
|
2333
2355
|
}
|
|
2334
2356
|
.meta {
|
|
2335
2357
|
display: flex;
|
|
2336
2358
|
flex-wrap: wrap;
|
|
2337
2359
|
gap: 8px;
|
|
2338
2360
|
margin-top: 12px;
|
|
2361
|
+
min-width: 0;
|
|
2339
2362
|
}
|
|
2340
2363
|
.pill,
|
|
2341
2364
|
.status {
|
|
2342
2365
|
display: inline-flex;
|
|
2366
|
+
max-width: 100%;
|
|
2367
|
+
min-width: 0;
|
|
2343
2368
|
min-height: 32px;
|
|
2344
2369
|
align-items: center;
|
|
2345
2370
|
border: 1px solid var(--line);
|
|
@@ -2347,6 +2372,7 @@ function renderAgentReportBaseCss() {
|
|
|
2347
2372
|
padding: 0 12px;
|
|
2348
2373
|
color: var(--muted);
|
|
2349
2374
|
font-size: 13px;
|
|
2375
|
+
overflow-wrap: anywhere;
|
|
2350
2376
|
}
|
|
2351
2377
|
.status {
|
|
2352
2378
|
font-weight: 700;
|
|
@@ -2366,6 +2392,14 @@ function renderAgentReportBaseCss() {
|
|
|
2366
2392
|
border-radius: 8px;
|
|
2367
2393
|
background: var(--panel);
|
|
2368
2394
|
padding: 18px;
|
|
2395
|
+
min-width: 0;
|
|
2396
|
+
}
|
|
2397
|
+
.panel > * {
|
|
2398
|
+
min-width: 0;
|
|
2399
|
+
}
|
|
2400
|
+
.panel p {
|
|
2401
|
+
margin: 0;
|
|
2402
|
+
max-width: 100%;
|
|
2369
2403
|
}
|
|
2370
2404
|
@media (max-width: 720px) {
|
|
2371
2405
|
main {
|
|
@@ -2386,15 +2420,18 @@ function renderAgentReportCommandsCss() {
|
|
|
2386
2420
|
return ` .commands {
|
|
2387
2421
|
display: grid;
|
|
2388
2422
|
gap: 10px;
|
|
2423
|
+
min-width: 0;
|
|
2389
2424
|
}
|
|
2390
2425
|
.command {
|
|
2391
2426
|
display: grid;
|
|
2392
2427
|
gap: 5px;
|
|
2428
|
+
min-width: 0;
|
|
2393
2429
|
}
|
|
2394
2430
|
.command span {
|
|
2395
2431
|
color: var(--muted);
|
|
2396
2432
|
font-size: 13px;
|
|
2397
2433
|
font-weight: 700;
|
|
2434
|
+
overflow-wrap: anywhere;
|
|
2398
2435
|
}
|
|
2399
2436
|
.artifact code,
|
|
2400
2437
|
pre {
|
|
@@ -2402,6 +2439,8 @@ function renderAgentReportCommandsCss() {
|
|
|
2402
2439
|
}
|
|
2403
2440
|
pre {
|
|
2404
2441
|
overflow: auto;
|
|
2442
|
+
max-width: 100%;
|
|
2443
|
+
min-width: 0;
|
|
2405
2444
|
margin: 0;
|
|
2406
2445
|
border-radius: 8px;
|
|
2407
2446
|
background: oklch(20% 0.015 230);
|
|
@@ -2415,25 +2454,29 @@ function renderAgentReportCommandsCss() {
|
|
|
2415
2454
|
function renderAgentReportSummaryCss() {
|
|
2416
2455
|
return ` .summary {
|
|
2417
2456
|
display: grid;
|
|
2418
|
-
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
2457
|
+
grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
|
|
2419
2458
|
gap: 12px;
|
|
2459
|
+
min-width: 0;
|
|
2420
2460
|
}
|
|
2421
2461
|
.metric {
|
|
2422
2462
|
border: 1px solid var(--line);
|
|
2423
2463
|
border-radius: 8px;
|
|
2424
2464
|
padding: 14px;
|
|
2425
2465
|
background: color-mix(in oklch, var(--panel) 82%, var(--bg));
|
|
2466
|
+
min-width: 0;
|
|
2426
2467
|
}
|
|
2427
2468
|
.metric strong {
|
|
2428
2469
|
display: block;
|
|
2429
2470
|
font-size: 24px;
|
|
2430
2471
|
line-height: 1.1;
|
|
2472
|
+
overflow-wrap: anywhere;
|
|
2431
2473
|
}
|
|
2432
2474
|
.metric span {
|
|
2433
2475
|
display: block;
|
|
2434
2476
|
margin-top: 4px;
|
|
2435
2477
|
color: var(--muted);
|
|
2436
2478
|
font-size: 13px;
|
|
2479
|
+
overflow-wrap: anywhere;
|
|
2437
2480
|
}`;
|
|
2438
2481
|
}
|
|
2439
2482
|
//#endregion
|
|
@@ -2909,15 +2952,101 @@ async function waitForStableDom(page, args) {
|
|
|
2909
2952
|
throw new Error(`timed out waiting for stable terminal DOM`);
|
|
2910
2953
|
}
|
|
2911
2954
|
async function readTerminalText(page) {
|
|
2912
|
-
const text = await page
|
|
2955
|
+
const text = await readTerminalProjection(page, "text");
|
|
2956
|
+
if (text === null) throw new Error("terminal root is not attached");
|
|
2957
|
+
return text;
|
|
2958
|
+
}
|
|
2959
|
+
async function readTerminalLayout(page) {
|
|
2960
|
+
const layout = await readTerminalProjection(page, "layout");
|
|
2961
|
+
if (layout === null) throw new Error("terminal root is not attached");
|
|
2962
|
+
return layout;
|
|
2963
|
+
}
|
|
2964
|
+
async function readTerminalProjection(page, mode) {
|
|
2965
|
+
return page.evaluate((projectionMode) => {
|
|
2913
2966
|
const node = document.querySelector("[data-terminal-root]");
|
|
2914
2967
|
if (!node) return null;
|
|
2915
2968
|
const rows = Array.from(node.querySelectorAll(".term-grid .term-row"));
|
|
2916
|
-
if (
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2969
|
+
if (projectionMode === "text") {
|
|
2970
|
+
if (rows.length > 0) return rows.map((row) => serializeTerminalRowText(row)).join("\n");
|
|
2971
|
+
return node.textContent ?? "";
|
|
2972
|
+
}
|
|
2973
|
+
return serializeTerminalLayout(node);
|
|
2974
|
+
function serializeTerminalLayout(root) {
|
|
2975
|
+
const grid = root.querySelector(".term-grid");
|
|
2976
|
+
const target = grid ?? root;
|
|
2977
|
+
const lines = [`# terminal-layout v1 cols=${readElementInteger(grid, "data-cols") ?? "unknown"} rows=${readElementInteger(grid, "data-rows") ?? "unknown"}`];
|
|
2978
|
+
for (const child of Array.from(target.children)) serializeTerminalLayoutElement(child, "", lines);
|
|
2979
|
+
return lines.join("\n");
|
|
2980
|
+
}
|
|
2981
|
+
function serializeTerminalLayoutElement(element, indent, lines) {
|
|
2982
|
+
if (element.classList.contains("term-wide-row-block")) {
|
|
2983
|
+
lines.push(`${indent}wide-block kind=${JSON.stringify(readWideBlockKind(element))} cols=${readWideBlockCols(element) ?? "unknown"}`);
|
|
2984
|
+
for (const child of Array.from(element.children)) serializeTerminalLayoutElement(child, `${indent} `, lines);
|
|
2985
|
+
lines.push(`${indent}end-wide-block`);
|
|
2986
|
+
return;
|
|
2987
|
+
}
|
|
2988
|
+
if (element.classList.contains("term-row")) {
|
|
2989
|
+
lines.push(`${indent}row cols=${readElementInteger(element, "data-aitty-line-cols") ?? "unknown"} text=${JSON.stringify(serializeTerminalRowText(element))}`);
|
|
2990
|
+
return;
|
|
2991
|
+
}
|
|
2992
|
+
for (const child of Array.from(element.children)) serializeTerminalLayoutElement(child, indent, lines);
|
|
2993
|
+
}
|
|
2994
|
+
function readWideBlockKind(element) {
|
|
2995
|
+
if (!(element instanceof HTMLElement)) return "wide";
|
|
2996
|
+
return element.dataset.aittyWideBlockKind || "wide";
|
|
2997
|
+
}
|
|
2998
|
+
function readWideBlockCols(element) {
|
|
2999
|
+
if (!(element instanceof HTMLElement)) return null;
|
|
3000
|
+
const styleCols = element.style.getPropertyValue("--aitty-wide-block-cols").trim();
|
|
3001
|
+
const cols = Number.parseInt(styleCols, 10);
|
|
3002
|
+
return Number.isFinite(cols) && cols > 0 ? cols : null;
|
|
3003
|
+
}
|
|
3004
|
+
function readElementInteger(element, attribute) {
|
|
3005
|
+
const raw = element?.getAttribute(attribute) ?? "";
|
|
3006
|
+
const value = Number.parseInt(raw, 10);
|
|
3007
|
+
return Number.isFinite(value) && value >= 0 ? value : null;
|
|
3008
|
+
}
|
|
3009
|
+
function serializeTerminalRowText(row) {
|
|
3010
|
+
let text = "";
|
|
3011
|
+
for (const child of Array.from(row.childNodes)) text += serializeTerminalNodeText(child);
|
|
3012
|
+
return text.trimEnd();
|
|
3013
|
+
}
|
|
3014
|
+
function serializeTerminalNodeText(node) {
|
|
3015
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
3016
|
+
const text = normalizeTerminalTextSegment(node.textContent ?? "");
|
|
3017
|
+
return text.trim().length === 0 ? "" : text;
|
|
3018
|
+
}
|
|
3019
|
+
if (!(node instanceof HTMLElement)) return "";
|
|
3020
|
+
const text = normalizeTerminalTextSegment(node.textContent ?? "");
|
|
3021
|
+
const cols = parseTerminalCellWidth(node);
|
|
3022
|
+
if (cols === null) return text;
|
|
3023
|
+
const width = terminalTextDisplayWidth(text);
|
|
3024
|
+
const padding = Math.max(0, cols - width);
|
|
3025
|
+
return text + " ".repeat(padding);
|
|
3026
|
+
}
|
|
3027
|
+
function normalizeTerminalTextSegment(text) {
|
|
3028
|
+
return text.replace(/\u00a0/g, " ");
|
|
3029
|
+
}
|
|
3030
|
+
function parseTerminalCellWidth(element) {
|
|
3031
|
+
const width = element.style.getPropertyValue("width");
|
|
3032
|
+
if (/^var\(--term-cell-width\b/.test(width)) return 1;
|
|
3033
|
+
const calcMatch = /calc\(\s*var\(--term-cell-width[^)]*\)\s*\*\s*(\d+(?:\.\d+)?)\s*\)/.exec(width);
|
|
3034
|
+
if (!calcMatch) return null;
|
|
3035
|
+
const cols = Number.parseFloat(calcMatch[1] ?? "");
|
|
3036
|
+
return Number.isFinite(cols) && cols > 0 ? Math.round(cols) : null;
|
|
3037
|
+
}
|
|
3038
|
+
function terminalTextDisplayWidth(text) {
|
|
3039
|
+
let width = 0;
|
|
3040
|
+
for (const char of text) {
|
|
3041
|
+
if (/[\u0300-\u036f]/u.test(char)) continue;
|
|
3042
|
+
width += isWideTerminalChar(char) ? 2 : 1;
|
|
3043
|
+
}
|
|
3044
|
+
return width;
|
|
3045
|
+
}
|
|
3046
|
+
function isWideTerminalChar(char) {
|
|
3047
|
+
return /[\u1100-\u115f\u2329\u232a\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe10-\ufe19\ufe30-\ufe6f\uff00-\uff60\uffe0-\uffe6]/u.test(char) || /\p{Extended_Pictographic}/u.test(char);
|
|
3048
|
+
}
|
|
3049
|
+
}, mode);
|
|
2921
3050
|
}
|
|
2922
3051
|
async function readTerminalDom(page) {
|
|
2923
3052
|
const dom = await readTerminalDomIfPresent(page);
|
|
@@ -2964,6 +3093,19 @@ async function captureSnapshotStep(ctx, step) {
|
|
|
2964
3093
|
});
|
|
2965
3094
|
continue;
|
|
2966
3095
|
}
|
|
3096
|
+
if (target === "layout") {
|
|
3097
|
+
const layout = normalizeTerminalText(await readTerminalLayout(ctx.page), ctx.masks);
|
|
3098
|
+
await writeComparableArtifact(ctx, {
|
|
3099
|
+
name: step.name,
|
|
3100
|
+
kind: "layout",
|
|
3101
|
+
relativePath: `${base}.layout.txt`,
|
|
3102
|
+
baselineRelativePath: `${base}.layout.snap.txt`,
|
|
3103
|
+
diffRelativePath: `${base}.layout.diff.txt`,
|
|
3104
|
+
content: layout + "\n",
|
|
3105
|
+
compare: step.compare ?? true
|
|
3106
|
+
});
|
|
3107
|
+
continue;
|
|
3108
|
+
}
|
|
2967
3109
|
const screenshotPath = join(ctx.artifactsDir, `${base}.png`);
|
|
2968
3110
|
await ctx.page.screenshot({
|
|
2969
3111
|
path: screenshotPath,
|
|
@@ -3123,7 +3265,7 @@ async function captureCassetteFrame(ctx, frame) {
|
|
|
3123
3265
|
stepIndex: frame.stepIndex,
|
|
3124
3266
|
stepType: frame.stepType,
|
|
3125
3267
|
terminalText: normalizeTerminalText(await readTerminalText(ctx.page), ctx.masks),
|
|
3126
|
-
dom:
|
|
3268
|
+
dom: normalizeReplayDom(await readTerminalDom(ctx.page), ctx.masks),
|
|
3127
3269
|
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3128
3270
|
});
|
|
3129
3271
|
}
|
package/package.json
CHANGED
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"properties": {
|
|
130
130
|
"name": { "type": "string", "minLength": 1 },
|
|
131
131
|
"viewport": { "type": "string", "minLength": 1 },
|
|
132
|
-
"kind": { "type": "string", "enum": ["terminal", "dom", "screenshot"] },
|
|
132
|
+
"kind": { "type": "string", "enum": ["terminal", "dom", "layout", "screenshot"] },
|
|
133
133
|
"path": { "type": "string", "minLength": 1 },
|
|
134
134
|
"baselinePath": { "type": "string", "minLength": 1 },
|
|
135
135
|
"diffPath": { "type": "string", "minLength": 1 },
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"properties": {
|
|
114
114
|
"name": { "type": "string", "minLength": 1 },
|
|
115
115
|
"viewport": { "type": "string", "minLength": 1 },
|
|
116
|
-
"kind": { "type": "string", "enum": ["terminal", "dom", "screenshot"] },
|
|
116
|
+
"kind": { "type": "string", "enum": ["terminal", "dom", "layout", "screenshot"] },
|
|
117
117
|
"path": { "type": "string", "minLength": 1 },
|
|
118
118
|
"baselinePath": { "type": "string", "minLength": 1 },
|
|
119
119
|
"diffPath": { "type": "string", "minLength": 1 },
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"compare": { "type": "boolean" },
|
|
124
124
|
"targets": {
|
|
125
125
|
"type": "array",
|
|
126
|
-
"items": { "type": "string", "enum": ["terminal", "dom", "screenshot"] }
|
|
126
|
+
"items": { "type": "string", "enum": ["terminal", "dom", "layout", "screenshot"] }
|
|
127
127
|
},
|
|
128
128
|
"fullPage": { "type": "boolean" }
|
|
129
129
|
}
|