Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4fc79c0
fix(ci): parsing ids to detox configuration file
tsdamas Jun 5, 2026
e4b57ed
fix(e2e): prevent multiple BrowserStack sessions per CI run
tsdamas Jun 5, 2026
66ce922
chore(detox): update the cloud provider
tsdamas Jun 5, 2026
35e5ca9
fix(ci): revert browserstack app id changes
tsdamas Jun 5, 2026
e1bc678
fix(ce2e): resolve BrowserStack Android SSL failure and clean up stal…
tsdamas Jun 8, 2026
b6f298b
chore(ci): test two concurrent sessions
tsdamas Jun 8, 2026
fc3c0dc
fix(ci): rollback changes and adding retries
tsdamas Jun 8, 2026
7829cdd
fix(device-profile): fix bridge pre-populating collectors
tsdamas Jun 8, 2026
9792896
fix(detox): increase timeout and retries to fix android e2e failures
tsdamas Jun 8, 2026
1da620c
feat(ci): split BrowserStack Android E2E into parallel core and journ…
tsdamas Jun 9, 2026
c36694c
chore(e2e): fix script and change workflow name
tsdamas Jun 9, 2026
aac6962
fix(e2e-ios): fix ios app craches in bs
tsdamas Jun 9, 2026
3ce527e
fix(ci): remove test all device profile collectors due to flackiness
tsdamas Jun 9, 2026
8eb1a94
chore(apps): upgrading bundler and ios dependencies
tsdamas Jun 9, 2026
8b696ea
fix(ci): upgrade Ruby from 2.6.10 to 3.3.6 to support Bundler 4
tsdamas Jun 9, 2026
f405fb6
chore(dependencies): upgrade sample ap dependencies to resolve critic…
tsdamas Jun 10, 2026
0cf0be9
chore(ci): increase the detox timeout and retries
tsdamas Jun 10, 2026
7e5c3a3
chore(ci): add android devices matrix
tsdamas Jun 10, 2026
48fcd06
chore(ci): revert android e2e matrix changes
tsdamas Jun 10, 2026
d4b3eb0
chore(ci): update ruby version on e2e flows
tsdamas Jun 11, 2026
73d531f
chore(ci): hide e2e build links and add npm badge
tsdamas Jun 11, 2026
6f2ea5d
fix(ci): force espresso 3.7.0 and fix android.emu detox config
tsdamas Jun 12, 2026
114dfe4
fix(ci): remove positional e2e arg from detox testRunner to honour te…
tsdamas Jun 15, 2026
b0bd43c
fix(ci): add Detox-level file retry for transient BrowserStack laun…
tsdamas Jun 15, 2026
8ac2c74
fix(ios): wire xcconfig chain and add Sign in with Apple entitlement
tsdamas Jun 15, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This software may be modified and distributed under the terms
# of the MIT license. See the LICENSE file for details.
#
name: BrowserStack E2E — Android
name: BrowserStack E2E — Android Foundation Modules

on:
workflow_call:
Expand All @@ -18,7 +18,7 @@ on:
description: BrowserStack session name used by Detox
required: false
type: string
default: android-detox-e2e
default: android-detox-e2e-core
secrets:
BROWSERSTACK_USERNAME:
description: BrowserStack account username
Expand Down Expand Up @@ -61,23 +61,18 @@ permissions:
contents: read

jobs:
e2e-android-browserstack:
name: E2E — Android BrowserStack
e2e-android-core:
name: E2E — Android BrowserStack (foundation)
runs-on: ubuntu-latest
timeout-minutes: 60
timeout-minutes: 45
defaults:
run:
working-directory: PingTestRunner
shell: bash

env:
# APK paths — defined once, referenced in upload steps
APP_APK_PATH: android/app/build/outputs/apk/release/app-release.apk
TEST_APK_PATH: android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk
# BrowserStack credentials available to all steps
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
# Ping server configuration available to all steps
PING_SERVER_URL: ${{ secrets.PING_SERVER_URL }}
PING_REALM_PATH: ${{ secrets.PING_REALM_PATH }}
PING_COOKIE_NAME: ${{ secrets.PING_COOKIE_NAME }}
Expand All @@ -101,17 +96,23 @@ jobs:
npm install -g jest
npm install -g detox-cli

- name: Set up Java
uses: actions/setup-java@v4
- name: Download app APK artifact
uses: actions/download-artifact@v4
with:
distribution: temurin
java-version: 17
name: pingtestrunner-android-bs-app
path: PingTestRunner/android/app/build/outputs/apk/release

- name: Download test APK artifact
uses: actions/download-artifact@v4
with:
name: pingtestrunner-android-bs-test-suite
path: PingTestRunner/android/app/build/outputs/apk/androidTest/release

- name: Compute BrowserStack identifiers
# Naming convention:
# Project : rn-<moduleName>-test → rn-sdk-test
# Build : <EVENT_PREFIX>-<RUN_ID>-<RUN_ATTEMPT>-<SHORT_SHA>
# Session : <platform>-<framework>-<test_name>
# Build : <EVENT_PREFIX>-<RUN_ID>-<RUN_ATTEMPT>-<SHORT_SHA>-core
# Session : <platform>-<framework>-core
run: |
set -euo pipefail
SHORT_SHA="${GITHUB_SHA:0:7}"
Expand All @@ -126,49 +127,17 @@ jobs:
BUILD_PREFIX="run"
;;
esac
echo "BROWSERSTACK_BUILD_ID=${BUILD_PREFIX}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${SHORT_SHA}" >> "$GITHUB_ENV"
echo "BROWSERSTACK_BUILD_ID=${BUILD_PREFIX}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${SHORT_SHA}-core" >> "$GITHUB_ENV"
echo "BROWSERSTACK_PROJECT_NAME=${{ inputs.browserstack_project_name }}" >> "$GITHUB_ENV"
echo "BROWSERSTACK_SESSION_NAME=${{ inputs.browserstack_session_name }}" >> "$GITHUB_ENV"

- name: Build SDK packages
# Metro bundles the JS at release build time and resolves the Ping SDK
# packages via their compiled lib/ output. Build all packages first so
# lib/module/index.js exists for every dependency.
run: yarn packages:build
working-directory: ${{ github.workspace }}

- name: Generate codegen artifacts for all SDK modules
# React Native New Architecture requires each library's codegen JNI
# directories to exist before CMake configures the app. Run codegen
# across all included modules so the directories are present.
run: |
cd android && ./gradlew \
:ping-identity_rn-binding:generateCodegenArtifactsFromSchema \
:ping-identity_rn-browser:generateCodegenArtifactsFromSchema \
:ping-identity_rn-device-client:generateCodegenArtifactsFromSchema \
:ping-identity_rn-device-id:generateCodegenArtifactsFromSchema \
:ping-identity_rn-device-profile:generateCodegenArtifactsFromSchema \
:ping-identity_rn-external-idp:generateCodegenArtifactsFromSchema \
:ping-identity_rn-fido:generateCodegenArtifactsFromSchema \
:ping-identity_rn-journey:generateCodegenArtifactsFromSchema \
:ping-identity_rn-logger:generateCodegenArtifactsFromSchema \
:ping-identity_rn-oath:generateCodegenArtifactsFromSchema \
:ping-identity_rn-oidc:generateCodegenArtifactsFromSchema \
:ping-identity_rn-push:generateCodegenArtifactsFromSchema \
:ping-identity_rn-storage:generateCodegenArtifactsFromSchema \
:react-native-async-storage_async-storage:generateCodegenArtifactsFromSchema

- name: Build Release APK and androidTest APK
run: yarn build:runner:bs:android
working-directory: ${{ github.workspace }}

- name: Upload app to BrowserStack
id: upload-app
run: |
response=$(curl --silent --fail-with-body \
-u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/detox/v2/android/app" \
-F "file=@$APP_APK_PATH")
-F "file=@android/app/build/outputs/apk/release/app-release.apk")
app_url=$(echo "$response" | jq -r '.app_url')
if [[ "$app_url" == "null" || -z "$app_url" ]]; then
echo "::error::Failed to get app_url from BrowserStack response: $response"
Expand All @@ -182,22 +151,40 @@ jobs:
response=$(curl --silent --fail-with-body \
-u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/detox/v2/android/app-client" \
-F "file=@$TEST_APK_PATH")
-F "file=@android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk")
test_url=$(echo "$response" | jq -r '.app_client_url')
if [[ "$test_url" == "null" || -z "$test_url" ]]; then
echo "::error::Failed to get app_client_url from BrowserStack response: $response"
exit 1
fi
echo "test_url=$test_url" >> "$GITHUB_OUTPUT"

- name: Run E2E tests on BrowserStack real devices
- name: Run E2E core tests on BrowserStack real devices
id: run-tests
run: yarn test:runner:bs:android 2>&1 | tee /tmp/detox-bs.log; exit "${PIPESTATUS[0]}"
run: yarn test:runner:bs:android:core 2>&1 | tee /tmp/detox-bs.log; exit "${PIPESTATUS[0]}"
working-directory: ${{ github.workspace }}
env:
BROWSERSTACK_APP_URL: ${{ steps.upload-app.outputs.app_url }}
BROWSERSTACK_TEST_URL: ${{ steps.upload-test.outputs.test_url }}

- name: View BrowserStack test results
if: always() && steps.run-tests.outcome != 'skipped'
shell: bash
run: |
set -euo pipefail

session_id="$(grep -oP '(?<=session_id=)[^[:space:]]+' /tmp/detox-bs.log | head -1 || true)"

if [ -z "$session_id" ]; then
echo "Session ID not found in Detox logs — visit https://app-automate.browserstack.com/dashboard/v2 to view results."
exit 0
fi

echo "Fetching BrowserStack session details for session: $session_id"
curl -s \
-u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/detox/v2/android/sessions/${session_id}"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Prepare test summary report
if: always()
shell: bash
Expand All @@ -213,7 +200,6 @@ jobs:
result_label="❌ Failed"
fi

# Extract Jest-style test counts written by Detox to stdout
test_detail=""
if [ -f /tmp/detox-bs.log ]; then
suites_line="$(grep -E "^Test Suites:" /tmp/detox-bs.log | tail -1 || true)"
Expand All @@ -226,11 +212,11 @@ jobs:
fi

{
echo "## BrowserStack Android Detox Summary"
echo "## BrowserStack Android Detox Summary — Core"
echo
echo "- Build ID: \`${build_id}\`"
echo "- Overall status: ${overall_status}"
echo "- Result: ${result_label}"
echo "- BrowserStack dashboard: https://app-automate.browserstack.com/dashboard/v2"
echo "- [BrowserStack dashboard](https://app-automate.browserstack.com/dashboard/v2/builds/${build_id})"
echo -e "$test_detail"
} >> "$GITHUB_STEP_SUMMARY"
Loading
Loading