uncloseai.com/tests/setup.js
Russell Ballestrini c721b88473 fix: add fallback handling for window modal functions in embed modal
- Add safety checks for window.openTTSModal and window.openTranslateModal availability
- Implement fallback dynamic imports if window functions not available
- Prevents "window.openTTSModal is not a function" and "window.openTranslateModal is not a function" errors
- Provides graceful error handling with user feedback if modal imports fail
- Resolves loading order dependency issues between ui.js and embed modal

This ensures modal buttons work regardless of script loading order.
2025-07-03 18:51:48 -04:00

108 lines
No EOL
2.6 KiB
JavaScript

// Jest test setup for modal testing
import { JSDOM } from 'jsdom';
// Set up DOM environment
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
url: 'https://example.com',
pretendToBeVisual: true,
resources: 'usable'
});
global.document = dom.window.document;
global.window = dom.window;
global.navigator = dom.window.navigator;
global.HTMLElement = dom.window.HTMLElement;
global.Element = dom.window.Element;
// Mock localStorage
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
};
global.localStorage = localStorageMock;
// Mock fetch
global.fetch = jest.fn();
// Mock window.matchMedia
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
// Mock dialog element if not available
if (typeof HTMLDialogElement === 'undefined') {
global.HTMLDialogElement = class HTMLDialogElement extends HTMLElement {
constructor() {
super();
this.open = false;
}
show() {
this.open = true;
}
showModal() {
this.open = true;
}
close() {
this.open = false;
}
};
// Register as a custom element
if (customElements && !customElements.get('dialog')) {
customElements.define('dialog', HTMLDialogElement);
}
}
// Global test helpers
global.createMockModal = () => {
const modal = document.createElement('dialog');
modal.id = 'test-modal';
document.body.appendChild(modal);
return modal;
};
global.createMockEvent = (type, properties = {}) => {
const event = new Event(type, { bubbles: true, cancelable: true });
Object.assign(event, properties);
return event;
};
// Cleanup function to reset mocks between tests
global.resetMocks = () => {
localStorageMock.getItem.mockClear();
localStorageMock.setItem.mockClear();
localStorageMock.removeItem.mockClear();
localStorageMock.clear.mockClear();
global.fetch.mockClear();
// Clear DOM
document.body.innerHTML = '';
document.head.innerHTML = '';
// Reset window properties
delete window.UNCLOSEAI_CUSTOM_STYLING;
delete window.uncloseaiEmbeddedModalOpen;
delete window.openTTSModal;
delete window.openTranslateModal;
delete window.toggleUncloseaiEmbeddedModal;
};
// Run cleanup before each test
beforeEach(() => {
resetMocks();
});