Skip to content

fix(test): Check notification permission before requesting to fix flaky API 34 tests#5146

Closed
romtsn wants to merge 17 commits intomainfrom
rz/fix/flaky-notification-test-api34
Closed

fix(test): Check notification permission before requesting to fix flaky API 34 tests#5146
romtsn wants to merge 17 commits intomainfrom
rz/fix/flaky-notification-test-api34

Conversation

@romtsn
Copy link
Member

@romtsn romtsn commented Mar 3, 2026

📜 Description

On API 34+, the notification button in the critical UI test app always launched the permission request dialog, even when permission was already granted. This caused flaky test behavior because the permission dialog would overlay the UI unexpectedly.

The fix adds a ContextCompat.checkSelfPermission check before launching the permission request. If the permission is already granted, it skips the request and directly posts the notification.

💡 Motivation and Context

Critical UI tests on API 34 emulators were flaky because the notification permission request was being triggered even when the permission was already granted from a previous test run or interaction. This caused the permission dialog to appear unexpectedly, interfering with test assertions.

💚 How did you test it?

Ran the critical UI tests on an API 34 emulator and verified the notification flow works correctly both when permission is already granted and when it needs to be requested.

📝 Checklist

  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

None

…fix flaky API 34 tests

On API 34, Maestro's `permissions: all: allow` pre-grants POST_NOTIFICATIONS
via `pm grant`. The ActivityResult callback from `requestPermissionLauncher`
is not always reliably invoked when the permission is already granted,
causing the notification to never be posted. This adds a checkSelfPermission
guard so the notification is posted directly when already permitted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


Bug Fixes 🐛

  • (test) Check notification permission before requesting to fix flaky API 34 tests by romtsn in #5146

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 349.67 ms 413.47 ms 63.80 ms
Size 1.58 MiB 2.29 MiB 722.96 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
91bb874 314.47 ms 440.00 ms 125.53 ms
dba088c 333.98 ms 381.16 ms 47.18 ms
d15471f 310.66 ms 368.19 ms 57.53 ms
bbc35bb 298.53 ms 372.17 ms 73.64 ms
d15471f 307.28 ms 381.85 ms 74.57 ms
ad8da22 362.98 ms 453.94 ms 90.96 ms
cf708bd 408.35 ms 458.98 ms 50.63 ms
96449e8 361.30 ms 423.39 ms 62.09 ms
27d7cf8 309.43 ms 364.27 ms 54.85 ms
91bb874 311.00 ms 363.47 ms 52.47 ms

App size

Revision Plain With Sentry Diff
91bb874 1.58 MiB 2.13 MiB 559.07 KiB
dba088c 1.58 MiB 2.13 MiB 558.99 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
bbc35bb 1.58 MiB 2.12 MiB 553.01 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
ad8da22 1.58 MiB 2.29 MiB 719.83 KiB
cf708bd 1.58 MiB 2.11 MiB 539.71 KiB
96449e8 1.58 MiB 2.11 MiB 539.35 KiB
27d7cf8 1.58 MiB 2.12 MiB 549.42 KiB
91bb874 1.58 MiB 2.13 MiB 559.07 KiB

Previous results on branch: rz/fix/flaky-notification-test-api34

Startup times

Revision Plain With Sentry Diff
f1cc8c9 324.39 ms 379.83 ms 55.44 ms
b51e769 309.53 ms 366.82 ms 57.29 ms
06b4d04 344.02 ms 412.70 ms 68.68 ms
4a898ed 314.14 ms 358.00 ms 43.86 ms
d326a0d 311.04 ms 365.46 ms 54.42 ms
65bdd9b 365.50 ms 428.45 ms 62.95 ms
b6344f5 313.35 ms 363.47 ms 50.12 ms
be17dea 345.68 ms 407.27 ms 61.59 ms
25c258f 293.67 ms 393.28 ms 99.61 ms
0f654b6 312.67 ms 350.31 ms 37.64 ms

App size

Revision Plain With Sentry Diff
f1cc8c9 1.58 MiB 2.29 MiB 722.92 KiB
b51e769 1.58 MiB 2.29 MiB 722.93 KiB
06b4d04 1.58 MiB 2.29 MiB 722.92 KiB
4a898ed 1.58 MiB 2.29 MiB 722.92 KiB
d326a0d 1.58 MiB 2.29 MiB 722.93 KiB
65bdd9b 1.58 MiB 2.29 MiB 722.97 KiB
b6344f5 1.58 MiB 2.29 MiB 722.93 KiB
be17dea 1.58 MiB 2.29 MiB 722.91 KiB
25c258f 1.58 MiB 2.29 MiB 722.93 KiB
0f654b6 1.58 MiB 2.29 MiB 722.91 KiB

romtsn and others added 15 commits March 3, 2026 15:37
The Pixel Launcher can become unresponsive on CI emulators,
showing a system dialog that blocks Maestro from interacting
with the app under test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IMPORTANCE_DEFAULT notifications may be silently delivered on some
emulators, causing the notification to not appear in the shade
when Maestro swipes down to find it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use a shorter, faster swipe from the center-top (50%, 1%) to
center (50%, 50%) with 1s duration instead of a slow full-screen
swipe. Also increase retries from 3 to 5 to handle slower emulators.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes for flaky notification tests on CI emulators:

1. Handle the POST_NOTIFICATIONS permission dialog explicitly in the
   Maestro flow, in case Maestro's `permissions: all: allow` doesn't
   grant it reliably.
2. Collapse the notification shade in onFlowStart to prevent cascade
   failures when a previous test left it open.
3. Add waitForAnimationToEnd inside the swipe retry loop to give the
   shade time to render.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tings

The swipe from 50%,1% to 50%,50% was too long — it expanded
straight to the quick settings panel, hiding the notification
entries behind it. Use a shorter swipe (0% to 25%) to only open
the notification shade where notification entries are visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n channel

Two issues found from analyzing the accessibility hierarchy dump:

1. Repeated swipe-downs accumulated into full quick settings expansion,
   hiding the notification list. Fix: press home before each swipe retry
   to reset the shade state, so each attempt opens a fresh notification
   shade instead of expanding quick settings further.

2. adb install -r preserves app data including notification channels.
   The old IMPORTANCE_DEFAULT channel persists and Android ignores the
   code change to IMPORTANCE_HIGH. Fix: delete the channel before
   recreating it to ensure correct importance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IMPORTANCE_HIGH shows the notification as a heads-up banner at the
top of the screen. When Maestro swipes down to open the notification
shade, it instead dismisses the heads-up notification, causing it
to disappear entirely. IMPORTANCE_DEFAULT puts the notification
directly in the shade without a heads-up, so the swipe opens the
shade as intended.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore the original swipe values (90%,0% -> 90%,100%, 4s) that
are proven to work on main, but keep the pressKey:home +
waitForAnimationToEnd before each swipe to prevent quick settings
accumulation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…otification shade

The full-screen swipe (90%,0% -> 90%,100%) was expanding into quick
settings on API 34 instead of showing the notification shade. Changed to
a half-screen swipe (90%,0% -> 90%,50%) which is long enough to open
the shade on API 36 but short enough to avoid quick settings on API 34.

Also uses pressKey:back + pressKey:home to reliably collapse any open
shade/quick settings before retrying, and increased retries from 3 to 5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ition

The notification shade was closing between the repeat loop's visibility
check and the subsequent tapOn command. By moving the tapOn inside the
loop (with optional: true) and changing the loop condition to check for
the app's expected screen instead, we tap the notification immediately
after the swipe while the shade is still open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ve notifications

am force-stop (used by Maestro's killApp) clears all notifications on
API 33+, causing Test 4 (COLD start via notification) to always fail.

Adds a "Kill Process" button that calls Process.killProcess() which
kills the app process without clearing notifications. The Maestro test
now taps this button instead of using killApp.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous approach of using Process.killProcess() without Finish
Activity didn't work because the notification wasn't surviving process
death on API 33+. Analysis of main branch (where all API levels pass)
shows that the original flow works: Trigger Notification → Finish
Activity → killApp → open shade → tap notification.

Restores original swipe values (90%,0% → 90%,100%, 4000ms) and killApp
which work on main. Keeps the runFlow for permission dialog handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@romtsn romtsn closed this Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants