Skip to content

Add Maestro chat tests for Claude Code and OpenCode #7

Add Maestro chat tests for Claude Code and OpenCode

Add Maestro chat tests for Claude Code and OpenCode #7

Workflow file for this run

name: Mobile E2E Tests
on:
push:
branches: [main]
paths:
- 'mobile/**'
pull_request:
branches: [main]
paths:
- 'mobile/**'
workflow_dispatch:
# Weekly run to catch regressions
schedule:
- cron: '0 9 * * 1' # Monday 9am UTC
jobs:
maestro-ios:
runs-on: macos-14
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Cache bun dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
mobile/node_modules
web/node_modules
key: ${{ runner.os }}-bun-all-${{ hashFiles('bun.lock', 'mobile/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-all-
- name: Install dependencies
run: |
bun install
cd mobile && bun install
cd ../web && bun install
- name: Install Docker via Colima
run: |
brew install colima docker
colima start --cpu 4 --memory 8 --disk 20
docker info
- name: Build workspace image
run: docker build -t perry:latest ./perry
- name: Start Perry agent
run: |
bun run src/index.ts agent run --port 7391 &
sleep 5
curl -s http://localhost:7391/health || (echo "Agent failed to start" && exit 1)
- name: Create test workspace
run: |
bun run src/index.ts start test
bun run src/index.ts list
- name: Select Xcode version
run: |
# Try Xcode 16.2 first, fall back to 16.1 if not available
if [ -d "/Applications/Xcode_16.2.app" ]; then
sudo xcode-select -s /Applications/Xcode_16.2.app
elif [ -d "/Applications/Xcode_16.1.app" ]; then
sudo xcode-select -s /Applications/Xcode_16.1.app
elif [ -d "/Applications/Xcode_16.app" ]; then
sudo xcode-select -s /Applications/Xcode_16.app
else
echo "Available Xcode versions:"
ls -d /Applications/Xcode*.app 2>/dev/null || echo "No Xcode found"
exit 1
fi
xcodebuild -version
- name: Generate iOS native code
working-directory: mobile
run: bunx expo prebuild --platform ios --clean
- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: mobile/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('mobile/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Install CocoaPods dependencies
working-directory: mobile/ios
run: pod install
- name: List available simulators
run: xcrun simctl list devices available
- name: Boot iOS Simulator
run: |
DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone 16" | head -1 | grep -oE '[A-F0-9-]{36}')
if [ -z "$DEVICE_ID" ]; then
DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone 15" | head -1 | grep -oE '[A-F0-9-]{36}')
fi
if [ -z "$DEVICE_ID" ]; then
DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone" | head -1 | grep -oE '[A-F0-9-]{36}')
fi
echo "DEVICE_ID=$DEVICE_ID" >> $GITHUB_ENV
xcrun simctl boot "$DEVICE_ID" || true
xcrun simctl bootstatus "$DEVICE_ID" -b
- name: Cache Xcode build
uses: actions/cache@v4
with:
path: mobile/ios/build
key: ${{ runner.os }}-xcode-${{ hashFiles('mobile/ios/Podfile.lock', 'mobile/src/**/*.ts', 'mobile/src/**/*.tsx') }}
restore-keys: |
${{ runner.os }}-xcode-
- name: Build iOS app for simulator
working-directory: mobile/ios
run: |
xcodebuild -workspace Perry.xcworkspace \
-scheme Perry \
-configuration Release \
-sdk iphonesimulator \
-destination "id=${{ env.DEVICE_ID }}" \
-derivedDataPath build \
build
- name: Install app on simulator
run: |
APP_PATH=$(find mobile/ios/build -name "*.app" -type d | head -1)
xcrun simctl install "${{ env.DEVICE_ID }}" "$APP_PATH"
- name: Install Maestro
run: |
curl -Ls "https://get.maestro.mobile.dev" | bash
echo "$HOME/.maestro/bin" >> $GITHUB_PATH
- name: Launch app and take debug screenshot
run: |
export PATH="$HOME/.maestro/bin:$PATH"
xcrun simctl launch "${{ env.DEVICE_ID }}" com.gricha.perry || true
sleep 5
xcrun simctl io "${{ env.DEVICE_ID }}" screenshot /tmp/app-launch-debug.png || true
- name: Run Maestro tests
working-directory: mobile
run: |
export PATH="$HOME/.maestro/bin:$PATH"
maestro test .maestro/flows/ --format junit --output maestro-report.xml
env:
MAESTRO_DRIVER_STARTUP_TIMEOUT: 120000
- name: Upload debug screenshot
uses: actions/upload-artifact@v4
if: failure()
with:
name: debug-screenshot
path: /tmp/app-launch-debug.png
retention-days: 7
- name: Upload Maestro report
uses: actions/upload-artifact@v4
if: always()
with:
name: maestro-report
path: mobile/maestro-report.xml
retention-days: 7
- name: Upload Maestro screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: maestro-screenshots
path: ~/.maestro/tests/
retention-days: 7