// jest.setup.js // Setup global browser APIs not provided by jsdom // Mock confirm/alert global.confirm = jest.fn().mockReturnValue(true); global.alert = jest.fn(); // Mock fetch as a global no-op that can be overridden per-test global.fetch = jest.fn(); // Ensure TextEncoder/TextDecoder are available (Node.js polyfill) const { TextEncoder, TextDecoder } = require('util'); global.TextEncoder = TextEncoder; global.TextDecoder = TextDecoder; // Ensure AbortController/AbortSignal are available if (!global.AbortController) { global.AbortController = class AbortController { constructor() { this.signal = { aborted: false, addEventListener: jest.fn(), removeEventListener: jest.fn(), dispatchEvent: jest.fn(), throwIfAborted: () => {}, }; } abort() { this.signal.aborted = true; } }; } // Extend HTMLElement with Obsidian-style createEl helper // This allows test elements to create children just like Obsidian's DOM API if (typeof HTMLElement !== 'undefined') { HTMLElement.prototype.createEl = function (tag, options) { const el = document.createElement(tag); if (options) { if (options.cls) { const classes = Array.isArray(options.cls) ? options.cls : options.cls.split(' '); classes.forEach((c) => { if (c) el.classList.add(c); }); } if (options.text) { el.textContent = options.text; } if (options.html) { el.innerHTML = options.html; } if (options.attr) { Object.entries(options.attr).forEach(([k, v]) => { el.setAttribute(k, v); }); } if (options.prop) { Object.entries(options.prop).forEach(([k, v]) => { el[k] = v; }); } if (options.select) { options.select(el); } } this.appendChild(el); return el; }; }