-
Notifications
You must be signed in to change notification settings - Fork 8
test: Add e2e tests using react-native-harness #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5591834
702464e
ee40a70
0e0ec44
83f3845
62a79cb
2cb9b1a
80427c9
3c2b056
a59557b
fb0de54
6b96db9
2edfa1e
e4ef041
150b0ba
3c80a54
94252f4
5e178d7
bc73651
46474f8
f936c19
e3b4a6a
fd585fc
e263839
8899b84
3fa7c60
180cdd2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,235 @@ | ||||||
| name: E2E Tests | ||||||
|
|
||||||
| on: | ||||||
| push: | ||||||
| branches: [main] | ||||||
| pull_request: | ||||||
| branches: [main] | ||||||
| workflow_dispatch: | ||||||
|
|
||||||
| concurrency: | ||||||
| group: e2e-${{ github.ref }} | ||||||
| cancel-in-progress: true | ||||||
|
|
||||||
| jobs: | ||||||
| e2e-ios: | ||||||
| name: E2E Tests (iOS) | ||||||
| runs-on: macos-15 | ||||||
| timeout-minutes: 30 | ||||||
| steps: | ||||||
| - name: Checkout | ||||||
| uses: actions/checkout@v4 | ||||||
|
|
||||||
| - name: Setup Node.js | ||||||
| uses: actions/setup-node@v4 | ||||||
| with: | ||||||
| node-version: '20' | ||||||
| cache: 'yarn' | ||||||
|
|
||||||
| - name: Cache CocoaPods | ||||||
| uses: actions/cache@v4 | ||||||
| with: | ||||||
| path: | | ||||||
| example/showcase/ios/Pods | ||||||
| ~/Library/Caches/CocoaPods | ||||||
| key: pods-e2e-${{ runner.os }}-${{ hashFiles('**/Podfile.lock') }} | ||||||
| restore-keys: | | ||||||
| pods-e2e-${{ runner.os }}- | ||||||
|
|
||||||
| - name: Install dependencies | ||||||
| run: yarn install --immutable | ||||||
|
|
||||||
| - name: Build library | ||||||
| run: yarn prepare | ||||||
|
|
||||||
| - name: Install example dependencies | ||||||
| working-directory: example/showcase | ||||||
| run: yarn install --immutable | ||||||
|
|
||||||
| - name: Install Pods | ||||||
| working-directory: example/showcase/ios | ||||||
| run: pod install | ||||||
|
|
||||||
| - name: List available simulators | ||||||
| run: xcrun simctl list devices available | ||||||
|
|
||||||
| - name: Boot iOS Simulator | ||||||
| run: | | ||||||
| # Find iPhone 16 Pro first (available on macos-15), fallback to any iPhone | ||||||
| DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone 16 Pro" | head -1 | awk -F '[()]' '{print $2}') | ||||||
| if [ -z "$DEVICE_ID" ]; then | ||||||
| DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone" | head -1 | awk -F '[()]' '{print $2}') | ||||||
| fi | ||||||
| echo "Booting simulator: $DEVICE_ID" | ||||||
| xcrun simctl boot "$DEVICE_ID" || true | ||||||
| echo "SIMULATOR_DEVICE_ID=$DEVICE_ID" >> $GITHUB_ENV | ||||||
|
|
||||||
| - name: Build iOS App | ||||||
| working-directory: example/showcase | ||||||
| run: | | ||||||
| xcodebuild -workspace ios/NitroDeviceInfoExample.xcworkspace \ | ||||||
| -scheme NitroDeviceInfoExample \ | ||||||
| -configuration Debug \ | ||||||
| -sdk iphonesimulator \ | ||||||
| -destination "id=$SIMULATOR_DEVICE_ID" \ | ||||||
| -derivedDataPath ios/build \ | ||||||
| build | ||||||
|
|
||||||
| - name: Install iOS App | ||||||
| run: | | ||||||
| APP_PATH=$(find example/showcase/ios/build -name "*.app" -type d | head -1) | ||||||
| echo "Installing app from: $APP_PATH" | ||||||
| xcrun simctl install "$SIMULATOR_DEVICE_ID" "$APP_PATH" | ||||||
|
|
||||||
| - name: Run E2E Tests | ||||||
| working-directory: example/showcase | ||||||
| run: npx react-native-harness --harnessRunner ios | ||||||
| env: | ||||||
| CI: true | ||||||
|
|
||||||
| - name: Upload test results | ||||||
| if: always() | ||||||
| uses: actions/upload-artifact@v4 | ||||||
| with: | ||||||
| name: e2e-ios-results | ||||||
| path: | | ||||||
| example/showcase/jest-results.xml | ||||||
| example/showcase/coverage/ | ||||||
| retention-days: 7 | ||||||
|
|
||||||
| e2e-android: | ||||||
| name: E2E Tests (Android) | ||||||
| runs-on: ubuntu-latest | ||||||
| timeout-minutes: 45 | ||||||
| steps: | ||||||
| - name: Free Disk Space | ||||||
| uses: jlumbroso/free-disk-space@main | ||||||
| with: | ||||||
| tool-cache: false | ||||||
| android: false # Keep Android SDK | ||||||
| dotnet: true | ||||||
| haskell: true | ||||||
| large-packages: true | ||||||
| docker-images: true | ||||||
| swap-storage: true | ||||||
|
|
||||||
| - name: Checkout | ||||||
| uses: actions/checkout@v4 | ||||||
|
|
||||||
| - name: Setup Node.js | ||||||
| uses: actions/setup-node@v4 | ||||||
| with: | ||||||
| node-version: '20' | ||||||
| cache: 'yarn' | ||||||
|
|
||||||
| - name: Setup Java | ||||||
| uses: actions/setup-java@v4 | ||||||
| with: | ||||||
| distribution: 'temurin' | ||||||
| java-version: '17' | ||||||
|
|
||||||
| - 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: Cache Gradle | ||||||
| uses: actions/cache@v4 | ||||||
| with: | ||||||
| path: | | ||||||
| ~/.gradle/caches | ||||||
| ~/.gradle/wrapper | ||||||
| key: gradle-e2e-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | ||||||
| restore-keys: | | ||||||
| gradle-e2e-${{ runner.os }}- | ||||||
|
|
||||||
| - name: Cache AVD | ||||||
| uses: actions/cache@v4 | ||||||
| with: | ||||||
| path: | | ||||||
| ~/.android/avd/* | ||||||
| ~/.android/adb* | ||||||
| key: avd-api-30-${{ runner.os }} | ||||||
| restore-keys: | | ||||||
| avd-api-30- | ||||||
|
|
||||||
| - name: Install dependencies | ||||||
| run: yarn install --immutable | ||||||
|
|
||||||
| - name: Build library | ||||||
| run: yarn prepare | ||||||
|
|
||||||
| - name: Install example dependencies | ||||||
| working-directory: example/showcase | ||||||
| run: yarn install --immutable | ||||||
|
|
||||||
| - name: Build Android App | ||||||
| working-directory: example/showcase/android | ||||||
| run: ./gradlew assembleDebug | ||||||
|
|
||||||
| - name: Create AVD and run E2E tests | ||||||
| uses: reactivecircus/android-emulator-runner@v2 | ||||||
| with: | ||||||
| api-level: 30 | ||||||
| arch: x86_64 | ||||||
| profile: pixel_4 | ||||||
| target: google_apis | ||||||
|
||||||
| target: google_apis | |
| target: google_apis_playstore |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| module.exports = { | ||
| preset: 'react-native-harness', | ||
| testMatch: ['**/__tests__/**/*.harness.(ts|tsx)'], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { | ||
| androidPlatform, | ||
| androidEmulator, | ||
| } from '@react-native-harness/platform-android'; | ||
| import { | ||
| applePlatform, | ||
| appleSimulator, | ||
| } from '@react-native-harness/platform-apple'; | ||
|
|
||
| // CI environment detection - GitHub Actions sets CI=true | ||
| const isCI = process.env.CI === 'true'; | ||
|
|
||
| /** @type {import('react-native-harness').HarnessConfig} */ | ||
| const config = { | ||
| entryPoint: './index.js', | ||
| appRegistryComponentName: 'NitroDeviceInfoExample', | ||
| // CI: 300s timeout for slower Metro startup and simulator response on shared runners | ||
| // Local: 60s timeout for faster feedback during development | ||
| bridgeTimeout: isCI ? 300000 : 60000, | ||
| // CI: Disable app restart between test files to avoid simulator timeout issues | ||
| // Local: Enable for better test isolation during development | ||
| resetEnvironmentBetweenTestFiles: !isCI, | ||
|
|
||
| runners: [ | ||
| applePlatform({ | ||
| name: 'ios', | ||
| device: appleSimulator('iPhone 16 Pro', '18.4'), | ||
| bundleId: 'nitrodeviceinfo.example', | ||
| }), | ||
| androidPlatform({ | ||
| name: 'android', | ||
| device: androidEmulator('test'), | ||
| bundleId: 'nitrodeviceinfo.example', | ||
| }), | ||
| ], | ||
|
|
||
| defaultRunner: 'ios', | ||
| }; | ||
|
|
||
| export default config; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
SIMULATOR_DEVICE_IDenvironment variable is set but never used in subsequent steps. If this was intended for use by react-native-harness, consider documenting it or removing it if unused.