import { describe, expect, it } from "vitest"; import { addGlobalStyle, addParent, getSiblingsFrame, getUnsafeWindow, interceptEvent, isDomLoaded, observeElementProp, preloadImages, probeElementStyle, setInnerHtmlUnsafe } from "./dom.js"; //#region getUnsafeWindow describe("dom/getUnsafeWindow", () => { it("Returns the correct window objects", () => { expect(getUnsafeWindow()).toBe(window); var unsafeWindow = window; expect(getUnsafeWindow()).toBe(unsafeWindow); }); }); //#region addParent describe("dom/addParent", () => { it("Adds a parent to an element", () => { const container = document.createElement("div"); container.id = "container"; const child = document.createElement("div"); child.id = "child"; document.body.appendChild(child); addParent(child, container); expect(child.parentNode).toBe(container); container.remove(); }); }); //#region addGlobalStyle describe("dom/addGlobalStyle", () => { it("Adds a global style to the document", () => { const el = addGlobalStyle(`body { background-color: red; }`); el.id = "test-style"; expect(document.querySelector("head #test-style")).toBe(el); }); }); //#region preloadImages //TODO:FIXME: no workis describe.skip("dom/preloadImages", () => { it("Preloads images", async () => { const res = await preloadImages(["https://picsum.photos/50/50"]); expect(Array.isArray(res)).toBe(true); expect(res.every(r => r.status === "fulfilled")).toBe(true); }); }); //#region openInNewTab describe.skip("dom/openInNewTab", () => { // obviously cant test this }); //#region interceptEvent describe("dom/interceptEvent", () => { it("Intercepts an event", () => { const el = document.createElement("div"); el.id = "test-intercept"; document.body.appendChild(el); let clickedTimes = 0; el.addEventListener("click", () => ++clickedTimes); interceptEvent(el, "click", () => true); el.addEventListener("click", () => ++clickedTimes); el.click(); expect(clickedTimes).toBe(1); document.body.removeChild(el); }); }); //#region interceptWindowEvent describe("dom/interceptWindowEvent", () => { it("Intercepts a window event", () => { let clickedTimes = 0; const inc = () => clickedTimes++; window.addEventListener("foo", inc); interceptEvent(window, "foo", () => true); window.addEventListener("foo", inc); window.dispatchEvent(new Event("foo")); expect(clickedTimes).toBe(1); window.removeEventListener("foo", inc); }); }); //#region observeElementProp //TODO:FIXME: no workio describe.skip("dom/observeElementProp", () => { it("Observes an element property", () => { const el = document.createElement("input"); el.type = "text"; document.body.appendChild(el); let newVal = ""; observeElementProp(el, "value", (_oldVal, newVal) => { newVal = newVal; }); el.value = "foo"; expect(newVal).toBe("foo"); }); }); //#region getSiblingsFrame describe("dom/getSiblingsFrame", () => { it("Returns the correct frame", () => { const container = document.createElement("div"); for(let i = 0; i < 10; i++) { const el = document.createElement("div"); el.id = `e${i}`; container.appendChild(el); } const cntrEl = container.querySelector("#e5")!; expect(getSiblingsFrame(cntrEl, 2).map(e => e.id)).toEqual(["e5", "e6"]); expect(getSiblingsFrame(cntrEl, 2, "top", false).map(e => e.id)).toEqual(["e6", "e7"]); expect(getSiblingsFrame(cntrEl, 2, "bottom", false).map(e => e.id)).toEqual(["e3", "e4"]); expect(getSiblingsFrame(cntrEl, 2, "center-top", false).map(e => e.id)).toEqual(["e4", "e6"]); expect(getSiblingsFrame(cntrEl, 3, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6"]); expect(getSiblingsFrame(cntrEl, 4, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6", "e7"]); expect(getSiblingsFrame(cntrEl, 4, "center-bottom", true).map(e => e.id)).toEqual(["e3", "e4", "e5", "e6"]); }); }); //#region setInnerHtmlUnsafe describe("dom/setInnerHtmlUnsafe", () => { it("Sets inner HTML", () => { const el = document.createElement("div"); setInnerHtmlUnsafe(el, "
foo
"); expect(el.querySelector("div")?.textContent).toBe("foo"); }); }); //#region probeElementStyle //TODO:FIXME: no workiong describe.skip("dom/probeElementStyle", () => { it("Resolves a CSS variable", async () => { addGlobalStyle(`:root { --foo: #f00; --bar: var(--foo, #00f); }`); const tryResolveCol = (i = 0) => new Promise((res, rej) => { if(i > 100) return rej(new Error("Could not resolve color after 100 tries")); const probedCol = probeElementStyle( (style) => style.backgroundColor, () => { const elem = document.createElement("span"); elem.style.backgroundColor = "var(--foo, #000)"; return elem; }, true, ); if(probedCol.length === 0 || probedCol.match(/^rgba?\((?:(?:255,\s?255,\s?255)|(?:0,\s?0,\s?0))/) || probedCol.match(/^#(?:fff(?:fff)?|000(?:000)?)/)) return setTimeout(async () => res(await tryResolveCol(++i)), 100); return res(probedCol); }); const val = await tryResolveCol(); expect(val).toBe("rgb(255, 0, 0)"); }); }); const initialState = document.readyState; //#region isDomLoaded describe.skip("dom/isDomLoaded", () => { it("Returns the correct state", () => { // doesn't work cause the lib isn't loaded before DOMContentLoaded expect(isDomLoaded()).toBe(initialState === "complete"); }); }); //#region onDomLoad describe.skip("dom/onDomLoad", () => { // see above });