const os = require("node:os"); const fs = require("node:fs"); const jsdom = require("jsdom"); const indexFile = `${__dirname}/../../../index.html`; const cssFile = `${__dirname}/../../../css/custom.css`; const sampleCss = [ ".region.row3 {", " top: 0;", "}", ".region.row3.left {", " top: 100%;", "}" ]; var indexData = []; var cssData = []; exports.startApplication = async (configFilename, exec) => { jest.resetModules(); if (global.app) { await this.stopApplication(); } // Set config sample for use in test if (configFilename === "") { process.env.MM_CONFIG_FILE = "config/config.js"; } else { process.env.MM_CONFIG_FILE = configFilename; } process.env.mmTestMode = "true"; if (exec) exec; global.app = require("../../../js/app"); return global.app.start(); }; exports.stopApplication = async (waitTime = 1000) => { if (global.window) { // no closing causes jest errors and memory leaks global.window.close(); delete global.window; // give above closing some extra time to finish await new Promise((resolve) => setTimeout(resolve, waitTime)); } if (!global.app) { return Promise.resolve(); } await global.app.stop(); delete global.app; }; exports.getDocument = () => { return new Promise((resolve) => { const url = `http://${config.address || "localhost"}:${config.port || "8080"}`; jsdom.JSDOM.fromURL(url, { resources: "usable", runScripts: "dangerously" }).then((dom) => { dom.window.name = "jsdom"; global.window = dom.window; // Following fixes `navigator is not defined` errors in e2e tests, found here // https://www.appsloveworld.com/reactjs/100/37/mocha-react-navigator-is-not-defined global.navigator = { useragent: "node.js" }; dom.window.fetch = fetch; dom.window.onload = () => { global.document = dom.window.document; resolve(); }; }); }); }; exports.waitForElement = (selector, ignoreValue = "", timeout = 0) => { return new Promise((resolve) => { let oldVal = "dummy12345"; let element = null; const interval = setInterval(() => { element = document.querySelector(selector); if (element) { let newVal = element.textContent; if (newVal === oldVal) { clearInterval(interval); resolve(element); } else { if (ignoreValue === "") { oldVal = newVal; } else { if (!newVal.includes(ignoreValue)) oldVal = newVal; } } } }, 100); if (timeout !== 0) { setTimeout(() => { if (interval) clearInterval(interval); resolve(null); }, timeout); } }); }; exports.waitForAllElements = (selector) => { return new Promise((resolve) => { let oldVal = 999999; const interval = setInterval(() => { const element = document.querySelectorAll(selector); if (element) { let newVal = element.length; if (newVal === oldVal) { clearInterval(interval); resolve(element); } else { if (newVal !== 0) oldVal = newVal; } } }, 100); }); }; exports.testMatch = async (element, regex) => { const elem = await this.waitForElement(element); expect(elem).not.toBeNull(); expect(elem.textContent).toMatch(regex); return true; }; exports.fixupIndex = async () => { // read and save the git level index file indexData = (await fs.promises.readFile(indexFile)).toString(); // make lines of the content let workIndexLines = indexData.split(os.EOL); // loop thru the lines to find place to insert new region for (let l in workIndexLines) { if (workIndexLines[l].includes("region top right")) { // insert a new line with new region definition workIndexLines.splice(l, 0, "