android / android/android-test

Intents.intended if flaky when dialog is shown in Android 11

Open
#1,072 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.