Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/actions/setup-appium-server/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: 'Start Appium Server'
description: 'Start Appium server with configurable arguments and wait for startup'

inputs:
port:
description: 'Appium server port'
required: false
default: '4723'
host:
description: 'Appium server host'
required: false
default: '127.0.0.1'
timeout:
description: 'Timeout in seconds to wait for server startup'
required: false
default: '25'
server_args:
description: 'Additional server arguments (space-separated)'
required: false
default: ''
log_file:
description: 'Log file name'
required: false
default: 'appium.log'

runs:
using: 'composite'
steps:
- name: Start Appium server
shell: bash
run: |
nohup appium server \
--port=${{ inputs.port }} \
--address=${{ inputs.host }} \
--log-no-colors \
--log-timestamp \
--keep-alive-timeout 1200 \
${{ inputs.server_args }} \
2>&1 > ${{ inputs.log_file }} &

- name: Wait for Appium server to start
shell: bash
run: |
TIMEOUT_SEC=${{ inputs.timeout }}
INTERVAL_SEC=1

start_time=$(date +%s)
while true; do
current_time=$(date +%s)
elapsed=$((current_time - start_time))

if nc -z ${{ inputs.host }} ${{ inputs.port }}; then
echo "Appium server is running after $elapsed seconds"
cat ${{ inputs.log_file }}
exit 0
fi

if [[ "$elapsed" -ge "$TIMEOUT_SEC" ]]; then
echo "${elapsed} seconds timeout reached: Appium server is NOT running"
exit 1
fi

echo "Waiting $elapsed seconds for Appium server to start..."
sleep "$INTERVAL_SEC"
done
145 changes: 105 additions & 40 deletions .github/workflows/functional-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ name: Functional Tests
on:
# Run by manual at this time
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
APPIUM_TEST_SERVER_PORT: '4723'
APPIUM_TEST_SERVER_HOST: '127.0.0.1'

jobs:
ios_test:
strategy:
Expand All @@ -26,9 +28,10 @@ jobs:
# Please make sure the available Xcode versions and iOS versions
# on the runner images. https://github.com/actions/runner-images
env:
XCODE_VERSION: 16.4
IOS_VERSION: 18.5
IPHONE_MODEL: iPhone 16 Plus
XCODE_VERSION: '16.4'
IOS_VERSION: '18.5'
IPHONE_MODEL: 'iPhone 16 Plus'
PREBUILT_WDA_PATH: ${{ github.workspace }}/wda/WebDriverAgentRunner-Runner.app

steps:
- uses: actions/checkout@v4
Expand All @@ -42,43 +45,61 @@ jobs:
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}

- run: defaults write com.apple.iphonesimulator PasteboardAutomaticSync -bool false

- uses: futureware-tech/simulator-action@v3
- name: Prepare iOS simulator
uses: futureware-tech/simulator-action@v4
with:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md
model: ${{ env.IPHONE_MODEL }}
os_version: ${{ env.IOS_VERSION }}
wait_for_boot: true
shutdown_after_job: false

# needed?
- run: brew install ffmpeg

# Start Appium
- run: npm install -g appium
- run: |
- name: Install Appium and drivers
run: |
npm install -g appium
appium driver install xcuitest
appium driver run xcuitest build-wda --sdk=${{ env.IOS_VERSION }} --name='${{ env.IPHONE_MODEL }}'
appium plugin install images
appium plugin install execute-driver
nohup appium --use-plugins=images,execute-driver --relaxed-security --log-timestamp --log-no-colors > appium.log &

- run: |
appium driver run xcuitest download-wda-sim --platform=ios --outdir=${{ github.workspace }}/wda
name: Downloading prebuilt WDA
- name: Start Appium server
uses: ./.github/actions/setup-appium-server
with:
port: ${{ env.APPIUM_TEST_SERVER_PORT }}
host: ${{ env.APPIUM_TEST_SERVER_HOST }}
server_args: '--relaxed-security'

- name: Set up Python 3.12
- name: Downloading prebuilt WDA
run: |
appium driver run xcuitest download-wda-sim --platform=ios --outdir=$(dirname "$PREBUILT_WDA_PATH")

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Cache uv modules
uses: actions/cache@v4
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-shared-${{ hashFiles('**/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-shared-

- name: Install uv
run: make install-uv

- name: Run Tests
run: |
uv run pytest ${{ matrix.test_targets.target}} --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html
uv run pytest ${{ matrix.test_targets.target}} \
--doctest-modules \
--junitxml=junit/test-results.xml \
--cov=com \
--cov-report=xml \
--cov-report=html
env:
LOCAL_PREBUILT_WDA: ${{ github.workspace }}/wda/WebDriverAgentRunner-Runner.app
LOCAL_PREBUILT_WDA: ${{ env.PREBUILT_WDA_PATH }}

- name: Save server output
if: ${{ always() }}
Expand Down Expand Up @@ -115,13 +136,19 @@ jobs:
with:
node-version: 'lts/*'

# Start Appium
- run: npm install -g appium
- run: |
- name: Install Appium and drivers
run: |
npm install -g appium
appium driver install uiautomator2
appium driver install espresso
appium plugin install execute-driver
nohup appium --use-plugins=execute-driver --relaxed-security --log-timestamp --log-no-colors 2>&1 > appium.log &

- name: Start Appium server
uses: ./.github/actions/setup-appium-server
with:
port: ${{ env.APPIUM_TEST_SERVER_PORT }}
host: ${{ env.APPIUM_TEST_SERVER_HOST }}
server_args: '--relaxed-security --use-plugins=execute-driver'

- name: Enable KVM group perms
run: |
Expand Down Expand Up @@ -154,6 +181,16 @@ jobs:
with:
python-version: 3.12

- name: Cache uv modules
uses: actions/cache@v4
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-shared-${{ hashFiles('**/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-shared-

- name: run tests
uses: reactivecircus/android-emulator-runner@v2
with:
Expand Down Expand Up @@ -230,15 +267,31 @@ jobs:
with:
node-version: 'lts/*'

- name: Install Appium
run: npm install --location=global appium

- name: Install Android drivers and Run Appium
- name: Install Appium and drivers
if: matrix.e2e-tests == 'flutter-android'
run: |
npm install --location=global appium
appium driver install uiautomator2
appium driver install appium-flutter-integration-driver --source npm
nohup appium --allow-insecure=adb_shell --relaxed-security --log-timestamp --log-no-colors 2>&1 > appium_flutter_android.log &

- name: Start Appium server for Android
if: matrix.e2e-tests == 'flutter-android'
uses: ./.github/actions/setup-appium-server
with:
port: ${{ env.APPIUM_TEST_SERVER_PORT }}
host: ${{ env.APPIUM_TEST_SERVER_HOST }}
server_args: '--relaxed-security'
log_file: 'appium_flutter_android.log'

- name: Cache uv modules
uses: actions/cache@v4
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-shared-${{ hashFiles('**/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-shared-

- name: Run Android tests
if: matrix.e2e-tests == 'flutter-android'
Expand All @@ -265,28 +318,40 @@ jobs:
with:
xcode-version: ${{ env.XCODE_VERSION }}

- uses: futureware-tech/simulator-action@v3
- uses: futureware-tech/simulator-action@v4
if: matrix.e2e-tests == 'flutter-ios'
with:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md
model: ${{ env.IPHONE_MODEL }}
os_version: ${{ env.IOS_VERSION }}
wait_for_boot: true
shutdown_after_job: false

- name: install dependencies
if: matrix.e2e-tests == 'flutter-ios'
run: brew install ffmpeg

- name: Install IOS drivers and Run Appium
- name: Install Appium and drivers
if: matrix.e2e-tests == 'flutter-ios'
run: |
npm install --location=global appium
appium driver install xcuitest
appium driver install appium-flutter-integration-driver --source npm
appium driver run xcuitest build-wda
nohup appium --allow-insecure=adb_shell --relaxed-security --log-timestamp --log-no-colors 2>&1 > appium_ios.log &

- name: Start Appium server for iOS
if: matrix.e2e-tests == 'flutter-ios'
uses: ./.github/actions/setup-appium-server
with:
port: ${{ env.APPIUM_TEST_SERVER_PORT }}
host: ${{ env.APPIUM_TEST_SERVER_HOST }}
server_args: '--relaxed-security'
log_file: 'appium_ios.log'

- name: Run IOS tests
if: matrix.e2e-tests == 'flutter-ios'
run: |
make install-uv
export PLATFORM=ios
uv run pytest test/functional/flutter_integration/*_test.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html
uv run pytest test/functional/flutter_integration/*_test.py \
--doctest-modules \
--junitxml=junit/test-results.xml \
--cov=com \
--cov-report=xml \
--cov-report=html
9 changes: 9 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache uv modules
uses: actions/cache@v4
with:
path: |
~/.cache/uv
.venv
key: ${{ runner.os }}-uv-shared-${{ hashFiles('**/uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-shared-
- name: Install uv
run: make install-uv
- name: Run Checks
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ install-uv:

.PHONY: sync-dev
sync-dev:
uv sync
uv sync --dev

.PHONY: unittest
unittest: ## Run unittest
Expand Down
4 changes: 4 additions & 0 deletions appium/options/ios/xcuitest/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
from .wda.keychain_path_option import KeychainPathOption
from .wda.max_typing_frequency_option import MaxTypingFrequencyOption
from .wda.mjpeg_server_port_option import MjpegServerPortOption
from .wda.prebuilt_wda_path_option import PrebuiltWdaPathOption
from .wda.process_arguments_option import ProcessArgumentsOption
from .wda.result_bundle_path_option import ResultBundlePathOption
from .wda.screenshot_quality_option import ScreenshotQualityOption
Expand All @@ -83,6 +84,7 @@
from .wda.use_native_caching_strategy_option import UseNativeCachingStrategyOption
from .wda.use_new_wda_option import UseNewWdaOption
from .wda.use_prebuilt_wda_option import UsePrebuiltWdaOption
from .wda.use_preinstalled_wda_option import UsePreinstalledWdaOption
from .wda.use_simple_build_test_option import UseSimpleBuildTestOption
from .wda.use_xctestrun_file_option import UseXctestrunFileOption
from .wda.wait_for_idle_timeout_option import WaitForIdleTimeoutOption
Expand Down Expand Up @@ -171,6 +173,7 @@ class XCUITestOptions(
KeychainPathOption,
MaxTypingFrequencyOption,
MjpegServerPortOption,
PrebuiltWdaPathOption,
ProcessArgumentsOption,
ResultBundlePathOption,
ScreenshotQualityOption,
Expand All @@ -182,6 +185,7 @@ class XCUITestOptions(
UseNativeCachingStrategyOption,
UseNewWdaOption,
UsePrebuiltWdaOption,
UsePreinstalledWdaOption,
UseSimpleBuildTestOption,
UseXctestrunFileOption,
WaitForIdleTimeoutOption,
Expand Down
Loading