Restore development clients for nightly E2E

This commit is contained in:
Samuel Newman
2026-07-17 17:31:49 +03:00
parent b6b0e41fd4
commit 7a0d9180c7
6 changed files with 57 additions and 30 deletions
+1
View File
@@ -28,6 +28,7 @@ stop_pid_file() {
} }
stop_pid_file "$artifact_dir/logcat.pid" stop_pid_file "$artifact_dir/logcat.pid"
stop_pid_file "$artifact_dir/metro.pid"
stop_pid_file "$artifact_dir/mock-server.pid" stop_pid_file "$artifact_dir/mock-server.pid"
stop_pid_file "$artifact_dir/emulator.pid" stop_pid_file "$artifact_dir/emulator.pid"
+12 -1
View File
@@ -53,7 +53,7 @@ stop_pid_file() {
pid="$(cat "$pid_file")" pid="$(cat "$pid_file")"
[[ -n "$pid" ]] || return 0 [[ -n "$pid" ]] || return 0
# pnpm can spawn multiple generations of children. # pnpm and Expo both spawn multiple generations of children.
stop_process_tree "$pid" stop_process_tree "$pid"
} }
@@ -61,6 +61,7 @@ stop_pid_file() {
cleanup() { cleanup() {
set +e set +e
stop_pid_file "$artifact_dir/logcat.pid" stop_pid_file "$artifact_dir/logcat.pid"
stop_pid_file "$artifact_dir/metro.pid"
stop_pid_file "$artifact_dir/mock-server.pid" stop_pid_file "$artifact_dir/mock-server.pid"
if [[ "$platform" == "ios" ]]; then if [[ "$platform" == "ios" ]]; then
@@ -133,9 +134,19 @@ fi
printf '%s\n' "$!" >"$artifact_dir/mock-server.pid" printf '%s\n' "$!" >"$artifact_dir/mock-server.pid"
wait_for_port 1986 "the E2E mock-server manager" wait_for_port 1986 "the E2E mock-server manager"
phase "Starting Metro"
EXPO_PUBLIC_ENV=e2e \
NODE_ENV=test \
RN_SRC_EXT=e2e.ts,e2e.tsx \
pnpm exec expo start --dev-client --clear --port 8081 \
>"$artifact_dir/metro.log" 2>&1 &
printf '%s\n' "$!" >"$artifact_dir/metro.pid"
wait_for_port 8081 "Metro"
if [[ "$platform" == "android" ]]; then if [[ "$platform" == "android" ]]; then
phase "Configuring Android localhost routing" phase "Configuring Android localhost routing"
adb -s "$device_id" reverse tcp:3000 tcp:3000 adb -s "$device_id" reverse tcp:3000 tcp:3000
adb -s "$device_id" reverse tcp:8081 tcp:8081
fi fi
phase "Running Maestro flows" phase "Running Maestro flows"
+8 -8
View File
@@ -117,10 +117,10 @@ jobs:
xcrun simctl bootstatus "$udid" -b xcrun simctl bootstatus "$udid" -b
echo "Using $device_name on $runtime_name ($udid)" echo "Using $device_name on $runtime_name ($udid)"
- name: Mark iOS E2E app build phase - name: Mark iOS development client build phase
run: echo "Building the iOS E2E app" > artifacts/ios/phase.txt run: echo "Building the iOS development client" > artifacts/ios/phase.txt
- name: Build iOS E2E app - name: Build iOS development client
uses: ./.github/actions/eas-local-build uses: ./.github/actions/eas-local-build
with: with:
platform: ios platform: ios
@@ -128,7 +128,7 @@ jobs:
output: ${{ runner.temp }}/nightly-e2e-ios.tar.gz output: ${{ runner.temp }}/nightly-e2e-ios.tar.gz
log-path: artifacts/ios/build.log log-path: artifacts/ios/build.log
- name: Install iOS E2E app - name: Install iOS development client
run: | run: |
build_contents="$RUNNER_TEMP/nightly-e2e-ios-build" build_contents="$RUNNER_TEMP/nightly-e2e-ios-build"
mkdir -p "$build_contents" mkdir -p "$build_contents"
@@ -275,10 +275,10 @@ jobs:
adb -s emulator-5554 shell settings put global transition_animation_scale 0 adb -s emulator-5554 shell settings put global transition_animation_scale 0
adb -s emulator-5554 shell settings put global animator_duration_scale 0 adb -s emulator-5554 shell settings put global animator_duration_scale 0
- name: Mark Android E2E app build phase - name: Mark Android development client build phase
run: echo "Building the Android E2E app" > artifacts/android/phase.txt run: echo "Building the Android development client" > artifacts/android/phase.txt
- name: Build Android E2E app - name: Build Android development client
uses: ./.github/actions/eas-local-build uses: ./.github/actions/eas-local-build
with: with:
platform: android platform: android
@@ -286,7 +286,7 @@ jobs:
output: ${{ runner.temp }}/nightly-e2e-android.apk output: ${{ runner.temp }}/nightly-e2e-android.apk
log-path: artifacts/android/build.log log-path: artifacts/android/build.log
- name: Install Android E2E app - name: Install Android development client
run: | run: |
adb -s emulator-5554 install -r "$RUNNER_TEMP/nightly-e2e-android.apk" \ adb -s emulator-5554 install -r "$RUNNER_TEMP/nightly-e2e-android.apk" \
2>&1 | tee -a artifacts/android/build.log 2>&1 | tee -a artifacts/android/build.log
+22
View File
@@ -3,6 +3,28 @@ appId: xyz.blueskyweb.app
- launchApp: - launchApp:
appId: "xyz.blueskyweb.app" appId: "xyz.blueskyweb.app"
clearState: true clearState: true
arguments:
"-EXDevMenuIsOnboardingFinished": true
- runFlow:
when:
platform: iOS
commands:
- extendedWaitUntil:
visible: "http://localhost:8081"
timeout: 60000
- tapOn: "http://localhost:8081"
- runFlow:
when:
platform: Android
commands:
- extendedWaitUntil:
visible: "http://10.0.2.2:8081"
timeout: 60000
- tapOn: "http://10.0.2.2:8081"
- extendedWaitUntil:
visible: "Continue"
timeout: 180000
- tapOn: "Continue"
- extendedWaitUntil: - extendedWaitUntil:
visible: visible:
id: e2eProxyHeaderInput id: e2eProxyHeaderInput
+13 -15
View File
@@ -42,23 +42,21 @@ used. iOS runs on `macos-26-xlarge` with Xcode 26.4. Android runs on
`Linux-x64-32core`. Both use Java 17 and the Node and pnpm versions declared in `Linux-x64-32core`. Both use Java 17 and the Node and pnpm versions declared in
`package.json`. The iOS job selects an iPhone 17 simulator running iOS 26.5; `package.json`. The iOS job selects an iPhone 17 simulator running iOS 26.5;
Android uses a Pixel 6 AVD with the API 35 Google APIs x86_64 image. Android uses a Pixel 6 AVD with the API 35 Google APIs x86_64 image.
Both standalone E2E apps use the `e2e` EAS profile and the same reusable local Both development clients use the `e2e` EAS profile and the same reusable local
EAS build action as the release build workflows. The profile embeds the E2E JS EAS build action as the release build workflows; the resulting simulator app
bundle during the native build, so CI does not run Metro or the Expo development and APK are installed directly on the selected devices.
client. The resulting simulator app and APK are installed directly on the
selected devices.
The mock-server manager listens on host port 1986 and creates test services on The mock-server manager listens on host port 1986 and creates test services on
port 3000. Android reverses port 3000 into the emulator; port 1986 remains port 3000. Metro listens on 8081. Android reverses ports 3000 and 8081 into the
host-side because Maestro JavaScript calls it from the runner. Android uses the emulator; port 1986 remains host-side because Maestro JavaScript calls it from
existing Docker Compose PostgreSQL 14 and Redis 7 services on ports 5433 and the runner. Android uses the existing Docker Compose PostgreSQL 14 and Redis 7
6380. GitHub-hosted macOS cannot run nested Docker virtualization, so iOS services on ports 5433 and 6380. GitHub-hosted macOS cannot run nested Docker
provisions ephemeral native PostgreSQL 14.x and Redis 7.4.7 on those same ports virtualization, so iOS provisions ephemeral native PostgreSQL 14.x and Redis
and starts `pnpm --dir dev-env start:external`. 7.4.7 on those same ports and starts `pnpm --dir dev-env start:external`.
Each platform uploads a `nightly-e2e-<platform>-<run-id>` artifact for 14 days. Each platform uploads a `nightly-e2e-<platform>-<run-id>` artifact for 14 days.
It contains JUnit at `report.xml`, Maestro screenshots, videos, command metadata It contains JUnit at `report.xml`, Maestro screenshots, videos, command metadata
and `maestro.log` under `maestro/`, plus native build, mock-server, service, and `maestro.log` under `maestro/`, plus Metro, native build, mock-server, service,
dependency, and translation logs. The workflow always uploads what was captured, dependency, and translation logs. The workflow always uploads what was captured,
including when setup or the native build fails before Maestro starts. including when setup or the native build fails before Maestro starts.
@@ -69,9 +67,9 @@ the failed setup phase, the commit and workflow links, and links to both artifac
sets. Successful runs do not post to Slack. sets. Successful runs do not post to Slack.
Before relying on the schedule, manually dispatch the workflow and verify both Before relying on the schedule, manually dispatch the workflow and verify both
embedded E2E apps against `dev-env`, Android localhost routing, artifact uploads platforms against live Metro and `dev-env`, Android localhost routing, artifact
on success and failure, one Slack message for a forced failure, and no Slack uploads on success and failure, one Slack message for a forced failure, and no
message for an all-green run. Slack message for an all-green run.
## Using Flashlight for Performance Testing ## Using Flashlight for Performance Testing
1. Make sure Maestro is installed (optional: only for automated testing) by following the instructions above 1. Make sure Maestro is installed (optional: only for automated testing) by following the instructions above
+1 -6
View File
@@ -22,12 +22,7 @@
} }
}, },
"e2e": { "e2e": {
"extends": "base", "extends": "development",
"distribution": "internal",
"ios": {
"simulator": true,
"resourceClass": "large"
},
"android": { "android": {
"buildType": "apk" "buildType": "apk"
}, },