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

Open
#2,279 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
android, kotlin

Research direction

Reproduce the instrumented test from the issue with ScreenOrientationRule, then read androidx.test.espresso.device.action.ScreenOrientationAction.kt and ScreenOrientationRule.kt around the reported stack-trace lines. Check how DeviceInteraction.perform invokes the orientation action and verify that both the explicit change and rule cleanup complete successfully without the DeviceControllerOperationException.

Written by the indexing model from the issue text.

Description

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
Dominant language
Java
Stars
1.2k
Forks
342
Avg merge
1d 14h
Merged PRs (30d)
5

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from android/android-test

All issues in android/android-test

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.