Espresso - click on the dialog button

I want to check permissions for Android 6, but I have not found a way to click the "Allow" button using Espresso. Is there any way to do this?

enter image description here

Espresso version is 2.2.1.

Test:

@Test public void acceptFirstPermission() throws Exception { onView(withText("ALLOW")).perform(click()); } 

Behavior:

I still get a frozen screen using the dialog (as in the screenshot). Testing is performed all the time until it finishes.

Output:

 Running tests Test running started android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)? at dalvik.system.VMStack.getThreadStackTrace(Native Method) at java.lang.Thread.getStackTrace(Thread.java:580) at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:82) at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:53) at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184) at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115) at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87) at com.walletsaver.app.test.espresso.MarshmallowPermissionsTest.acceptFirstPermission(MarshmallowPermissionsTest.java:31) at java.lang.reflect.Method.invoke(Native Method) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:257) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54) at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:240) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879) Finish 
+8
android android-6.0-marshmallow android-espresso runtime-permissions
source share
5 answers

I see that you are trying to check the resolution of the application. I think it would be impossible to test it with Espresso. You may need to take this action as another user interface testing tool called uiatomator .

uiatomator , another great tool made by Google, lets you test your Android system features like notifications and screen lock. You can use it with the Espresso test environment.

For more information, read this article:

http://qathread.blogspot.com/2015/05/espresso-uiautomator-perfect-tandem.html

and uiautomator, which you will find here .

+7
source share

Well, it can be as simple as

 onView(withText("Allow")).perform(click()); 

Of course, this is not an ideal solution, so there are two ways to make it more reliable: either analyze the application using a hierarchical view to find tips on how to identify the button (for example, a description of the content), or plunge into the Android source code for tips (for example , button resource identifier).

EDIT

Well, it's not that simple. I wrote an article about using UiAutomator to do this job.

+7
source share

You can use the dynamic way to accept permissions, if a dialog box appears, permission will be granted, if it does not appear, it will not give any error.

  private static void allowPermissionsIfNeeded() { if (Build.VERSION.SDK_INT >= 23) { UiDevice device = UiDevice.getInstance(getInstrumentation()); UiObject allowPermissions = device.findObject(new UiSelector().text("ALLOW")); if (allowPermissions.exists()) { try { allowPermissions.click(); } catch (UiObjectNotFoundException e) { e.printStackTrace(); } } } } 
+1
source share

If you use UI-Automator with AndroidX, you can find the dialog box and buttons.

This is the gradle dependency code.

 dependencies { androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' } 

You can access the ALLOW button with this code.

This is the Kotlin code.

 val button = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) .findObject( UiSelector().text( activityTestRule .activity .getString(R.string.allow_button) .toUpperCase() ) ) if (button.exists() && button.isEnabled) { button.click() } 
0
source share

The snippet below will give grants before running the tests. Hope it solves your problem :)

  @Before public void grantPhonePermission() { // In M+, trying to call a number will trigger a runtime dialog. Make sure // the permission is granted before running this test. // goo.gl/C8T4BU if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { getInstrumentation().getUiAutomation().executeShellCommand( "pm grant " + getTargetContext().getPackageName() + " android.permission.READ_PHONE_STATE" + " android.permission.PHONE"); } } 
-3
source share