Appium and iOS Mobile Safari automation, can it be done?

Wulf picture Wulf · May 21, 2013 · Viewed 12.6k times · Source

I cannot get any automation working with Appium vs the Safari mobile browser on an iOS emulator. In my Java project, Safari will launch, but the browser will not even navigate to the specified website. Can anyone tell me what I'm doing wrong with my code?

1) Launch the Appium application on my OSX machine. It is configured with the following settings:

IP Address: 127.0.0.1
Port: 4723
Force Device: Checked - iPhone
User Mobile Safari: Checked

(Note: No messages scroll across the Appium application log screen when I run my project. Previously, I got complaints about a missing iOS 6.0 library, but when I duplicated the 6.1 iOS library and then renamed the directory to 6.0, the messages went away.)

2) Launch Eclipse and open Appium Project

3) Right-click on test code and click RunAs Junit

4) The iPhone emulator launches -- iPhone iOS 6.1

5) Mobile Safari launches...and then goes nowhere (should be going to cnn.com). I get no errors.

Can Appium Java projects actually be used for mobile-Safari automation? I don't see any examples of Safari automation in the Appium sample code repo.

What gives?

Thanks,

Larry

------------------Java code below----------------------------------------

Eclipse Juno is being used to run my Java/Appium project. Here is a much simplified listing of the Java JUnit project code (which, when modified accordingly, and used with iWebDriver and the deprecated iPhoneDriver(), works fine):

import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class AppiumiPhoneWebDriverDemo {

    private String baseUrl;
    private WebDriver driver;

    @Before
    public void setup() throws Exception
    {

        WebDriver driver;
        DesiredCapabilities cap = new DesiredCapabilities();
        //cap.setCapability("", "");
        //cap.setCapability("browsername", "");
        //cap.setCapability("os", "iOS 6.1");
        cap.setCapability("device", "iPhone Simulator");
        cap.setCapability("app", "safari");

        driver = new RemoteWebDriver(new URL("http://localhost:4723/wd/hub"), cap);

    baseUrl = "http://www.cnn.com";

    }   

    @After
    public void tearDown() throws Exception
    {

    driver.quit();

    }


    @Test
    public void test_searchWorks() throws Exception
    {
        this.driver.get(baseUrl);

        driver.quit();
    }

  }

Answer

Dan Cuellar picture Dan Cuellar · May 31, 2013

You can definitely do this.

See this code

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    serverConfigs = require('./helpers/appium-servers');

describe("ios safari", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.SAUCE ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    require("./helpers/logging").configure(driver);

    var desired = _.clone(require("./helpers/caps").ios81);
    desired.browserName = 'safari';
    if (process.env.SAUCE) {
      desired.name = 'ios - safari';
      desired.tags = ['sample'];
    }
    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.SAUCE) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });


  it("should get the url", function () {
    return driver
      .get('https://www.google.com')
      .sleep(1000)
      .waitForElementByName('q', 5000)
        .sendKeys('sauce labs')
        .sendKeys(wd.SPECIAL_KEYS.Return)
      .sleep(1000)
      .title().should.eventually.include('sauce labs');
  });

  it("should delete cookie passing domain and path", function () {
    var complexCookieDelete = function(name, path, domain) {
      return function() {
        path = path || '|';
        return driver.setCookie({name: name, value: '', path: path, 
          domain: domain, expiry: 0});        
      };
    };

    return driver
      .get('http://en.wikipedia.org')
      .waitForElementByCss('.mediawiki', 5000)
      .allCookies() // 'GeoIP' cookie is there
      .deleteCookie('GeoIP') 
      .allCookies() // 'GeoIP' is still there, because it is set on
                    // the .wikipedia.org domain
      .then(complexCookieDelete('GeoIP', '/', '.wikipedia.org'))
      .allCookies() // now 'GeoIP' cookie is gone
      .sleep(1000);
  });

});