Android Espresso: PerformException
Asked Answered
A

8

38

I`m getting

android.support.test.espresso.PerformException: Error performing 'send keyCode: 4, metaState: 0 key event' on view 'Animations or transitions are enabled on the target device.

I read articles with same error but didnt find answer.

I have simple android app and I try to test simple thing:

  1. Load RecyclerView
  2. Click on RecyclerView`s item
  3. Open Activity
  4. Press button inside Activity
  5. Press back
  6. Repeat from part 1.

Code is extremely easy:

@Test
public void getOver500Products() {
    onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
    onView(withId(R.id.layout2)).perform(click());
    clickExactItem(2);
    for (int i = 0; i< 501; i++) {
        clickRandomItem();
        addedToCart();
        Espresso.pressBack();
    }
}

public void clickRandomItem() {
    try {
        int x = getRandomRecyclerPosition(R.id.list);
        clickExactItem(x);
    } catch (NoMatchingViewException e) {
    }
}

public void clickExactItem(int position) {
    onView(withId(R.id.list))
            .perform(RecyclerViewActions
                    .actionOnItemAtPosition(position, click()));
}

public boolean addedToCart() {
    try {
        onView(withId(R.id.product_add_in_cart)).perform(click());
    } catch (NoMatchingViewException e) {
        return false;
    }
    return true;
}

It throws exception after 10-50 iterations (randomly) so basically code is right.

EspressoTestDev.java:88 line where it crashes is

Espresso.pressBack();

Exactly after this line I`m getting exception.

Exception stacktrace:

android.support.test.espresso.PerformException: Error performing 'send keyCode: 4, metaState: 0 key event' on view 'Animations or transitions are enabled on the target device.

is a root view.'.
at android.support.test.espresso.PerformException$Builder.build(PerformException.java:83)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:80)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56)
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 android.support.test.espresso.Espresso.pressBack(Espresso.java:189)
at com.app.myapp.EspressoTestDev.getOver500Products(EspressoTestDev.java:88)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
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:270)
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:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1851)
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
is displayed on the screen to the user
Target view: "PopupViewContainer{id=-1, visibility=VISIBLE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:138)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5549)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

Looks like it found problem with PopupViewContainer but I dont use it, dont click it and I have no idea how can it impact to Espresso.pressBack()

What I tried:

  1. Adding getInstrumentation().waitForIdleSync(); before and after Espresso.pressBack()

  2. Making delay as suggested here

The question is: how can I avoid this error or how can I ignore and continue iterations in my case?

Aeriell answered 16/5, 2017 at 15:14 Comment(0)
C
54

Animations or transitions are enabled on the target device.

Espresso doesn't work well with animations due to the visual state delays they introduce. You need to disable animations on your device. Firstly, enable developer options:

  1. Open the Settings app.
  2. Scroll to the bottom and select About phone.
  3. Scroll to the bottom and tap Build number 7 times.
  4. Return to the previous screen to find Developer options near the bottom.

Access Developer Options from Settings app, and under the Drawing section, switch all of the following options to Animation Off:

  • Window animation scale
  • Transition animation scale
  • Animator duration scale
Chalmers answered 16/5, 2017 at 15:38 Comment(4)
Well exactly the same error =( but at least that works a bit fasterAeriell
I need to work with devices where i can't disable them.Grith
at first i thought i was getting the same exception after applyig this fix, but upon closer inspection.... it was different. Error performing 'scroll to' on view 'with id: com.example.app:id/view_id'. so it fixed it, ThanksOvid
Is it possible to disable them from the code itself?Stopcock
G
10

In addition to the accepted answer, if you want to open the emulator from console, you have to add the following commands:

    - adb shell settings put global window_animation_scale 0 &
    - adb shell settings put global transition_animation_scale 0 &
    - adb shell settings put global animator_duration_scale 0 &
Giselegisella answered 31/1, 2019 at 12:19 Comment(0)
A
8

In my case, Espresso gave me the "Animations or transitions are not enabled..." error, but that wasn't actually the root cause.

Scrolling through the stack trace I found this:

androidx.test.espresso.PerformException: Error performing 'scroll to' on view 'Animations or transitions are enabled on the target device.

...

Caused by: java.lang.RuntimeException:
  Action will not be performed because the target view does not match one or more
  of the following constraints:
    (view has effective visibility=VISIBLE and is descendant of a: (
      is assignable from class: class android.widget.ScrollView or
      is assignable from class: class android.widget.HorizontalScrollView or
      is assignable from class: class android.widget.ListView
    ))
Target view: "LinearLayout{...}"

That is, I was trying to scroll something that can't be scrolled.

So, always read through the stacktrace folks 👌

Acuna answered 8/5, 2020 at 2:40 Comment(0)
A
2

ensure the control you want to work with is visible. this worked for me. add "scrollTo()"

onView(...).perform(scrollTo(), click());
Allophane answered 22/7, 2018 at 1:2 Comment(1)
Seemed like a good suggestion, I tried it, but I got the same error unfortunately.Stroud
S
2

I've run into the error Animations or transitions are enabled on the target device several times. In the latest case, the real problem was that my UI code was throwing a NullPointerException. Unfortunately Espresso was "swallowing" the NullPointerException and giving me the irrelevant error Animations or transitions are enabled on the target device.

Stroud answered 18/2, 2020 at 0:42 Comment(0)
H
0

I had a similar error but after inspecting the logcat, I realised the fragment under test was trying to do a navigation and the nav graph wasn't defined in the test because the fragment had been launched with launchFragmentInContainer. Fixing that fixed the issue.

Headless answered 20/5, 2020 at 14:18 Comment(0)
D
0

Before clicking item on specific position, should be scroll that position,

onView(withId(R.id.list))
            .perform(RecyclerViewActions
                    .scrollToPosition(position));

onView(withId(R.id.list))
            .perform(RecyclerViewActions
                    .actionOnItemAtPosition(position, click()));
Deceitful answered 10/5, 2021 at 10:36 Comment(0)
C
-1

A simple try catch. Where you only pick up the exception if it is an PerformException.

Alternativ add the 500 items to your shopping cart by code, and then add 1 extra by UI test.

Clod answered 4/2, 2019 at 11:59 Comment(1)
A simple try catch would prevent the issue from breaking the test, but it won't prevent the issue from happening. This is exactly what tests are not about. medium.com/@richbray/why-should-you-write-tests-910a3175d33c Basically, never ever prevent tests from crashing if the code they are testing is also not supposed to crash in production.Simeon

© 2022 - 2024 — McMap. All rights reserved.