android / android/android-test
Intents.intended if flaky when dialog is shown in Android 11
- Dominant language
- Java
- Stars
- 1.2k
- Forks
- 342
- Avg merge
- 11h 29m
- Merged PRs (30d)
- 2
Description
### Description
`Intents.intended()` fails when a dialog is shown due to a wrongly picked root view (window).
### Steps to Reproduce
Test scenario:
1. Intents.init()
2. Intents.intending(...)
3. Launch activity
4. Open AlertDialog
5. Intents.intended(...) <-- fails
6. Intents.release()
### Expected Results
Matcher is working.
### Actual Results
`Intents.intended()` fails:
```
Waited for the root of the view hierarchy to have window focus and not request layout for 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Root:
Root{application-window-token=android.view.ViewRootImpl$W@29a8c2, window-token=android.view.ViewRootImpl$W@29a8c2, has-window-focus=false, layout-params-type=1, layout-params-string={(0,0)(fillxfill) sim={state=hidden adjust=resize} ty=BASE_APPLICATION
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
fitSides=}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=320, height=480, has-focus=false, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) sim={state=hidden adjust=resize} ty=BASE_APPLICATION
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
fitSides=}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}}
```
The activity window was picked, not the dialog.
For the context, all windows ([radiography](https://github.com/square/radiography) output):
```
my.app/app.MyActivity: <--- Activity
window-focus:false <--- no focus
DecorView { 320×480px }
├─LinearLayout { 320×480px }
│ ├─ViewStub { id:action_mode_bar_stub, GONE, 0×0px }
│ ╰─FrameLayout { 320×462px }
│ ╰─FitWindowsFrameLayout { id:action_bar_root, 320×462px }
│ ├─ContentFrameLayout { id:content, 320×462px }
....
my.app/app.MyActivity: <--- AlertDialog
window-focus:false <--- no focus
DecorView { 303×139px }
╰─LinearLayout { 279×115px }
├─ViewStub { id:action_mode_bar_stub, GONE, 0×0px }
╰─FrameLayout { 279×115px }
╰─FitWindowsFrameLayout { id:action_bar_root, 279×115px }
├─ContentFrameLayout { id:content, 279×115px }
│ ╰─AlertDialogLayout { id:parentPanel, 279×115px }
....
```
### AndroidX Test and Android OS Versions
- 1.3.0, but espresso-intents 1.4.0
- Android 11
### Link to a public git repo demonstrating the problem:
I couldn't reproduce it in a sample app.
In some cases, AlertDialog's window gains focus and is used.
It's easily reproducible in an internal repository. Feel free to ask to gather any additional information.
### Ideas
As I understand, the problem is here:
```kotlin
public static void intended(
final Matcher matcher, final VerificationMode verificationMode) {
...
instrumentation.waitForIdleSync();
if (resumedActivitiesExist(instrumentation)) {
// Running through Espresso to take advantage of its synchronization mechanism.
onView(isRoot()) <--- default root matcher
.check(
new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewFoundException) {
defaultInstance.internalIntended(matcher, verificationMode, recordedIntents);
}
});
} ...
```
Probable solution is to use `runOnMainSync` or `Espresso.onIdle` here.
Also, I don't understand what "synchronization mechanism" is needed after already done `waitForIdleSync()`.
Contributor guide
Research direction
Start at the intended(...) implementation shown in the issue, especially the waitForIdleSync() call and the default isRoot() matcher. Investigate how Android 11 selects the activity window when an AlertDialog is shown, then add a regression test that reproduces the dialog scenario and verifies Intents.intended() succeeds with the dialog window.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java
- Domain
- mobile, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100