android / android/android-test

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
Dominant language
Java
Stars
1.2k
Forks
342
Avg merge
11h 29m
Merged PRs (30d)
2

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
```

Contributor guide

Open the contributing guide

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.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.