Testing utilities
import ApiTable from "../../../../components/docs/ApiTable.astro"; Helpers for unit and integration testing. Import from `@arlopass/react/testing`. ```tsx import { createMockTransport, MockArlopassProvider, mockWindowArlopass, cleanupWindowArlopass, simulateExternalDisconnect, waitForSnapshot, waitForChat, waitForStream, waitForState, } from "@arlopass/react/testing"; ``` --- ### createMockTransport Creates a `ArlopassTransport` that responds to protocol capabilities without a real extension. Supports configurable responses, errors, latency, and streaming. <ApiTable props={[ { name: "capabilities", type: "readonly string[]", default: '["session.create", "provider.list", "chat.completions", "chat.stream"]', description: "Capabilities returned on session.create.", }, { name: "providers", type: "readonly { providerId: string; providerName: string; models: readonly string[] }[]", default: '[{ providerId: "mock", providerName: "Mock Provider", models: ["mock-model"] }]', description: "Providers returned on provider.list.", }, { name: "chatResponse", type: "string | (() => string)", default: '"Hello from mock!"', description: "Response for chat.completions. Can be a string or a factory function.", }, { name: "failOn", type: "string", description: 'Capability name to throw an error on (e.g. "chat.completions").', }, { name: "chatError", type: "Error", description: "Specific error to throw on chat.completions.", }, { name: "latency", type: "number", default: "0", description: "Simulated latency in milliseconds before responding.", }, { name: "streamChunks", type: "readonly string[]", description: "Individual chunks for chat.stream. Each string becomes a chunk payload.", }, { name: "streamResponse", type: "string", description: "Full stream response — overrides streamChunks when set.", }, ]} /> ```tsx const transport = createMockTransport({ chatResponse: "Hello!", latency: 100, }); ``` --- ### MockArlopassProvider Test wrapper that injects a mock transport into `window.arlopass` and wraps children with `<ArlopassProvider>`. Drop-in replacement for the real provider in test renders. <ApiTable props={[ { name: "transport", type: "ArlopassTransport", required: true, description: "Mock transport to inject as window.arlopass.", }, { name: "appId", type: "string", default: '"test"', description: "App ID for the provider.", }, { name: "children", type: "ReactNode", required: true, description: "Components under test.", }, { name: "...rest", type: "ArlopassProviderProps", description: "All other ArlopassProvider props (defaultProvider, autoConnect, etc.).", }, ]} /> ```tsx const transport = createMockTransport(); render( <MockArlopassProvider transport={transport}> <MyComponent /> </MockArlopassProvider>, ); ``` --- ### Window mocks Low-level functions for controlling `window.arlopass` in tests. <ApiTable props={[ { name: "mockWindowArlopass", type: "(transport: ArlopassTransport) => void", description: "Injects a transport as window.arlopass. Use before rendering ArlopassProvider in tests.", }, { name: "cleanupWindowArlopass", type: "() => void", description: "Removes window.arlopass to simulate extension not installed.", }, { name: "simulateExternalDisconnect", type: "(transport: ArlopassTransport) => Promise<void>", description: "Removes window.arlopass and calls transport.disconnect() if available.", }, ]} /> ```tsx // Setup mockWindowArlopass(transport); // Teardown cleanupWindowArlopass(); // Simulate disconnect await simulateExternalDisconnect(transport); ``` --- ### Wait helpers Polling utilities for async test assertions. All accept an optional `timeout` (default 3000ms, poll interval 50ms). <ApiTable props={[ { name: "waitForSnapshot", type: "(store: ClientStore, predicate: (snapshot: ClientSnapshot) => boolean, options?: { timeout?: number }) => Promise<ClientSnapshot>", description: "Polls the store until the predicate returns true. Default timeout: 3000ms.", }, { name: "waitForChat", type: "(screen: Screen, testId?: string) => Promise<HTMLElement>", description: 'Waits for an element with the given data-testid (default: "chat-ready") to appear.', }, { name: "waitForStream", type: "(screen: Screen, options?: { timeout?: number }) => Promise<void>", description: 'Waits until the streaming indicator disappears (data-testid="streaming" is removed).', }, { name: "waitForState", type: "(screen: Screen, state: string, options?: { timeout?: number }) => Promise<void>", description: 'Waits until data-testid="state" has the given text content.', }, ]} /> ```tsx // Wait for connected state await waitForState(screen, "connected"); // Wait for streaming to finish await waitForStream(screen, { timeout: 5000 }); ```Helpers for unit and integration testing. Import from @arlopass/react/testing.
import {
createMockTransport,
MockArlopassProvider,
mockWindowArlopass,
cleanupWindowArlopass,
simulateExternalDisconnect,
waitForSnapshot,
waitForChat,
waitForStream,
waitForState,
} from "@arlopass/react/testing";
createMockTransport
Creates a ArlopassTransport that responds to protocol capabilities without a real extension. Supports configurable responses, errors, latency, and streaming.
| Prop | Type | Default | Description |
|---|---|---|---|
capabilities | readonly string[] | ["session.create", "provider.list", "chat.completions", "chat.stream"] | Capabilities returned on session.create. |
providers | readonly { providerId: string; providerName: string; models: readonly string[] }[] | [{ providerId: "mock", providerName: "Mock Provider", models: ["mock-model"] }] | Providers returned on provider.list. |
chatResponse | string | (() => string) | "Hello from mock!" | Response for chat.completions. Can be a string or a factory function. |
failOn | string | — | Capability name to throw an error on (e.g. "chat.completions"). |
chatError | Error | — | Specific error to throw on chat.completions. |
latency | number | 0 | Simulated latency in milliseconds before responding. |
streamChunks | readonly string[] | — | Individual chunks for chat.stream. Each string becomes a chunk payload. |
streamResponse | string | — | Full stream response — overrides streamChunks when set. |
const transport = createMockTransport({
chatResponse: "Hello!",
latency: 100,
});
MockArlopassProvider
Test wrapper that injects a mock transport into window.arlopass and wraps children with <ArlopassProvider>. Drop-in replacement for the real provider in test renders.
| Prop | Type | Default | Description |
|---|---|---|---|
transport
required
| ArlopassTransport | — | Mock transport to inject as window.arlopass. |
appId | string | "test" | App ID for the provider. |
children
required
| ReactNode | — | Components under test. |
...rest | ArlopassProviderProps | — | All other ArlopassProvider props (defaultProvider, autoConnect, etc.). |
const transport = createMockTransport();
render(
<MockArlopassProvider transport={transport}>
<MyComponent />
</MockArlopassProvider>,
);
Window mocks
Low-level functions for controlling window.arlopass in tests.
| Prop | Type | Default | Description |
|---|---|---|---|
mockWindowArlopass | (transport: ArlopassTransport) => void | — | Injects a transport as window.arlopass. Use before rendering ArlopassProvider in tests. |
cleanupWindowArlopass | () => void | — | Removes window.arlopass to simulate extension not installed. |
simulateExternalDisconnect | (transport: ArlopassTransport) => Promise<void> | — | Removes window.arlopass and calls transport.disconnect() if available. |
// Setup
mockWindowArlopass(transport);
// Teardown
cleanupWindowArlopass();
// Simulate disconnect
await simulateExternalDisconnect(transport);
Wait helpers
Polling utilities for async test assertions. All accept an optional timeout (default 3000ms, poll interval 50ms).
| Prop | Type | Default | Description |
|---|---|---|---|
waitForSnapshot | (store: ClientStore, predicate: (snapshot: ClientSnapshot) => boolean, options?: { timeout?: number }) => Promise<ClientSnapshot> | — | Polls the store until the predicate returns true. Default timeout: 3000ms. |
waitForChat | (screen: Screen, testId?: string) => Promise<HTMLElement> | — | Waits for an element with the given data-testid (default: "chat-ready") to appear. |
waitForStream | (screen: Screen, options?: { timeout?: number }) => Promise<void> | — | Waits until the streaming indicator disappears (data-testid="streaming" is removed). |
waitForState | (screen: Screen, state: string, options?: { timeout?: number }) => Promise<void> | — | Waits until data-testid="state" has the given text content. |
// Wait for connected state
await waitForState(screen, "connected");
// Wait for streaming to finish
await waitForStream(screen, { timeout: 5000 });