4

Is there any way to do the following process in iOS Automation using Appium?

  1. Press home button.
  2. Put app in background.
  3. Open some other app (say Gmail) -> do operations there.
  4. Then relaunch our app and resume the methods check.

I tried these:

RemoteWebDriver wd = null;
wd.close();

But it just quits the app (just like wd.quit()) which I am automating and then when I try relaunching -> it starts from the scratch. I am running it on an iPhone simulator.

Mike Akers
  • 12,039
  • 14
  • 58
  • 71
Smriti
  • 1,552
  • 3
  • 15
  • 29
  • Hi, I do not know the answer yet but setting wd to null n then calling wd.close() - won't that cause NPE? I am also looking for similar behaviour. – Changdeo Jadhav Jun 25 '14 at 11:37

8 Answers8

5

Appium actually does provide client libraries that allow you to close the app, relaunch it (without starting from scratch), lock the sim, etc.

Libraries to do this exist in C#, Python, and Ruby as well as Java.

Migrating to those WebDrivers rather than selenium's WebDriver is SUPER simple and recommended, as you get access to all the goodies the Appium team added (like shaking your device, complex tapping, locking the device, etc)

Jess
  • 3,097
  • 2
  • 16
  • 42
  • Lol nice. Good to know they finally implemented that. Is swipe working with iOS 7.1 too? – HelloImNewHere Jun 25 '14 at 14:33
  • Yep! Atleast their python client they added it. (usage: driver.swipe(start_x, start_y, end_x, end_y, duration_in_ms). My current headache is figuring how to string together a series of swipes and taps to operate a UIDatePicker – Jess Jun 25 '14 at 15:07
  • I don't get closeApp() working properly (iOS), it's closing the simulator too. Seems I miss anything!? – HelloImNewHere Jun 26 '14 at 08:41
  • 1
    Hi, I could use the api closeApp but I want to launch another already installed app as a part of test case. For ex. I have launched my app "XYZ" , performed some steps. I sent my app in background using runInBackground or closeApp method. Now I want to launch other already installed app say "ABC", is there any way to achieve this? Thanks in advance – Changdeo Jadhav Jun 27 '14 at 12:55
  • 2
    @ChangdeoJadhav here's the answer on this (pretty much exactly what I would've typed in here): http://stackoverflow.com/a/24399468/3622606 – Jess Jun 28 '14 at 01:41
4

For iOS

Sending keys is not supported by Xcode according to this: https://github.com/appium/appium/issues/4479 Hence a possible workaround is: https://stackoverflow.com/a/24408831/2302437

For Android

To Put App in Background i.e Press Home Button-

((AppiumDriver) driver).sendKeyEvent(AndroidKeyCode.HOME);

To Relaunch app, I did the following- 1.First identified the Menu button using Monitor.bat i.e i got it as "android.widget.TextView" at index 5.

2.Click it i.e driver.findElementsByClassName("android.widget.TextView").get(5).click();

3.Find Your App in menu and click it. i.e.

driver.findElementsByName(AppName).get(0).click();
electronix384128
  • 6,625
  • 11
  • 45
  • 67
2

Getting out of the app you're testing really isn't that easy.

I'm using Appium (Selenium for Apps) to test an iOS app. What I wanted to do is to press the home button, unfortunately Appium doesn't have such a functionality (as well as a good bunch of other testing tools).

So what I'm going for was to simulate the keystroke CMD+SHIFT+H, which is the simulator's equivalent to the home button. That's also not possible with the most testing tools, as they interact 'inside' of the simulator, via the UIAutomation.

Finally I worked out the following solution (Java):

Runtime runtime = Runtime.getRuntime();
String[] args = { "osascript", "-e", "tell application \"System Events\" \n tell application \"Simulator\" to activate \n tell application \"System Events\" to keystroke \"h\" using {command down, shift down} \n end tell" };
runtime.exec(args);

At all it's really simple: executing an Applescript, which is then sending the keystroke to the simulator.

To provide some readability, here's the plain Applescript again:

tell application "System Events"
  tell application "Simulator" to activate
  tell application "System Events" to keystroke "h" using {command down, shift down}
end tell

Note: Make sure to esacpe the " (with \") in your code. Also make sure to insert \n after each line, because Applescript line-based.

Coming up with this solution took me a good amount of time. I haven't found any other working solution to get out of the app, without killing the whole test AND being able to test inside iOS then.

EDIT: You are able to relaunch the app then, that's the trick!

electronix384128
  • 6,625
  • 11
  • 45
  • 67
1

Yes, nothing impossible 1.Press home button + 2.Put app in background:

AppiumDriver dr = MobileDriverFactory.getDriver()
            try {
                dr.runAppInBackground(2)
            } catch (WebDriverException e) {
                if (e.getMessage().contains("An error occurred while executing user supplied JavaScript")) {
                } else {
                    throw new RuntimeException(e);
                }
            }

This function will cheat iOS and bring your app to background

3.Open some other app + 4.Then relaunch our app and resume the methods check.

ProcessBuilder pb = new ProcessBuilder("idevicedebug", "run", "YourAppNameHere")
            Thread.sleep(5000)
            Process p=pb.start()
            Thread.sleep(5000)
        p.destroy()

This function will call any app which's set up in your iOs devices, if you want to know your app name, turn on terminal, type:

ideviceinstaller -l

It will list all apps in your iOS devices like: com.google.ios.youtube, "11.11.8", "YouTube" com.google.ios.gmail, "11.11.8", "Gmail" copy line with style: com.xxx.xxx.xxx to this code above, you can also play this code with terminal, type

"idevicedebug run com.google.ios.youtube" 

(please plug your ios device first), press enter, youtube will auto turn on in your devices Thanks I'm from KMS Technology Vietnam

Dong Minh
  • 11
  • 1
1

Here's how to do it using the ruby library:

background_app 2

Where 2 is the number of seconds you want the app to be in the background.

Erik B
  • 40,889
  • 25
  • 119
  • 135
0

Have you tried using driver.execute_script "au.backgroundApp(5)" to background your app?

The problem with this method is that during that 5 seconds you can't interact with the device, backgroundApp is blocking.

YoDK
  • 447
  • 1
  • 4
  • 13
  • So, I can definitely background the app with this command. But, out of curiosity, where is this command documented? I can't find it in the UIAutomation docs and was looking for the apple docs on it. – stuckj Nov 18 '14 at 18:54
  • Reference to `au.backgroundApp` can be found here [Appium Discussion](https://groups.google.com/forum/#!msg/appium-discuss/s7GKQRH5qns/0kXB1_ynfM8J) – YoDK Nov 19 '14 at 04:12
  • Yeah, I had found that thread too. I was looking for actual docs, but it doesn't appear they exist. It wasn't clear to me at first whether this was a command provided by something in appium or if it was coming from Apple's UIAutomation. It was the former. – stuckj Nov 20 '14 at 22:42
  • right, sorry - here's the link to [docs](https://github.com/appium/appium/blob/4ac7a4ecd8fa1163051ba050d558b1f6cde3ddee/docs/en/writing-running-appium/appium-bindings.md) – YoDK Nov 21 '14 at 17:33
0

A way easier solution I found for using Android Appium with Ruby:

  def switch_back_to_app
    # For Android
    #
    # To Put App in Background Press recent apps to close
    $driver.press_keycode(187)

    sleep(1)
    # To bring the same app back i.e Press recent apps to open
    $driver.press_keycode(187)
  rescue => e
    p e.exception
  end
  module_function :switch_back_to_app

Refreshes the code so all elements are able to be found again.

Sal
  • 1
0

For Android:

driver.pressKeyCode(AndroidKeyCode.HOME);

For IOS:

driver.executeScript("mobile: pressButton", ImmutableMap.of("name", "home"));
Hacci56
  • 39
  • 5