diff --git a/.github/workflows/mobile-e2e.yml b/.github/workflows/mobile-e2e.yml index 0813deef..219a3590 100644 --- a/.github/workflows/mobile-e2e.yml +++ b/.github/workflows/mobile-e2e.yml @@ -129,7 +129,8 @@ jobs: working-directory: mobile run: | export PATH="$HOME/.maestro/bin:$PATH" - maestro test .maestro/flows/ --format junit --output maestro-report.xml + # Exclude chat tests (require backend) - run those locally + maestro test .maestro/flows/ --exclude-tags=chat --format junit --output maestro-report.xml env: MAESTRO_DRIVER_STARTUP_TIMEOUT: 120000 diff --git a/mobile/.maestro/flows/03-chat-claude-code.yaml b/mobile/.maestro/flows/03-chat-claude-code.yaml new file mode 100644 index 00000000..b5f246f8 --- /dev/null +++ b/mobile/.maestro/flows/03-chat-claude-code.yaml @@ -0,0 +1,66 @@ +appId: com.gricha.perry +name: Chat - Claude Code +tags: + - chat + - claude-code +--- +- launchApp: + clearState: true + +# Configure server connection +- tapOn: + id: "hostname-input" +- inputText: "localhost" +- tapOn: + id: "port-input" +- eraseText +- inputText: "7391" +- tapOn: + id: "connect-button" + +# Wait for workspace list to load +- extendedWaitUntil: + visible: "test" + timeout: 30000 + +# Tap on test workspace +- tapOn: "test" + +# Wait for workspace detail screen +- extendedWaitUntil: + visible: + id: "new-chat-button" + timeout: 10000 + +# Start new Claude Code chat +- tapOn: + id: "new-chat-button" + +# Select Claude Code from picker +- tapOn: + id: "new-chat-claude-code" + +# Wait for chat screen to load and connect +- extendedWaitUntil: + visible: + id: "chat-input" + timeout: 15000 + +# Type and send a simple message +- tapOn: + id: "chat-input" +- inputText: "Say hello" +- tapOn: + id: "send-button" + +# Verify thinking dots appear (streaming started) +- extendedWaitUntil: + visible: + id: "thinking-dots" + timeout: 10000 + +# Wait for response to complete (thinking dots disappear, assistant message appears) +- extendedWaitUntil: + visible: + id: "assistant-message" + timeout: 120000 diff --git a/mobile/.maestro/flows/04-chat-opencode.yaml b/mobile/.maestro/flows/04-chat-opencode.yaml new file mode 100644 index 00000000..8911dab2 --- /dev/null +++ b/mobile/.maestro/flows/04-chat-opencode.yaml @@ -0,0 +1,66 @@ +appId: com.gricha.perry +name: Chat - OpenCode +tags: + - chat + - opencode +--- +- launchApp: + clearState: true + +# Configure server connection +- tapOn: + id: "hostname-input" +- inputText: "localhost" +- tapOn: + id: "port-input" +- eraseText +- inputText: "7391" +- tapOn: + id: "connect-button" + +# Wait for workspace list to load +- extendedWaitUntil: + visible: "test" + timeout: 30000 + +# Tap on test workspace +- tapOn: "test" + +# Wait for workspace detail screen +- extendedWaitUntil: + visible: + id: "new-chat-button" + timeout: 10000 + +# Start new OpenCode chat +- tapOn: + id: "new-chat-button" + +# Select OpenCode from picker +- tapOn: + id: "new-chat-opencode" + +# Wait for chat screen to load and connect +- extendedWaitUntil: + visible: + id: "chat-input" + timeout: 15000 + +# Type and send a simple message +- tapOn: + id: "chat-input" +- inputText: "Say hello" +- tapOn: + id: "send-button" + +# Verify thinking dots appear (streaming started) +- extendedWaitUntil: + visible: + id: "thinking-dots" + timeout: 10000 + +# Wait for response to complete (thinking dots disappear, assistant message appears) +- extendedWaitUntil: + visible: + id: "assistant-message" + timeout: 120000 diff --git a/mobile/src/screens/SessionChatScreen.tsx b/mobile/src/screens/SessionChatScreen.tsx index 5a7e384c..43fbab16 100644 --- a/mobile/src/screens/SessionChatScreen.tsx +++ b/mobile/src/screens/SessionChatScreen.tsx @@ -177,7 +177,7 @@ function MessageBubble({ message }: { message: ChatMessage }) { if (message.role === 'user') { return ( - + {trimmedContent} ) @@ -192,7 +192,7 @@ function MessageBubble({ message }: { message: ChatMessage }) { } return ( - + {trimmedContent} ) @@ -230,7 +230,7 @@ function ThinkingDots() { }, [dot1, dot2, dot3]) return ( - + @@ -684,9 +684,10 @@ export function SessionChatScreen({ route, navigation }: any) { multiline maxLength={4000} editable={connected && !isStreaming} + testID="chat-input" /> {isStreaming ? ( - + Stop ) : ( @@ -694,6 +695,7 @@ export function SessionChatScreen({ route, navigation }: any) { style={[styles.sendBtn, (!connected || !input.trim()) && styles.sendBtnDisabled]} onPress={sendMessage} disabled={!connected || !input.trim()} + testID="send-button" > Send diff --git a/mobile/src/screens/WorkspaceDetailScreen.tsx b/mobile/src/screens/WorkspaceDetailScreen.tsx index e0accdb9..b68ca44b 100644 --- a/mobile/src/screens/WorkspaceDetailScreen.tsx +++ b/mobile/src/screens/WorkspaceDetailScreen.tsx @@ -260,6 +260,7 @@ export function WorkspaceDetailScreen({ route, navigation }: any) { setShowNewChatPicker(false) navigation.navigate('SessionChat', { workspaceName: name, isNew: true, agentType: type }) }} + testID={`new-chat-${type}`} > {type === 'claude-code' ? 'CC' : type === 'opencode' ? 'OC' : 'CX'}