Fix failing tests
This commit is contained in:
parent
0bbf4c2694
commit
51d2595d49
2 changed files with 126 additions and 62 deletions
|
|
@ -163,6 +163,10 @@ describe('Save to PC and Clipboard Combinations', () => {
|
||||||
// Reset mocks
|
// Reset mocks
|
||||||
mockCreateElement.mockClear();
|
mockCreateElement.mockClear();
|
||||||
mockCreateElement.mockReturnValue(mockLink);
|
mockCreateElement.mockReturnValue(mockLink);
|
||||||
|
// Ensure our mock is used even if the test environment adjusted document
|
||||||
|
if (global.document) {
|
||||||
|
global.document.createElement = mockCreateElement;
|
||||||
|
}
|
||||||
mockLink.click.mockClear();
|
mockLink.click.mockClear();
|
||||||
|
|
||||||
// Setup clipboard API mocks
|
// Setup clipboard API mocks
|
||||||
|
|
|
||||||
184
tests/setup.js
184
tests/setup.js
|
|
@ -3,6 +3,32 @@
|
||||||
* Provides common mocks and utilities for all test files
|
* Provides common mocks and utilities for all test files
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Keep global and window navigator in sync regardless of direct reassignment
|
||||||
|
(() => {
|
||||||
|
try {
|
||||||
|
let navigatorStore = (typeof global !== 'undefined' && global.navigator) || (typeof window !== 'undefined' && window.navigator) || {};
|
||||||
|
if (typeof global !== 'undefined') {
|
||||||
|
Object.defineProperty(global, 'navigator', {
|
||||||
|
configurable: true,
|
||||||
|
get: () => navigatorStore,
|
||||||
|
set: (val) => {
|
||||||
|
navigatorStore = val || {};
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
try { window.navigator = navigatorStore; } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
Object.defineProperty(window, 'navigator', {
|
||||||
|
configurable: true,
|
||||||
|
get: () => navigatorStore,
|
||||||
|
set: (val) => { navigatorStore = val || {}; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
})();
|
||||||
|
|
||||||
// Global test utilities
|
// Global test utilities
|
||||||
global.createMockBlob = (data = 'mock data', type = 'image/png', size = 1024) => {
|
global.createMockBlob = (data = 'mock data', type = 'image/png', size = 1024) => {
|
||||||
const blob = new Blob([data], { type });
|
const blob = new Blob([data], { type });
|
||||||
|
|
@ -56,30 +82,39 @@ global.createMockElement = (options = {}) => {
|
||||||
|
|
||||||
// Mock Chrome extension APIs consistently
|
// Mock Chrome extension APIs consistently
|
||||||
global.mockChromeAPIs = () => {
|
global.mockChromeAPIs = () => {
|
||||||
|
const existingChrome = global.chrome || {};
|
||||||
|
const existingStorage = (existingChrome.storage && existingChrome.storage.sync) || {};
|
||||||
|
const existingRuntime = existingChrome.runtime || {};
|
||||||
|
const existingTabs = existingChrome.tabs || {};
|
||||||
|
|
||||||
global.chrome = {
|
global.chrome = {
|
||||||
storage: {
|
storage: {
|
||||||
sync: {
|
sync: {
|
||||||
get: jest.fn().mockResolvedValue({}),
|
get: existingStorage.get || jest.fn().mockResolvedValue({}),
|
||||||
set: jest.fn().mockResolvedValue()
|
set: existingStorage.set || jest.fn().mockResolvedValue()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
runtime: {
|
runtime: {
|
||||||
sendMessage: jest.fn().mockResolvedValue(),
|
sendMessage: existingRuntime.sendMessage || jest.fn().mockResolvedValue(),
|
||||||
onMessage: {
|
onMessage: {
|
||||||
addListener: jest.fn()
|
addListener: (existingRuntime.onMessage && existingRuntime.onMessage.addListener) || jest.fn()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
query: jest.fn().mockResolvedValue([{ id: 123, url: 'https://example.com' }]),
|
query: existingTabs.query || jest.fn().mockResolvedValue([{ id: 123, url: 'https://example.com' }]),
|
||||||
sendMessage: jest.fn().mockResolvedValue()
|
sendMessage: existingTabs.sendMessage || jest.fn().mockResolvedValue()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock DOM APIs consistently
|
// Mock DOM APIs consistently
|
||||||
global.mockDOMAPIs = () => {
|
global.mockDOMAPIs = () => {
|
||||||
global.document = {
|
// Document
|
||||||
createElement: jest.fn(() => ({
|
const existingDocument = global.document || {};
|
||||||
|
const existingCreateElement = existingDocument.createElement;
|
||||||
|
global.document = existingDocument;
|
||||||
|
if (!global.document.createElement) {
|
||||||
|
global.document.createElement = jest.fn(() => ({
|
||||||
style: {},
|
style: {},
|
||||||
classList: { add: jest.fn(), remove: jest.fn() },
|
classList: { add: jest.fn(), remove: jest.fn() },
|
||||||
appendChild: jest.fn(),
|
appendChild: jest.fn(),
|
||||||
|
|
@ -92,80 +127,105 @@ global.mockDOMAPIs = () => {
|
||||||
className: '',
|
className: '',
|
||||||
checked: false,
|
checked: false,
|
||||||
value: ''
|
value: ''
|
||||||
})),
|
}));
|
||||||
head: { appendChild: jest.fn() },
|
}
|
||||||
body: { appendChild: jest.fn() },
|
if (!global.document.head) global.document.head = { appendChild: jest.fn() };
|
||||||
addEventListener: jest.fn(),
|
if (!global.document.body) global.document.body = { appendChild: jest.fn() };
|
||||||
removeEventListener: jest.fn(),
|
if (!global.document.addEventListener) global.document.addEventListener = jest.fn();
|
||||||
querySelectorAll: jest.fn(() => []),
|
if (!global.document.removeEventListener) global.document.removeEventListener = jest.fn();
|
||||||
getElementById: jest.fn(() => null)
|
if (!global.document.querySelectorAll) global.document.querySelectorAll = jest.fn(() => []);
|
||||||
};
|
if (!global.document.getElementById) global.document.getElementById = jest.fn(() => null);
|
||||||
|
|
||||||
global.window = {
|
// Window
|
||||||
getComputedStyle: jest.fn(() => ({})),
|
const existingWindow = global.window || {};
|
||||||
devicePixelRatio: 2,
|
global.window = existingWindow;
|
||||||
isSecureContext: true,
|
// Ensure a shared navigator reference exists early
|
||||||
CSS: { escape: jest.fn(str => str) },
|
if (!global.navigator) global.navigator = (existingWindow && existingWindow.navigator) || {};
|
||||||
setTimeout: jest.fn((fn, delay) => {
|
if (!global.window.navigator) global.window.navigator = global.navigator;
|
||||||
|
if (!global.window.getComputedStyle) global.window.getComputedStyle = jest.fn(() => ({}));
|
||||||
|
if (typeof global.window.devicePixelRatio === 'undefined') global.window.devicePixelRatio = 2;
|
||||||
|
if (typeof global.window.isSecureContext === 'undefined') global.window.isSecureContext = true;
|
||||||
|
if (!global.window.CSS) global.window.CSS = { escape: jest.fn(str => str) };
|
||||||
|
if (!global.window.setTimeout) {
|
||||||
|
global.window.setTimeout = jest.fn((fn, delay) => {
|
||||||
if (delay === 0) fn();
|
if (delay === 0) fn();
|
||||||
return 1;
|
return 1;
|
||||||
}),
|
});
|
||||||
clearTimeout: jest.fn(),
|
}
|
||||||
close: jest.fn()
|
if (!global.window.clearTimeout) global.window.clearTimeout = jest.fn();
|
||||||
};
|
if (!global.window.close) global.window.close = jest.fn();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock clipboard APIs with different scenarios
|
// Mock clipboard APIs with different scenarios
|
||||||
global.mockClipboardAPI = (scenario = 'supported') => {
|
global.mockClipboardAPI = (scenario = 'supported') => {
|
||||||
switch (scenario) {
|
switch (scenario) {
|
||||||
case 'supported':
|
case 'supported': {
|
||||||
global.navigator = {
|
const existingNavigator = global.navigator || {};
|
||||||
clipboard: {
|
const existingClipboard = existingNavigator.clipboard || {};
|
||||||
write: jest.fn().mockResolvedValue()
|
if (!existingClipboard.write || !jest.isMockFunction?.(existingClipboard.write)) {
|
||||||
}
|
existingClipboard.write = jest.fn().mockResolvedValue();
|
||||||
};
|
}
|
||||||
global.window.ClipboardItem = jest.fn();
|
const mergedNavigator = { ...existingNavigator, clipboard: existingClipboard };
|
||||||
global.window.isSecureContext = true;
|
global.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
if (!global.window.ClipboardItem) global.window.ClipboardItem = jest.fn();
|
||||||
|
if (typeof global.window.isSecureContext === 'undefined') global.window.isSecureContext = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'no-clipboard':
|
case 'no-clipboard':
|
||||||
global.navigator = {};
|
global.navigator = {};
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.navigator = global.navigator;
|
||||||
break;
|
break;
|
||||||
|
case 'no-clipboarditem': {
|
||||||
case 'no-clipboarditem':
|
const existingNavigator = global.navigator || {};
|
||||||
global.navigator = {
|
const clipboard = existingNavigator.clipboard || { write: jest.fn() };
|
||||||
clipboard: { write: jest.fn() }
|
const mergedNavigator = { ...existingNavigator, clipboard };
|
||||||
};
|
global.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
global.window.ClipboardItem = undefined;
|
global.window.ClipboardItem = undefined;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'insecure-context':
|
case 'insecure-context': {
|
||||||
global.navigator = {
|
const existingNavigator = global.navigator || {};
|
||||||
clipboard: { write: jest.fn() }
|
const clipboard = existingNavigator.clipboard || { write: jest.fn() };
|
||||||
};
|
const mergedNavigator = { ...existingNavigator, clipboard };
|
||||||
global.window.ClipboardItem = jest.fn();
|
global.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.ClipboardItem = global.window.ClipboardItem || jest.fn();
|
||||||
global.window.isSecureContext = false;
|
global.window.isSecureContext = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'permission-denied':
|
case 'permission-denied': {
|
||||||
global.navigator = {
|
const existingNavigator = global.navigator || {};
|
||||||
clipboard: {
|
const clipboard = { write: jest.fn().mockRejectedValue(new DOMException('Permission denied', 'NotAllowedError')) };
|
||||||
write: jest.fn().mockRejectedValue(new DOMException('Permission denied', 'NotAllowedError'))
|
const mergedNavigator = { ...existingNavigator, clipboard };
|
||||||
}
|
global.navigator = mergedNavigator;
|
||||||
};
|
if (!global.window) global.window = {};
|
||||||
global.window.ClipboardItem = jest.fn();
|
global.window.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.ClipboardItem = global.window.ClipboardItem || jest.fn();
|
||||||
global.window.isSecureContext = true;
|
global.window.isSecureContext = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'security-error':
|
case 'security-error': {
|
||||||
global.navigator = {
|
const existingNavigator = global.navigator || {};
|
||||||
clipboard: {
|
const clipboard = { write: jest.fn().mockRejectedValue(new DOMException('Security error', 'SecurityError')) };
|
||||||
write: jest.fn().mockRejectedValue(new DOMException('Security error', 'SecurityError'))
|
const mergedNavigator = { ...existingNavigator, clipboard };
|
||||||
}
|
global.navigator = mergedNavigator;
|
||||||
};
|
if (!global.window) global.window = {};
|
||||||
global.window.ClipboardItem = jest.fn();
|
global.window.navigator = mergedNavigator;
|
||||||
|
if (!global.window) global.window = {};
|
||||||
|
global.window.ClipboardItem = global.window.ClipboardItem || jest.fn();
|
||||||
global.window.isSecureContext = true;
|
global.window.isSecureContext = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue