/** * Test setup for TASTE Voice Bot frontend tests */ // Mock Web APIs that are not available in Jest environment global.AudioContext = jest.fn(() => ({ createScriptProcessor: jest.fn(), createGain: jest.fn(), createBuffer: jest.fn(), createBufferSource: jest.fn(), destination: {}, sampleRate: 44100, close: jest.fn(), suspend: jest.fn(), resume: jest.fn() })); global.MediaStream = jest.fn(() => ({ getTracks: jest.fn(() => []), getAudioTracks: jest.fn(() => []), addTrack: jest.fn(), removeTrack: jest.fn() })); // Mock navigator.mediaDevices global.navigator.mediaDevices = { getUserMedia: jest.fn() }; // Mock HTMLCanvasElement and its context global.HTMLCanvasElement.prototype.getContext = jest.fn(() => ({ fillRect: jest.fn(), clearRect: jest.fn(), fillStyle: '', strokeStyle: '', lineWidth: 1, beginPath: jest.fn(), moveTo: jest.fn(), lineTo: jest.fn(), stroke: jest.fn() })); // Mock console methods to reduce noise in tests global.console = { ...console, log: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn() }; // Mock grpc-web (since it's not available in test environment) jest.mock('grpc-web', () => ({ GrpcWebClientBase: jest.fn(() => ({ rpcCall: jest.fn(), serverStreaming: jest.fn(), thenableCall: jest.fn() })) }), { virtual: true }); // Setup DOM elements that tests might need document.body.innerHTML = `

        
        
        
`; // Global test utilities global.testUtils = { /** * Create a mock audio buffer * @param {number} length - Buffer length * @returns {ArrayBuffer} Mock audio buffer */ createMockAudioBuffer(length = 1024) { const buffer = new ArrayBuffer(length * 2); // 16-bit audio const view = new Int16Array(buffer); for (let i = 0; i < length; i++) { view[i] = Math.random() * 32767 - 16384; } return buffer; }, /** * Create a mock gRPC response * @param {Object} data - Response data * @returns {Object} Mock response */ createMockGrpcResponse(data = {}) { return { status: 'success', message: 'Mock response', ...data }; }, /** * Wait for a specified time * @param {number} ms - Milliseconds to wait * @returns {Promise} Promise that resolves after wait */ wait(ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)); }, /** * Trigger a DOM event * @param {HTMLElement} element - Target element * @param {string} eventType - Event type * @param {Object} options - Event options */ triggerEvent(element, eventType, options = {}) { const event = new Event(eventType, { bubbles: true, ...options }); element.dispatchEvent(event); } }; // Cleanup after each test afterEach(() => { jest.clearAllMocks(); }); // Global setup beforeAll(() => { // Suppress console.error for expected test failures jest.spyOn(console, 'error').mockImplementation(() => {}); }); afterAll(() => { // Restore console.error console.error.mockRestore(); });