diff --git a/.github/workflows/android-emulator.yml b/.github/workflows/android-emulator.yml new file mode 100644 index 00000000..c8a5a2db --- /dev/null +++ b/.github/workflows/android-emulator.yml @@ -0,0 +1,254 @@ +name: Android Emulator E2E + +on: + workflow_call: + inputs: + package-name: + required: false + type: string + api-version: + required: false + type: string + default: '29' + espresso-version: + description: espresso version to use + required: false + default: 3.5.1 + type: string + +env: + output_folder: ./TestsAutomation/Output + +jobs: + e2e-emulator-tests: + runs-on: ubuntu-large-emulator + continue-on-error: true + strategy: + matrix: + suite: + - 01_InitEnrollement + - 01_InitFirstSync + - 02_SetupWorkspaces + - 03_SDetAlerts + - 03_SDetAlertsFilter + - 03_2_SDetScan + - 30_Diagnostic + fail-fast: false + env: + TZ: Europe/Paris + CI: true + ANDROID_HOME: /usr/local/lib/android/sdk + ANDROID_AVD_HOME: /home/runner/.config/.android/avd + ANDROID_SDK_ROOT: /usr/local/lib/android/sdk + ANDROID_DEVICE: smartemu + arch: x86_64 + APPIUM_TEST_SERVER_PORT: 4723 + APPIUM_TEST_SERVER_HOST: 127.0.0.1 + _FORCE_LOGS: 1 + ANDROID_PACKAGE: ${{ inputs.package-name }} + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: 📦 Setup Node + uses: actions/setup-node@v6 + with: + node-version: 20 + cache-dependency-path: src/ + cache: npm + + - name: 📦 Setup Python + uses: actions/setup-python@v6 + with: + python-version: "3.9" + + - name: 📦 Setup Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '17' + + - name: ♻️ Gradle cache + uses: gradle/actions/setup-gradle@v5 + + - name: 📦 Install XVFB + run: sudo apt -y install xvfb + + - name: Add Android SDK to PATH + run: echo "$ANDROID_HOME/cmdline-tools/latest/bin" >> $GITHUB_PATH + + - name: Add Android Platform-tools to PATH + run: echo "$ANDROID_HOME/platform-tools" >> $GITHUB_PATH + + - name: Add Android Emulator to PATH + run: echo "$ANDROID_HOME/emulator" >> $GITHUB_PATH + + - name: ♻️ Restore Cache Android SDK + id: cache-android-sdk + uses: actions/cache/restore@v5 + with: + path: | + ${{ env.ANDROID_HOME }}/system-images + ${{ env.ANDROID_HOME }}/emulator + ${{ env.ANDROID_HOME }}/licenses + ${{ env.ANDROID_HOME }}/build-tools + key: android-sdk-${{ inputs.api-version }} + + - name: ♻️ Restore Cache Android AVD + id: cache-avd + uses: actions/cache/restore@v5 + with: + path: ${{ env.ANDROID_AVD_HOME }} + key: android-avd-${{ inputs.api-version }} + + - name: ♻️ Restore Cache Appium Dependencies + id: cache-appium + uses: actions/cache/restore@v5 + with: + path: TestsAutomation/node_modules + key: appium-node-modules-${{ hashFiles('TestsAutomation/package-lock.json') }} + + - name: 📦 Setup Command Line Tools + # if: steps.cache-android-sdk.outputs.cache-hit != 'true' + run: | + echo "➡️ Deleting default SDK setup" + rm -rf $ANDROID_HOME/* + echo "➡️ Creating ANDROID_HOME dir at: $ANDROID_HOME" + mkdir -p $ANDROID_HOME/cmdline-tools/latest && cd $_ + echo "➡️ Downloading Command Line Tools" + wget --progress=bar:force:noscroll -O ./cltools.zip https://dl.google.com/android/repository/commandlinetools-linux-14742923_latest.zip + echo "➡️ Uncompressing Command Line Tools" + unzip -q ./cltools.zip && mv ./cmdline-tools/* . && rmdir ./cmdline-tools + echo "➡️ Deleting AVD lock files" + rm -rf $ANDROID_AVD_HOME/*/*.lock + + + - name: Accept Android SDK Licenses + if: steps.cache-android-sdk.outputs.cache-hit != 'true' + run: | + yes | sdkmanager --licenses + + - name: 📦 Install Android SDK + if: steps.cache-android-sdk.outputs.cache-hit != 'true' + run: | + sdkmanager --install "platform-tools" "platforms;android-${{ inputs.api-version }}" "system-images;android-${{ inputs.api-version }};google_apis;x86_64" "build-tools;${{ inputs.api-version }}.0.0" "emulator" + + - name: Create AVD Home Directory + if: steps.cache-avd.outputs.cache-hit != 'true' + run: mkdir -p ${{ env.ANDROID_AVD_HOME }} + + - name: Create AVD + if: steps.cache-avd.outputs.cache-hit != 'true' + run: | + avdmanager create avd -n $ANDROID_DEVICE -k "system-images;android-${{ inputs.api-version }};google_apis;x86_64" --device "pixel_8" + + - name: 📦 Install Node dependencies + working-directory: TestsAutomation + run: | + npm install + echo "$PWD/node_modules/.bin/" >> $GITHUB_PATH + + - name: 📦 Install python packages + working-directory: TestsAutomation + run: pip3 install -U -r pip_requirements.txt + + - name: 📦 Install Appium dependencies + working-directory: TestsAutomation + run: | + appium driver install espresso@${{ inputs.espresso-version }} + + # - name: Download Artifact + # uses: actions/Download-artifact@v7 + # with: + # name: app-e2e.apk + # path: TestsAutomation/ + + - name: Start appium + working-directory: TestsAutomation + run: | + # CONFIG_CONTENT=$(cat ./config.json) + xvfb-run appium -a 127.0.0.1 -p 4723 --base-path /wd/hub/ \ + --allow-insecure=adb_shell \ + --default-capabilities '{"appium:app": "./app-e2e.apk", "appium:espressoBuildConfig": "./config.json"}' \ + --shell \ + --log-timestamp \ + --log ./appium-server.log & + + - name: Start Emulator + run: | + emulator -avd $ANDROID_DEVICE -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none -cores 4 -memory 4096 -verbose -qemu -m 4096 -smp cores=4 -enable-kvm & + + - name: Check emulator Readiness + run: | + adb wait-for-device + # Health Check - Verify emulator is fully booted + echo "🔍 Checking emulator health status..." + adb shell getprop sys.boot_completed + adb shell getprop init.svc.bootanim + # Wait for emulator to fully ready + sleep 20 + # Try to close SystemUI ANR prompt + adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS + adb shell settings put secure immersive_mode_confirmations confirmed + adb shell input keyevent 3 + # Enable developer mode + adb shell settings put global development_settings_enabled 1 + + + - name: Run tests + working-directory: TestsAutomation/Suites + env: + ROOT_PROJECT_PATH: ${{ github.workspace }}/TestsAutomation + run: python3 -m robot -s 01_InitApplication -s ${{ matrix.suite }} -d ../Output/ --variable DEVICE_ADB_ID:emulator-5554 --variable DEVICE_SERIAL:emulator-5554 --variable APP_PACKAGE:ai.smartway.smartapp ./ + + ################################ + # DEBUG MODE + ################################# + # - name: Setup tmate session + # if: always() + # uses: mxschmitt/action-tmate@v3 + + - name: ♻️ Save Cache Android SDK + if: steps.cache-android-sdk.outputs.cache-hit != 'true' # && always() # REMOVE ALWAYS AFTER DEBUG + uses: actions/cache/save@v5 + with: + path: | + ${{ env.ANDROID_HOME }}/system-images + ${{ env.ANDROID_HOME }}/emulator + key: android-sdk-${{ inputs.api-version }} + + - name: ♻️ Save Cache Android AVD + if: steps.cache-avd.outputs.cache-hit != 'true' # && always() # REMOVE ALWAYS AFTER DEBUG + uses: actions/cache/save@v5 + with: + path: ${{ env.ANDROID_AVD_HOME }} + key: android-avd-${{ inputs.api-version }} + + - name: ♻️ Save Appium Cache + if: steps.cache-appium.outputs.cache-hit != 'true' # && always() # REMOVE ALWAYS AFTER DEBUG + uses: actions/cache/save@v5 + with: + path: TestsAutomation/node_modules + key: appium-node-modules-${{ hashFiles('TestsAutomation/package-lock.json') }} + + - name: 📋 Upload Appium Server Logs + if: always() + uses: actions/upload-artifact@v5 + with: + name: Appium-Server-Logs-${{ matrix.suite }} + path: ./TestsAutomation/appium-server.log + if-no-files-found: warn + + - name: 📋 Upload Tests Report + if: always() + uses: actions/upload-artifact@v5 + with: + name: RobotFramework-TestReport-${{ matrix.suite }} + path: ${{ env.output_folder }} + if-no-files-found: warn \ No newline at end of file