/** @vitest-environment happy-dom */ import { create as createTestRenderer, ReactTestRendererTree, } from "react-test-renderer"; import { describe, expect, it } from "vitest"; const allStories = import.meta.glob("../src/**/*.stories.tsx"); for (const [path, module] of Object.entries(allStories)) { const segments = path.split("/"); const componentName = segments[segments.length - 1]!.replace( ".stories.tsx", "" ); const shortPath = segments.slice(-2).join("/"); describe(shortPath, () => { it(`renders ${componentName}`, async () => { for (const story of Object.values(await module())) { if (typeof story === "function") { const Component = story; const renderer = createTestRenderer(); const tree = renderer.toTree()!; const found = breadthFirstSearch(tree, (node) => { const type = node.type as string | React.ComponentType | undefined; const name = type && (typeof type === "string" ? type : type.displayName || type.name); return name === componentName; }); expect(found?.type).toBeInstanceOf(Function); } } }); }); } function breadthFirstSearch( tree: ReactTestRendererTree, predicate: (node: ReactTestRendererTree) => boolean ) { const queue = [tree]; while (queue.length) { const node = queue.shift(); if (!node) continue; if (predicate(node)) return node; if (node.rendered) queue.push( ...(Array.isArray(node.rendered) ? node.rendered : [node.rendered]) ); } return undefined; }