// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // State visualizer snapshot tests. // // Snapshots are stored as .html files in `test/state-viz-cases/`. // To (re)generate snapshots: // node --test --test-update-snapshots test/stateViz.js // @ts-check import { JSDOM } from "jsdom"; import fs from "node:fs"; import path from "node:path"; import { afterEach, beforeEach, test } from "node:test"; import { fileURLToPath } from "node:url"; import prettier from "prettier"; import { createStatePanel, updateStatePanelFromColumns, } from "../dist/ux/circuit-vis/state-viz/stateViz.js"; import { prepareStateVizColumnsFromAmpMap } from "../dist/ux/circuit-vis/state-viz/worker/stateVizPrep.js"; const documentTemplate = `
`; /** @type {JSDOM | null} */ let jsdom = null; beforeEach(() => { jsdom = new JSDOM(documentTemplate, { pretendToBeVisual: true, }); // Override the globals used by product code // @ts-expect-error - the `jsdom` typings and DOM typings don't match globalThis.window = jsdom.window; globalThis.document = jsdom.window.document; globalThis.Node = jsdom.window.Node; globalThis.HTMLElement = jsdom.window.HTMLElement; globalThis.SVGElement = jsdom.window.SVGElement; globalThis.SVGSVGElement = jsdom.window.SVGSVGElement; globalThis.XMLSerializer = jsdom.window.XMLSerializer; globalThis.getComputedStyle = jsdom.window.getComputedStyle.bind( jsdom.window, ); globalThis.requestAnimationFrame = jsdom.window.requestAnimationFrame.bind( jsdom.window, ); }); afterEach(() => { jsdom?.window.close(); jsdom = null; }); function getCasesDirectory() { return path.join( path.dirname(fileURLToPath(import.meta.url)), "state-viz-cases", ); } /** * @param {string} name */ function htmlSnapshotPath(name) { // Keep snapshots stable across OSes and paths. const safe = name.replace(/[^a-zA-Z0-9_.-]+/g, "_"); return path.join(getCasesDirectory(), safe + ".snapshot.html"); } /** * Check the current document against the stored snapshot. * @param {import("node:test").TestContext} t * @param {string} name */ async function checkDocumentSnapshot(t, name) { const rawHtml = new XMLSerializer().serializeToString(document) + "\n"; const formattedHtml = await prettier.format(rawHtml, { parser: "html", printWidth: 80, tabWidth: 2, useTabs: false, }); t.assert.fileSnapshot(formattedHtml, htmlSnapshotPath(name), { serializers: [(s) => String(s)], }); } /** * Creates a state panel, attaches it to the DOM, renders an amp map, * and returns the panel. * * @param {Record