android-test icon indicating copy to clipboard operation
android-test copied to clipboard

setScreenOrientation() fails test when trying to restore screen orientation (after a successful usage earlier)

Open jdkoren opened this issue 1 year ago • 0 comments

Description

onDevice().setScreenOrientation() is failing in an instrumented test, even after calling it once successfully earlier in the test. This can happen inside of ScreenOrientationRule as well.

Steps to Reproduce

Create a test in androidTest like the following and run it on a device.

@RunWith(AndroidJUnit4::class)
class EspressoOnDeviceTest {

    @get:Rule
    val screenOrientationRule = ScreenOrientationRule()

    // NOTE: assumes starting the test with the device in portrait.
    @Test
    fun setScreenOrientation_configUpdated() {
        val scenario = ActivityScenario.launch(MainActivity::class.java)

        scenario.onActivity { activity ->
            with(activity.resources.configuration) {
                assertThat(orientation).isEqualTo(Configuration.ORIENTATION_PORTRAIT)
            }
        }

        onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)

        scenario.onActivity { activity ->
            with(activity.resources.configuration) {
                assertThat(orientation).isEqualTo(Configuration.ORIENTATION_LANDSCAPE)
            }
        }
    }
}

Expected Results

Test should pass.

Actual Results

Test fails with a stack trace pointing to a line in ScreenOrientationRule where it tries to restore the original screen orientation:

androidx.test.espresso.device.controller.DeviceControllerOperationException: Device could not be set to the requested screen orientation.
at androidx.test.espresso.device.action.ScreenOrientationAction.perform(ScreenOrientationAction.kt:154)
at androidx.test.espresso.device.DeviceInteraction.perform(DeviceInteraction.kt:45)
at androidx.test.espresso.device.rules.ScreenOrientationRule$apply$1.evaluate(ScreenOrientationRule.kt:41)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:162)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:68)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:463)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2596)

If I remove the test rule in this file, then the test passes, so the test itself is not broken.

As an experiment, I tried adding this line to the end of the test:

onDevice().setScreenOrientation(ScreenOrientation.PORTRAIT)

This also failed, with a stack trace pointing to this new line, which leads me to think the issue is something in ScreenOrientationAction.

AndroidX Test and Android OS Versions

androidx.test.espresso:espresso-core:3.6.1
androidx.test.espresso:espresso-device:1.0.1

jdkoren avatar Sep 04 '24 19:09 jdkoren