/ tests / web_terminal_console / utils / renderWithProviders.tsx
renderWithProviders.tsx
 1  import { render, RenderOptions } from '@testing-library/react';
 2  import React, { ReactElement } from 'react';
 3  import { BrowserRouter, MemoryRouter } from 'react-router-dom';
 4  import { AuthProvider } from '../../../src/web_terminal_client/src/AuthContext';
 5  
 6  interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
 7    initialEntries?: string[];
 8    useMemoryRouter?: boolean;
 9  }
10  
11  /**
12   * Custom render function that wraps components with all necessary providers.
13   */
14  export function renderWithProviders(
15    ui: ReactElement,
16    options: CustomRenderOptions = {}
17  ) {
18    const { initialEntries = ['/'], useMemoryRouter = false, ...renderOptions } = options;
19  
20    function Wrapper({ children }: { children: React.ReactNode }) {
21      const Router = useMemoryRouter
22        ? ({ children }: { children: React.ReactNode }) => (
23            <MemoryRouter initialEntries={initialEntries}>{children}</MemoryRouter>
24          )
25        : BrowserRouter;
26  
27      return (
28        <Router>
29          <AuthProvider>{children}</AuthProvider>
30        </Router>
31      );
32    }
33  
34    return {
35      ...render(ui, { wrapper: Wrapper, ...renderOptions }),
36    };
37  }
38  
39  /**
40   * Render with just a router (no AuthProvider) for simpler component tests.
41   */
42  export function renderWithRouter(
43    ui: ReactElement,
44    options: CustomRenderOptions = {}
45  ) {
46    const { initialEntries = ['/'], useMemoryRouter = true, ...renderOptions } = options;
47  
48    function Wrapper({ children }: { children: React.ReactNode }) {
49      return useMemoryRouter ? (
50        <MemoryRouter initialEntries={initialEntries}>{children}</MemoryRouter>
51      ) : (
52        <BrowserRouter>{children}</BrowserRouter>
53      );
54    }
55  
56    return {
57      ...render(ui, { wrapper: Wrapper, ...renderOptions }),
58    };
59  }
60  
61  /**
62   * Wait for async operations to complete.
63   */
64  export function waitForAsync(ms: number = 0): Promise<void> {
65    return new Promise((resolve) => setTimeout(resolve, ms));
66  }
67  
68  /**
69   * Create a deferred promise for testing async flows.
70   */
71  export function createDeferred<T>() {
72    let resolve: (value: T) => void;
73    let reject: (reason?: unknown) => void;
74  
75    const promise = new Promise<T>((res, rej) => {
76      resolve = res;
77      reject = rej;
78    });
79  
80    return { promise, resolve: resolve!, reject: reject! };
81  }