mirror of
https://github.com/jlengrand/Maestro.git
synced 2026-03-10 00:21:21 +00:00
- Create InlineWizardFlow.test.tsx with 53 tests covering the complete
inline wizard end-to-end flow
- Test coverage includes:
- Intent parsing (/wizard command modes)
- useInlineWizard hook lifecycle
- Confidence updates and "Let's Go" button rendering
- Error handling and retry flow
- Document generation progress tracking
- UI state restoration on wizard end
- Streaming and loading states
- Context provider behavior
- Update vitest.integration.config.ts to support React component tests
in integration folder with jsdom environment and setup files
- Fix pre-existing test failures:
- InlineWizardContext.test.tsx: Add missing state fields
(streamingContent, generationProgress, lastUserMessageContent)
- system.test.ts: Add new logger IPC handlers
(getLogFilePath, isFileLoggingEnabled, enableFileLogging)
747 lines
21 KiB
TypeScript
747 lines
21 KiB
TypeScript
/**
|
|
* Tests for InlineWizardContext
|
|
*
|
|
* This context provides cross-component access to inline wizard state.
|
|
* It wraps the useInlineWizard hook and exposes it via React context.
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { renderHook, act } from '@testing-library/react';
|
|
import React, { ReactNode } from 'react';
|
|
import {
|
|
InlineWizardProvider,
|
|
useInlineWizardContext,
|
|
} from '../../../renderer/contexts/InlineWizardContext';
|
|
import type { PreviousUIState } from '../../../renderer/hooks/useInlineWizard';
|
|
|
|
// Mock the dependencies used by useInlineWizard
|
|
vi.mock('../../../renderer/services/wizardIntentParser', () => ({
|
|
parseWizardIntent: vi.fn().mockReturnValue({ mode: 'iterate', goal: 'test goal' }),
|
|
}));
|
|
|
|
vi.mock('../../../renderer/utils/existingDocsDetector', () => ({
|
|
hasExistingAutoRunDocs: vi.fn().mockResolvedValue(false),
|
|
getExistingAutoRunDocs: vi.fn().mockResolvedValue([]),
|
|
getAutoRunFolderPath: vi.fn((projectPath: string) => `${projectPath}/Auto Run Docs`),
|
|
}));
|
|
|
|
vi.mock('../../../renderer/services/inlineWizardConversation', () => ({
|
|
startInlineWizardConversation: vi.fn().mockReturnValue({
|
|
sessionId: 'test-session-id',
|
|
agentType: 'claude-code',
|
|
directoryPath: '/test/project',
|
|
projectName: 'Test Project',
|
|
systemPrompt: 'Test system prompt',
|
|
isActive: true,
|
|
}),
|
|
sendWizardMessage: vi.fn().mockResolvedValue({
|
|
success: true,
|
|
response: {
|
|
confidence: 50,
|
|
ready: false,
|
|
message: 'Test response',
|
|
},
|
|
}),
|
|
endInlineWizardConversation: vi.fn().mockResolvedValue(undefined),
|
|
READY_CONFIDENCE_THRESHOLD: 80,
|
|
}));
|
|
|
|
// Wrapper component for testing hooks that need the provider
|
|
function createWrapper() {
|
|
return function Wrapper({ children }: { children: ReactNode }) {
|
|
return <InlineWizardProvider>{children}</InlineWizardProvider>;
|
|
};
|
|
}
|
|
|
|
describe('InlineWizardContext', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('useInlineWizardContext outside provider', () => {
|
|
it('should throw an error when used outside InlineWizardProvider', () => {
|
|
// Suppress console.error for this test since React will log the error
|
|
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
|
|
expect(() => {
|
|
renderHook(() => useInlineWizardContext());
|
|
}).toThrow('useInlineWizardContext must be used within an InlineWizardProvider');
|
|
|
|
consoleSpy.mockRestore();
|
|
});
|
|
});
|
|
|
|
describe('initial state', () => {
|
|
it('should return inactive wizard state initially', () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
expect(result.current.isWizardActive).toBe(false);
|
|
expect(result.current.wizardMode).toBeNull();
|
|
expect(result.current.wizardGoal).toBeNull();
|
|
expect(result.current.confidence).toBe(0);
|
|
expect(result.current.conversationHistory).toEqual([]);
|
|
expect(result.current.isGeneratingDocs).toBe(false);
|
|
expect(result.current.generatedDocuments).toEqual([]);
|
|
expect(result.current.error).toBeNull();
|
|
});
|
|
|
|
it('should return full state object', () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
expect(result.current.state).toEqual({
|
|
isActive: false,
|
|
isInitializing: false,
|
|
isWaiting: false,
|
|
mode: null,
|
|
goal: null,
|
|
confidence: 0,
|
|
ready: false,
|
|
conversationHistory: [],
|
|
isGeneratingDocs: false,
|
|
generatedDocuments: [],
|
|
existingDocuments: [],
|
|
previousUIState: null,
|
|
error: null,
|
|
projectPath: null,
|
|
agentType: null,
|
|
sessionName: null,
|
|
streamingContent: '',
|
|
generationProgress: null,
|
|
lastUserMessageContent: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('startWizard', () => {
|
|
it('should activate the wizard when called', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
expect(result.current.isWizardActive).toBe(true);
|
|
});
|
|
|
|
it('should set mode to new when no input provided and no existing docs', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
// No project path provided → no existing docs check → defaults to 'new'
|
|
expect(result.current.wizardMode).toBe('new');
|
|
});
|
|
|
|
it('should parse intent and set mode when input is provided', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard('add authentication');
|
|
});
|
|
|
|
expect(result.current.isWizardActive).toBe(true);
|
|
// Mode is now determined by intent parser (mocked to return 'iterate')
|
|
expect(result.current.wizardMode).toBe('iterate');
|
|
});
|
|
|
|
it('should store previous UI state', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
const previousUIState: PreviousUIState = {
|
|
readOnlyMode: true,
|
|
saveToHistory: false,
|
|
showThinking: true,
|
|
};
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard('test', previousUIState);
|
|
});
|
|
|
|
expect(result.current.state.previousUIState).toEqual(previousUIState);
|
|
});
|
|
|
|
it('should reset conversation history when starting', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
// Start wizard and add a message
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.sendMessage('test message');
|
|
});
|
|
|
|
expect(result.current.conversationHistory.length).toBeGreaterThan(0);
|
|
|
|
// Start wizard again - should reset
|
|
await act(async () => {
|
|
await result.current.startWizard('new session');
|
|
});
|
|
|
|
expect(result.current.conversationHistory).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('endWizard', () => {
|
|
it('should deactivate the wizard', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
expect(result.current.isWizardActive).toBe(true);
|
|
|
|
await act(async () => {
|
|
await result.current.endWizard();
|
|
});
|
|
|
|
expect(result.current.isWizardActive).toBe(false);
|
|
});
|
|
|
|
it('should return the previous UI state', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
const previousUIState: PreviousUIState = {
|
|
readOnlyMode: true,
|
|
saveToHistory: false,
|
|
showThinking: true,
|
|
};
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard('test', previousUIState);
|
|
});
|
|
|
|
let returnedState: PreviousUIState | null = null;
|
|
await act(async () => {
|
|
returnedState = await result.current.endWizard();
|
|
});
|
|
|
|
expect(returnedState).toEqual(previousUIState);
|
|
});
|
|
|
|
it('should reset all state to initial values', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
// Build up some state
|
|
await act(async () => {
|
|
await result.current.startWizard('test');
|
|
});
|
|
|
|
await act(async () => {
|
|
result.current.setMode('new');
|
|
result.current.setGoal('add feature');
|
|
result.current.setConfidence(75);
|
|
await result.current.sendMessage('hello');
|
|
result.current.setGeneratingDocs(true);
|
|
result.current.setError('test error');
|
|
});
|
|
|
|
// End wizard
|
|
await act(async () => {
|
|
await result.current.endWizard();
|
|
});
|
|
|
|
// All state should be reset
|
|
expect(result.current.state).toEqual({
|
|
isActive: false,
|
|
isInitializing: false,
|
|
isWaiting: false,
|
|
mode: null,
|
|
goal: null,
|
|
confidence: 0,
|
|
ready: false,
|
|
conversationHistory: [],
|
|
isGeneratingDocs: false,
|
|
generatedDocuments: [],
|
|
existingDocuments: [],
|
|
previousUIState: null,
|
|
error: null,
|
|
projectPath: null,
|
|
agentType: null,
|
|
sessionName: null,
|
|
streamingContent: '',
|
|
generationProgress: null,
|
|
lastUserMessageContent: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('sendMessage', () => {
|
|
it('should add a user message to conversation history', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.sendMessage('Hello, wizard!');
|
|
});
|
|
|
|
expect(result.current.conversationHistory).toHaveLength(1);
|
|
expect(result.current.conversationHistory[0].role).toBe('user');
|
|
expect(result.current.conversationHistory[0].content).toBe('Hello, wizard!');
|
|
});
|
|
|
|
it('should generate unique message IDs', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.sendMessage('Message 1');
|
|
result.current.sendMessage('Message 2');
|
|
});
|
|
|
|
const ids = result.current.conversationHistory.map((m) => m.id);
|
|
expect(ids[0]).not.toBe(ids[1]);
|
|
});
|
|
|
|
it('should include timestamp on messages', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
const beforeTime = Date.now();
|
|
|
|
act(() => {
|
|
result.current.sendMessage('Test message');
|
|
});
|
|
|
|
const afterTime = Date.now();
|
|
const messageTime = result.current.conversationHistory[0].timestamp;
|
|
|
|
expect(messageTime).toBeGreaterThanOrEqual(beforeTime);
|
|
expect(messageTime).toBeLessThanOrEqual(afterTime);
|
|
});
|
|
});
|
|
|
|
describe('addAssistantMessage', () => {
|
|
it('should add an assistant message to conversation history', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.addAssistantMessage('I can help with that!');
|
|
});
|
|
|
|
expect(result.current.conversationHistory).toHaveLength(1);
|
|
expect(result.current.conversationHistory[0].role).toBe('assistant');
|
|
expect(result.current.conversationHistory[0].content).toBe('I can help with that!');
|
|
});
|
|
|
|
it('should include confidence when provided', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.addAssistantMessage('Understanding better...', 65);
|
|
});
|
|
|
|
expect(result.current.conversationHistory[0].confidence).toBe(65);
|
|
expect(result.current.confidence).toBe(65);
|
|
});
|
|
|
|
it('should include ready flag when provided', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.addAssistantMessage('Ready to generate!', 85, true);
|
|
});
|
|
|
|
expect(result.current.conversationHistory[0].ready).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('setConfidence', () => {
|
|
it('should update confidence value', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setConfidence(50);
|
|
});
|
|
|
|
expect(result.current.confidence).toBe(50);
|
|
});
|
|
|
|
it('should clamp confidence to 0-100 range', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setConfidence(150);
|
|
});
|
|
|
|
expect(result.current.confidence).toBe(100);
|
|
|
|
act(() => {
|
|
result.current.setConfidence(-50);
|
|
});
|
|
|
|
expect(result.current.confidence).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('setMode', () => {
|
|
it('should update wizard mode', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setMode('new');
|
|
});
|
|
|
|
expect(result.current.wizardMode).toBe('new');
|
|
|
|
act(() => {
|
|
result.current.setMode('iterate');
|
|
});
|
|
|
|
expect(result.current.wizardMode).toBe('iterate');
|
|
});
|
|
});
|
|
|
|
describe('setGoal', () => {
|
|
it('should update wizard goal', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setGoal('add user authentication');
|
|
});
|
|
|
|
expect(result.current.wizardGoal).toBe('add user authentication');
|
|
});
|
|
|
|
it('should allow null goal', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setGoal('some goal');
|
|
});
|
|
|
|
expect(result.current.wizardGoal).toBe('some goal');
|
|
|
|
act(() => {
|
|
result.current.setGoal(null);
|
|
});
|
|
|
|
expect(result.current.wizardGoal).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('setGeneratingDocs', () => {
|
|
it('should update generating docs state', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setGeneratingDocs(true);
|
|
});
|
|
|
|
expect(result.current.isGeneratingDocs).toBe(true);
|
|
|
|
act(() => {
|
|
result.current.setGeneratingDocs(false);
|
|
});
|
|
|
|
expect(result.current.isGeneratingDocs).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('setGeneratedDocuments', () => {
|
|
it('should update generated documents', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
const docs = [
|
|
{ filename: 'phase-1.md', content: '# Phase 1', taskCount: 5 },
|
|
{ filename: 'phase-2.md', content: '# Phase 2', taskCount: 3 },
|
|
];
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setGeneratedDocuments(docs);
|
|
});
|
|
|
|
expect(result.current.generatedDocuments).toEqual(docs);
|
|
});
|
|
|
|
it('should set isGeneratingDocs to false when documents are set', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setGeneratingDocs(true);
|
|
});
|
|
|
|
expect(result.current.isGeneratingDocs).toBe(true);
|
|
|
|
act(() => {
|
|
result.current.setGeneratedDocuments([
|
|
{ filename: 'test.md', content: '# Test', taskCount: 1 },
|
|
]);
|
|
});
|
|
|
|
expect(result.current.isGeneratingDocs).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('setError', () => {
|
|
it('should update error state', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setError('Something went wrong');
|
|
});
|
|
|
|
expect(result.current.error).toBe('Something went wrong');
|
|
});
|
|
|
|
it('should allow clearing error', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setError('Error');
|
|
});
|
|
|
|
expect(result.current.error).toBe('Error');
|
|
|
|
act(() => {
|
|
result.current.setError(null);
|
|
});
|
|
|
|
expect(result.current.error).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('clearConversation', () => {
|
|
it('should clear conversation history', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
await act(async () => {
|
|
await result.current.startWizard();
|
|
});
|
|
|
|
act(() => {
|
|
result.current.sendMessage('Message 1');
|
|
result.current.addAssistantMessage('Response 1');
|
|
result.current.sendMessage('Message 2');
|
|
});
|
|
|
|
expect(result.current.conversationHistory).toHaveLength(3);
|
|
|
|
act(() => {
|
|
result.current.clearConversation();
|
|
});
|
|
|
|
expect(result.current.conversationHistory).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('reset', () => {
|
|
it('should reset all state to initial values', async () => {
|
|
const { result } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
// Build up state
|
|
await act(async () => {
|
|
await result.current.startWizard('test', {
|
|
readOnlyMode: true,
|
|
saveToHistory: false,
|
|
showThinking: true,
|
|
});
|
|
});
|
|
|
|
act(() => {
|
|
result.current.setMode('iterate');
|
|
result.current.setGoal('add feature');
|
|
result.current.setConfidence(80);
|
|
result.current.sendMessage('test');
|
|
result.current.setGeneratingDocs(true);
|
|
result.current.setError('error');
|
|
});
|
|
|
|
// Reset
|
|
act(() => {
|
|
result.current.reset();
|
|
});
|
|
|
|
// Verify everything is reset
|
|
expect(result.current.isWizardActive).toBe(false);
|
|
expect(result.current.wizardMode).toBeNull();
|
|
expect(result.current.wizardGoal).toBeNull();
|
|
expect(result.current.confidence).toBe(0);
|
|
expect(result.current.conversationHistory).toEqual([]);
|
|
expect(result.current.isGeneratingDocs).toBe(false);
|
|
expect(result.current.generatedDocuments).toEqual([]);
|
|
expect(result.current.error).toBeNull();
|
|
expect(result.current.state.previousUIState).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('callback stability', () => {
|
|
it('should return stable action callbacks across renders', () => {
|
|
const { result, rerender } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper: createWrapper(),
|
|
});
|
|
|
|
const startWizard1 = result.current.startWizard;
|
|
const endWizard1 = result.current.endWizard;
|
|
const sendMessage1 = result.current.sendMessage;
|
|
const setConfidence1 = result.current.setConfidence;
|
|
const setMode1 = result.current.setMode;
|
|
const setGoal1 = result.current.setGoal;
|
|
const reset1 = result.current.reset;
|
|
|
|
rerender();
|
|
|
|
expect(result.current.startWizard).toBe(startWizard1);
|
|
expect(result.current.endWizard).toBe(endWizard1);
|
|
expect(result.current.sendMessage).toBe(sendMessage1);
|
|
expect(result.current.setConfidence).toBe(setConfidence1);
|
|
expect(result.current.setMode).toBe(setMode1);
|
|
expect(result.current.setGoal).toBe(setGoal1);
|
|
expect(result.current.reset).toBe(reset1);
|
|
});
|
|
});
|
|
|
|
describe('multiple consumers', () => {
|
|
it('should share state between multiple consumers', async () => {
|
|
// Create a shared wrapper
|
|
const wrapper = createWrapper();
|
|
|
|
// First consumer
|
|
const { result: consumer1 } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper,
|
|
});
|
|
|
|
// Second consumer (same wrapper instance)
|
|
const { result: consumer2 } = renderHook(() => useInlineWizardContext(), {
|
|
wrapper,
|
|
});
|
|
|
|
// Start wizard from consumer1
|
|
await act(async () => {
|
|
await consumer1.current.startWizard('test');
|
|
});
|
|
|
|
// Both consumers should see the change
|
|
// Note: In a real app they'd share the same provider instance
|
|
// This test verifies the context value structure is consistent
|
|
expect(consumer1.current.isWizardActive).toBe(true);
|
|
// consumer2 has its own instance in this test setup
|
|
});
|
|
});
|
|
});
|