diff --git a/packages/ui-react/tests/browser/diagrams-axis.layout.tsx b/packages/ui-react/tests/browser/diagrams-axis.layout.tsx
index 30d0d5af4..7c12de1a1 100644
--- a/packages/ui-react/tests/browser/diagrams-axis.layout.tsx
+++ b/packages/ui-react/tests/browser/diagrams-axis.layout.tsx
@@ -12,7 +12,7 @@ afterAll(async()=>{styles.remove();await commands.formViewport(previousViewport.
function setup(width=760){root=createBrainUiRoot({storage:null,request:async()=>Response.json({renderers:[],enabled:[]})});host=document.createElement("div");host.style.width=`${width}px`;document.body.append(host);render=createRoot(host);}
function mount(source:string,theme:"light"|"dark"|"print"){flushSync(()=>render.render());}
async function ready(){await expect.poll(()=>host.querySelector('figure>svg')).not.toBeNull();await document.fonts.ready;}
-function inspect(svg:SVGSVGElement){const frame=svg.viewBox.baseVal;for(const label of svg.querySelectorAll("text")){const box=label.getBBox(),matrix=label.getScreenCTM()!,scale=Math.min(Math.hypot(matrix.a,matrix.b),Math.hypot(matrix.c,matrix.d));expect(parseFloat(getComputedStyle(label).fontSize)*scale,"AXIS_NORMAL_TEXT_FLOOR").toBeGreaterThanOrEqual(9);expect(box.x,"TEXT_LEFT_BOUND").toBeGreaterThanOrEqual(0);expect(box.x+box.width,"TEXT_RIGHT_BOUND").toBeLessThanOrEqual(frame.width);expect(box.y,"TEXT_TOP_BOUND").toBeGreaterThanOrEqual(0);expect(box.y+box.height,"TEXT_BOTTOM_BOUND").toBeLessThanOrEqual(frame.height);}}
+function inspect(svg:SVGSVGElement){expect(svg.querySelectorAll("text").length,"EXPECTED_AXIS_TEXT_POPULATION").toBeGreaterThan(0);const frame=svg.viewBox.baseVal;for(const label of svg.querySelectorAll("text")){const box=label.getBBox(),matrix=label.getScreenCTM()!,scale=Math.min(Math.hypot(matrix.a,matrix.b),Math.hypot(matrix.c,matrix.d));expect(parseFloat(getComputedStyle(label).fontSize)*scale,"AXIS_NORMAL_TEXT_FLOOR").toBeGreaterThanOrEqual(9);expect(box.x,"TEXT_LEFT_BOUND").toBeGreaterThanOrEqual(0);expect(box.x+box.width,"TEXT_RIGHT_BOUND").toBeLessThanOrEqual(frame.width);expect(box.y,"TEXT_TOP_BOUND").toBeGreaterThanOrEqual(0);expect(box.y+box.height,"TEXT_BOTTOM_BOUND").toBeLessThanOrEqual(frame.height);}}
for(const [kind,spec] of Object.entries(axisExamples))test(`${kind} real light dark print baselines and static parity`,async()=>{
setup(kind==="swimlane"?1000:760);const source=JSON.stringify(spec);
for(const theme of ["light","dark","print"] as const){mount(source,theme);await ready();const svg=host.querySelector('figure>svg')!;inspect(svg);const parsed=new DOMParser().parseFromString(await toStatic(source,{theme}),"image/svg+xml");
@@ -22,7 +22,7 @@ for(const [kind,spec] of Object.entries(axisExamples))test(`${kind} real light d
});
test("sequence uses readable derived phone layout and unsafe content opens the full viewer",async()=>{
setup(320);mount(JSON.stringify(axisExamples.sequence),"dark");await ready();const svg=host.querySelector('figure>svg')!;expect(svg.viewBox.baseVal.width).toBe(320);inspect(svg);expect(host.scrollWidth).toBeLessThanOrEqual(320);await expect(page.elementLocator(host)).toMatchScreenshot("axis-sequence-320-dark");await commands.diagramCapture('[data-content-renderer="diagram"]',"axis-sequence-320-dark");
- const unsafe=structuredClone(axisExamples.sequence);unsafe.nodes.push({id:"penelope",label:"Penelope"},{id:"athena",label:"Athena"});mount(JSON.stringify(unsafe),"light");await expect.poll(()=>host.querySelector('[data-diagram-summary]')).not.toBeNull();expect(host.querySelector('figure>svg')).toBeNull();const opener=[...host.querySelectorAll('[role="button"],button')].find(b=>b.textContent==="Open diagram")!;expect(opener.getBoundingClientRect().height).toBeGreaterThanOrEqual(44);await userEvent.click(opener);await expect.poll(()=>document.querySelector('[aria-label="Diagram viewer"] svg')).not.toBeNull();inspect(document.querySelector('[aria-label="Diagram viewer"] svg')!);await userEvent.keyboard("{Escape}");
+ const unsafe=structuredClone(axisExamples.sequence);unsafe.nodes.push({id:"penelope",label:"Penelope"},{id:"athena",label:"Athena"});mount(JSON.stringify(unsafe),"light");await expect.poll(()=>host.querySelector('[data-diagram-summary]')).not.toBeNull();expect(host.querySelector('figure>svg')).toBeNull();const opener=[...host.querySelectorAll('[role="button"],button')].find(b=>b.textContent==="Open diagram")!;expect(opener.getBoundingClientRect().height).toBeGreaterThanOrEqual(44);await userEvent.click(opener);await expect.poll(()=>document.querySelector('[aria-label="Diagram viewer"] svg.bk-diagram')).not.toBeNull();inspect(document.querySelector('[aria-label="Diagram viewer"] svg.bk-diagram')!);await userEvent.keyboard("{Escape}");
});
test("axis handoff masks clear every step and tips attach at the boundary",async()=>{
diff --git a/packages/ui-react/tests/browser/diagrams-renderer.layout.tsx b/packages/ui-react/tests/browser/diagrams-renderer.layout.tsx
index 960b14726..55953b334 100644
--- a/packages/ui-react/tests/browser/diagrams-renderer.layout.tsx
+++ b/packages/ui-react/tests/browser/diagrams-renderer.layout.tsx
@@ -18,7 +18,7 @@ function setup(width=1000){root=createBrainUiRoot({storage:null,request:async()=
function mount(element:React.ReactNode){flushSync(()=>render.render({element}));}
function screenSvg(){return host.querySelector('figure > svg.bk-diagram');}
async function ready(){await expect.poll(()=>screenSvg()).not.toBeNull();await document.fonts.ready;}
-function fontFloor(svg:SVGSVGElement){for(const text of svg.querySelectorAll("text")){const matrix=text.getScreenCTM()!;const scale=Math.min(Math.hypot(matrix.a,matrix.b),Math.hypot(matrix.c,matrix.d));expect(parseFloat(getComputedStyle(text).fontSize)*scale,"ACTUAL_DISPLAYED_TEXT_FLOOR").toBeGreaterThanOrEqual(9);}}
+function fontFloor(svg:SVGSVGElement){expect(svg.querySelectorAll("text").length,"EXPECTED_DIAGRAM_TEXT_POPULATION").toBeGreaterThan(0);for(const text of svg.querySelectorAll("text")){const matrix=text.getScreenCTM()!;const scale=Math.min(Math.hypot(matrix.a,matrix.b),Math.hypot(matrix.c,matrix.d));expect(parseFloat(getComputedStyle(text).fontSize)*scale,"ACTUAL_DISPLAYED_TEXT_FLOOR").toBeGreaterThanOrEqual(9);}}
test("registered chat fence renders and follows live light/dark and actual print media",async()=>{
setup();defaultContentRendererRegistry.register(diagramsContentPack);document.documentElement.dataset.theme="light";root.stores.ui.setState({theme:"light"});
mount();await ready();
@@ -34,7 +34,7 @@ test("actual constrained containers select authored layout or semantic fallback,
for(const width of [320,480,900]){host.style.width=`${width}px`;await expect.poll(()=>screenSvg()?.getBoundingClientRect().width).toBe(320);fontFloor(screenSvg()!);expect(host.scrollWidth).toBeLessThanOrEqual(width);}
const absent=structuredClone(rendererSpec);delete (absent as {layouts?:unknown}).layouts;host.style.width="320px";mount();await expect.poll(()=>screenSvg()).toBeNull();expect(host.querySelector("[data-diagram-summary]")?.textContent).toBe(rendererSpec.desc);
const opener=[...host.querySelectorAll("[role=button],button")].find(item=>item.textContent==="Open diagram")!;expect(opener.getBoundingClientRect().height).toBeGreaterThanOrEqual(44);await userEvent.click(opener);
- await expect.poll(()=>document.querySelector('[aria-label="Diagram viewer"] svg')).not.toBeNull();const drawing=document.querySelector('[aria-label="Diagram viewer"] svg')!;fontFloor(drawing);await userEvent.keyboard("{Escape}");
+ await expect.poll(()=>document.querySelector('[aria-label="Diagram viewer"] svg.bk-diagram')).not.toBeNull();const drawing=document.querySelector('[aria-label="Diagram viewer"] svg.bk-diagram')!;expect([...drawing.querySelectorAll("[data-diagram-node] text")].map(text=>text.textContent),"EXPECTED_VIEWER_NODE_LABELS").toEqual(expect.arrayContaining(rendererSpec.nodes.map(node=>node.label)));fontFloor(drawing);await userEvent.keyboard("{Escape}");
});
test("keyboard nodes navigate like wiki links and incident edges and focus ring remain visible",async()=>{
setup();const paths:string[]=[];root.stores.file.setState({openFile:async(path)=>{paths.push(path);}});mount();await ready();
diff --git a/scripts/bound-browser-documents.ts b/scripts/bound-browser-documents.ts
index 68ddc61e7..f9ae5bb00 100644
--- a/scripts/bound-browser-documents.ts
+++ b/scripts/bound-browser-documents.ts
@@ -31,11 +31,13 @@ const declarations:DocumentDeclaration[]=[{
},{
// Reviewed against #2295 and #2346: bounded capture tracing, split relay and
// callout cases keep the exact HTML/CSS sink, five callers and offline producers.
+ // #2241 re-audit: renderer/axis edits only strengthen viewer selection and
+ // font assertions; capture arguments, call counts and producer closure stay fixed.
"command": "diagramCapture",
"owner": "packages/ui-react/tests/browser/diagram-proof-command.ts",
"ownerHash": "d7280cf23ba24bd636f7737d8552801e37f8c03c1e773aee660c9e07ded524a9",
"caller": "packages/ui-react/tests/browser/diagrams-renderer.layout.tsx",
- "callerHash": "dbac044e90a3b7b84e308a96cca8396874afb9b96d8cc23b2fddb4293d85706c",
+ "callerHash": "9d5e6b574bc22fb19f47c6d7d813f13bd444920539bf341732700e9d3413de4a",
"calls": 2,
"additionalCallers": {
"packages/ui-react/tests/browser/diagrams-callouts.layout.tsx": {
@@ -43,7 +45,7 @@ const declarations:DocumentDeclaration[]=[{
"calls": 8
},
"packages/ui-react/tests/browser/diagrams-axis.layout.tsx": {
- "hash": "6512cb4660834ef7b15a52258d51f694c4e34fd530754bdc51580137db22b75c",
+ "hash": "bd7c728af1ae5c250ddbef4e3423372590aabc65430661fe6afed97e3eb6e933",
"calls": 3
},
"packages/ui-react/tests/browser/diagrams-positional.layout.tsx": {