showcase/integrations/langgraph-python/qa/voice.md
/demos/voiceshowcase-langgraph-python is healthy (/api/health returns 200)OPENAI_API_KEY is set on the Railway service (shared with other demos)MediaRecorder (Chromium, Firefox, Safari 14+)public/demo-audio/sample.wav saying "What is the weather in Tokyo?" is present/demos/voicedata-testid="voice-sample-audio") is visibleSample: "What is the weather in Tokyo?"data-testid="voice-sample-audio-button") is enabled<CopilotChat /> renders a message composer (data-testid="copilot-chat-input")data-testid="copilot-start-transcribe-button") — this is the authoritative signal that transcriptionService is mounted on /api/copilotkit-voicedata-testid="copilot-chat-textarea") contains text that includes "weather" (case-insensitive) AND/OR "Tokyo" (case-insensitive)data-testid="copilot-send-button")data-testid="copilot-start-transcribe-button") in the composerdata-testid="copilot-finish-transcribe-button") to stop recording In DevTools → Network, block requests to /demo-audio/sample.wav
Click "Play sample"
Verify the row shows the error state (data-testid="voice-sample-audio-error") reading "Error — see console"
Verify no page crash; composer remains interactive
Remove the block and click "Play sample" again — verify the button recovers and completes the round-trip
Deny microphone permission, click the mic button
Verify the UI handles permission denial gracefully (no crash, mic button remains visible)