From 5df8edf1c63637269b547554cd9da465c58ae7a6 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Thu, 21 Nov 2024 15:35:53 +1300 Subject: [PATCH] test: fix ios build and ui test script --- .github/workflows/ui-tests.yml | 214 +++++++++++++++--------------- sample/Tests/browserstack.ios.yml | 2 +- sample/Tests/test/test_ios.py | 11 +- sample/build_ios.sh | 99 +++++++++----- 4 files changed, 178 insertions(+), 148 deletions(-) diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index 7a4adae3..bddf23dc 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -11,125 +11,125 @@ concurrency: cancel-in-progress: true jobs: - build: - name: Build ${{ matrix.targetPlatform }} for AltTester 🛠️ - runs-on: ubuntu-latest-8-cores - strategy: - fail-fast: false - matrix: - include: - - targetPlatform: StandaloneOSX - buildMethod: MacBuilder.BuildForAltTester - buildPath: sample/Builds/MacOS - - targetPlatform: StandaloneWindows64 - buildMethod: WindowsBuilder.BuildForAltTester - buildPath: sample/Builds/Windows64 - - targetPlatform: Android - buildMethod: MobileBuilder.BuildForAltTester - buildPath: sample/Builds/Android - steps: - - uses: actions/checkout@v3 - with: - lfs: true - - uses: actions/cache@v3 - with: - path: Library - key: Library-${{ matrix.targetPlatform }}-${{ hashFiles('sample/Assets/**', 'sample/Packages/**', 'sample/ProjectSettings/**') }} - restore-keys: | - Library-${{ matrix.targetPlatform }} - Library- - - name: Build project - uses: game-ci/unity-builder@v4 - env: - UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} - UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} - UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} - with: - targetPlatform: ${{ matrix.targetPlatform }} - projectPath: sample - buildMethod: ${{ matrix.buildMethod }} - customParameters: -logFile logFile.log -quit -batchmode - - name: List build directory - run: ls -R ./ - - name: Upload artifact - uses: actions/upload-artifact@v4 - if: always() - with: - name: Build-${{ matrix.targetPlatform }} - path: ${{ matrix.buildPath }} - test: - name: Run ${{ matrix.targetPlatform }} UI tests 🧪 - needs: build - strategy: - matrix: - include: - - targetPlatform: StandaloneOSX - runs-on: [self-hosted, macOS] - test_script: pytest -xs test/test_mac.py::MacTest - - targetPlatform: StandaloneWindows64 - runs-on: [self-hosted, windows] - test_script: pytest -xs test/test_windows.py::WindowsTest + # build: + # name: Build ${{ matrix.targetPlatform }} for AltTester 🛠️ + # runs-on: ubuntu-latest-8-cores + # strategy: + # fail-fast: false + # matrix: + # include: + # - targetPlatform: StandaloneOSX + # buildMethod: MacBuilder.BuildForAltTester + # buildPath: sample/Builds/MacOS + # - targetPlatform: StandaloneWindows64 + # buildMethod: WindowsBuilder.BuildForAltTester + # buildPath: sample/Builds/Windows64 # - targetPlatform: Android - # runs-on: [ self-hosted, macOS ] - # test_script: browserstack-sdk pytest -s ./test/test_android.py --browserstack.config "browserstack.android.yml" - concurrency: - group: test-${{ matrix.targetPlatform }} - runs-on: ${{ matrix.runs-on }} - steps: - - uses: actions/checkout@v3 - with: - lfs: true - - uses: actions/download-artifact@v4 - with: - name: Build-${{ matrix.targetPlatform }} - path: sample/Tests - - name: Make macOS artifact executable - if: ${{ matrix.targetPlatform == 'StandaloneOSX' }} - run: chmod +x sample/Tests/SampleApp.app/Contents/MacOS/* - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install dependencies (Windows) - if: ${{ matrix.targetPlatform == 'StandaloneWindows64' }} - run: pip install -r "sample/Tests/requirements-desktop.txt" - - name: Install dependencies (Mac) - if: ${{ matrix.targetPlatform != 'StandaloneWindows64' }} - run: | - if [[ "${{ matrix.targetPlatform }}" == "StandaloneOSX" ]]; then - pip uninstall -y browserstack-sdk || true - pip install -r "sample/Tests/requirements-desktop.txt" - else - pip install -r "sample/Tests/requirements-mobile.txt" - fi - - name: Run UI tests - env: - UNITY_APP_PATH: SampleApp.app - UNITY_APP_NAME: SampleApp - MAILSLURP_API_KEY: ${{ secrets.MAILSLURP_API_KEY }} - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - working-directory: sample/Tests - run: ${{ matrix.test_script }} - # test-ios: - # name: Run iOS UI tests 🧪 - # runs-on: [ self-hosted, macOS ] + # buildMethod: MobileBuilder.BuildForAltTester + # buildPath: sample/Builds/Android + # steps: + # - uses: actions/checkout@v3 + # with: + # lfs: true + # - uses: actions/cache@v3 + # with: + # path: Library + # key: Library-${{ matrix.targetPlatform }}-${{ hashFiles('sample/Assets/**', 'sample/Packages/**', 'sample/ProjectSettings/**') }} + # restore-keys: | + # Library-${{ matrix.targetPlatform }} + # Library- + # - name: Build project + # uses: game-ci/unity-builder@v4 + # env: + # UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + # UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + # UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }} + # with: + # targetPlatform: ${{ matrix.targetPlatform }} + # projectPath: sample + # buildMethod: ${{ matrix.buildMethod }} + # customParameters: -logFile logFile.log -quit -batchmode + # - name: List build directory + # run: ls -R ./ + # - name: Upload artifact + # uses: actions/upload-artifact@v4 + # if: always() + # with: + # name: Build-${{ matrix.targetPlatform }} + # path: ${{ matrix.buildPath }} + # test: + # name: Run ${{ matrix.targetPlatform }} UI tests 🧪 + # needs: build + # strategy: + # matrix: + # include: + # # - targetPlatform: StandaloneOSX + # # runs-on: [self-hosted, macOS] + # # test_script: pytest -xs test/test_mac.py::MacTest + # # - targetPlatform: StandaloneWindows64 + # # runs-on: [self-hosted, windows] + # # test_script: pytest -xs test/test_windows.py::WindowsTest + # # - targetPlatform: Android + # # runs-on: [ self-hosted, macOS ] + # # test_script: browserstack-sdk pytest -s ./test/test_android.py --browserstack.config "browserstack.android.yml" + # concurrency: + # group: test-${{ matrix.targetPlatform }} + # runs-on: ${{ matrix.runs-on }} # steps: # - uses: actions/checkout@v3 # with: # lfs: true - # - name: build iOS app - # working-directory: sample - # run: ./build_ios.sh + # - uses: actions/download-artifact@v4 + # with: + # name: Build-${{ matrix.targetPlatform }} + # path: sample/Tests + # - name: Make macOS artifact executable + # if: ${{ matrix.targetPlatform == 'StandaloneOSX' }} + # run: chmod +x sample/Tests/SampleApp.app/Contents/MacOS/* # - uses: actions/setup-python@v4 # with: # python-version: "3.10" - # - name: Install dependencies - # run: pip install -r "sample/Tests/requirements.txt" + # - name: Install dependencies (Windows) + # if: ${{ matrix.targetPlatform == 'StandaloneWindows64' }} + # run: pip install -r "sample/Tests/requirements-desktop.txt" + # - name: Install dependencies (Mac) + # if: ${{ matrix.targetPlatform != 'StandaloneWindows64' }} + # run: | + # if [[ "${{ matrix.targetPlatform }}" == "StandaloneOSX" ]]; then + # pip uninstall -y browserstack-sdk || true + # pip install -r "sample/Tests/requirements-desktop.txt" + # else + # pip install -r "sample/Tests/requirements-mobile.txt" + # fi # - name: Run UI tests # env: + # UNITY_APP_PATH: SampleApp.app + # UNITY_APP_NAME: SampleApp # MAILSLURP_API_KEY: ${{ secrets.MAILSLURP_API_KEY }} # BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} # BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} # working-directory: sample/Tests - # run: browserstack-sdk pytest -s ./test/test_ios.py --browserstack.config "browserstack.ios.yml" + # run: ${{ matrix.test_script }} + test-ios: + name: Run iOS UI tests 🧪 + runs-on: [ self-hosted, macOS ] + steps: + - uses: actions/checkout@v3 + with: + lfs: true + - name: Build iOS app + working-directory: sample + run: ./build_ios.sh + - uses: actions/setup-python@v4 + with: + python-version: "3.10" + - name: Install dependencies + run: pip install -r "sample/Tests/requirements-mobile.txt" + - name: Run UI tests + env: + MAILSLURP_API_KEY: ${{ secrets.MAILSLURP_API_KEY }} + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + working-directory: sample/Tests + run: browserstack-sdk pytest -s ./test/test_ios.py --browserstack.config "browserstack.ios.yml" \ No newline at end of file diff --git a/sample/Tests/browserstack.ios.yml b/sample/Tests/browserstack.ios.yml index ed8a216f..4d39ce54 100644 --- a/sample/Tests/browserstack.ios.yml +++ b/sample/Tests/browserstack.ios.yml @@ -26,7 +26,7 @@ source: pytest-browserstack:sample-sdk:v1.0 # Set `app` to define the app that is to be used for testing. # It can either take the id of any uploaded app or the path of the app directly. #app: ./WikipediaSample.apk -app: ../build/output/iOS/IPA/Payload.ipa #For running local tests +app: ./Payload.ipa #For running local tests # ======================================= # Platforms (Browsers / Devices to test) diff --git a/sample/Tests/test/test_ios.py b/sample/Tests/test/test_ios.py index ce5f3aa9..828986bd 100644 --- a/sample/Tests/test/test_ios.py +++ b/sample/Tests/test/test_ios.py @@ -12,6 +12,8 @@ from alttester import AltDriver, By +from test import TestConfig + sys.path.insert(0, str(Path(__file__).resolve().parent.parent / 'src')) from fetch_otp import EMAIL, fetch_code @@ -24,9 +26,10 @@ class TestBase(unittest.TestCase): def setUpClass(cls): # https://appium.github.io/appium-xcuitest-driver/latest/preparation/real-device-config/ options = XCUITestOptions() - options.app = "./Payload.ipa" + # options.app = "./Payload.ipa" + # options.app = "com.immutable.Immutable-Sample-GameSDK" options.show_xcode_log = True - options.xcode_org_id = "APPLE_TEAM_ID" # Replace with Apple Team ID + # options.xcode_org_id = "54XMLXPF98" # Replace with Apple Team ID options.auto_accept_alerts = True cls.appium_driver = webdriver.Remote('https://hub-cloud.browserstack.com/wd/hub/', options=options) @@ -75,14 +78,14 @@ def test_1_pkce_login(self): # Found email target_context = context - email_field.send_keys("imx.game.sdk.demo@gmail.com") + email_field.send_keys(TestConfig.EMAIL) submit_button = driver.find_element(by=AppiumBy.XPATH, value="//form/div/div/div[2]/button") submit_button.click() time.sleep(10) # Wait for OTP code = fetch_gmail_code() - assert code, "Failed to fetch OTP from Gmail" + assert code, "Failed to fetch OTP from MailSlurp" print(f"Successfully fetched OTP: {code}") # Unlike on Android, each digit must be entered into a separate input field on iOS. diff --git a/sample/build_ios.sh b/sample/build_ios.sh index a9e3e5e4..0405106e 100755 --- a/sample/build_ios.sh +++ b/sample/build_ios.sh @@ -1,14 +1,15 @@ #!/bin/bash -PATH_UNITY="/Applications/Unity/Unity.app/Contents/MacOS/Unity" +PATH_UNITY="/Applications/Unity/Hub/Editor/2021.3.26f1/Unity.app/Contents/MacOS/Unity" PATH_TO_UNITY_SDK_SAMPLE_APP="./" BUILD_METHOD="MobileBuilder.BuildForAltTester" -APPLE_TEAM_ID="" +APPLE_TEAM_ID="54XMLXPF98" # Define the build paths BUILD_XCODE_PATH="$(pwd)/build/output/iOS/Xcode" BUILD_ARCHIVE_PATH="$(pwd)/build/output/iOS/Archive" BUILD_IPA_PATH="$(pwd)/build/output/iOS/IPA" +DERIVED_DATA_PATH="$(pwd)/build/output/iOS/DerivedData" # Function to clear a directory clear_directory() { @@ -25,6 +26,12 @@ clear_directory() { clear_directory "$BUILD_XCODE_PATH" clear_directory "$BUILD_ARCHIVE_PATH" clear_directory "$BUILD_IPA_PATH" +clear_directory "$DERIVED_DATA_PATH" + +mkdir -p "$BUILD_XCODE_PATH" +mkdir -p "$BUILD_ARCHIVE_PATH" +mkdir -p "$BUILD_IPA_PATH" +mkdir -p "$DERIVED_DATA_PATH" # Unity build command UNITY_COMMAND="$PATH_UNITY -projectPath \"$PATH_TO_UNITY_SDK_SAMPLE_APP\" -executeMethod $BUILD_METHOD -logFile logFile.log -quit -batchmode --buildPath \"$BUILD_XCODE_PATH\" --platform iOS" @@ -39,39 +46,59 @@ if [ $? -ne 0 ]; then exit 1 fi -# Build and archive project -xcodebuild -project "$(pwd)/build/output/iOS/Xcode/Unity-iPhone.xcodeproj" \ +echo "Building app..." +xcodebuild clean build \ + -project "$(pwd)/build/output/iOS/Xcode/Unity-iPhone.xcodeproj" \ -scheme Unity-iPhone \ - -archivePath "$(pwd)/build/output/iOS/Archive/Unity-iPhone.xcarchive" \ - -configuration Release \ + -destination "generic/platform=iOS" \ DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ - CODE_SIGN_STYLE=Automatic \ - archive - -# Create ExportOptions.plist with the correct APPLE_TEAM_ID -EXPORT_OPTIONS_PATH="$(pwd)/build/output/iOS/Archive/ExportOptions.plist" - -cat < "$EXPORT_OPTIONS_PATH" - - - - - method - development - teamID - $APPLE_TEAM_ID - signingStyle - automatic - compileBitcode - - thinning - <none> - - -EOF - -# Generate .ipa file -xcodebuild -exportArchive \ - -archivePath "$(pwd)/build/output/iOS/Archive/Unity-iPhone.xcarchive" \ - -exportPath "$(pwd)/build/output/iOS/IPA" \ - -exportOptionsPlist "$EXPORT_OPTIONS_PATH" + PRODUCT_BUNDLE_IDENTIFIER=com.immutable.Immutable-Sample-GameSDK \ + -allowProvisioningUpdates \ + -derivedDataPath "$(pwd)/build/output/iOS/DerivedData" \ + -target UnityFramework \ + PRODUCT_BUNDLE_IDENTIFIER=com.immutable.Immutable-Sample-GameSDK.Framework + +mkdir -p "$(pwd)/build/output/iOS/IPA/Payload" + +mv "$(pwd)/build/output/iOS/DerivedData/Build/Products/ReleaseForRunning-iphoneos/ImmutableSample.app" "$(pwd)/build/output/iOS/IPA/Payload" + +pushd "$(pwd)/build/output/iOS/IPA" && zip -r Payload.zip Payload && popd + +mv "$(pwd)/build/output/iOS/IPA/Payload.zip" "$(pwd)/Tests/Payload.ipa" + +# # Build and archive project +# xcodebuild -project "$(pwd)/build/output/iOS/Xcode/Unity-iPhone.xcodeproj" \ +# -scheme Unity-iPhone \ +# -archivePath "$(pwd)/build/output/iOS/Archive/Unity-iPhone.xcarchive" \ +# -configuration Release \ +# DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ +# CODE_SIGN_STYLE=Automatic \ +# archive + +# # Create ExportOptions.plist with the correct APPLE_TEAM_ID +# EXPORT_OPTIONS_PATH="$(pwd)/build/output/iOS/Archive/ExportOptions.plist" + +# cat < "$EXPORT_OPTIONS_PATH" +# +# +# +# +# method +# development +# teamID +# $APPLE_TEAM_ID +# signingStyle +# automatic +# compileBitcode +# +# thinning +# <none> +# +# +# EOF + +# # Generate .ipa file +# xcodebuild -exportArchive \ +# -archivePath "$(pwd)/build/output/iOS/Archive/Unity-iPhone.xcarchive" \ +# -exportPath "$(pwd)/build/output/iOS/IPA" \ +# -exportOptionsPlist "$EXPORT_OPTIONS_PATH"