Search code examples
androidadbcalabashcalabash-android

Tests fail when device screen is sleeping


I am trying to run some Calabash tests on an Android device. If I manually turn the screen before running the tests then everything works. On a Nexus 4 if I turn the screen off and try to run the tests then my first scenario times out waiting for elements to appear. On a Galaxy Nexus if I start the tests with the screen off then Calabash wakes up the device and the tests pass.

Are there some devices that Calabash simply cannot wake up? Is the Nexus 4 one of these? Turning on the devices manually is not feasible since I will run these tests frequently on many devices.

I have found some outdated references to this issue. A post from 2012 by Adam Niedzielski at https://groups.google.com/forum/#!topic/calabash-android/o6lUuEOuGtE suggests the following hook in app_life_cycle_hooks.rb

include Calabash::Android::Operations

AfterConfiguration do |config|
  wake_up
end

but code was added to ruby-gem/bin/calabash-android in Calabash that explicitly disallows inclusion of the Operations module: https://github.com/calabash/calabash-android/commit/995daef9b6636e7e4e572aeb5d4f90d6d072320f so I guess this is no longer the recommended approach. If I remove the include and just type Calabash::Android::Operations.wake_up I get a NameError.


Solution

  • I've run into this error occasionally and ended up setting the screen timeout to longer than a minute and running this method before starting the tests:

      def self.turn_on_screen(device_serial_number)
        # Switches on the android devices screen if it isn’t already on.
        if `adb -s #{device_serial_number} shell dumpsys input_method | grep mScreenOn`.include? 'false'
          `adb -s #{device_serial_number} shell input keyevent KEYCODE_POWER`
        end
      end
    

    This will turn simulate a keypress of the power button if the screen isn't already on. I've used this on about 4 different devices and not had any issues so far so hopefully it'll work for you.

    It may be worth noting that I've also turned lockscreens off the the devices.

    EDIT: After an update to lollipop I had to add in another check. Using both seems to do the trick on all of my test devices.

    if `adb shell dumpsys input_method | grep mInteractive`.include? 'false'
      `adb shell input keyevent KEYCODE_POWER`
    end