fix(studio): render complete interactive gallery previews
This commit is contained in:
1 parent
c765d76a06
commit
9520651330
26 files changed
+5761
-39
No files matched your search
@@ -0,0 +1,65 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { COMPONENT_CONTRACTS, CORE_DESIGN_SYSTEMS } from "@wrnexus/design-system";
|
||||
import { runWithRequestContext } from "@wrnexus/core";
|
||||
import { gallerySample, previewSlots, previewSampleMarkup } from "../src/gallery.ts";
|
||||
import { previewIconCss } from "../src/preview-assets.ts";
|
||||
import { previewDocument } from "../src/preview.ts";
|
||||
|
||||
test("every contracted gallery component has an explicit populated standalone sample", () => {
|
||||
for (const name of Object.keys(COMPONENT_CONTRACTS)) {
|
||||
const sample = gallerySample(name);
|
||||
expect(Object.keys(sample.props).length).toBeGreaterThan(0);
|
||||
expect(sample.hint).toBeTruthy();
|
||||
expect(JSON.stringify(sample.props)).not.toContain("/showcase-images/");
|
||||
}
|
||||
for (const name of ["Accordion", "DataMap", "Tabs", "TreeView", "FeatureGrid", "MetricGrid"]) {
|
||||
expect((gallerySample(name).props.items as unknown[]).length).toBeGreaterThan(0);
|
||||
}
|
||||
expect(gallerySample("DrawflowCanvas").props.nodes).toHaveLength(2);
|
||||
expect(gallerySample("Map").props.imageSrc).toMatch(/^data:image\/svg\+xml,/);
|
||||
expect(gallerySample("DeviceFrame").content).toContain("Sample mobile page");
|
||||
expect(gallerySample("BackToTop").props.alwaysVisible).toBe(true);
|
||||
});
|
||||
|
||||
test("sample slot insertion preserves nested markup and fallback labels", () => {
|
||||
const html =
|
||||
'<slot data-wrn-events="open" name="trigger"></slot><slot data-wrn-events="close"></slot><slot name="footer">Fallback</slot>';
|
||||
const result = previewSlots(
|
||||
html,
|
||||
'<div data-slot="trigger"><div><button>Open</button></div></div><p>Body</p>',
|
||||
);
|
||||
expect(result).toContain("<div><button>Open</button></div>");
|
||||
expect(result).toContain("<p>Body</p>");
|
||||
expect(result).toContain('name="footer">Fallback');
|
||||
expect(previewSlots('<slot data-wrn-events="click"><span>Save</span></slot>', "")).toContain(
|
||||
"<span>Save</span>",
|
||||
);
|
||||
expect(() =>
|
||||
runWithRequestContext({} as never, () => previewSampleMarkup("<p>Sample</p>", "")),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
test("icons embed real local SVG masks, including upstream icon aliases", () => {
|
||||
const css = previewIconCss("icon-[lucide--code-2] icon-[lucide--check-circle-2]");
|
||||
expect(css).toContain("data:image/svg+xml,");
|
||||
expect(css).toContain("stroke");
|
||||
expect(css).toContain("icon-[lucide--code-2]");
|
||||
expect(css).not.toMatch(/https?:\/\/[^"\s]*\.svg/);
|
||||
});
|
||||
|
||||
test("all gallery pages include real browser functions and fully rendered nested components", async () => {
|
||||
let count = 0;
|
||||
for (let page = 0; page < 7; page++) {
|
||||
const html = await previewDocument(CORE_DESIGN_SYSTEMS.square, { content: "catalog", page });
|
||||
count += [...html.matchAll(/<section class="sample" data-gallery-component=/g)].length;
|
||||
expect(html).toContain("Interactive samples");
|
||||
expect(html).toContain("bindPreview()");
|
||||
expect(html).toContain("__wrnexusClientFunctions");
|
||||
expect(html).not.toMatch(/<div[^>]*\bdata-component=/);
|
||||
expect(html).toContain("data:image/svg+xml,");
|
||||
if (page === 0) expect(html).toContain("Supporting content belongs inside the default slot.");
|
||||
if (page === 2) expect(html).toContain("Sample row 12");
|
||||
if (page === 5) expect(html).toContain("data-preview-toast");
|
||||
}
|
||||
expect(count).toBe(104);
|
||||
}, 20_000);
|
||||
@@ -168,7 +168,7 @@ test("catalog previews cover all 104 component defaults and unknown routes do no
|
||||
});
|
||||
const { url } = await result.json();
|
||||
const html = await (await send(url)).text();
|
||||
count += (html.match(/data-wrn-component=/g) ?? []).length;
|
||||
count += (html.match(/<section class="sample" data-gallery-component=/g) ?? []).length;
|
||||
}
|
||||
expect(count).toBe(104);
|
||||
expect((await send("/../../package.json")).status).toBe(404);
|
||||
|
||||
Reference in new issue
Block a user