-
Notifications
You must be signed in to change notification settings - Fork 37
242 lines (212 loc) · 10.8 KB
/
inapp-e2e-tests.yml
File metadata and controls
242 lines (212 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: In-App Message E2E Tests
on:
push:
branches: [ InApp-Display-E2E ]
pull_request:
branches: [ InApp-Display-E2E, master, develop ]
workflow_dispatch: # Allow manual triggering
jobs:
inapp-e2e-tests:
name: In-App Message E2E Tests
runs-on: macos-15-intel
strategy:
matrix:
api-level: [34] # MVP testing on most relevant API level only
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Android SDK
uses: android-actions/setup-android@v2
- name: Create local.properties
run: |
echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties
echo "ndk.dir=$ANDROID_SDK_ROOT/ndk" >> local.properties
- name: Accept Android SDK Licenses
run: |
echo "Accepting Android SDK licenses..."
yes | sdkmanager --licenses || true
echo "SDK licenses accepted"
- name: Setup Google Services Configuration
run: |
echo "Setting up Google Services configuration for CI..."
# Ensure the google-services.json file exists for the build
if [ ! -f "integration-tests/google-services.json" ]; then
echo "Creating google-services.json from template..."
cp integration-tests/google-services.json.template integration-tests/google-services.json
fi
echo "Google Services configuration ready"
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Pre-download Gradle and Build (Parallel with Emulator)
run: |
echo "Pre-downloading Gradle and building while emulator boots..."
# Download Gradle wrapper in background
./gradlew --version &
# Start building APKs in background
./gradlew :integration-tests:assembleDebug :integration-tests:assembleDebugAndroidTest --no-daemon &
echo "Build started in background..."
- name: Run UI Tests with Emulator (Intel / x86_64)
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: google_apis
arch: x86_64
profile: pixel_6
cores: 2
ram-size: 3072M
heap-size: 576M
force-avd-creation: true
disable-animations: true
emulator-boot-timeout: 900
emulator-options: -no-window -no-snapshot -gpu swiftshader_indirect -no-boot-anim -camera-back none -partition-size 6000
pre-emulator-launch-script: |
# Clean + start adb after platform-tools exist (avoids tcp:5037 noise)
adb kill-server >/dev/null 2>&1 || true
adb start-server
script: |
# SDK-170 OBSERVABILITY: capture diagnostics that survive the action exit.
# The android-emulator-runner kills the emulator on its way out, so any
# adb-dependent capture MUST happen before this script returns. We write
# everything under $GITHUB_WORKSPACE so a later step can upload it.
DIAG_DIR="$GITHUB_WORKSPACE/integration-tests/build/diagnostics"
mkdir -p "$DIAG_DIR"
capture_diag() {
local label="$1"
local prefix="$2"
echo "=== diag capture: $label ==="
{
echo "# label: $label"
echo "# t: $(date -u +%FT%TZ)"
echo
echo "## adb devices"
adb devices 2>&1
echo
echo "## top activities"
adb shell dumpsys activity activities 2>&1 | head -200
echo
echo "## window state (focused app + visible windows)"
adb shell dumpsys window 2>&1 | head -200
echo
echo "## connectivity (active default network, link addresses, dns)"
adb shell dumpsys connectivity 2>&1 | head -120
echo
echo "## meminfo (system_server + integration tests)"
adb shell dumpsys meminfo 2>&1 | head -80
echo
echo "## installed iterable packages"
adb shell pm list packages 2>&1 | grep iterable || true
echo
echo "## boot props"
adb shell getprop sys.boot_completed dev.bootcomplete init.svc.netd net.dns1 ro.build.version.release ro.build.version.sdk 2>&1 | head -10
} > "$DIAG_DIR/${prefix}-state.txt" 2>&1
# UiAutomator hierarchy and screenshot — the smoking gun for "button not found"
adb shell uiautomator dump /sdcard/hierarchy.xml >/dev/null 2>&1 || true
adb pull /sdcard/hierarchy.xml "$DIAG_DIR/${prefix}-hierarchy.xml" >/dev/null 2>&1 || echo "(no hierarchy)"
adb shell screencap -p /sdcard/screenshot.png >/dev/null 2>&1 || true
adb pull /sdcard/screenshot.png "$DIAG_DIR/${prefix}-screenshot.png" >/dev/null 2>&1 || echo "(no screenshot)"
}
echo "Emulator is ready! Running tests..."
echo "Setting up permissions..."
adb shell pm grant com.iterable.integration.tests android.permission.POST_NOTIFICATIONS || true
adb shell pm grant com.iterable.integration.tests android.permission.INTERNET || true
adb shell pm grant com.iterable.integration.tests android.permission.ACCESS_NETWORK_STATE || true
adb shell pm grant com.iterable.integration.tests android.permission.WAKE_LOCK || true
echo "Running In-App Message MVP test..."
echo "Debug: Checking if APKs are ready..."
ls -la integration-tests/build/outputs/apk/ || echo "APK directory not found"
echo "Debug: Verifying API keys are set..."
echo "ITERABLE_API_KEY length: ${#ITERABLE_API_KEY}"
echo "ITERABLE_SERVER_API_KEY length: ${#ITERABLE_SERVER_API_KEY}"
echo "ITERABLE_TEST_USER_EMAIL: $ITERABLE_TEST_USER_EMAIL"
# Snapshot pre-test device state. If tests fail because the activity never
# foregrounded, this captures what was on screen *before* we even ran.
capture_diag "pre-test" "00-pre-test"
# Stream full logcat to the workspace so we get an artifact even on success.
adb logcat -c >/dev/null 2>&1 || true
adb logcat > "$DIAG_DIR/10-logcat-full.txt" &
LOGCAT_PID=$!
GRADLE_EXIT=0
./gradlew :integration-tests:connectedDebugAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.class=com.iterable.integration.tests.InAppMessageIntegrationTest#testInAppMessageMVP \
--stacktrace --no-daemon || GRADLE_EXIT=$?
# Stop logcat ASAP so post-test capture isn't entangled with it.
kill $LOGCAT_PID 2>/dev/null || true
wait $LOGCAT_PID 2>/dev/null || true
# Always capture post-test state — useful on success too (proves the test
# really did exercise the SDK and surface campaigns).
capture_diag "post-test" "20-post-test"
# Filtered logcat for fast triage; full logcat is also uploaded.
grep -E 'IterableApi|IterableRequest|IterableInApp|IterableEmbedded|IntegrationMainActivity|BaseIntegrationTest|InAppMessageIntegrationTest|PushNotificationIntegrationTest|EmbeddedMessageIntegrationTest|DeepLinkIntegrationTest|FATAL|AndroidRuntime|ANR' \
"$DIAG_DIR/10-logcat-full.txt" > "$DIAG_DIR/11-logcat-filtered.txt" 2>/dev/null || true
echo
echo "=== diagnostics summary ==="
ls -la "$DIAG_DIR"
echo
echo "Last 50 logcat lines (full file uploaded as artifact):"
tail -50 "$DIAG_DIR/10-logcat-full.txt" || true
if [ "$GRADLE_EXIT" != "0" ]; then
echo "::error::Test gradle task failed with exit code $GRADLE_EXIT — see e2e-diagnostics-api-${{ matrix.api-level }} artifact"
exit "$GRADLE_EXIT"
fi
env:
ITERABLE_API_KEY: ${{ secrets.BCIT_ITERABLE_API_KEY }}
ITERABLE_SERVER_API_KEY: ${{ secrets.BCIT_ITERABLE_SERVER_API_KEY }}
ITERABLE_TEST_USER_EMAIL: ${{ secrets.BCIT_ITERABLE_TEST_USER_EMAIL }}
- name: Upload E2E diagnostics
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-diagnostics-api-${{ matrix.api-level }}
path: |
integration-tests/build/diagnostics/
integration-tests/build/reports/
integration-tests/build/outputs/
if-no-files-found: warn
retention-days: 7
# test-summary:
# name: Test Summary
# runs-on: ubuntu-latest
# needs: inapp-e2e-tests
# if: always()
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Download Test Results
# uses: actions/download-artifact@v4
# with:
# name: inapp-e2e-test-results-api-34
# path: test-results/
# - name: Generate Test Summary
# run: |
# echo "## In-App Message E2E Test Results" >> $GITHUB_STEP_SUMMARY
# echo "" >> $GITHUB_STEP_SUMMARY
# echo "### Test Execution Summary" >> $GITHUB_STEP_SUMMARY
# echo "- **Branch**: InApp-Display-E2E" >> $GITHUB_STEP_SUMMARY
# echo "- **API Level Tested**: 34" >> $GITHUB_STEP_SUMMARY
# echo "- **Test Method**: testInAppMessageMVP" >> $GITHUB_STEP_SUMMARY
# echo "- **Test Type**: E2E Integration Test" >> $GITHUB_STEP_SUMMARY
# echo "" >> $GITHUB_STEP_SUMMARY
# echo "### E2E Test Scenarios" >> $GITHUB_STEP_SUMMARY
# echo "- ✅ User Sign-in Verification" >> $GITHUB_STEP_SUMMARY
# echo "- ✅ In-App Message Trigger" >> $GITHUB_STEP_SUMMARY
# echo "- ✅ Message Display Verification" >> $GITHUB_STEP_SUMMARY
# echo "- ✅ Button Click Interaction" >> $GITHUB_STEP_SUMMARY
# echo "- ✅ Message Dismissal" >> $GITHUB_STEP_SUMMARY
# echo "" >> $GITHUB_STEP_SUMMARY
# echo "### Artifacts Available" >> $GITHUB_STEP_SUMMARY
# echo "- Test execution reports" >> $GITHUB_STEP_SUMMARY
# echo "- Code coverage reports" >> $GITHUB_STEP_SUMMARY
# echo "- Debug screenshots" >> $GITHUB_STEP_SUMMARY
# echo "- Detailed test logs" >> $GITHUB_STEP_SUMMARY