81 lines
3.5 KiB
JavaScript
81 lines
3.5 KiB
JavaScript
import { readFileSync } from "node:fs";
|
|
|
|
const page = readFileSync(new URL("../src/features/dataflow/DataflowPage.tsx", import.meta.url), "utf8");
|
|
const canvas = readFileSync(new URL("../src/features/dataflow/DataflowCanvas.tsx", import.meta.url), "utf8");
|
|
const interactions = readFileSync(new URL("../src/features/dataflow/graphInteractions.ts", import.meta.url), "utf8");
|
|
const css = readFileSync(new URL("../src/styles/dataflow.css", import.meta.url), "utf8");
|
|
const moduleEntry = readFileSync(new URL("../src/module.ts", import.meta.url), "utf8");
|
|
|
|
const checks = [
|
|
[page.includes("<DataflowCanvas"), "graph canvas"],
|
|
[page.includes("Apply SQL"), "SQL workbench"],
|
|
[page.includes("<NodeInspector"), "node inspector"],
|
|
[page.includes("previewDataflowPipeline"), "preview action"],
|
|
[
|
|
page.includes('inactiveLabel="Manual"')
|
|
&& page.includes('activeLabel="Auto"')
|
|
&& page.includes("void runPreview(selectedNodeId, true)"),
|
|
"selection-driven automatic and manual preview modes"
|
|
],
|
|
[
|
|
!page.includes('aria-label="Preview stage"')
|
|
&& page.includes('className="dataflow-preview-stage"'),
|
|
"selected-node preview stage without dropdown"
|
|
],
|
|
[
|
|
page.includes('resetKey={error} floating')
|
|
&& !css.includes(".dataflow-alerts"),
|
|
"central floating dismissible alerts"
|
|
],
|
|
[
|
|
!css.includes(".dataflow-results-toolbar .segmented-control"),
|
|
"ungapped shared results segmented control"
|
|
],
|
|
[
|
|
page.includes("response.graph.nodes.some((node) => node.id === selectedNodeId)"),
|
|
"selected node preservation across SQL roundtrips"
|
|
],
|
|
[page.includes("useUnsavedDraftGuard"), "unsaved-change guard"],
|
|
[canvas.includes("application/x-govoplan-dataflow-node"), "palette drop handling"],
|
|
[canvas.includes("isValidConnection"), "edge validation"],
|
|
[canvas.includes("connectionRadius={32}"), "visible connection drop radius"],
|
|
[canvas.includes("initialWidth: 180"), "known initial node width"],
|
|
[canvas.includes('change.type !== "dimensions"'), "measurement-only change filtering"],
|
|
[canvas.includes("onReconnect={onReconnect}"), "edge reconnection"],
|
|
[canvas.includes("onReconnectEnd="), "edge deletion on dropped reconnection"],
|
|
[canvas.includes("selectedEdgeId"), "persistent edge selection"],
|
|
[
|
|
canvas.includes("newGraphEdgeId()")
|
|
&& interactions.includes("return `edge-${crypto.randomUUID()}`"),
|
|
"bounded opaque edge identifiers"
|
|
],
|
|
[
|
|
canvas.includes("closestProximityConnection")
|
|
&& interactions.includes("definitionConnectionError"),
|
|
"validated proximity connection"
|
|
],
|
|
[css.includes(".dataflow-edge-proximity"), "proximity connection indicator"],
|
|
[
|
|
moduleEntry.indexOf("@xyflow/react/dist/style.css") <
|
|
moduleEntry.indexOf("./styles/dataflow.css"),
|
|
"XyFlow base styles before GovOPlaN overrides"
|
|
],
|
|
[css.includes("height: calc(100vh - 115px)"), "full-height workspace"],
|
|
[css.includes(".dataflow-preview-table-wrap"), "bounded preview scrolling"],
|
|
[
|
|
/\.dataflow-palette-items\s*\{[^}]*grid-auto-rows:\s*max-content;[^}]*overflow-y:\s*auto;/s.test(css),
|
|
"bounded palette scrolling"
|
|
],
|
|
[
|
|
/\.dataflow-inspector-fields\s*\{[^}]*grid-auto-rows:\s*max-content;[^}]*overflow-y:\s*auto;/s.test(css),
|
|
"bounded inspector scrolling"
|
|
]
|
|
];
|
|
|
|
const missing = checks.filter(([present]) => !present).map(([, label]) => label);
|
|
if (missing.length) {
|
|
throw new Error(`Dataflow UI structure is missing: ${missing.join(", ")}`);
|
|
}
|
|
|
|
console.log("Dataflow page structure checks passed.");
|