v1.1.357 #523
This file contains 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: Native Integration Tests | |
env: | |
# Relative path from the monorepo root to the app | |
test_app_path: tests/test | |
# Package name in the monorepo | |
test_app_package_name: test-test | |
# Used for cache keys, must be unique among all workflows | |
app_identifier: ios-test-app | |
on: | |
push: | |
pull_request: | |
jobs: | |
build-ios-test-dev-container: | |
name: Build iOS Test Development Container App | |
uses: ./.github/workflows/build-ios-test-app.yml | |
secrets: inherit | |
permissions: | |
contents: read | |
pull-requests: read | |
with: | |
configuration: Debug | |
build-ios-test-app: | |
name: Build iOS Release App | |
uses: ./.github/workflows/build-ios-test-app.yml | |
secrets: inherit | |
permissions: | |
contents: read | |
pull-requests: read | |
with: | |
configuration: Release | |
# test-ios-native: | |
# name: iOS Development Integration Test | |
# needs: | |
# - build-ios-test-dev-container | |
# runs-on: macos-14 | |
# defaults: | |
# run: | |
# working-directory: ${{ env.test_app_path }} | |
# steps: | |
# - name: Checkout | |
# uses: actions/checkout@v4 | |
# - name: Install | |
# uses: ./.github/actions/install | |
# with: | |
# workspace-focus: ${{ env.test_app_package_name }} | |
# - name: Start Dev Server | |
# run: node scripts/start-dev-server.mjs --no-wait | |
# - name: Download Dev Container App | |
# uses: actions/cache/restore@v4 | |
# with: | |
# fail-on-cache-miss: true | |
# key: ${{ needs.build-ios-test-dev-container.outputs.built-app-cache-key }} | |
# path: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }} | |
# - name: Get Simulator UDID | |
# id: get-simulator-udid | |
# run: | | |
# AVAILABLE_SIMULATORS=$(xcrun simctl list devices available --json) | |
# echo "Available simulators: $AVAILABLE_SIMULATORS" | |
# RUNTIME=$(echo $AVAILABLE_SIMULATORS | jq -r '.devices | keys | map(select(test("iOS"))) | last') | |
# echo "Runtime: $RUNTIME" | |
# SIMULATOR_INFO=$(echo $AVAILABLE_SIMULATORS | jq ".devices.\"$RUNTIME\" | map(select(.name | test(\"iPhone\"))) | last") | |
# SIMULATOR_UDID=$(echo $SIMULATOR_INFO | jq -r .udid) | |
# echo "Simulator info: $SIMULATOR_INFO" | |
# echo "Simulator UDID: $SIMULATOR_UDID" | |
# echo "simulator_udid=$SIMULATOR_UDID" >> $GITHUB_OUTPUT | |
# - name: Boot Simulator | |
# env: | |
# SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }} | |
# run: xcrun simctl boot $SIMULATOR_UDID | |
# - name: Install Maestro | |
# uses: ./.github/actions/install-maestro | |
# id: install-maestro | |
# - name: Wait for Dev Server to Be Ready | |
# run: node scripts/start-dev-server.mjs --check-only | |
# - name: Get a Copy of the Bundle | |
# run: | | |
# echo 'Fetching the React Native bundle in the background, since the first request can take a while pre-bundling dependencies and producing the first bundle without a cache. The bundle we got can also serve as troubleshooting material in case of a failure, and will be uploaded as an artifact.' | |
# wget -O bundle.ios.js 'http://localhost:8081/index.bundle?platform=ios' & | |
# - name: Install Dev Container App in Simulator | |
# env: | |
# SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }} | |
# APP_PATH: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }} | |
# working-directory: . | |
# run: xcrun simctl install $SIMULATOR_UDID $APP_PATH | |
# - name: Test | |
# run: | | |
# export PATH="$PATH":"$HOME/.maestro/bin" | |
# export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000 # 3 minutes | |
# maestro test maestro-flows/basic.yaml | |
# - name: Upload Dev Container App | |
# uses: actions/[email protected] | |
# # Only upload if the test failed to save space | |
# if: ${{ failure() }} | |
# continue-on-error: true | |
# with: | |
# name: dev-container-app | |
# path: | | |
# path: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }} | |
# - name: Upload Server Log | |
# uses: actions/[email protected] | |
# if: ${{ always() }} | |
# continue-on-error: true | |
# with: | |
# name: dev-server.log | |
# path: | | |
# ${{ env.test_app_path }}/dev-server.log | |
# - name: Prepare Maestro Logs | |
# id: prepare-maestro-logs | |
# if: ${{ always() && steps.install-maestro.outcome == 'success' }} | |
# continue-on-error: true | |
# run: cp -r "$HOME/.maestro/tests" maestro-logs | |
# - name: Upload Maestro Logs | |
# uses: actions/[email protected] | |
# if: ${{ always() && steps.prepare-maestro-logs.outcome == 'success' }} | |
# continue-on-error: true | |
# with: | |
# name: release-maestro-logs | |
# path: | | |
# ${{ env.test_app_path }}/maestro-logs | |
# - name: Upload Maestro Screenshots | |
# uses: actions/[email protected] | |
# if: ${{ always() && steps.install-maestro.outcome == 'success' }} | |
# continue-on-error: true | |
# with: | |
# name: release-maestro-screenshots | |
# path: | | |
# ${{ env.test_app_path }}/maestro-screenshots | |
# - name: Upload Reference React Native Bundle | |
# uses: actions/[email protected] | |
# if: ${{ always() }} | |
# continue-on-error: true | |
# with: | |
# name: dev-sample-bundle.ios.js | |
# path: | | |
# ${{ env.test_app_path }}/bundle.ios.js | |
test-ios-native-release: | |
name: iOS Release Integration Test | |
# Note: Some parts of the native build process are not covered by this test: | |
# * We do not test the generated Xcode project has the Build Phase "Bundle React Native code and images" setup correctly using the standard `react-native bundle` command. This is done by the "vxrn/expo-plugin" Expo plugin which users should include in their `app.json` configuration. If that didn't work properally, Expo prebuild may setup the Xcode project to use Expo's custom bundle command that uses Metro. | |
# * We do not test `react-native/scripts/react-native-xcode.sh`, instead we copy parts of it into our test scripts, simulating parts of the build process without running the whole native build. | |
needs: | |
- build-ios-test-app | |
runs-on: macos-14 | |
defaults: | |
run: | |
working-directory: ${{ env.test_app_path }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install | |
uses: ./.github/actions/install | |
with: | |
workspace-focus: ${{ env.test_app_package_name }} | |
- name: Download Built Native App | |
uses: actions/cache/restore@v4 | |
with: | |
fail-on-cache-miss: true | |
key: ${{ needs.build-ios-test-app.outputs.built-app-cache-key }} | |
path: ${{ needs.build-ios-test-app.outputs.built-app-path }} | |
- name: Get Simulator UDID | |
id: get-simulator-udid | |
run: | | |
AVAILABLE_SIMULATORS=$(xcrun simctl list devices available --json) | |
echo "Available simulators: $AVAILABLE_SIMULATORS" | |
RUNTIME=$(echo $AVAILABLE_SIMULATORS | jq -r '.devices | keys | map(select(test("iOS"))) | last') | |
echo "Runtime: $RUNTIME" | |
SIMULATOR_INFO=$(echo $AVAILABLE_SIMULATORS | jq ".devices.\"$RUNTIME\" | map(select(.name | test(\"iPhone\"))) | last") | |
SIMULATOR_UDID=$(echo $SIMULATOR_INFO | jq -r .udid) | |
echo "Simulator info: $SIMULATOR_INFO" | |
echo "Simulator UDID: $SIMULATOR_UDID" | |
echo "simulator_udid=$SIMULATOR_UDID" >> $GITHUB_OUTPUT | |
- name: Boot Simulator | |
env: | |
SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }} | |
run: xcrun simctl boot $SIMULATOR_UDID | |
- name: Install Maestro | |
id: install-maestro | |
uses: ./.github/actions/install-maestro | |
- name: Patch Packages | |
run: | | |
node_modules/.bin/one patch | |
# Prebuild and pod install because we need hermesc which is installed by pod install | |
- name: Prebuild | |
run: | | |
node_modules/.bin/expo prebuild --platform ios --no-install # --no-install is used to skip installing dependencies, specifically `pod install` as we want to do it after the Cache Pods step | |
- name: Cache Pods | |
uses: actions/cache@v4 | |
env: | |
cache-name: ${{ env.app_identifier }}-pods | |
with: | |
path: ${{ env.test_app_path }}/ios/Pods | |
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles(format('{0}/ios/Podfile.lock', env.test_app_path)) }} | |
restore-keys: | | |
${{ runner.os }}-${{ env.cache-name }}- | |
- name: Pod Install | |
run: | | |
cd ios && pod install | |
- name: Bundle React Native code and images | |
run: | | |
mkdir test-bundle-output | |
node_modules/.bin/react-native bundle --platform ios --dev false --bundle-output test-bundle-output/main.tmp.jsbundle --assets-dest test-bundle-output | |
ios/Pods/hermes-engine/destroot/bin/hermesc -emit-binary -max-diagnostic-width=80 -O -output-source-map -out test-bundle-output/main.jsbundle test-bundle-output/main.tmp.jsbundle | |
- name: Replace JS Bundle and Assets in App | |
run: | | |
cp -r test-bundle-output/. ${{ github.workspace }}/${{ needs.build-ios-test-app.outputs.built-app-path }}/ | |
- name: Check .app | |
id: check-app | |
run: | | |
if [ ! -e ${{ github.workspace }}/${{ needs.build-ios-test-app.outputs.built-app-path }} ]; then | |
echo "Error: .app not found" | |
exit 1 | |
fi | |
- name: Install App in Simulator | |
env: | |
SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }} | |
APP_PATH: ${{ needs.build-ios-test-app.outputs.built-app-path }} | |
working-directory: . | |
run: xcrun simctl install $SIMULATOR_UDID $APP_PATH | |
- name: Test | |
run: | | |
export PATH="$PATH":"$HOME/.maestro/bin" | |
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000 # 3 minutes | |
maestro test maestro-flows/basic.yaml | |
- name: Upload App | |
uses: actions/[email protected] | |
if: ${{ always() && steps.check-app.outcome == 'success' }} | |
continue-on-error: true | |
with: | |
name: release-app | |
path: | | |
${{ needs.build-ios-test-app.outputs.built-app-path }} | |
- name: Prepare Maestro Logs | |
id: prepare-maestro-logs | |
if: ${{ always() && steps.install-maestro.outcome == 'success' }} | |
continue-on-error: true | |
run: cp -r "$HOME/.maestro/tests" maestro-logs | |
- name: Upload Maestro Logs | |
uses: actions/[email protected] | |
if: ${{ always() && steps.prepare-maestro-logs.outcome == 'success' }} | |
continue-on-error: true | |
with: | |
name: release-maestro-logs | |
path: | | |
${{ env.test_app_path }}/maestro-logs | |
- name: Upload Maestro Screenshots | |
uses: actions/[email protected] | |
if: ${{ always() && steps.install-maestro.outcome == 'success' }} | |
continue-on-error: true | |
with: | |
name: release-maestro-screenshots | |
path: | | |
${{ env.test_app_path }}/maestro-screenshots |