test: mark presentation focal surfaces
This commit is contained in:
@@ -15,7 +15,7 @@ type AuthoringPhaseVisualProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const InventoryVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "inventory" }> }) => (
|
const InventoryVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "inventory" }> }) => (
|
||||||
<section className="authoring-visual authoring-visual--inventory" aria-label="discovery evidence" data-presentation-surface="editorial">
|
<section className="authoring-visual authoring-visual--inventory" aria-label="discovery evidence" data-presentation-surface="editorial" data-visual-role="authoring-phase">
|
||||||
<div className="authoring-inventory__sources">
|
<div className="authoring-inventory__sources">
|
||||||
{visual.sources.map((source) => (
|
{visual.sources.map((source) => (
|
||||||
<div key={source}><Database aria-hidden="true" /><code>{source}</code></div>
|
<div key={source}><Database aria-hidden="true" /><code>{source}</code></div>
|
||||||
@@ -31,7 +31,7 @@ const InventoryVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection[
|
|||||||
);
|
);
|
||||||
|
|
||||||
const GraphVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "graph" }> }) => (
|
const GraphVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "graph" }> }) => (
|
||||||
<section className="authoring-visual authoring-visual--graph" aria-label="draft graph evidence" data-presentation-surface="editorial">
|
<section className="authoring-visual authoring-visual--graph" aria-label="draft graph evidence" data-presentation-surface="editorial" data-visual-role="authoring-phase">
|
||||||
<div className="authoring-graph__node"><Database aria-hidden="true" /><strong>{visual.nodes[0]}</strong></div>
|
<div className="authoring-graph__node"><Database aria-hidden="true" /><strong>{visual.nodes[0]}</strong></div>
|
||||||
<div className="authoring-graph__edge"><span>{visual.inputBinding}</span><ArrowRight aria-hidden="true" /></div>
|
<div className="authoring-graph__edge"><span>{visual.inputBinding}</span><ArrowRight aria-hidden="true" /></div>
|
||||||
<div className="authoring-graph__node"><Workflow aria-hidden="true" /><strong>{visual.nodes[1]}</strong></div>
|
<div className="authoring-graph__node"><Workflow aria-hidden="true" /><strong>{visual.nodes[1]}</strong></div>
|
||||||
@@ -41,7 +41,7 @@ const GraphVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["vis
|
|||||||
);
|
);
|
||||||
|
|
||||||
const RepairVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "repair" }> }) => (
|
const RepairVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "repair" }> }) => (
|
||||||
<section className="authoring-visual authoring-visual--repair" aria-label="validation repair evidence" data-presentation-surface="editorial">
|
<section className="authoring-visual authoring-visual--repair" aria-label="validation repair evidence" data-presentation-surface="editorial" data-visual-role="authoring-phase">
|
||||||
<div className="authoring-repair__diagnostic"><AlertTriangle aria-hidden="true" /><span>Diagnostic</span><strong>{visual.diagnostic}</strong></div>
|
<div className="authoring-repair__diagnostic"><AlertTriangle aria-hidden="true" /><span>Diagnostic</span><strong>{visual.diagnostic}</strong></div>
|
||||||
<ArrowRight aria-hidden="true" />
|
<ArrowRight aria-hidden="true" />
|
||||||
<div className="authoring-repair__correction"><Link2 aria-hidden="true" /><span>Repair</span><code>{visual.correction}</code></div>
|
<div className="authoring-repair__correction"><Link2 aria-hidden="true" /><span>Repair</span><code>{visual.correction}</code></div>
|
||||||
@@ -50,7 +50,7 @@ const RepairVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["vi
|
|||||||
);
|
);
|
||||||
|
|
||||||
const ArtifactVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "artifact" }> }) => (
|
const ArtifactVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "artifact" }> }) => (
|
||||||
<section className="authoring-visual authoring-visual--artifact" aria-label="artifact evidence" data-presentation-surface="editorial">
|
<section className="authoring-visual authoring-visual--artifact" aria-label="artifact evidence" data-presentation-surface="editorial" data-visual-role="authoring-phase">
|
||||||
<LockKeyhole aria-hidden="true" />
|
<LockKeyhole aria-hidden="true" />
|
||||||
<div><span>Immutable workflow artifact</span><strong>{visual.artifactId}</strong></div>
|
<div><span>Immutable workflow artifact</span><strong>{visual.artifactId}</strong></div>
|
||||||
<dl><div><dt>Version</dt><dd>Version {visual.version}</dd></div><div><dt>Requirements</dt><dd>{visual.requiredSources} local sources</dd></div></dl>
|
<dl><div><dt>Version</dt><dd>Version {visual.version}</dd></div><div><dt>Requirements</dt><dd>{visual.requiredSources} local sources</dd></div></dl>
|
||||||
@@ -58,7 +58,7 @@ const ArtifactVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["
|
|||||||
);
|
);
|
||||||
|
|
||||||
const BindingsVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "bindings" }> }) => (
|
const BindingsVisual = ({ visual }: { visual: Extract<AuthoringPhaseProjection["visual"], { kind: "bindings" }> }) => (
|
||||||
<section className="authoring-visual authoring-visual--bindings" aria-label="deployment binding evidence" data-presentation-surface="editorial">
|
<section className="authoring-visual authoring-visual--bindings" aria-label="deployment binding evidence" data-presentation-surface="editorial" data-visual-role="authoring-phase">
|
||||||
<header><Link2 aria-hidden="true" /><div><span>Deployment</span><strong>{visual.deploymentId}</strong></div><b><CheckCircle2 aria-hidden="true" />{visual.status}</b></header>
|
<header><Link2 aria-hidden="true" /><div><span>Deployment</span><strong>{visual.deploymentId}</strong></div><b><CheckCircle2 aria-hidden="true" />{visual.status}</b></header>
|
||||||
<div className="authoring-bindings__rows">
|
<div className="authoring-bindings__rows">
|
||||||
{visual.bindings.map((binding) => (
|
{visual.bindings.map((binding) => (
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ describe("PreparedAuthoringLifecycleScene", () => {
|
|||||||
expect(workspace.querySelector("[aria-label='authoring phase rail']"))
|
expect(workspace.querySelector("[aria-label='authoring phase rail']"))
|
||||||
.toBeInTheDocument();
|
.toBeInTheDocument();
|
||||||
expect(visual).toHaveAttribute("data-presentation-surface", "editorial");
|
expect(visual).toHaveAttribute("data-presentation-surface", "editorial");
|
||||||
|
expect(visual).toHaveAttribute("data-visual-role", "authoring-phase");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("synchronizes the assistant phase, active group, rail, and visual", () => {
|
it("synchronizes the assistant phase, active group, rail, and visual", () => {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ describe("ConclusionScene", () => {
|
|||||||
it.each(["limits", "future", "conclusion", "questions"])("preserves the labelled contribution boundary for %s", (beatId) => {
|
it.each(["limits", "future", "conclusion", "questions"])("preserves the labelled contribution boundary for %s", (beatId) => {
|
||||||
render(<ConclusionScene scene={scene} beat={beat(beatId)} />);
|
render(<ConclusionScene scene={scene} beat={beat(beatId)} />);
|
||||||
const map = screen.getByRole("region", { name: "thesis contribution boundary" });
|
const map = screen.getByRole("region", { name: "thesis contribution boundary" });
|
||||||
|
expect(map).toHaveAttribute("data-visual-role", "contribution-boundary");
|
||||||
expect(map).toHaveAttribute("data-conclusion-beat", beatId);
|
expect(map).toHaveAttribute("data-conclusion-beat", beatId);
|
||||||
for (const label of [
|
for (const label of [
|
||||||
"External planner",
|
"External planner",
|
||||||
|
|||||||
@@ -33,7 +33,12 @@ export const ConclusionScene: FC<ConclusionSceneProps> = ({ scene, beat }) => {
|
|||||||
<StageCaption eyebrow={`Act IV · ${scene.claimClass}`} title={scene.title}>
|
<StageCaption eyebrow={`Act IV · ${scene.claimClass}`} title={scene.title}>
|
||||||
<p>{beat.caption}</p>
|
<p>{beat.caption}</p>
|
||||||
</StageCaption>
|
</StageCaption>
|
||||||
<section className="conclusion-map" aria-label="thesis contribution boundary" data-conclusion-beat={beatId}>
|
<section
|
||||||
|
className="conclusion-map"
|
||||||
|
aria-label="thesis contribution boundary"
|
||||||
|
data-conclusion-beat={beatId}
|
||||||
|
data-visual-role="contribution-boundary"
|
||||||
|
>
|
||||||
<div className="conclusion-map__flow" aria-label="contribution flow">
|
<div className="conclusion-map__flow" aria-label="contribution flow">
|
||||||
<div className="conclusion-map__flow-unit conclusion-map__flow-unit--planner" data-flow-unit="planner">
|
<div className="conclusion-map__flow-unit conclusion-map__flow-unit--planner" data-flow-unit="planner">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ afterEach(() => cleanup());
|
|||||||
describe("EvaluationEvidenceScene", () => {
|
describe("EvaluationEvidenceScene", () => {
|
||||||
it.each(["cohort", "validity", "findings"])("renders the persistent board for %s", (beatId) => {
|
it.each(["cohort", "validity", "findings"])("renders the persistent board for %s", (beatId) => {
|
||||||
render(<EvaluationEvidenceScene scene={scene} beat={beat(beatId)} />);
|
render(<EvaluationEvidenceScene scene={scene} beat={beat(beatId)} />);
|
||||||
expect(screen.getByRole("group", { name: /evaluation evidence board/i })).toHaveAttribute(
|
const board = screen.getByRole("group", { name: /evaluation evidence board/i });
|
||||||
|
expect(board).toHaveAttribute("data-visual-role", "evaluation-summary");
|
||||||
|
expect(board).toHaveAttribute(
|
||||||
"data-evaluation-beat",
|
"data-evaluation-beat",
|
||||||
beatId,
|
beatId,
|
||||||
);
|
);
|
||||||
expect(screen.getByRole("group", { name: /evaluation evidence board/i })).toHaveAttribute(
|
expect(board).toHaveAttribute(
|
||||||
"data-evaluation-focus",
|
"data-evaluation-focus",
|
||||||
beatId,
|
beatId,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export const EvaluationEvidenceScene: FC<EvaluationEvidenceSceneProps> = ({ scen
|
|||||||
aria-label="evaluation evidence board"
|
aria-label="evaluation evidence board"
|
||||||
data-evaluation-beat={beatId}
|
data-evaluation-beat={beatId}
|
||||||
data-evaluation-focus={beatId}
|
data-evaluation-focus={beatId}
|
||||||
|
data-visual-role="evaluation-summary"
|
||||||
>
|
>
|
||||||
<div className="evaluation-board__cohort" aria-label="campaign cohort equation">
|
<div className="evaluation-board__cohort" aria-label="campaign cohort equation">
|
||||||
<span className="evaluation-board__cohort-total">{evaluationEvidence.totalTrials}</span>
|
<span className="evaluation-board__cohort-total">{evaluationEvidence.totalTrials}</span>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ describe("OpeningThesisScene", () => {
|
|||||||
|
|
||||||
const opening = screen.getByRole("region", { name: /thesis opening/i });
|
const opening = screen.getByRole("region", { name: /thesis opening/i });
|
||||||
expect(opening).toHaveAttribute("data-opening-focus", "title");
|
expect(opening).toHaveAttribute("data-opening-focus", "title");
|
||||||
|
expect(opening).toHaveAttribute("data-presentation-surface", "editorial");
|
||||||
|
expect(screen.getByRole("heading", { name: "An AI Agent for Workspace Workflows" }).parentElement)
|
||||||
|
.toHaveAttribute("data-visual-role", "title-hero");
|
||||||
expect(screen.getByRole("heading", { name: /Design and Implementation of lda\.chat/i })).toBeInTheDocument();
|
expect(screen.getByRole("heading", { name: /Design and Implementation of lda\.chat/i })).toBeInTheDocument();
|
||||||
expect(screen.getByRole("heading", { name: "An AI Agent for Workspace Workflows" })).toBeInTheDocument();
|
expect(screen.getByRole("heading", { name: "An AI Agent for Workspace Workflows" })).toBeInTheDocument();
|
||||||
const roles = screen.getByRole("group", { name: "AI agent roles" });
|
const roles = screen.getByRole("group", { name: "AI agent roles" });
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const OpeningThesisScene = ({ scene, beat }: OpeningThesisSceneProps) =>
|
|||||||
className="opening-thesis-scene"
|
className="opening-thesis-scene"
|
||||||
aria-label="thesis opening"
|
aria-label="thesis opening"
|
||||||
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
||||||
|
data-presentation-surface="editorial"
|
||||||
>
|
>
|
||||||
<StageCaption eyebrow="Title" title={title}>
|
<StageCaption eyebrow="Title" title={title}>
|
||||||
<p>{beat.caption}</p>
|
<p>{beat.caption}</p>
|
||||||
@@ -26,7 +27,7 @@ export const OpeningThesisScene = ({ scene, beat }: OpeningThesisSceneProps) =>
|
|||||||
data-opening-beat={beat.id}
|
data-opening-beat={beat.id}
|
||||||
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
||||||
>
|
>
|
||||||
<header className="opening-thesis__statement">
|
<header className="opening-thesis__statement" data-visual-role="title-hero">
|
||||||
<p>Product goal</p>
|
<p>Product goal</p>
|
||||||
<h2>An AI Agent for Workspace Workflows</h2>
|
<h2>An AI Agent for Workspace Workflows</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ describe("ProblemLoopScene", () => {
|
|||||||
expect(scene).toHaveAttribute("data-problem-focus", "tool-loop");
|
expect(scene).toHaveAttribute("data-problem-focus", "tool-loop");
|
||||||
expect(scene).toHaveAttribute("data-support-state", "quiet");
|
expect(scene).toHaveAttribute("data-support-state", "quiet");
|
||||||
const transcript = screen.getByRole("log", { name: /one-off assistant transcript/i });
|
const transcript = screen.getByRole("log", { name: /one-off assistant transcript/i });
|
||||||
|
expect(screen.getByRole("article", { name: /one-off chat and tool loop/i }))
|
||||||
|
.toHaveAttribute("data-visual-role", "conversation");
|
||||||
|
expect(screen.getByRole("group", { name: /durable workflow blueprint/i }))
|
||||||
|
.toHaveAttribute("data-visual-role", "automation");
|
||||||
expect(transcript).toHaveClass("assistant-operator-thread");
|
expect(transcript).toHaveClass("assistant-operator-thread");
|
||||||
expect(within(transcript).getByText("Can you finish this workspace task?")).toBeInTheDocument();
|
expect(within(transcript).getByText("Can you finish this workspace task?")).toBeInTheDocument();
|
||||||
const toolButtons = within(transcript).getAllByRole("button", { name: /fetchData|transformPayload|writeOutput/i });
|
const toolButtons = within(transcript).getAllByRole("button", { name: /fetchData|transformPayload|writeOutput/i });
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export const ProblemLoopScene = ({ scene, beat }: ProblemLoopSceneProps) => {
|
|||||||
className="problem-chat-card"
|
className="problem-chat-card"
|
||||||
data-problem-active={automationBeat ? "false" : "true"}
|
data-problem-active={automationBeat ? "false" : "true"}
|
||||||
data-problem-role="tool-loop"
|
data-problem-role="tool-loop"
|
||||||
|
data-visual-role="conversation"
|
||||||
aria-label="one-off chat and tool loop"
|
aria-label="one-off chat and tool loop"
|
||||||
>
|
>
|
||||||
<header className="problem-artifact-header">
|
<header className="problem-artifact-header">
|
||||||
@@ -89,6 +90,7 @@ export const ProblemLoopScene = ({ scene, beat }: ProblemLoopSceneProps) => {
|
|||||||
aria-label="durable workflow blueprint"
|
aria-label="durable workflow blueprint"
|
||||||
data-blueprint-active={automationBeat ? "true" : "false"}
|
data-blueprint-active={automationBeat ? "true" : "false"}
|
||||||
data-problem-role="workflow-blueprint"
|
data-problem-role="workflow-blueprint"
|
||||||
|
data-visual-role="automation"
|
||||||
>
|
>
|
||||||
<header className="problem-artifact-header">
|
<header className="problem-artifact-header">
|
||||||
<span>Reusable</span>
|
<span>Reusable</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user