Wulf
Wulf

Reputation: 489

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

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();
    }

  }

Upvotes: 4

Views: 13836

Answers (4)

AdrianM
AdrianM

Reputation: 175

Assuming you're using Java on Mac, here's something which works for me, including the code to start Appium Service itself, then the driver to connect to it:

package baseTest;

import com.groupon.tests.mainapp.pages.*;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;

import java.io.File;
import java.io.IOException;
import java.net.URL;


public class AppiumSafariBaseUITest {

private WebDriver wd;

protected WebDriver getDriver(){
    return wd;
}

String nodePath = "/Applications/Appium.app/Contents/Resources/node/bin/node";
String appiumJSPath = "/usr/local/lib/node_modules/appium/build/lib/main.js";

AppiumDriverLocalService service;
String service_url;

private void startAppiumServer() throws IOException {
    service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder()
                    .usingPort(4890)
                    .usingDriverExecutable(new File(nodePath))
                    .withAppiumJS(new File(appiumJSPath))
    );
    service.start();
}

@BeforeClass(alwaysRun = true)
public void setUpAppiumDriver() throws IOException {

    startAppiumServer();

    service_url = service.getUrl().toString();

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("appium-version", "1.0");
    capabilities.setCapability("platformName", "iOS");
    capabilities.setCapability("platformVersion", "9.3");
    capabilities.setCapability("deviceName", "iPhone 5s");
    capabilities.setCapability("newCommandTimeout", 600);
    capabilities.setCapability("bundleId", "com.apple.mobilesafari");
    capabilities.setCapability("useLocationServices", false);

    wd = new IOSDriver(new URL(service_url), capabilities);
}

@BeforeMethod(alwaysRun = true)
public void beforeMethod(){
    if(!service.isRunning())
    {
        service.start();
    }
}

@AfterClass(alwaysRun = true)
public void killSimulatorAndAppium(){
    service.stop();
}
}

Upvotes: 0

Dan Cuellar
Dan Cuellar

Reputation: 269

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);
  });

});

Upvotes: 2

kavita
kavita

Reputation: 63

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

should be

  DesiredCapabilities cap = new DesiredCapabilities();
        cap.setCapability("deviceName", "iPhone Simulator");
        cap.setCapability("browsername", "safari");
        cap.setCapability("platformVersion", "7.1");
        cap.setCapability("platformName", "iOS");

It works for me. hope it fix your issue. Good luck.

Upvotes: 0

JaZoN
JaZoN

Reputation: 11

Why do you define a second WebDriver in your setUp method ? Remove this second definition to set up the class member driver.

Upvotes: 1

Related Questions