Files
tutti/tools/scripts/agent-gui-presentation-performance-policy.test.mjs
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

155 lines
4.7 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
agentGuiPresentationStylesheet,
analyzeAgentGuiPresentationCss,
countInlineCompositorHints,
countPresentationSchedulers,
hasPresentationWorkReason,
isInlineCompositorHintLine,
isPresentationSchedulerLine,
validatePresentationHintReasons
} from "./agent-gui-presentation-performance-policy.mjs";
test("finds persistent compositor hints and infinite animations outside keyframes", () => {
const source = `
.viewer {
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
will-change: opacity, transform;
animation: pulse 1s linear infinite;
}
@keyframes pulse {
from { transform: translate3d(0, 1px, 0); }
to { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
.viewer { will-change: auto; }
}
`;
const result = analyzeAgentGuiPresentationCss(
"packages/agent/gui/view.css",
source
);
assert.deepEqual(
result.hints.map(({ property }) => property),
["transform", "backface-visibility", "will-change", "animation"]
);
assert.equal(result.violations.length, 0);
});
test("rejects transition all but permits explicit transition properties", () => {
const result = analyzeAgentGuiPresentationCss(
"packages/agent/gui/view.css",
`
.bad { transition: all 180ms ease; }
.also-bad { transition-property: opacity, all; }
.good { transition: opacity 180ms ease, transform 180ms ease; }
`
);
assert.deepEqual(
result.violations.map(({ rule }) => rule),
["no-transition-all", "no-transition-all"]
);
});
test("requires the hidden and inactive AgentGUI pruning declarations", () => {
const missing = analyzeAgentGuiPresentationCss(
agentGuiPresentationStylesheet,
".unrelated { color: red; }"
);
assert.equal(missing.missingRequiredDeclarations.length, 4);
const complete = analyzeAgentGuiPresentationCss(
agentGuiPresentationStylesheet,
`
.agent-gui-node__layout[data-agent-gui-visible="false"]
:where(*, *::before, *::after) {
animation-play-state: paused !important;
}
.agent-gui-node__layout[data-agent-gui-visible="false"] {
content-visibility: hidden;
}
.agent-gui-node__layout[data-agent-gui-active="false"]
.agent-gui-node__composer-prompt-tip-track,
.agent-gui-node__layout[data-agent-gui-active="false"]
.agent-gui-node__composer-prompt-tip-item {
animation: none;
will-change: auto;
}
`
);
assert.deepEqual(complete.missingRequiredDeclarations, []);
});
test("validates exact presentation-hint reasons and rejects stale reasons", () => {
const { hints } = analyzeAgentGuiPresentationCss(
"packages/agent/gui/view.css",
".viewer { will-change: transform; }"
);
const fingerprint = hints[0]?.fingerprint;
assert.ok(fingerprint);
assert.deepEqual(validatePresentationHintReasons(hints, {}), {
missing: [fingerprint],
stale: []
});
assert.deepEqual(
validatePresentationHintReasons(hints, {
[fingerprint]: "Mounted only while the zoom viewer is open"
}),
{ missing: [], stale: [] }
);
assert.deepEqual(
validatePresentationHintReasons(hints, {
stale: "Removed selector"
}),
{ missing: [fingerprint], stale: ["stale"] }
);
});
test("counts raw presentation schedulers without counting comments or strings", () => {
const source = `
// requestAnimationFrame(ignored)
const label = "new ResizeObserver(ignored)";
requestAnimationFrame(render);
requestIdleCallback(load);
const observer = new ResizeObserver(measure);
`;
assert.equal(countPresentationSchedulers(source), 3);
assert.equal(
isPresentationSchedulerLine("window.requestAnimationFrame(run)"),
true
);
assert.equal(isPresentationSchedulerLine("cancelAnimationFrame(id)"), false);
});
test("counts inline compositor hints including template transform values", () => {
const source = `
// willChange: "transform"
const style = {
willChange: "opacity, transform",
transform: \`translate3d(\${x}px, 0, 0)\`
};
`;
assert.equal(countInlineCompositorHints(source), 2);
assert.equal(isInlineCompositorHintLine('willChange: "transform"'), true);
assert.equal(
isInlineCompositorHintLine("transform: `translate3d(${x}px, 0, 0)`"),
true
);
});
test("requires a presentation-work reason on the same or previous line", () => {
const contentLines = [
"// presentation-work: one frame while the visible viewer is dragging",
"requestAnimationFrame(commit);",
"requestAnimationFrame(unexplained);"
];
assert.equal(hasPresentationWorkReason(contentLines, 2), true);
assert.equal(hasPresentationWorkReason(contentLines, 3), false);
});