Search code examples
javaseleniumdrag-and-drophtmlunit-driver

htmlunit-driver - how to simulate drag-and-drop?


Is there a way to simulate a drag-and-drop with htmlunit-driver?

When using Actions it throws an UnsupportedException

Inside the class HtmlUnitMouse:

  @Override
  public void mouseMove(Coordinates where, long xOffset, long yOffset) {
    throw new UnsupportedOperationException("Moving to arbitrary X,Y coordinates not supported.");
  }

My attempts for trying to do this:

first attempt

(new Actions(driver)).dragAndDropBy(sliderHandle, 50, 0)
                     .build()
                     .perform();

second attempt

(new Actions(driver)).moveToElement(sliderHandle)
                     .clickAndHold()
                     .moveToElement(sliderHandle, 50, 0)
                     .release()
                     .build()
                     .perform();

Is there a workaround for this?


Solution

  • HtmlUnit is a GUI-Less browser for Java programs that can do a lot for us, but not everything. And, as you have noticed, it has no support for operations such as drag and drop

    new UnsupportedOperationException("Moving to arbitrary X,Y coordinates not supported.");
    

    contrary to other Selenium drivers, like , in which one your example should work fine.

    However, if you still need it to work with a headless web testing, there's an option with PhantomJS. Yes, it is focused for JS testing, but there is a great project called Ghost Driver (a implementation of Webdriver Wire protocol in simple JS for PhantomJS) that enables Java bindings along with Selenium API.

    The steps to use it are very simple:

    1. Install PhantomJS in your OS and add the executable file to your PATH env variable properly.
    2. Add the Maven dependency to your pom.xml (along with Selenium libs: selenium-java and selenium-support):

      <dependency>
          <groupId>com.github.detro</groupId>
          <artifactId>phantomjsdriver</artifactId>
          <version>1.2.0</version>
      </dependency>
      
    3. And adapt your code to make use of it:

      // Set this property, in order to specify path that PhantomJS executable will use
      System.setProperty("phantomjs.binary.path", System.getenv("PHANTOM_JS") + "/bin/phantomjs.exe");
      
      // New PhantomJS driver from ghostdriver
      WebDriver driver = new PhantomJSDriver();
      driver.get("https://jqueryui.com/resources/demos/draggable/default.html");
      
      // Find draggable element
      WebElement draggable = driver.findElement(By.id("draggable"));
      
      System.out.println("x: " + draggable.getLocation().x 
              + ", y: " + draggable.getLocation().y);
      
      // Perform drag and drop
      (new Actions(driver)).dragAndDropBy(draggable, 50, 0)
          .build()
          .perform();
      
      System.out.println("x: " + draggable.getLocation().x 
              + ", y: " + draggable.getLocation().y);
      

    Final output:

    x: 8, y: 8
    x: 58, y: 8