dom.spec.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import { describe, expect, it } from "vitest";
  2. import { addGlobalStyle, addParent, getSiblingsFrame, getUnsafeWindow, interceptEvent, isDomLoaded, observeElementProp, preloadImages, probeElementStyle, setInnerHtmlUnsafe } from "./dom.js";
  3. //#region getUnsafeWindow
  4. describe("dom/getUnsafeWindow", () => {
  5. it("Returns the correct window objects", () => {
  6. expect(getUnsafeWindow()).toBe(window);
  7. var unsafeWindow = window;
  8. expect(getUnsafeWindow()).toBe(unsafeWindow);
  9. });
  10. });
  11. //#region addParent
  12. describe("dom/addParent", () => {
  13. it("Adds a parent to an element", () => {
  14. const container = document.createElement("div");
  15. container.id = "container";
  16. const child = document.createElement("div");
  17. child.id = "child";
  18. document.body.appendChild(child);
  19. addParent(child, container);
  20. expect(child.parentNode).toBe(container);
  21. container.remove();
  22. });
  23. });
  24. //#region addGlobalStyle
  25. describe("dom/addGlobalStyle", () => {
  26. it("Adds a global style to the document", () => {
  27. const el = addGlobalStyle(`body { background-color: red; }`);
  28. el.id = "test-style";
  29. expect(document.querySelector("head #test-style")).toBe(el);
  30. });
  31. });
  32. //#region preloadImages
  33. //TODO:FIXME: no workis
  34. describe.skip("dom/preloadImages", () => {
  35. it("Preloads images", async () => {
  36. const res = await preloadImages(["https://picsum.photos/50/50"]);
  37. expect(Array.isArray(res)).toBe(true);
  38. expect(res.every(r => r.status === "fulfilled")).toBe(true);
  39. });
  40. });
  41. //#region openInNewTab
  42. describe.skip("dom/openInNewTab", () => {
  43. // obviously cant test this
  44. });
  45. //#region interceptEvent
  46. describe("dom/interceptEvent", () => {
  47. it("Intercepts an event", () => {
  48. const el = document.createElement("div");
  49. el.id = "test-intercept";
  50. document.body.appendChild(el);
  51. let clickedTimes = 0;
  52. el.addEventListener("click", () => ++clickedTimes);
  53. interceptEvent(el, "click", () => true);
  54. el.addEventListener("click", () => ++clickedTimes);
  55. el.click();
  56. expect(clickedTimes).toBe(1);
  57. document.body.removeChild(el);
  58. });
  59. });
  60. //#region interceptWindowEvent
  61. describe("dom/interceptWindowEvent", () => {
  62. it("Intercepts a window event", () => {
  63. let clickedTimes = 0;
  64. const inc = () => clickedTimes++;
  65. window.addEventListener("foo", inc);
  66. interceptEvent(window, "foo", () => true);
  67. window.addEventListener("foo", inc);
  68. window.dispatchEvent(new Event("foo"));
  69. expect(clickedTimes).toBe(1);
  70. window.removeEventListener("foo", inc);
  71. });
  72. });
  73. //#region observeElementProp
  74. //TODO:FIXME: no workio
  75. describe.skip("dom/observeElementProp", () => {
  76. it("Observes an element property", () => {
  77. const el = document.createElement("input");
  78. el.type = "text";
  79. document.body.appendChild(el);
  80. let newVal = "";
  81. observeElementProp(el, "value", (_oldVal, newVal) => {
  82. newVal = newVal;
  83. });
  84. el.value = "foo";
  85. expect(newVal).toBe("foo");
  86. });
  87. });
  88. //#region getSiblingsFrame
  89. describe("dom/getSiblingsFrame", () => {
  90. it("Returns the correct frame", () => {
  91. const container = document.createElement("div");
  92. for(let i = 0; i < 10; i++) {
  93. const el = document.createElement("div");
  94. el.id = `e${i}`;
  95. container.appendChild(el);
  96. }
  97. const cntrEl = container.querySelector<HTMLElement>("#e5")!;
  98. expect(getSiblingsFrame(cntrEl, 2).map(e => e.id)).toEqual(["e5", "e6"]);
  99. expect(getSiblingsFrame(cntrEl, 2, "top", false).map(e => e.id)).toEqual(["e6", "e7"]);
  100. expect(getSiblingsFrame(cntrEl, 2, "bottom", false).map(e => e.id)).toEqual(["e3", "e4"]);
  101. expect(getSiblingsFrame(cntrEl, 2, "center-top", false).map(e => e.id)).toEqual(["e4", "e6"]);
  102. expect(getSiblingsFrame(cntrEl, 3, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6"]);
  103. expect(getSiblingsFrame(cntrEl, 4, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6", "e7"]);
  104. expect(getSiblingsFrame(cntrEl, 4, "center-bottom", true).map(e => e.id)).toEqual(["e3", "e4", "e5", "e6"]);
  105. });
  106. });
  107. //#region setInnerHtmlUnsafe
  108. describe("dom/setInnerHtmlUnsafe", () => {
  109. it("Sets inner HTML", () => {
  110. const el = document.createElement("div");
  111. setInnerHtmlUnsafe(el, "<div>foo</div>");
  112. expect(el.querySelector("div")?.textContent).toBe("foo");
  113. });
  114. });
  115. //#region probeElementStyle
  116. //TODO:FIXME: no workiong
  117. describe.skip("dom/probeElementStyle", () => {
  118. it("Resolves a CSS variable", async () => {
  119. addGlobalStyle(`:root { --foo: #f00; --bar: var(--foo, #00f); }`);
  120. const tryResolveCol = (i = 0) => new Promise<string>((res, rej) => {
  121. if(i > 100)
  122. return rej(new Error("Could not resolve color after 100 tries"));
  123. const probedCol = probeElementStyle(
  124. (style) => style.backgroundColor,
  125. () => {
  126. const elem = document.createElement("span");
  127. elem.style.backgroundColor = "var(--foo, #000)";
  128. return elem;
  129. },
  130. true,
  131. );
  132. if(probedCol.length === 0 || probedCol.match(/^rgba?\((?:(?:255,\s?255,\s?255)|(?:0,\s?0,\s?0))/) || probedCol.match(/^#(?:fff(?:fff)?|000(?:000)?)/))
  133. return setTimeout(async () => res(await tryResolveCol(++i)), 100);
  134. return res(probedCol);
  135. });
  136. const val = await tryResolveCol();
  137. expect(val).toBe("rgb(255, 0, 0)");
  138. });
  139. });
  140. const initialState = document.readyState;
  141. //#region isDomLoaded
  142. describe.skip("dom/isDomLoaded", () => {
  143. it("Returns the correct state", () => {
  144. // doesn't work cause the lib isn't loaded before DOMContentLoaded
  145. expect(isDomLoaded()).toBe(initialState === "complete");
  146. });
  147. });
  148. //#region onDomLoad
  149. describe.skip("dom/onDomLoad", () => {
  150. // see above
  151. });