fix: harden presentation trace evidence
This commit is contained in:
@@ -332,6 +332,14 @@ describe("useDemoTimeline", () => {
|
||||
|
||||
expect(result.current.state.phase).toBe("completed");
|
||||
expect(result.current.trace?.frames).toHaveLength(1);
|
||||
expect(mockedCallOperation.mock.calls.map(([operation]) => operation)).toEqual([
|
||||
"workflow.deployments.inspect",
|
||||
"workflow.runs.start",
|
||||
"workflow.runs.resume",
|
||||
"workflow.runs.trace",
|
||||
]);
|
||||
await act(async () => vi.advanceTimersByTimeAsync(1800));
|
||||
expect(mockedCallOperation).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
|
||||
it("shows a failed phase when a live operation rejects", async () => {
|
||||
@@ -441,6 +449,20 @@ describe("useDemoTimeline", () => {
|
||||
expect(result.current.state.events[result.current.state.appliedCount - 1]?.stage).toBe("run_resume");
|
||||
});
|
||||
|
||||
it("primes replay to trace_read with all canonical trace frames", () => {
|
||||
const { result } = renderHook(() => useDemoTimeline("http://127.0.0.1:8765/rpc", vi.fn()));
|
||||
|
||||
act(() => result.current.start("replay"));
|
||||
act(() => result.current.primeReplayToStage("trace_read"));
|
||||
|
||||
expect(result.current.state.events[result.current.state.appliedCount - 1]?.stage).toBe("trace_read");
|
||||
expect(result.current.trace?.frames.map((frame) => frame.nodeId)).toEqual([
|
||||
"list_documents",
|
||||
"review_issues",
|
||||
"finalise_report",
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not prime live timelines", () => {
|
||||
const { result } = renderHook(() => useDemoTimeline("http://127.0.0.1:8765/rpc", vi.fn()));
|
||||
|
||||
|
||||
@@ -366,6 +366,22 @@ describe("PresentationRoute", () => {
|
||||
|
||||
expect(await screen.findByRole("region", { name: /workflow trace frames/i })).toBeInTheDocument();
|
||||
expect(screen.queryByText("No trace frames captured.")).not.toBeInTheDocument();
|
||||
expect(screen.getByText("list_documents")).toBeInTheDocument();
|
||||
expect(screen.getByText("review_issues")).toBeInTheDocument();
|
||||
expect(screen.getByText("finalise_report")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps trace frames when navigating from output to trace", async () => {
|
||||
window.location.hash = "#scene/resume-output-evidence/output";
|
||||
const { PresentationRoute } = await import("./PresentationRoute.js");
|
||||
render(<PresentationRoute />);
|
||||
|
||||
expect(await screen.findByRole("region", { name: /workflow output report/i })).toBeInTheDocument();
|
||||
window.location.hash = "#scene/resume-output-evidence/trace";
|
||||
fireEvent(window, new Event("hashchange"));
|
||||
|
||||
expect(await screen.findByText("finalise_report")).toBeInTheDocument();
|
||||
expect(screen.queryByText("No trace frames captured.")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("navigates to Scene 8 request beat via hash", async () => {
|
||||
|
||||
@@ -232,6 +232,7 @@ describe("RunTraceFacts", () => {
|
||||
|
||||
expect(screen.getByText("list_documents")).toBeDefined();
|
||||
expect(screen.getByText("review_issues")).toBeDefined();
|
||||
expect(screen.getByText("2 captured")).toBeInTheDocument();
|
||||
expect(screen.getAllByText("captured as empty object").length).toBeGreaterThanOrEqual(2);
|
||||
});
|
||||
|
||||
|
||||
@@ -140,7 +140,9 @@ type RunTraceFactsProps = {
|
||||
|
||||
export const RunTraceFacts = ({ facts }: RunTraceFactsProps) => (
|
||||
<div className="run-facts-card run-trace-facts" role="region" aria-label="workflow trace proof">
|
||||
<h3>Trace frames</h3>
|
||||
<h3>
|
||||
Trace frames <span className="run-facts-count">{facts.trace.frames.length} captured</span>
|
||||
</h3>
|
||||
{facts.trace.frames.length === 0 ? (
|
||||
<p>No trace frames captured.</p>
|
||||
) : (
|
||||
|
||||
@@ -2206,6 +2206,13 @@
|
||||
color: var(--accent-cyan);
|
||||
}
|
||||
|
||||
.run-facts-count {
|
||||
margin-left: 0.4rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.72em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.run-facts-dl {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
@@ -1453,4 +1453,23 @@
|
||||
.guided-product-moment__trace-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.guided-product-moment[data-moment="trace"] .guided-product-moment__trace-grid {
|
||||
grid-template-rows: minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.guided-product-moment[data-moment="trace"] .run-facts-card[data-output-priority="summary"] {
|
||||
max-height: 7.25rem;
|
||||
overflow: auto;
|
||||
padding: 0.65rem 0.8rem;
|
||||
}
|
||||
|
||||
.guided-product-moment[data-moment="trace"] .run-facts-card[data-output-priority="summary"] h3 {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.guided-product-moment[data-moment="trace"] .run-facts-card[data-output-priority="summary"] .run-facts-dl {
|
||||
gap: 0.2rem 0.55rem;
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user