[REFACTORING] Indoor Poi Marker Factory (#218) #142
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Maestro E2E iOS | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| types: [opened, reopened] | |
| workflow_dispatch: | |
| jobs: | |
| e2e-ios: | |
| runs-on: macos-latest | |
| timeout-minutes: 75 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Inject Google API key for Expo build | |
| run: | | |
| if [ -n "${{ secrets.EXPO_PUBLIC_GOOGLE_API_KEY }}" ]; then | |
| echo "EXPO_PUBLIC_GOOGLE_API_KEY=${{ secrets.EXPO_PUBLIC_GOOGLE_API_KEY }}" >> "$GITHUB_ENV" | |
| elif [ -n "${{ secrets.GOOGLE_API_KEY }}" ]; then | |
| echo "EXPO_PUBLIC_GOOGLE_API_KEY=${{ secrets.GOOGLE_API_KEY }}" >> "$GITHUB_ENV" | |
| else | |
| echo "ERROR: Missing GitHub secret. Set EXPO_PUBLIC_GOOGLE_API_KEY (preferred) or GOOGLE_API_KEY." >&2 | |
| exit 1 | |
| fi | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20.19.4" | |
| cache: "npm" | |
| - name: Install JS dependencies | |
| run: npm ci --ignore-scripts --prefer-offline --no-audit | |
| - name: Ensure iOS native project | |
| run: | | |
| if [ ! -d ios ]; then | |
| npx expo prebuild -p ios --clean --no-install --non-interactive | |
| fi | |
| - name: Install CocoaPods | |
| run: | | |
| cd ios | |
| pod install | |
| cd .. | |
| - name: Select simulator | |
| run: | | |
| LINE=$(xcrun simctl list devices available | grep "iPhone" | head -1) | |
| DEVICE=$(echo "$LINE" | sed -nE 's/.*\(([0-9A-F-]{36})\).*/\1/p') | |
| echo "DEVICE_UDID=$DEVICE" >> $GITHUB_ENV | |
| - name: Resolve workspace and scheme | |
| id: xcode | |
| run: | | |
| cd ios | |
| WORKSPACE=$(find . -maxdepth 1 -name '*.xcworkspace' | head -1) | |
| SCHEME=$(xcodebuild -list 2>/dev/null | sed -n '1,/Schemes:/d;/^$/q;p' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v -E 'Tests|UITests' | head -1) | |
| echo "workspace=$(basename "$WORKSPACE")" >> $GITHUB_OUTPUT | |
| echo "scheme=$SCHEME" >> $GITHUB_OUTPUT | |
| cd .. | |
| - name: Build iOS app for Simulator | |
| run: | | |
| xcodebuild \ | |
| -workspace "ios/${{ steps.xcode.outputs.workspace }}" \ | |
| -scheme "${{ steps.xcode.outputs.scheme }}" \ | |
| -configuration Release \ | |
| -sdk iphonesimulator \ | |
| -derivedDataPath "$GITHUB_WORKSPACE/build/ios/DerivedData" \ | |
| -destination 'generic/platform=iOS Simulator' \ | |
| build | |
| - name: Locate built app | |
| id: app | |
| run: | | |
| APP=$(find "$GITHUB_WORKSPACE/build/ios/DerivedData" -type d -name "*.app" | head -1) | |
| echo "path=$APP" >> $GITHUB_OUTPUT | |
| - name: Boot simulator | |
| run: | | |
| if [ -z "$DEVICE_UDID" ]; then | |
| echo "ERROR: DEVICE_UDID is not set or empty. Cannot boot simulator." >&2 | |
| exit 1 | |
| fi | |
| xcrun simctl boot "$DEVICE_UDID" 2>/dev/null | |
| open -a Simulator | |
| sleep 20 | |
| - name: Install Maestro CLI | |
| run: | | |
| curl --proto '=https' --tlsv1.2 -fsSL "https://get.maestro.mobile.dev" | bash | |
| echo "$HOME/.maestro/bin" >> $GITHUB_PATH | |
| export PATH="$HOME/.maestro/bin:$PATH" | |
| maestro --version | |
| - name: Install app on simulator | |
| run: | | |
| xcrun simctl install "$DEVICE_UDID" "${{ steps.app.outputs.path }}" | |
| - name: Run Maestro flow | |
| run: | | |
| export PATH="$HOME/.maestro/bin:$PATH" | |
| export MAESTRO_DRIVER_STARTUP_TIMEOUT=600000 | |
| mkdir -p .maestro/output .maestro/debug .maestro/artifacts .maestro/recordings | |
| VIDEO_FILE=".maestro/recordings/maestro-ios-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}.mp4" | |
| xcrun simctl io "$DEVICE_UDID" recordVideo --codec=h264 "$VIDEO_FILE" >/tmp/simctl-record-video.log 2>&1 & | |
| REC_PID=$! | |
| set +e | |
| maestro --verbose --device "$DEVICE_UDID" test .maestro/automated/suite.yaml \ | |
| --format html-detailed \ | |
| --output .maestro/output/report.html \ | |
| --debug-output .maestro/debug \ | |
| --test-output-dir .maestro/artifacts \ | |
| 2>&1 | tee .maestro/output/maestro-console.log | |
| FLOW_EXIT=${PIPESTATUS[0]} | |
| set -e | |
| if kill -0 "$REC_PID" 2>/dev/null; then | |
| kill -INT "$REC_PID" 2>/dev/null || true | |
| wait "$REC_PID" 2>/dev/null || true | |
| fi | |
| exit $FLOW_EXIT | |
| - name: Upload screen recording (mp4) | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: maestro-ios-recording | |
| path: .maestro/recordings/*.mp4 | |
| if-no-files-found: ignore | |
| - name: Upload Maestro outputs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: maestro-ios-outputs | |
| path: | | |
| .maestro/output/** | |
| .maestro/debug/** | |
| .maestro/artifacts/** | |
| .maestro/recordings/*.mp4 | |
| if-no-files-found: ignore | |
| include-hidden-files: true |