name: Detox E2E Tests Template on: workflow_call: inputs: MM_TEST_SERVER_URL: description: "The test server URL" required: false type: string MM_TEST_USER_NAME: description: "The admin username of the test instance" required: false type: string MM_TEST_PASSWORD: description: "The admin password of the test instance" required: false type: string MOBILE_VERSION: description: "The mobile version to test" required: false default: ${{ github.head_ref || github.ref }} type: string run-ios-tests: description: "Run iOS tests" required: true type: boolean run-android-tests: description: "Run Android tests" required: true type: boolean run-type: type: string required: false default: "PR" testcase_failure_fatal: description: "Should failures be considered fatal" required: false type: boolean default: false outputs: STATUS: value: ${{ jobs.generate-report.outputs.STATUS }} TARGET_URL: value: ${{ jobs.generate-report.outputs.TARGET_URL }} FAILURES: value: ${{ jobs.generate-report.outputs.FAILURES }} env: AWS_REGION: "us-east-1" ADMIN_EMAIL: ${{ secrets.MM_MOBILE_E2E_ADMIN_EMAIL }} ADMIN_USERNAME: ${{ inputs.MM_TEST_USER_NAME || secrets.MM_MOBILE_E2E_ADMIN_USERNAME }} ADMIN_PASSWORD: ${{ inputs.MM_TEST_PASSWORD || secrets.MM_MOBILE_E2E_ADMIN_PASSWORD }} DETOX_AWS_S3_BUCKET: "mattermost-detox-report" HEADLESS: "true" TYPE: ${{ inputs.run-type }} PULL_REQUEST: "https://github.com/mattermost/mattermost-mobile/pull/${{ github.event.number }}" SITE_1_URL: ${{ inputs.MM_TEST_SERVER_URL || secrets.MM_MOBILE_E2E_SITE_1_URL }} SITE_2_URL: ${{ secrets.MM_MOBILE_E2E_SITE_2_URL }} SITE_3_URL: ${{ secrets.MM_MOBILE_E2E_SITE_3_URL }} ZEPHYR_ENABLE: false JIRA_PROJECT_KEY: "MM" ZEPHYR_API_KEY: ${{ secrets.MM_MOBILE_E2E_ZEPHYR_API_KEY }} ZEPHYR_FOLDER_ID: "3233873" TEST_CYCLE_LINK_PREFIX: ${{ secrets.MM_MOBILE_E2E_TEST_CYCLE_LINK_PREFIX }} WEBHOOK_URL: ${{ secrets.MM_MOBILE_E2E_WEBHOOK_URL }} FAILURE_MESSAGE: "Something has failed" jobs: generate-specs: runs-on: ubuntu-22.04 if: ${{ inputs.run-ios-tests || inputs.run-android-tests }} outputs: specs: ${{ steps.generate-specs.outputs.specs }} build_id: ${{ steps.resolve-device.outputs.BUILD_ID }} device_name: ${{ steps.resolve-device.outputs.DEVICE_NAME }} device_os_version: ${{ steps.resolve-device.outputs.DEVICE_OS_VERSION }} mobile_sha: ${{ steps.resolve-device.outputs.MOBILE_SHA }} mobile_ref: ${{ steps.resolve-device.outputs.MOBILE_REF }} workflow_hash: ${{ steps.resolve-device.outputs.WORKFLOW_HASH }} steps: - name: Checkout Repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ inputs.MOBILE_VERSION }} - name: Set Build ID id: resolve-device run: | cd detox DEVICE_NAME=$(node -p "require('./.detoxrc').devices['ios.simulator'].device.type") DEVICE_OS_VERSION=$(node -p "require('./.detoxrc').devices['ios.simulator'].device.os") WORKFLOW_HASH=$(tr -dc a-z0-9 > ${GITHUB_OUTPUT} echo "BUILD_ID=$(echo ${BUILD_ID} | sed 's/ /_/g')" >> ${GITHUB_OUTPUT} echo "DEVICE_NAME=${DEVICE_NAME}" >> ${GITHUB_OUTPUT} echo "DEVICE_OS_VERSION=${DEVICE_OS_VERSION}" >> ${GITHUB_OUTPUT} echo "MOBILE_SHA=$(git rev-parse HEAD)" >> ${GITHUB_OUTPUT} echo "MOBILE_REF=$(git rev-parse --abbrev-ref HEAD)" >> ${GITHUB_OUTPUT} - name: Generate Test Specs id: generate-specs uses: ./.github/actions/generate-specs with: parallelism: 10 search_path: detox/e2e/test device_name: ${{ steps.resolve-device.outputs.DEVICE_NAME }} device_os_version: ${{ steps.resolve-device.outputs.DEVICE_OS_VERSION }} e2e-ios: name: ios-detox-e2e-${{ matrix.runId }}-${{ matrix.deviceName }}-${{ matrix.deviceOsVersion }} if: ${{ inputs.run-ios-tests }} runs-on: macos-14 continue-on-error: true timeout-minutes: 40 env: IOS: true needs: - generate-specs strategy: fail-fast: false matrix: ${{ fromJSON(needs.generate-specs.outputs.specs) }} steps: - name: Checkout Repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ inputs.MOBILE_VERSION }} - name: ci/prepare-node-deps uses: ./.github/actions/prepare-node-deps - name: Install Homebrew Dependencies run: | brew tap wix/brew brew install applesimutils - name: Download iOS Simulator Build uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: name: ios-build-simulator-${{ github.run_id }} path: mobile-artifacts - name: Unzip iOS Simulator Build run: unzip -o mobile-artifacts/*.zip -d mobile-artifacts/ - name: Start React Native Metro Server run: npm run start & - name: Install Detox Dependencies run: cd detox && npm i - name: Run Detox E2E Tests continue-on-error: true # Label might have been removed manually run: cd detox && npm run e2e:ios-test -- ${{ matrix.specs }} - name: Upload iOS Test Report if: always() uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: ios-results-${{ needs.generate-specs.outputs.workflow_hash }}-${{ matrix.runId }} path: detox/artifacts/ generate-report: runs-on: ubuntu-22.04 if: ${{ inputs.run-ios-tests || inputs.run-android-tests }} needs: - generate-specs - e2e-ios outputs: TARGET_URL: ${{ steps.set-url.outputs.TARGET_URL }} STATUS: ${{ steps.determine-status.outputs.STATUS }} FAILURES: ${{ steps.summary.outputs.FAILURES }} steps: - name: Checkout Repository uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ inputs.MOBILE_VERSION }} - name: ci/prepare-node-deps uses: ./.github/actions/prepare-node-deps - name: Download All Artifacts uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: path: detox/artifacts/ pattern: ios-results-${{ needs.generate-specs.outputs.workflow_hash }}-* - name: Generate Report Path id: s3 run: | path="${{ needs.generate-specs.outputs.build_id }}-${{ needs.generate-specs.outputs.mobile_sha }}-${{ needs.generate-specs.outputs.mobile_ref }}" echo "path=$(echo "${path}" | sed 's/\./-/g')" >> ${GITHUB_OUTPUT} - name: Save report Detox Dependencies id: report-link run: | cd detox npm ci npm run e2e:save-report env: DETOX_AWS_ACCESS_KEY_ID: ${{ secrets.MM_MOBILE_DETOX_AWS_ACCESS_KEY_ID }} DETOX_AWS_SECRET_ACCESS_KEY: ${{ secrets.MM_MOBILE_DETOX_AWS_SECRET_ACCESS_KEY }} IOS: ${{ inputs.run-ios-tests }} BUILD_ID: ${{ needs.generate-specs.outputs.build_id }} DEVICE_NAME: ${{ needs.generate-specs.outputs.device_name }} DEVICE_OS_VERSION: ${{ needs.generate-specs.outputs.device_os_version }} REPORT_PATH: ${{ steps.s3.outputs.path }} ## These are needed for the MM Webhook report COMMIT_HASH: ${{ needs.generate-specs.outputs.mobile_sha }} BRANCH: ${{ needs.generate-specs.outputs.mobile_ref }} - name: Calculate failures id: summary run: | echo "FAILURES=$(cat detox/artifacts/summary.json | jq .stats.failures)" >> ${GITHUB_OUTPUT} echo "PASSES=$(cat detox/artifacts/summary.json | jq .stats.passes)" >> ${GITHUB_OUTPUT} echo "SKIPPED=$(cat detox/artifacts/summary.json | jq .stats.skipped)" >> ${GITHUB_OUTPUT} echo "TOTAL=$(cat detox/artifacts/summary.json | jq .stats.tests)" >> ${GITHUB_OUTPUT} echo "ERRORS=$(cat detox/artifacts/summary.json | jq .stats.errors)" >> ${GITHUB_OUTPUT} echo "PERCENTAGE=$(cat detox/artifacts/summary.json | jq .stats.passPercent)" >> ${GITHUB_OUTPUT} - name: Set Target URL id: set-url run: | if ${{ inputs.run-ios-tests }}; then echo "TARGET_URL=https://${{ env.DETOX_AWS_S3_BUCKET }}.s3.amazonaws.com/${{ steps.s3.outputs.path }}/jest-stare/ios-report.html" >> ${GITHUB_OUTPUT} else echo "TARGET_URL=https://${{ env.DETOX_AWS_S3_BUCKET }}.s3.amazonaws.com/${{ steps.s3.outputs.path }}/jest-stare/android-report.html" >> ${GITHUB_OUTPUT} fi - name: Determine Status id: determine-status run: | if [[ ${{ steps.summary.outputs.failures }} -gt 0 && "${{ inputs.testcase_failure_fatal }}" == "true" ]]; then echo "STATUS=failure" >> ${GITHUB_OUTPUT} else echo "STATUS=success" >> ${GITHUB_OUTPUT} fi - name: Generate Summary run: | echo "| Tests | Passed :white_check_mark: | Failed :x: | Skipped :fast_forward: | Errors :warning: | " >> ${GITHUB_STEP_SUMMARY} echo "|:---:|:---:|:---:|:---:|:---:|" >> ${GITHUB_STEP_SUMMARY} echo "| ${{ steps.summary.outputs.TOTAL }} | ${{ steps.summary.outputs.PASSES }} | ${{ steps.summary.outputs.FAILURES }} | ${{ steps.summary.outputs.SKIPPED }} | ${{ steps.summary.outputs.ERRORS }} |" >> ${GITHUB_STEP_SUMMARY} echo "" >> ${GITHUB_STEP_SUMMARY} echo "You can check the full report [here](${{ steps.set-url.outputs.TARGET_URL }})" >> ${GITHUB_STEP_SUMMARY} echo "There was **${{ steps.summary.outputs.PERCENTAGE }}%** success rate." >> ${GITHUB_STEP_SUMMARY}