15

The app is passing the espresso tests locally, i mean directly to the devices and genymotion emulators. When I use Jenkins to built an app's image. The espresso test are not successful I get this error.

JENKINS:

 java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong. Selected Root:
Root{application-window-token=android.view.ViewRootImpl$W@536a97d4, window-token=android.view.ViewRootImpl$W@536a97d4, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#100 ty=1 fl=#1810100 pfl=0x8 wanim=0x103028f}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=800, height=1184, has-focus=true, has-focusable=true, has-window-focus=false, 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}}
. All Roots:
Root{application-window-token=android.view.ViewRootImpl$W@536a97d4, window-token=android.view.ViewRootImpl$W@536a97d4, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#100 ty=1 fl=#1810100 pfl=0x8 wanim=0x103028f}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=800, height=1184, has-focus=true, has-focusable=true, has-window-focus=false, 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 com.google.android.apps.common.testing.ui.espresso.base.RootViewPicker.get(RootViewPicker.java:84)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:51)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule$$ModuleAdapter$ProvideRootViewProvidesAdapter.get(ViewInteractionModule$$ModuleAdapter.java:187)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule$$ModuleAdapter$ProvideRootViewProvidesAdapter.get(ViewInteractionModule$$ModuleAdapter.java:151)
at com.google.android.apps.common.testing.ui.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:52)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction$2.run(ViewInteraction.java:141)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Alfaplus
  • 1,713
  • 2
  • 19
  • 29
  • What device is this stack trace from? – yogurtearl Oct 01 '14 at 14:36
  • that is what jenkins says. – Alfaplus Oct 02 '14 at 07:20
  • That stack trace is from Espresso running on either an android emulator or android device. Are you running emulators on your Jenkins server? – yogurtearl Oct 02 '14 at 14:41
  • Yes I am. Is that a problem? I have using Robotium instead of espresso and with the emulators I got any problem until espresso's test. – Alfaplus Oct 06 '14 at 15:06
  • 1
    Are your emulators running with "--no-window" ? Try reproducing locally with the exact same AVD as on your Jenkins machine. – yogurtearl Oct 07 '14 at 19:18
  • 1
    I'm having the same problem with drone, have you found a solution for this problem? – marbarfa Mar 06 '15 at 18:10
  • No i don't. I refused to use espresso beacuse of this issue. Intead I use calabash to test UI and mokito to test the behaviour. – Alfaplus Mar 07 '15 at 09:46
  • Sounds like a window outside of your process had focus. You could take a screenshot with `InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot()` when a test fails. That should reveal what's going on. Or VNC into the Jenkins slave and manually observe it. – Daniel Lubarov Jun 03 '15 at 00:30
  • For me this only appears to happen on the first run, when the emulator does a complete cold start. If I run it again a second time, it works fine (I believe some emulator things are cached). Any reason why? – AdamMc331 Nov 08 '16 at 14:35
  • is it resolved ? did you completed your espresso integration with Jenkins ? – Andrew Kramer Nov 20 '19 at 10:06

4 Answers4

10

Stacktrace means that Espresso can't find application window. During testing on emulators screen usually hidden behind Screen Lock. You need use some code to disable ScreenLock programmatically. The most convenient way for me to unlock screen is using Robotium. It has solo.unlockScreen() method. I've put it into setUp() method of testing lifecycle.

Links: https://github.com/RobotiumTech/robotium/blob/master/robotium-solo/src/main/java/com/robotium/solo/Solo.java

QZenn
  • 101
  • 1
  • 3
  • 2
    On top of scytale's response - you can also provide a simple example of the implementation that you're suggesting. – g00dy Jul 03 '15 at 07:57
1

The solution is to create a custom test runner to unlock the screen and start a wake lock until the tests are done.

public class TestRunner extends android.support.test.runner.AndroidJUnitRunner
{
    private PowerManager.WakeLock mWakeLock;

    @Override
    public void callApplicationOnCreate(Application app)
    {
        // Unlock the screen
        KeyguardManager keyguard = (KeyguardManager) app.getSystemService(Context.KEYGUARD_SERVICE);
        keyguard.newKeyguardLock(getClass().getSimpleName()).disableKeyguard();

        // Start a wake lock
        PowerManager power = (PowerManager) app.getSystemService(Context.POWER_SERVICE);
        mWakeLock = power.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, getClass().getSimpleName());
        mWakeLock.acquire();

        super.callApplicationOnCreate(app);
    }

    @Override
    public void onDestroy()
    {
        mWakeLock.release();

        super.onDestroy();
    }
}

Then AndroidManifest.xml of your tests and add the necessary permissions:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

Don't forget to edit your build.gradle to use the new testInstrumentationRunner class.

Source

ByteWelder
  • 5,464
  • 1
  • 38
  • 45
  • This solution uses some deprecated methods and constants. Could you provide some alternative? – MeLean Mar 23 '17 at 10:32
0

From my point of view, you need to organize your Jenkins job in the following way: before running Espresso tests (I suppose you have connectedAndroidTest in a gradle post-build action there or something like this), add a post-build action to uninstall the app package and another one to uninstall the app test package. Example: com.example.mypackage.debug and com.example.mypackage.debug.test. This is a good way to refresh the app into your smartphone/emulator, in order to let Espresso use its magic.

Also be sure that you have the Always On option in Developer Tools activated (depending on the device, in Settings you have Developer options or Developer tools submenu).

If none of this work, it means that somewhere in your Jenkins job you have some order of actions issue and need to be clarified. For me the uninstalling of the packages helped me clean the system of all the things related to my app.

Hopefully it will work for you too.

If not, please write comment and I will help you.

Good luck!

sunlover3
  • 1,999
  • 1
  • 20
  • 25
0

I suggest using Test-Butler, to disable animation and unlock screen while testing.

Arade
  • 567
  • 6
  • 14
  • Test-Butler can only be used for emulators, so it's a good idea if you're using an emulator to run your tests. If you are testing on real devices, I would suggest `UiAutomator`. – carvaq Mar 23 '17 at 09:53