", () => {
+ document.body.innerHTML = `
+
+ Q3
+
+ `;
+ let labelOpacity = "1";
+ installFixture({
+ rects: {
+ root: ROOT,
+ panel: { left: 40, top: 40, width: 200, height: 48 },
+ label: { left: 40, top: 40, width: 40, height: 48 },
+ },
+ styles: {
+ label: {
+ get opacity() {
+ return labelOpacity;
+ },
+ } as StyleOverride,
+ },
+ });
+
+ const collect = installScript();
+ const before = collect();
+ labelOpacity = "0.5";
+
+ expect(collect()).not.toBe(before);
+ });
+
it("changes the sweep fingerprint when only clip-path moves", () => {
document.body.innerHTML = `
@@ -836,3 +1124,33 @@ describe("motion-signature.browser counter channel", () => {
expect(collect()).toBe(before);
});
});
+
+// layout-audit.browser.js is installed standalone, so it cannot import this
+// module's container list; the two literals are kept in step by hand. This
+// pins that they have not drifted. layout-audit spells the names as the SVG
+// DOM does (`clipPath`) while this module matches lower-cased tag names, so
+// the two spellings of one name compare equal.
+describe("motion-signature.browser source parity", () => {
+ function containerNames(source: string, listPattern: RegExp, file: string): string[] {
+ const list = listPattern.exec(source)?.[1];
+ if (list === undefined) throw new Error(`${file}: container list not found`);
+ return Array.from(list.matchAll(/[A-Za-z]+/g), (name) => name[0].toLowerCase()).sort();
+ }
+
+ it("keeps UNPAINTED_SVG_CONTAINERS equal to layout-audit's CONNECTOR_SKIP_CONTAINERS", () => {
+ const layoutAudit = readFileSync(join(__dirname, "layout-audit.browser.js"), "utf-8");
+ const unpainted = containerNames(
+ script,
+ /const UNPAINTED_SVG_CONTAINERS = new Set\(\[([^\]]*)\]\)/,
+ "motion-signature.browser.js",
+ );
+ const skipped = containerNames(
+ layoutAudit,
+ /const CONNECTOR_SKIP_CONTAINERS = "([^"]*)"/,
+ "layout-audit.browser.js",
+ );
+
+ expect(unpainted.length).toBeGreaterThan(0);
+ expect(unpainted).toEqual(skipped);
+ });
+});