From 151d4ea68c2ccde26b5f9e01ac06f5a41742bc98 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 26 Jul 2024 09:57:46 -0700 Subject: [PATCH] Create GHA action to run Maestro in CI (#45704) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45704 ## Context Running manual tests when preparing a release, it's time consuming. We have to do the cherry picks, wait for CI to finish, and then manually test 8 configurations. Maestro is a tool that allow us to run E2E tests automatically, and we can wire it to CI. ## Change Create a reusable GHA to run Maestro tests on iOS Changelog: [Internal] - Exploration to integrate maestro Reviewed By: blakef Differential Revision: D60282657 fbshipit-source-id: 3a2a427f0954b46fc6c3a8bf753e807371eb0239 --- .github/actions/maestro-ios/action.yml | 95 ++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .github/actions/maestro-ios/action.yml diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml new file mode 100644 index 00000000000..ae5fcd61397 --- /dev/null +++ b/.github/actions/maestro-ios/action.yml @@ -0,0 +1,95 @@ +name: Maestro E2E iOS +description: Runs E2E Tests on iOS using Maestro +inputs: + app-path: + required: true + description: The path to the .app file + app-id: + required: true + description: The id of the app to test + jsengine: + required: true + description: The js engine we are using + maestro-flow: + required: true + description: the folder that contains the maestro tests +runs: + using: composite + steps: + - name: Installing Maestro + shell: bash + run: curl -Ls "https://get.maestro.mobile.dev" | bash + - name: Installing Maestro dependencies + shell: bash + run: | + brew tap facebook/fb + brew install facebook/fb/idb-companion jq + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'zulu' + - name: Run tests + id: run-tests + shell: bash + run: | + echo "Launching iOS Simulator: iPhone 15 Pro" + xcrun simctl boot "iPhone 15 Pro" + + echo "Installing app on Simulator" + xcrun simctl install booted "${{ inputs.app-path }}" + + echo "Retrieving device UDID" + UDID=$(xcrun simctl list devices booted -j | jq -r '[.devices[]] | add | first | .udid') + echo "UDID is $UDID" + + echo "Bring simulator in foreground" + open -a simulator + + + + echo "Launch the app" + xcrun simctl launch $UDID ${{ inputs.app-id }} + + echo "Running tests with Maestro" + + export MAESTRO_DRIVER_STARTUP_TIMEOUT=1500000 # 25 min. CI is extremely slow + + # Add retries for flakyness + MAX_ATTEMPTS=3 + CURR_ATTEMPT=0 + RESULT=1 + + while [[ $CURR_ATTEMPT -lt $MAX_ATTEMPT ]] && [[ $RESULT -ne 0 ]]; do + CURR_ATTEMPT=$((CURR_ATTEMPT+1)) + echo "Attempt number $CURR_ATTEMPT" + + echo "Start video record using pid: video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid" + xcrun simctl io booted recordVideo video_record_$CURR_ATTEMPT.mov & echo $! > video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid + + echo '$HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }}' + $HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }} --debug-output /tmp/MaestroLogs + + RESULT=$? + + # Stop video + kill -SIGINT $(cat video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid) + done + + exit $RESULT + - name: Store video record + if: always() + uses: actions/upload-artifact@v4 + with: + name: e2e_ios_${{ inputs.app-id }}_report_${{ inputs.jsengine }} + path: | + video_record_1.mov + video_record_2.mov + video_record_3.mov + report.xml + - name: Store Logs + if: failure() && steps.run-tests.outcome == 'failure' + uses: actions/upload-artifact@v4 + with: + name: maestro-logs-${{ inputs.app-id }}-${{ inputs.jsengine }} + path: /tmp/MaestroLogs