-
Notifications
You must be signed in to change notification settings - Fork 4
315 lines (283 loc) · 12.7 KB
/
Copy pathdemo-e2e.yml
File metadata and controls
315 lines (283 loc) · 12.7 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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
name: Demo Embedded E2E (Flutter)
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
checks: write
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [master, main]
workflow_dispatch:
concurrency:
group: demo-e2e-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
matrix_android: ${{ steps.set-matrix-android.outputs.matrix_android }}
steps:
- uses: actions/checkout@v5
# Webview-based login flows have not yet been validated in CI.
# iOS matrix: tests that work in the current Patrol/Flutter setup.
#
# WEBVIEW LOGIN BLOCKER: All tests that require an embedded WebView login
# are excluded. The Frontegg iOS SDK's CustomWebView blocks navigation
# to 127.0.0.1, and the only way to whitelist it (FronteggRuntime.isTesting,
# added in master) requires `frontegg-testing=true` to be in
# ProcessInfo.processInfo.environment AT PROCESS START. Patrol launches
# the Flutter app via XCUITest with default launch params and gives us no
# hook to inject app.launchEnvironment, so we cannot meet that contract.
# See frontegg-ios-swift demo-embedded-e2e for the working pattern (uses
# XCUIApplication.launchEnvironment directly from the test class).
#
# ANDROID PARITY: The Android Frontegg SDK has no equivalent of
# FronteggRuntime.isTesting, no LocalMockAuthServer, no manualInit, and
# no offline mode — confirmed by reading frontegg-android-kotlin master.
# Webview-login E2E will require upstream SDK work on the Android side.
- id: set-matrix
env:
INPUT_EXCLUDE_METHODS: >-
testPasswordLoginAndSessionRestore,
testEmbeddedSamlLogin,
testEmbeddedOidcLogin,
testCustomSSOBrowserHandoff,
testDirectSocialBrowserHandoff,
testEmbeddedGoogleSocialLoginWithSystemWebAuthenticationSession,
testEmbeddedGoogleSocialLoginOAuthErrorShowsToastAndKeepsLoginOpen,
testLogoutTerminateTransientProbeFailureDoesNotBlinkNoConnectionPage,
testAuthenticatedOfflineModeWhenNetworkPathUnavailable,
testExpiredAccessTokenRefreshesOnAuthenticatedRelaunch,
testAuthenticatedOfflineModeRecoversToOnlineAndRefreshesToken,
testAuthenticatedOfflineModeKeepsUserLoggedInUntilReconnectRefreshesExpiredToken,
testLogoutTerminateTransientNoConnectionThenCustomSSORecovers,
testOfflineModeDisabledPreservesSessionDuringConnectionLossAndRecovers,
testPasswordLoginWorksWithOfflineModeDisabled,
testLogoutClearsSessionAndRelaunchShowsLogin,
testExpiredRefreshTokenClearsSessionAndShowsLogin,
testScheduledTokenRefreshFiresBeforeExpiry,
testAuthenticatedRelaunchWithExpiredAccessTokenAndFreshRefreshToken
run: |
JSON=$(env -u GITHUB_OUTPUT node .github/scripts/generate_e2e_matrix.js)
{
echo "matrix<<MATRIX_JSON_EOF"
echo "$JSON"
echo "MATRIX_JSON_EOF"
} >> "$GITHUB_OUTPUT"
# Android matrix: only non-login tests pass today.
#
# Tried enabling testPasswordLoginAndSessionRestore / testEmbeddedSamlLogin /
# testEmbeddedOidcLogin / testLogoutClearsSessionAndRelaunchShowsLogin — all
# fail with `visible: LoginPageRoot` after 60s, same signature as iOS. The
# reflection-based singleton replace + re-subscribe fix resolves the stale-
# observer problem but there's a second issue in the Android login flow that
# isn't diagnosable from CI logs alone (Patrol doesn't surface logcat).
# Likely candidates: EmbeddedAuthActivity not receiving the deep-link
# callback through CustomSchemeActivity, or the SDK picking up stale
# BuildConfig values despite the rebind. Revisit once frontegg-android-kotlin
# v1.3.26 ships the first-party `initializeEmbeddedForLocalE2E` API.
- id: set-matrix-android
env:
INPUT_EXCLUDE_METHODS: >-
testPasswordLoginAndSessionRestore,
testEmbeddedSamlLogin,
testEmbeddedOidcLogin,
testRequestAuthorizeFlow,
testCustomSSOBrowserHandoff,
testDirectSocialBrowserHandoff,
testEmbeddedGoogleSocialLoginWithSystemWebAuthenticationSession,
testEmbeddedGoogleSocialLoginOAuthErrorShowsToastAndKeepsLoginOpen,
testLogoutTerminateTransientProbeFailureDoesNotBlinkNoConnectionPage,
testAuthenticatedOfflineModeWhenNetworkPathUnavailable,
testExpiredAccessTokenRefreshesOnAuthenticatedRelaunch,
testAuthenticatedOfflineModeRecoversToOnlineAndRefreshesToken,
testAuthenticatedOfflineModeKeepsUserLoggedInUntilReconnectRefreshesExpiredToken,
testLogoutTerminateTransientNoConnectionThenCustomSSORecovers,
testOfflineModeDisabledPreservesSessionDuringConnectionLossAndRecovers,
testPasswordLoginWorksWithOfflineModeDisabled,
testLogoutClearsSessionAndRelaunchShowsLogin,
testExpiredRefreshTokenClearsSessionAndShowsLogin,
testScheduledTokenRefreshFiresBeforeExpiry,
testAuthenticatedRelaunchWithExpiredAccessTokenAndFreshRefreshToken
run: |
JSON=$(env -u GITHUB_OUTPUT node .github/scripts/generate_e2e_matrix.js)
{
echo "matrix_android<<MATRIX_JSON_ANDROID_EOF"
echo "$JSON"
echo "MATRIX_JSON_ANDROID_EOF"
} >> "$GITHUB_OUTPUT"
embedded-e2e-android:
runs-on: ubuntu-latest
# 1 test/shard + build + emulator; allow long token/offline scenarios
timeout-minutes: 120
needs: matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.matrix.outputs.matrix_android) }}
env:
# Retries double runtime and often hit the job timeout while the first run is stuck.
PATROL_MAX_RETRIES: "2"
steps:
- uses: actions/checkout@v5
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "17"
- name: Install Patrol CLI
run: dart pub global activate patrol_cli 3.6.0
- name: Install dependencies
working-directory: embedded
run: flutter pub get
- name: Validate E2E scenario catalog
run: env -u GITHUB_OUTPUT node .github/scripts/generate_e2e_matrix.js > /dev/null
- 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: Build debug APK + test APK
working-directory: embedded
run: patrol build android --target integration_test/e2e/embedded_e2e_test.dart
- name: Run embedded E2E on emulator
env:
E2E_METHODS: ${{ matrix['test-methods'] }}
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 31
arch: x86_64
profile: pixel_6
disable-animations: true
emulator-boot-timeout: 300
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim
script: bash .github/scripts/run_embedded_e2e_shard.sh
- name: Collect test reports
if: always()
run: |
mkdir -p e2e-artifacts
find . -name "TEST-*.xml" -exec cp -f {} e2e-artifacts/ \; 2>/dev/null || true
# Annotate only: do not create a second GitHub Check per shard (the matrix job
# already reports pass/fail; duplicate check_name was cluttering the PR checks list).
- name: JUnit report (annotations + job summary)
uses: mikepenz/action-junit-report@v5
if: always()
with:
report_paths: e2e-artifacts/*.xml
annotate_only: true
# continue-on-error: transient GitHub Actions blob-storage ENOTFOUND has
# failed entire shards whose tests passed cleanly. Artifact loss is
# annoying but not a reason to mark the suite red.
- uses: actions/upload-artifact@v6
if: always()
continue-on-error: true
with:
name: flutter-e2e-shard-${{ matrix['shard-index'] }}
path: e2e-artifacts/
if-no-files-found: ignore
embedded-e2e-ios:
# Apple Silicon runner — matches frontegg-ios-swift demo-e2e workflow.
runs-on: macos-15-xlarge
timeout-minutes: 120
needs: matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
env:
PATROL_MAX_RETRIES: "2"
steps:
- uses: actions/checkout@v5
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- name: Enable Swift Package Manager
run: flutter config --enable-swift-package-manager
- name: Reset SwiftPM caches (force fresh FronteggSwift resolution)
run: |
rm -rf ~/Library/Developer/Xcode/DerivedData
rm -rf ~/Library/Caches/org.swift.swiftpm
rm -rf ~/Library/org.swift.swiftpm
- name: Install Patrol CLI
run: dart pub global activate patrol_cli 3.6.0
- name: Install dependencies
working-directory: embedded
run: flutter pub get
- name: Fix generated SPM platform version
run: |
PKG="embedded/ios/Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage/Package.swift"
sed -i '' 's/.iOS("13.0")/.iOS("14.0")/' "$PKG"
- name: Install pods
working-directory: embedded/ios
run: pod install
- name: Verify FronteggSwift revision pinned in plugin
run: |
echo "=== ios/frontegg_flutter/Package.swift ==="
grep -A1 "frontegg-ios-swift" ios/frontegg_flutter/Package.swift
echo "=== embedded/ios/Runner.xcworkspace/.../Package.resolved ==="
cat embedded/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved | grep -A4 frontegg-ios-swift
# Match frontegg-ios-swift demo-e2e: same DEVELOPMENT_TEAM in the Xcode project and
# iPhone 16 Pro simulator. Shard tests via E2E_METHODS + E2E_TEST_FILTER (same as Android).
- name: Run embedded E2E on iOS Simulator
env:
E2E_METHODS: ${{ matrix['test-methods'] }}
PATROL_VERBOSE: "1"
run: |
set -euo pipefail
LOG="${RUNNER_TEMP}/ios-e2e-shard-${{ matrix['shard-index'] }}.log"
: > "$LOG"
export PATROL_LOG_FILE="$LOG"
UDID=$(xcrun simctl list devices available -j | jq -r '
[.devices | to_entries[].value[]
| select(.isAvailable == true and .name == "iPhone 16 Pro")]
| .[0].udid // empty')
if [[ -z "$UDID" || "$UDID" == "null" ]]; then
UDID=$(xcrun simctl list devices available -j | jq -r '
[.devices | to_entries[] | .value[]
| select(.isAvailable == true and (.name | startswith("iPhone")))]
| sort_by(.name) | .[0].udid // empty')
fi
if [[ -z "$UDID" || "$UDID" == "null" ]]; then
echo "::error::No available iPhone simulator"
xcrun simctl list devices available
exit 1
fi
export IOS_DEVICE="$UDID"
echo "::notice::Using iOS Simulator UDID=$UDID"
xcrun simctl boot "$UDID" 2>/dev/null || true
xcrun simctl bootstatus "$UDID" -b
open -a Simulator || true
sleep 5
bash .github/scripts/run_embedded_e2e_shard.sh
- uses: actions/upload-artifact@v6
if: always()
continue-on-error: true
with:
name: flutter-e2e-ios-shard-${{ matrix['shard-index'] }}
path: |
${{ runner.temp }}/ios-e2e-shard-${{ matrix['shard-index'] }}.log
embedded/build/ios_integ/
if-no-files-found: ignore
summary:
runs-on: ubuntu-latest
needs: [embedded-e2e-android, embedded-e2e-ios]
if: always()
steps:
- uses: actions/download-artifact@v6
continue-on-error: true
with:
path: all-e2e
- uses: actions/checkout@v5
- name: Combine summary
run: node .github/scripts/combine_e2e_summary.js --artifacts-dir all-e2e --summary e2e-summary.md
- name: Upload summary
uses: actions/upload-artifact@v6
continue-on-error: true
with:
name: e2e-summary
path: e2e-summary.md