Question

I was trying to run Sikuli WebDriver based tests on Sauce On Demand infrastructure. But I have a problem with RemoteWebDriver.

I have this BaseSikuliWebDriver class

package com.pitito.sikuli.base;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.openqa.selenium.Platform;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import com.pitito.core.basetests.BaseLoggingTest;
import com.pitito.selenium.webdriver.RemoteWebDriverSession;
import com.pitito.selenium.webdriver.WebDriverScreenshooter;
import com.pitito.sikuli.webdriver.SikuliFirefoxDriver;

/**
 * Base class for all Sikuli WebDriver tests.
 *
 * @author guillem.hernandez
 */
public abstract class BaseSikuliWebDriverTest {

  Map<String, Object> sauceJob = new HashMap<String, Object>();

  private static SikuliFirefoxDriver sikuliDriver;

  protected SikuliFirefoxDriver driver() {
    return getDriver();
  }

  public static SikuliFirefoxDriver getDriver() {
    return sikuliDriver;
  }

  public static void setDriver(SikuliFirefoxDriver driver) {
    BaseSikuliWebDriverTest.sikuliDriver = driver;
  }

  @Override
  @BeforeMethod(alwaysRun = true)
  protected void setup(Method method, Object[] testArguments) {
    super.setup(method, testArguments);
    String sessionId = method.getName() + "_" + testArguments.hashCode();
    DesiredCapabilities caps = DesiredCapabilities.firefox();
    caps.setCapability("id", sessionId);
    caps.setCapability("name", sessionId);
    caps.setCapability(CapabilityType.BROWSER_NAME, "firefox");
    caps.setCapability("platform", Platform.XP);
    caps.setCapability("version", "21");
    try {
    sikuliDriver = (SikuliFirefoxDriver) new Augmenter().augment(new RemoteWebDriver(new URL("http://"
          + RemoteWebDriverSession.USER + ":" + RemoteWebDriverSession.APIKEY
          + "@ondemand.saucelabs.com:80/wd/hub"), caps));
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    setDriver(sikuliDriver);
  }

  @Override
  @AfterMethod(alwaysRun = true)
  protected void teardown(ITestResult tr, Method method) {
    if ((logger() != null) && (tr.getStatus() == ITestResult.FAILURE)) {
      logUnexpectedException(tr.getThrowable());
    }
    super.teardown(tr, method);
    sikuliDriver.quit();
  }

  @Override
  protected void logScreenshot(String screenshotName) {
    logResource(new WebDriverScreenshooter(driver(), screenshotName).getScreenshot());
  }
}

The test I implemented is the Sikuli WebDriver example and the code is as follows:

package com.pitito.sikuli.tests;

import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;

import com.pitito.sikuli.base.BaseSikuliWebDriverTest;
import com.pitito.sikuli.webdriver.ImageElement;

/**
 * Sikuli Firefox WebDriver Automated Test Example.
 *
 * @author guillem.hernandez
 */
public class SikuliGoogleCodeTest extends BaseSikuliWebDriverTest {

  @Test(groups = { "ES" }, description = "Use Sikuli to search on Google Maps")
  public void testSikuliWebDriverPassingExample_ES() {
    verifySikuliWebDriverPassingTest();
  }

  private void verifySikuliWebDriverPassingTest() {
    // visit Google Map
    driver().get("https://maps.google.com/");

    // enter "Denver, CO" as search terms
    WebElement input = driver().findElement(By.id("gbqfq"));
    input.sendKeys("Denver, CO");
    input.sendKeys(Keys.ENTER);

    ImageElement image;

    // find and click on the image of the lakewood area
    try {
      image = driver().findImageElement(new URL("https://dl.dropbox.com/u/5104407/lakewood.png"));

      image.doubleClick();

      // find and click on the image of the kendrick lake area
      image =
          driver().findImageElement(new URL("https://dl.dropbox.com/u/5104407/kendrick_lake.png"));
      image.doubleClick();

      // find and click the Satellite icon to switch to the satellite view
      image = driver().findImageElement(new URL("https://dl.dropbox.com/u/5104407/satellite.png"));
      image.click();

      // find and click the plus button to zoom in
      image = driver().findImageElement(new URL("https://dl.dropbox.com/u/5104407/plus.png"));
      image.click();

      // find and click the link button
      WebElement linkButton = driver().findElement(By.id("link"));
      linkButton.click();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
  }
}

When I try to run the test, the error I get is this one:

[Invoker 18958118] Invoking @BeforeMethod BaseSikuliWebDriverTest.setup(java.lang.reflect.Method, [Ljava.lang.Object;)[pri:0, instance:com.pitito.sikuli.tests.SikuliGoogleCodeTest@137008a]
Failed to invoke configuration method com.pitito.sikuli.base.BaseSikuliWebDriverTest.setup:org.openqa.selenium.remote.RemoteWebDriver$$EnhancerByCGLIB$$52a1cf6f cannot be cast to com.pitito.sikuli.webdriver.SikuliFirefoxDriver

The problem resides here:

sikuliDriver = (SikuliFirefoxDriver) new Augmenter().augment(new RemoteWebDriver(new URL("http://"
          + RemoteWebDriverSession.USER + ":" + RemoteWebDriverSession.APIKEY
          + "@ondemand.saucelabs.com:80/wd/hub"), caps));

How can I use SikuliFirefoxDriver remotely? How can I cast RemoteWebDriver with SikuliFirefoxDriver? Can I do it?

Was it helpful?

Solution

As far as I know, the Selenium Grid server does not have the capability of passing Sikuli commands (and binary screenshots for comparison purposes) through its JSON api. Not even SauceLabs has this capability. Hopefully, its on the radar to be implemented someday. On the SauceLabs forum, there is someone that asked this question (and I answered that one also with this same answer).

I know that there is a project in-progress called Marionette that is supposed to be able to automate browser/Firefox menus and native dialogs.

OTHER TIPS

I implemented a remote driver version of sikuli driver. You can use that to do this action. Please feel free to fork: https://github.com/AJ-72/SikuliRemoteWebdriver

My guess is that SikuliFirefoxDriver cannot be augmented because it was not invoked as RemoteWebdriver. Try invoke it as Remote webdriver with sikuli as desired capabilities. Please, post here if it worked (I could not find proofs if it is possible, but still worth a shot)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top