-
Notifications
You must be signed in to change notification settings - Fork 319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dialog click not working on Pixel 3 (Android 10) #444
Comments
We are seeing this as well. The first click on the dialog just doesn't seem to register. If you put a Thread.Sleep() (hack) just after the dialog is displayed (right before the click), it will work. If you change the click to a doubleClick(), it will also work. If we run our tests individually, they pass. But if we run the entire class with multiple tests, that is when they become flaky. I have created a sample project here https://github.com/asavill/esspresso_alert_dialog_issue with an espresso test class which fails 100% of the time when running on Android 10 and passes 100% of the time when running < Android 10. Thank you to @lsuski for providing the other sample application. Steps to ReproduceRun ExampleInstrumentedTest Expected ResultsExampleInstrumentedTest should pass Actual ResultsExampleInstrumentedTest fails on API 29 and passes on older API versions. AndroidX Test and Android OS Versions (have also tested on latest alpha versions as of 16/11/19) espresso-core:3.1.1 Android 10 - api 29 |
Can you reproduce the issue with animations disabled? Its strongly recommended to disable animations when using espresso. |
Hello, yes animations on or off does not make a difference. |
Thanks we'll take a look |
Loved the way you closed the issue without waiting for a response. And then haven't updated anything for like 4 months now? |
This is android 10 issue. It happens in couple of devices with 10 we have for testing. Even after updating Nokia7.2 to android 10 this bug starts to show up. |
Will this be fixed ? I'm also encountering this issue. |
I confirm this happens on Samsung S10. |
For what it's worth, I can confirm this happens on the SDK 29 emulator (with about a 50% failure rate for me) but not on the SDK 24 emulator. |
Also encountering this. Have not managed to find a robust solution other than adding a |
I have also struggled with this bug and can add the observation, that when the failure occurs, the click seems to miss the dialogue, i.e. it is executed, but the event gets routed towards the activity window behind the dialog. |
@brettchabot is this being looked at all? This seems to be forcing people to (I definitely have had to) add |
@adazh any thoughts? |
Can you try using our latest Espresso release Espresso 3.5.0-alpha04? Not sure if it could fix this issue, but it contains a fix that uses consistent input device source for event injection, which may be something relevant. |
I've run our suite a few times with |
Nice! Thanks for confirming! |
I am still seeing the problem after running on Espresso 3.5.0. |
@dabrosch Can you also try with |
I will have to extract out non-proprietary code to publish that, and I am not 100% sure I can repro it because the entire application is huge, and this failure is definitely related to a race condition, which means it is "touchy." But what I can 100% say is that without a 250 msec wait hack placed immediately after a popup is found to exist (via UiAutomator), the espresso click attempt fails 95% of the time. |
FWIW I did some testing using the sample posted earlier: https://github.com/asavill/esspresso_alert_dialog_issue Interestingly this sample (with espresso 3.1.1) can repro the problem 100% on an API 29 emulator, but the test passes reliably on every other API level (24, 28, 30,31,33) I've tried. Using the latest stable release of all dependencies, including espresso (3.5.0) helps a little but the failure rate still seems > 50%). I tried adding logging and investigating more but didn't find anything yet |
I've created few workarounds in our internal library for dialog clicking:
|
The other issue I faced rarely was due to View not being in touch mode. I faced this with sending KEYCODE_BACK as first event in a test. In such case motion down event is ignored |
I can try the other versions though. |
@lsuski do you mind providing more details how you are monitoring for dialog enter animation? I would hope disabling animations would prevent dialog and activity animations from occurring in the first place but I suspect that might not be the case. |
This line of code also in Instrumentation.startActivitySync seems potentially relevant: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/Instrumentation.java;drc=0f9ea02be099947968936258e1f0746a43470a7c;l=568 Unfortunately I don't see a way of calling that outside of the android framework either on API 29. API 33 introduces a TransactionCommittedListener but that doesn't help here... Another workaround that appeared to work on @asavill sample is to force a redraw on the dialog. Basically this logic here used for androidx.test screenshots . |
I'll share it on Monday. The code you mentioned is for Activity only started by test but during the test other activities can be started by app and this logic does not apply. Also afaik dialog has its own enter animation. |
|
Thanks for the details, interesting approach. Correct me if I'm wrong but that solution appears to be essentially a conditional sleep, set to the value of animation duration. I realize the limitations of the solutions I posted earlier, but unfortunately our options to work around this particular issue seem limited. |
@brettchabot yes, you're right |
My workaround is to use the This is the custom class ViewInstruction(
private val viewMatcher: Matcher<View>,
private val idleMatcher: Matcher<View>,
private val rootMatcher: Matcher<Root> = RootMatchers.DEFAULT,
) : Instruction() {
private var assertionThrowable: Throwable? = null
override fun getDescription(): String {
val stringBuilder = StringBuilder()
.append(toString())
.append(" ")
.append(viewMatcher.description())
assertionThrowable?.let { assertionThrowable ->
stringBuilder
.append(" ")
.append("(${assertionThrowable.message ?: "$assertionThrowable"})")
}
val viewException = getExceptionWithViewHierarchy()
stringBuilder
.append("\nView hierarchy:\n")
.append(viewException.stackTraceToString())
return stringBuilder.toString()
}
override fun checkCondition(): Boolean =
idleMatcher.matches(
getView(viewMatcher),
)
private fun getView(
viewMatcher: Matcher<View>,
): View? =
try {
var view: View? = null
runOnUiThread {
val viewInteraction = onView(viewMatcher).inRoot(rootMatcher)
val finderField: Field = viewInteraction
.javaClass
.getDeclaredField("viewFinder").apply {
isAccessible = true
}
val finder = finderField.get(viewInteraction) as ViewFinder
view = finder.view
}
view
} catch (e: Throwable) {
assertionThrowable = e
null
}
private fun getExceptionWithViewHierarchy(): Throwable =
runCatching {
assertDisplayed("Force non existent text to print hierarchy")
}.exceptionOrNull()!!
} These are some helper methods to wait for view conditions: fun waitUntilViewIsDisplayedInDialog(text: String) {
waitUntilViewMatchesCondition(text, isDisplayed())
}
fun waitUntilViewIsDisplayedInDialog(viewStringId: Int) {
waitUntilViewMatchesCondition(viewStringId, isDisplayed())
}
private fun waitUntilViewMatchesCondition(viewStringId: Int, condition: Matcher<View>) {
ConditionWatcher.waitForCondition(
ViewInstruction(
viewStringId.resourceMatcher(),
condition,
isDialog(),
),
)
}
private fun waitUntilViewMatchesCondition(text: String, condition: Matcher<View>) {
ConditionWatcher.waitForCondition(
ViewInstruction(
withText(text),
condition,
isDialog(),
),
)
} And this is how I use it with the robot pattern: fun someDialog(
func: SomeDialogRobot.() -> Unit,
): SomeDialogRobot {
waitUntilViewIsDisplayedInDialog(R.string.some_string_on_the_dialog)
return SomeDialogRobot().apply(func)
}
class SomeDialogRobot That solves the dialog click 100% of the time in my tests. |
Description
On Pixel 3 (this is probably android 10 specific issue but I've tested it only on Pixel 3) simple clicking on dialog button immediately after it is shown does not work
Steps to Reproduce
Animations are enabled on device.
Run ExampleInstrumentedTest
Expected Results
ExampleInstrumentedTest should pass
Actual Results
ExampleInstrumentedTest fails on Pixel 3 and passes on older devices
AndroidX Test and Android OS Versions
espresso-core:3.2.0
androidx.test.ext:junit:1.1.1
androidx.appcompat:appcompat:1.0.2
Android 10 - api 29
Link to a public git repo demonstrating the problem:
https://github.com/lsuski/espresso-android10-bug-sample
The text was updated successfully, but these errors were encountered: