Speed Up iOS Appium Test Automation

vector-frameworks-appium_2x

     Appium users have the question like how to speed up the iOS tests, citing the length of time it takes to start tests which use the WebDriverAgent library (all tests using the XCUITest driver).

     Most of the perceived speed of an Appium test can’t be improved due to the base speed of booting devices or the UI actions themselves. The slowest part, which users were asking how to avoid, is the initial startup of a test: the time between sending the first POST /session command and the response indicating that your test script can begin sending commands. We can call this time period the “session creation” time.

     There are desired capabilities we can specify to greatly reduce the time it takes to create a session. Appium is built to cater to a large number of devices, for use in many different situations, but we also want to make sure that it is easy to get started automating your first test. When specifying desired capabilities, Appium will analyze the state of your system and choose default values for every desired capability which you don’t specify. By being more specific, we can have Appium skip the work it does to choose the default values.

     Our first improvement is to set the app location to a file already on the host device. Then you can directly use the bundleId 

caps.setCapability(“bundleId”, “io.test.app”);

      Please ignore the remote path of your application in the code instead of that you can use the local application path, once it gets installed on the device avoid the local path and stick to use bundleId

     Running the tests, it’s easy to notice that the app gets reinstalled on the device for each test. This takes a lot of time and can be skipped. You may have certain tests which require a fresh install or need all the app data cleaned, but those tests could be put into a separate suite, leaving the majority of tests to run faster by reusing the same app. Most users should be familiar with the noReset desired capability.

 caps.setCapability(“noReset”, true)

    Appium uses the simctl command-line tool provided by Apple to match the deviceName desired capability to the udid of the device. We can skip this step by specifying the device udid ourselves.

caps.setCapability(“udid”, “009D802528AB4A1BA7C885A9F6FDBE95”);

      When loading the WedDriverAgent server, Appium loads the files from wherever XCode saved it after compilation. This location is called the “Derived Data Directory” and Appium executes an xcodebuild command in order to get the location. Below desired capability derivedDataPath allowing Appium to skip the work of calculating it:

caps.setCapability(“derivedDataPath”, “/Users/sanojs/Library/Developer/Xcode/DerivedData/WebDriverAgent-apridxpigtzdjdecthgzpygcmdkp”);

     The last optimization is to specify the webDriverAgentUrl desired capability. If specified, Appium skips a step where it checks to make sure that there are no obsolete or abandoned WebDriverAgent processes still running. The WebDriverAgent server needs to already be running at this location, so we can only use this desired capability after the first test starts the server.

caps.setCapability(“webDriverAgentUrl”, “http://localhost:8100”);

       I hope the above tips will help you to speed up the iOS automation using Appium. Please try to change your Desired Capability today to get a better speed of automation on the iOS platform.

Refer the tips to improve the speed for Android @https://journeyofquality.wordpress.com/category/speed-up-android-appium-test-automation/

Reference: Appium Pro

make it perfect!

Automate Picker Wheel Controls and Physical Buttons on iOS Devices

iphone6_hands_resetpicker_2x

     Here I would like to share two common activities while automating in iOS devices, automation of picker wheel and actions over the physical buttons. First, we will discuss the automation of the picker wheel.

      Appium also makes available a mobile: method called selectPickerWheelValue, which is primarily useful for navigating a picker wheel using forward-and-back gestures. The command takes 3 parameters:

  • order: whether you want to go forward (“next”) or backward (“previous”) in the list of options.
  • offset: how far (in ratios of the picker wheel height) you want the click to happen. The default is 0.2.
  • element: the internal ID of the picker wheel element we’re working with.

     Once we know what we want to do, we simply have to construct our typical executeScript call with these parameters. Below is the sample code snippet to do picker wheel automation:

HashMap<String, Object> params = new HashMap<>();
params.put(“order”, “next”);
params.put(“offset”, 0.15);
params.put(“element”, ((RemoteWebElement) pickerWheelElement).getId());
driver.executeScript(“mobile: selectPickerWheelValue“, params);

Below is the sample example code to access date from the picker wheel,

private static By pickers = MobileBy.className(“XCUIElementTypePickerWheel”);

// find the picker elements
List<WebElement> pickerEls = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(pickers));

// use the selectPickerWheelValue method to move to the next value in the ‘month’ wheel
HashMap<String, Object> params = new HashMap<>();
params.put(“order“, “next“);
params.put(“offset“, 0.15);
params.put(“element“, ((RemoteWebElement) pickerEls.get(0)).getId());
driver.executeScript(“mobile: selectPickerWheelValue“, params);

// and move to the previous value in the ‘day’ wheel
params.put(“order“, “previous“);
params.put(“element“, ((RemoteWebElement) pickerEls.get(1)).getId());
driver.executeScript(“mobile: selectPickerWheelValue“, params);

       Sometimes there’s an automation feature of apparently little utility, but it’s fun all the same. For some reason, Apple decided to allow the automation of the physical buttons on an iPhone. Some of them are the home button, the volume up, and down buttons. They’re accessible as one of Appium’s mobile: methods, like many other non-standard extensions to the WebDriver protocol. Here’s an example of how to press the home button:

driver.executeScript(“mobile: pressButton“, ImmutableMap.of(“name”, “home“));

In other words, there’s a single parameter name, and it takes one of three values:

  • home
  • volumeup
  • volumedown

Below is the example of how to press the volume up and volume down buttons:

driver.executeScript(“mobile: pressButton“, ImmutableMap.of(“name”, “volumeup“));

driver.executeScript(“mobile: pressButton“,ImmutableMap.of(“name”, “volumedown“));

     The only catch is that the volumeup and volumedown buttons can only be automated on a real device, not a simulator. Pressing the home button is a good way to get out of your app and back to the home screen. Pressing it twice will navigate back to the first home screen. And pressing it twice in quick succession should open up the app switcher.

   Please try to use the above picker wheel and physical button actions in your automation during the iOS application automation. Please use the latest java-client and Appium server.

Reference: Appium Pro

make it perfect!

Automate Complex iOS Alerts With Appium

1_iMPfw0qHQdgGzVdtAdJooQ

     iOS alert handling has often been a testy subject. Luckily, with the current XCUITest driver used by Appium, we can connect directly to the Apple-approved method for accepting or dismissing an alert, or even getting its text. Appium provides access to this behavior via the standard suite of WebDriver alert commands, for example:

driver.switchTo().alert().alert()
          driver.switchTo().alert().dismiss()
            driver.switchTo().alert().getText()

     Unfortunately, the WebDriver spec is not quite as flexible as mobile apps when it comes to the design of alerts. The WebDriver spec was based around web browser alerts, which can contain at most two action buttons. Mobile apps can create native alerts that contain 3 or even more buttons! So what do you do when you need to automate the action associated with a button which is not “OK” or “Cancel”?

     Luckily, Appium has a special command for handling alerts on iOS that you can use for this purpose: mobile: alert. This command does allow you to accept and dismiss alerts as usual, but that’s not very interesting. We’re going to look at two new use cases: getting a list of the available button labels, and tapping an alert action via its label. These features together will help solve the problem under consideration. Let’s take a look at an example:

HashMap<String, String> args = new HashMap<>();
            args.put("action", "getButtons");
            List<String> buttons = (List<String>)driver.executeScript("mobile: alert", args);

      Following the pattern of the other mobile: methods, we use executeScript with a special command and parameters to get the list of button labels. Once we have this list, we can do whatever we want with it.

String buttonLabel = null;
            for (String button : buttons) {
              if (button.equals("OK") || button.equals("Cancel")) {
                continue;
                  }
                  buttonLabel = button;
                  }
                  if (buttonLabel == null) {
                    throw new Error("Did not get a third alert button as we were expecting");
                      }

     At this point, we have the value of the button we want to press in the buttonLabel variable. We can again use mobile: alert to target this specific button, using a different action parameter than before (with a value of “accept”), and adding the new parameter buttonLabel to let Appium know which button we want it to tap for us:

args.put("action", "accept");
                    args.put("buttonLabel", buttonLabel);
                      driver.executeScript("mobile: alert", args);

That’s all there is to it! Using mobile: alert we have access to the full set of alert actions that can be displayed in an iOS app. Try to use the above logic to deal with complex alert in iOS native applications.

Reference: Appium Pro

make it perfect!