Merge pull request #3658 from cake-tech/integration-test-fixes
What changed, and why it matters
This commit fixes flaky integration tests in the project's automated CI pipeline and makes a small UI cleanup change in the app's authentication screen. It does not appear to fix a security vulnerability. The auth-page change replaces a direct 'dismiss' call on notification bars with a safer helper that checks whether the bar is actually showing before trying to dismiss it, preventing a possible crash or visual glitch during PIN entry.
No security action required. Treat as a normal quality/test-stability patch. If desired, verify the _removeBar helper handles all Flushbar lifecycle edge cases during QA.
Security signals we found
No security-relevant signals in commit title or message
No CVE, advisory, or security disclosure references present
Auth page change is defensive UI hardening, not an access-control or cryptographic fix
CI-only changes do not alter application code or secrets handling
Evidence from the diff
The diff updates GitHub Actions workflows to require a ‘check-suites’ job before running Android integration tests, bumps the emulator API level from 29 to 31, sets the AVD target to google_apis, and removes an explicit emulator/adb cleanup step. In lib/src/screens/auth/auth_page.dart, a new _removeBar helper is introduced: it checks if the Flushbar route exists and is active, dismisses the bar only if it is currently showing, otherwise removes the route directly. This avoids calling dismiss() on a bar that may not be on screen, which can throw or leave a stale route.
Changed components
.github/workflows/integration_tests.yml.github/workflows/reusable-integration-test.ymllib/src/screens/auth/auth_page.dartInspect captured patch +38 / −11
### .github/workflows/integration_tests.yml
@@ -17,8 +17,24 @@ concurrency:
cancel-in-progress: true
jobs:
- android-integration-tests:
+ check-suites:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.fork == false
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+ sparse-checkout: integration_test/suites
+
+ - name: Check the branch has the test suites
+ run: |
+ if [[ ! -d integration_test/suites/tier0 ]]; then
+ echo "::error::This branch has no integration test suites yet, sync it with dev to run them"
+ exit 1
+ fi
+
+ android-integration-tests:
+ needs: check-suites
uses: ./.github/workflows/reusable-integration-test.yml
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
### .github/workflows/reusable-integration-test.yml
@@ -288,7 +288,8 @@ jobs:
SUITE_DIR_INPUT: ${{ inputs.suite_dir }}
EXTRA_DART_DEFINES_INPUT: ${{ inputs.extra_dart_defines }}
with:
- api-level: 29
+ api-level: 31
+ target: google_apis
arch: x86_64
profile: pixel_5
force-avd-creation: false
@@ -320,7 +321,8 @@ jobs:
SUITE_DIR_INPUT: ${{ inputs.suite_dir }}
EXTRA_DART_DEFINES_INPUT: ${{ inputs.extra_dart_defines }}
with:
- api-level: 29
+ api-level: 31
+ target: google_apis
arch: x86_64
profile: pixel_5
force-avd-creation: false
@@ -590,9 +592,3 @@ jobs:
-H "Content-type: application/json; charset=utf-8" \
--data "$(jq -n --arg channel "$SLACK_CHANNEL" --arg ts "$thread_ts" --arg text "$passed" \
'{channel: $channel, thread_ts: $ts, text: $text}')" > /dev/null
-
- - name: Post-test cleanup
- if: always()
- run: |
- pkill -f emulator || echo "No emulator processes to kill"
- pkill -f adb || echo "No adb processes to kill"
### lib/src/screens/auth/auth_page.dart
@@ -116,9 +116,9 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
/// not the best scenario, but WidgetsBinding is not behaving correctly on Android
await Future<void>.delayed(Duration(milliseconds: 50));
- await _authBar?.dismiss();
+ await _removeBar(_authBar);
await Future<void>.delayed(Duration(milliseconds: 50));
- await _progressBar?.dismiss();
+ await _removeBar(_progressBar);
await Future<void>.delayed(Duration(milliseconds: 50));
if (route != null) {
Navigator.of(_key.currentContext!).pushReplacementNamed(route, arguments: arguments);
@@ -153,6 +153,21 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
);
}
+ Future<void> _removeBar(Flushbar<void>? bar) async {
+ final barRoute = bar?.flushbarRoute;
+
+ if (bar == null || barRoute == null || !barRoute.isActive) {
+ return;
+ }
+
+ if (bar.isShowing()) {
+ await bar.dismiss();
+ return;
+ }
+
+ barRoute.navigator?.removeRoute(barRoute);
+ }
+
void dismissFlushBar(Flushbar<dynamic>? bar) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await bar?.dismiss();Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.