diff --git a/frontend/src/components/LanguageSelector/__tests__/LanguageSelector.test.tsx b/frontend/src/components/LanguageSelector/__tests__/LanguageSelector.test.tsx
index 0ad7a26..b19a25b 100644
--- a/frontend/src/components/LanguageSelector/__tests__/LanguageSelector.test.tsx
+++ b/frontend/src/components/LanguageSelector/__tests__/LanguageSelector.test.tsx
@@ -1,5 +1,5 @@
import { describe, test, expect, vi, beforeEach } from 'vitest';
-import { screen, fireEvent } from '@testing-library/react';
+import { screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import LanguageSelector from '../LanguageSelector';
import { renderWithProviders } from '../../../test/test-utils';
@@ -259,7 +259,11 @@ describe('LanguageSelector Component', () => {
expect(button).toHaveFocus();
await user.keyboard('{Enter}');
- expect(screen.getByText('Available Languages')).toBeInTheDocument();
+
+ // Wait for the dialog to appear
+ await waitFor(() => {
+ expect(screen.getByText('Available Languages')).toBeInTheDocument();
+ });
});
test('should have proper button roles', () => {
diff --git a/frontend/src/components/__tests__/SyncProgressDisplay.simple.test.tsx b/frontend/src/components/__tests__/SyncProgressDisplay.simple.test.tsx
deleted file mode 100644
index d685d04..0000000
--- a/frontend/src/components/__tests__/SyncProgressDisplay.simple.test.tsx
+++ /dev/null
@@ -1,215 +0,0 @@
-import { describe, test, expect, vi, beforeEach } from 'vitest';
-import { screen, fireEvent, waitFor } from '@testing-library/react';
-import SyncProgressDisplay from '../SyncProgressDisplay';
-import { renderWithProviders } from '../../test/test-utils';
-
-// Simple mock EventSource that focuses on essential functionality
-const createMockEventSource = () => ({
- onopen: null as ((event: Event) => void) | null,
- onmessage: null as ((event: MessageEvent) => void) | null,
- onerror: null as ((event: Event) => void) | null,
- addEventListener: vi.fn(),
- removeEventListener: vi.fn(),
- close: vi.fn(),
- readyState: 0, // CONNECTING
- url: '',
- withCredentials: false,
- dispatchEvent: vi.fn(),
-});
-
-// Mock sourcesService
-const mockSourcesService = {
- getSyncProgressStream: vi.fn(),
- getSyncStatus: vi.fn(),
- triggerSync: vi.fn(),
- stopSync: vi.fn(),
- triggerDeepScan: vi.fn(),
-};
-
-// Mock the API - ensure EventSource is mocked first
-let currentMockEventSource = createMockEventSource();
-
-global.EventSource = vi.fn(() => currentMockEventSource) as any;
-(global.EventSource as any).CONNECTING = 0;
-(global.EventSource as any).OPEN = 1;
-(global.EventSource as any).CLOSED = 2;
-
-vi.mock('../../services/api', () => ({
- sourcesService: {
- ...mockSourcesService,
- getSyncProgressStream: vi.fn(() => currentMockEventSource),
- },
-}));
-
-const renderComponent = (props = {}) => {
- const defaultProps = {
- sourceId: 'test-source-123',
- sourceName: 'Test WebDAV Source',
- isVisible: true,
- ...props,
- };
-
- return renderWithProviders();
-};
-
-describe('SyncProgressDisplay Simple Tests', () => {
- beforeEach(() => {
- vi.clearAllMocks();
- // Reset the mock EventSource
- currentMockEventSource = createMockEventSource();
- global.EventSource = vi.fn(() => currentMockEventSource) as any;
- mockSourcesService.getSyncProgressStream.mockReturnValue(currentMockEventSource);
- });
-
- describe('Basic Rendering', () => {
- test('should not render when isVisible is false', () => {
- renderComponent({ isVisible: false });
- expect(screen.queryByText('Test WebDAV Source - Sync Progress')).not.toBeInTheDocument();
- });
-
- test('should render title when isVisible is true', () => {
- renderComponent({ isVisible: true });
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- test('should render with custom source name', () => {
- renderComponent({ sourceName: 'My Custom Source' });
- expect(screen.getByText('My Custom Source - Sync Progress')).toBeInTheDocument();
- });
-
- test('should show initial waiting message', () => {
- renderComponent();
- expect(screen.getByText('Waiting for sync progress information...')).toBeInTheDocument();
- });
- });
-
- describe('EventSource Connection', () => {
- test('should create EventSource with correct source ID', () => {
- renderComponent({ sourceId: 'test-123' });
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledWith('test-123');
- });
-
- test('should create EventSource only when visible', () => {
- renderComponent({ isVisible: false });
- expect(mockSourcesService.getSyncProgressStream).not.toHaveBeenCalled();
- });
-
- test('should show connecting status initially', () => {
- renderComponent();
- expect(screen.getByText('Connecting...')).toBeInTheDocument();
- });
- });
-
- describe('Expand/Collapse', () => {
- test('should have expand/collapse button', () => {
- renderComponent();
- // Look for the expand/collapse button by its tooltip or aria-label
- const buttons = screen.getAllByRole('button');
- const expandCollapseButton = buttons.find(button =>
- button.getAttribute('aria-label')?.includes('Collapse') ||
- button.getAttribute('aria-label')?.includes('Expand')
- );
- expect(expandCollapseButton).toBeInTheDocument();
- });
-
- test('should toggle expansion when button is clicked', async () => {
- renderComponent();
-
- // Find the expand/collapse button
- const buttons = screen.getAllByRole('button');
- const expandCollapseButton = buttons.find(button =>
- button.getAttribute('aria-label')?.includes('Collapse')
- );
-
- if (expandCollapseButton) {
- // Should be expanded initially
- expect(screen.getByText('Waiting for sync progress information...')).toBeInTheDocument();
-
- // Click to collapse
- fireEvent.click(expandCollapseButton);
-
- await waitFor(() => {
- expect(screen.queryByText('Waiting for sync progress information...')).not.toBeInTheDocument();
- });
- }
- });
- });
-
- describe('Component Cleanup', () => {
- test('should close EventSource on unmount', () => {
- const mockEventSource = createMockEventSource();
- mockSourcesService.getSyncProgressStream.mockReturnValue(mockEventSource);
-
- const { unmount } = renderComponent();
- unmount();
-
- expect(mockEventSource.close).toHaveBeenCalled();
- });
-
- test('should close EventSource when visibility changes to false', () => {
- const mockEventSource = createMockEventSource();
- mockSourcesService.getSyncProgressStream.mockReturnValue(mockEventSource);
-
- const { rerender } = renderComponent({ isVisible: true });
-
- rerender(
-
- );
-
- expect(mockEventSource.close).toHaveBeenCalled();
- });
- });
-
- describe('Error Handling', () => {
- test('should handle EventSource creation errors gracefully', () => {
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
- mockSourcesService.getSyncProgressStream.mockImplementation(() => {
- throw new Error('Failed to create EventSource');
- });
-
- // Should not crash when EventSource creation fails
- expect(() => renderComponent()).not.toThrow();
-
- consoleErrorSpy.mockRestore();
- });
- });
-
- describe('Props Validation', () => {
- test('should handle different source IDs', () => {
- renderComponent({ sourceId: 'different-id' });
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledWith('different-id');
- });
-
- test('should handle empty source name', () => {
- renderComponent({ sourceName: '' });
- expect(screen.getByText(' - Sync Progress')).toBeInTheDocument();
- });
-
- test('should handle very long source names', () => {
- const longName = 'A'.repeat(100);
- renderComponent({ sourceName: longName });
- expect(screen.getByText(`${longName} - Sync Progress`)).toBeInTheDocument();
- });
- });
-
- describe('Accessibility', () => {
- test('should have proper heading structure', () => {
- renderComponent();
- const heading = screen.getByText('Test WebDAV Source - Sync Progress');
- expect(heading.tagName).toBe('H6'); // Material-UI Typography variant="h6"
- });
-
- test('should have clickable buttons with proper attributes', () => {
- renderComponent();
- const buttons = screen.getAllByRole('button');
-
- buttons.forEach(button => {
- expect(button).toHaveAttribute('type', 'button');
- });
- });
- });
-});
\ No newline at end of file
diff --git a/frontend/src/pages/__tests__/SourcesPage.sync-progress.test.tsx b/frontend/src/pages/__tests__/SourcesPage.sync-progress.test.tsx
deleted file mode 100644
index deea9f0..0000000
--- a/frontend/src/pages/__tests__/SourcesPage.sync-progress.test.tsx
+++ /dev/null
@@ -1,497 +0,0 @@
-import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
-import { screen, fireEvent, waitFor, act } from '@testing-library/react';
-import SourcesPage from '../SourcesPage';
-import { renderWithProviders } from '../../test/test-utils';
-import type { SyncProgressInfo } from '../../services/api';
-
-// Mock the API module
-const mockApi = {
- get: vi.fn(),
- post: vi.fn(),
- put: vi.fn(),
- delete: vi.fn(),
-};
-
-const mockEventSource = {
- onopen: null as ((event: Event) => void) | null,
- onmessage: null as ((event: MessageEvent) => void) | null,
- onerror: null as ((event: Event) => void) | null,
- addEventListener: vi.fn(),
- removeEventListener: vi.fn(),
- close: vi.fn(),
- readyState: EventSource.CONNECTING,
- url: '',
- withCredentials: false,
- CONNECTING: 0,
- OPEN: 1,
- CLOSED: 2,
- dispatchEvent: vi.fn(),
-};
-
-global.EventSource = vi.fn(() => mockEventSource) as any;
-
-const mockSourcesService = {
- triggerSync: vi.fn(),
- stopSync: vi.fn(),
- getSyncStatus: vi.fn(),
- getSyncProgressStream: vi.fn(() => mockEventSource),
- triggerDeepScan: vi.fn(),
-};
-
-const mockQueueService = {
- getQueueStatus: vi.fn(),
- pauseQueue: vi.fn(),
- resumeQueue: vi.fn(),
- clearQueue: vi.fn(),
-};
-
-vi.mock('../../services/api', async () => {
- const actual = await vi.importActual('../../services/api');
- return {
- ...actual,
- api: mockApi,
- sourcesService: mockSourcesService,
- queueService: mockQueueService,
- };
-});
-
-// Mock react-router-dom
-const mockNavigate = vi.fn();
-vi.mock('react-router-dom', async () => {
- const actual = await vi.importActual('react-router-dom');
- return {
- ...actual,
- useNavigate: () => mockNavigate,
- };
-});
-
-// Create mock source data
-const createMockSource = (overrides: any = {}) => ({
- id: 'test-source-123',
- name: 'Test WebDAV Source',
- source_type: 'webdav',
- enabled: true,
- config: {
- server_url: 'https://nextcloud.example.com',
- username: 'testuser',
- password: 'password123',
- watch_folders: ['/Documents'],
- file_extensions: ['pdf', 'doc', 'docx'],
- },
- status: 'idle',
- last_sync_at: '2024-01-15T10:30:00Z',
- last_error: null,
- last_error_at: null,
- total_files_synced: 45,
- total_files_pending: 0,
- total_size_bytes: 15728640,
- total_documents: 42,
- total_documents_ocr: 38,
- created_at: '2024-01-01T00:00:00Z',
- updated_at: '2024-01-15T10:30:00Z',
- ...overrides,
-});
-
-const createMockProgressInfo = (overrides: Partial = {}): SyncProgressInfo => ({
- source_id: 'test-source-123',
- phase: 'processing_files',
- phase_description: 'Downloading and processing files',
- elapsed_time_secs: 120,
- directories_found: 10,
- directories_processed: 7,
- files_found: 50,
- files_processed: 30,
- bytes_processed: 1024000,
- processing_rate_files_per_sec: 2.5,
- files_progress_percent: 60.0,
- estimated_time_remaining_secs: 80,
- current_directory: '/Documents/Projects',
- current_file: 'important-document.pdf',
- errors: 0,
- warnings: 1,
- is_active: true,
- ...overrides,
-});
-
-describe('SourcesPage Sync Progress Integration', () => {
- beforeEach(() => {
- vi.clearAllMocks();
-
- // Default mock responses
- mockApi.get.mockImplementation((url: string) => {
- if (url === '/sources') {
- return Promise.resolve({ data: [createMockSource()] });
- }
- if (url === '/queue/status') {
- return Promise.resolve({
- data: {
- pending: 0,
- processing: 0,
- failed: 0,
- completed: 100,
- is_paused: false
- }
- });
- }
- return Promise.resolve({ data: [] });
- });
-
- mockSourcesService.triggerSync.mockResolvedValue({ data: { success: true } });
- mockSourcesService.stopSync.mockResolvedValue({ data: { success: true } });
- mockSourcesService.getSyncStatus.mockResolvedValue({ data: null });
- });
-
- afterEach(() => {
- vi.clearAllMocks();
- });
-
- describe('Progress Display Visibility', () => {
- test('should not show progress display for idle sources', async () => {
- const idleSource = createMockSource({ status: 'idle' });
- mockApi.get.mockResolvedValue({ data: [idleSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Progress display should not be visible
- expect(screen.queryByText('Test WebDAV Source - Sync Progress')).not.toBeInTheDocument();
- });
-
- test('should show progress display for syncing sources', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Progress display should be visible
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
- });
-
- test('should show progress display for multiple syncing sources', async () => {
- const sources = [
- createMockSource({ id: 'source-1', name: 'Source One', status: 'syncing' }),
- createMockSource({ id: 'source-2', name: 'Source Two', status: 'idle' }),
- createMockSource({ id: 'source-3', name: 'Source Three', status: 'syncing' }),
- ];
- mockApi.get.mockResolvedValue({ data: sources });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Source One - Sync Progress')).toBeInTheDocument();
- expect(screen.getByText('Source Three - Sync Progress')).toBeInTheDocument();
- expect(screen.queryByText('Source Two - Sync Progress')).not.toBeInTheDocument();
- });
- });
- });
-
- describe('Progress Data Integration', () => {
- test('should display real-time progress updates', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- // Simulate progress update via SSE
- const mockProgress = createMockProgressInfo();
- act(() => {
- const progressHandler = mockEventSource.addEventListener.mock.calls.find(
- call => call[0] === 'progress'
- )?.[1] as (event: MessageEvent) => void;
-
- if (progressHandler) {
- progressHandler(new MessageEvent('progress', {
- data: JSON.stringify(mockProgress)
- }));
- }
- });
-
- await waitFor(() => {
- expect(screen.getByText('Downloading and processing files')).toBeInTheDocument();
- expect(screen.getByText('30 / 50 files (60.0%)')).toBeInTheDocument();
- expect(screen.getByText('/Documents/Projects')).toBeInTheDocument();
- });
- });
-
- test('should handle progress updates for correct source', async () => {
- const sources = [
- createMockSource({ id: 'source-1', name: 'Source One', status: 'syncing' }),
- createMockSource({ id: 'source-2', name: 'Source Two', status: 'syncing' }),
- ];
- mockApi.get.mockResolvedValue({ data: sources });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Source One - Sync Progress')).toBeInTheDocument();
- expect(screen.getByText('Source Two - Sync Progress')).toBeInTheDocument();
- });
-
- // Each source should create its own EventSource
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledWith('source-1');
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledWith('source-2');
- });
- });
-
- describe('Sync Control Integration', () => {
- test('should trigger sync and show progress display', async () => {
- const idleSource = createMockSource({ status: 'idle' });
- mockApi.get.mockResolvedValue({ data: [idleSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Click sync button
- const syncButton = screen.getByLabelText('Trigger Sync');
- fireEvent.click(syncButton);
-
- expect(mockSourcesService.triggerSync).toHaveBeenCalledWith('test-source-123');
-
- // Simulate source status change to syncing after API call
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- // Progress display should appear
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
- });
-
- test('should stop sync and hide progress display', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- // Click stop sync button
- const stopButton = screen.getByLabelText('Stop Sync');
- fireEvent.click(stopButton);
-
- expect(mockSourcesService.stopSync).toHaveBeenCalledWith('test-source-123');
-
- // Simulate source status change to idle after API call
- const idleSource = createMockSource({ status: 'idle' });
- mockApi.get.mockResolvedValue({ data: [idleSource] });
-
- // Progress display should disappear
- await waitFor(() => {
- expect(screen.queryByText('Test WebDAV Source - Sync Progress')).not.toBeInTheDocument();
- });
- });
- });
-
- describe('Auto-refresh Behavior', () => {
- test('should enable auto-refresh when sources are syncing', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Auto-refresh should be enabled for syncing sources
- // This is tested indirectly by checking that the API is called multiple times
- await waitFor(() => {
- expect(mockApi.get).toHaveBeenCalledWith('/sources');
- }, { timeout: 3000 });
- });
-
- test('should disable auto-refresh when no sources are syncing', async () => {
- const idleSource = createMockSource({ status: 'idle' });
- mockApi.get.mockResolvedValue({ data: [idleSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Auto-refresh should not be running for idle sources
- const initialCallCount = mockApi.get.mock.calls.length;
-
- // Wait a bit and ensure no additional calls are made
- await new Promise(resolve => setTimeout(resolve, 1000));
-
- expect(mockApi.get.mock.calls.length).toBe(initialCallCount);
- });
- });
-
- describe('Error Handling', () => {
- test('should handle sync trigger errors gracefully', async () => {
- const idleSource = createMockSource({ status: 'idle' });
- mockApi.get.mockResolvedValue({ data: [idleSource] });
- mockSourcesService.triggerSync.mockRejectedValue(new Error('Sync failed'));
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source')).toBeInTheDocument();
- });
-
- // Click sync button
- const syncButton = screen.getByLabelText('Trigger Sync');
- fireEvent.click(syncButton);
-
- await waitFor(() => {
- expect(mockSourcesService.triggerSync).toHaveBeenCalledWith('test-source-123');
- });
-
- // Source should remain idle and no progress display should appear
- expect(screen.queryByText('Test WebDAV Source - Sync Progress')).not.toBeInTheDocument();
- });
-
- test('should handle progress stream connection errors', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- // Simulate SSE connection error
- act(() => {
- if (mockEventSource.onerror) {
- mockEventSource.onerror(new Event('error'));
- }
- });
-
- // Progress display should still be visible but show disconnected status
- await waitFor(() => {
- expect(screen.getByText('Disconnected')).toBeInTheDocument();
- });
- });
- });
-
- describe('Performance Considerations', () => {
- test('should only create progress streams for syncing sources', async () => {
- const sources = [
- createMockSource({ id: 'source-1', name: 'Source One', status: 'idle' }),
- createMockSource({ id: 'source-2', name: 'Source Two', status: 'syncing' }),
- createMockSource({ id: 'source-3', name: 'Source Three', status: 'error' }),
- ];
- mockApi.get.mockResolvedValue({ data: sources });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Source One')).toBeInTheDocument();
- expect(screen.getByText('Source Two')).toBeInTheDocument();
- expect(screen.getByText('Source Three')).toBeInTheDocument();
- });
-
- // Only the syncing source should create an SSE stream
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledTimes(1);
- expect(mockSourcesService.getSyncProgressStream).toHaveBeenCalledWith('source-2');
- });
-
- test('should cleanup progress streams when component unmounts', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- const { unmount } = renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- unmount();
-
- expect(mockEventSource.close).toHaveBeenCalled();
- });
- });
-
- describe('UI State Management', () => {
- test('should maintain progress display state during source list refresh', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- // Collapse the progress display
- const collapseButton = screen.getByLabelText('Collapse');
- fireEvent.click(collapseButton);
-
- await waitFor(() => {
- expect(screen.queryByText('Waiting for sync progress information...')).not.toBeInTheDocument();
- });
-
- // Simulate a source list refresh (which happens periodically)
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- // Force a re-render by triggering a state change
- await act(async () => {
- // The component should maintain the collapsed state
- });
-
- // Progress display should still be collapsed
- expect(screen.queryByText('Waiting for sync progress information...')).not.toBeInTheDocument();
- });
-
- test('should show appropriate status indicators', async () => {
- const syncingSource = createMockSource({ status: 'syncing' });
- mockApi.get.mockResolvedValue({ data: [syncingSource] });
-
- renderWithProviders();
-
- await waitFor(() => {
- expect(screen.getByText('Test WebDAV Source - Sync Progress')).toBeInTheDocument();
- });
-
- // Should show connecting status initially
- expect(screen.getByText('Connecting...')).toBeInTheDocument();
-
- // Simulate successful connection
- act(() => {
- if (mockEventSource.onopen) {
- mockEventSource.onopen(new Event('open'));
- }
- });
-
- // Simulate progress data
- const mockProgress = createMockProgressInfo();
- act(() => {
- const progressHandler = mockEventSource.addEventListener.mock.calls.find(
- call => call[0] === 'progress'
- )?.[1] as (event: MessageEvent) => void;
-
- if (progressHandler) {
- progressHandler(new MessageEvent('progress', {
- data: JSON.stringify(mockProgress)
- }));
- }
- });
-
- await waitFor(() => {
- expect(screen.getByText('Live')).toBeInTheDocument();
- });
- });
- });
-});
\ No newline at end of file