Thursday 16 February 2012

Information about the HtmlUnit Driver for selenium automation testing


This is currently the fastest and most lightweight implementation of WebDriver. As the name suggests, this is based on HtmlUnit.

Pros

  • Fastest implementation of WebDriver
  • A pure Java solution and so it is platform independent.
  • Supports Javascript

Cons

  • Emulates other browser's JS behaviour (see below)
















Javascript in the HtmlUnitDriver

None of the popular browsers uses the javascript engine used by HtmlUnit (Rhino). If you test javascript using HtmlUnit the results may differ significantly from those browsers.
When we say "javascript" we actually mean "javascript and the DOM". Although the DOM is defined by the W3C each browser out there has its own quirks and differences in their implementation of the DOM and in how javascript interacts with it. HtmlUnit has an impressively complete implementation of the DOM and has good support for using javascript, but it is no different from any other browser: it has its own quirks and differences from both the W3C standard and the DOM implementations of the major browsers, despite its ability to mimic other browsers.
With WebDriver, we had to make a choice; do we enable HtmlUnit's javascript capabilities and run the risk of teams running into problems that only manifest themselves there, or do we leave javascript disabled, knowing that there are more and more sites that rely on javascript? We took the conservative approach, and by default have disabled support when we use HtmlUnit. With each release of both WebDriver and HtmlUnit, we reassess this decision: we hope to enable javascript by default on the HtmlUnit at some point.

Enabling Javascript

If you can't wait, enabling Javascript support is very easy:
HtmlUnitDriver driver = new HtmlUnitDriver();
driver
.setJavascriptEnabled(true);
or
HtmlUnitDriver driver = new HtmlUnitDriver(true);
This will cause the HtmlUnitDriver to emulate IE's Javascript handling by default.

Emulating a Specific Browser

Notwithstanding other considerations above, it is possible to get HtmlUnitDriver to emulate a specific browser. You should not really be doing this, as web-applications are better coded to be neutral of which reasonably recent browser you are using. There are two more constructors forHtmlUnitDriver that take allow us to indicate a browser to emulate. One takes a browser version directly:
HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3);
The other uses a broader capabilities mechanism:
HtmlUnitDriver driver = new HtmlUnitDriver(capabilities);





Class HtmlUnitDriver


java.lang.Object
extended by org.openqa.selenium.htmlunit.HtmlUnitDriver
All Implemented Interfaces:
HasCapabilitiesHasInputDevicesFindsByCssSelectorFindsByIdFindsByLinkTextFindsByNameFindsByTagNameFindsByXPathJavascriptExecutorSearchContextWebDriver

public class HtmlUnitDriver
extends java.lang.Object

implements WebDriver, JavascriptExecutor, FindsById, FindsByLinkText, FindsByXPath, FindsByName, FindsByCssSelector, FindsByTagName, HasCapabilities, HasInputDevices


Nested Class Summary
protected static interfaceHtmlUnitDriver.JavaScriptResultsCollection             
 
Nested classes/interfaces inherited from interface org.openqa.selenium.WebDriver
WebDriver.ImeHandlerWebDriver.NavigationWebDriver.OptionsWebDriver.TargetLocatorWebDriver.TimeoutsWebDriver.Window
 
Field Summary
static java.lang.StringINVALIDSELECTIONERROR             
static java.lang.StringINVALIDXPATHERROR             
 
Constructor Summary
HtmlUnitDriver()             
HtmlUnitDriver(boolean enableJavascript)             
HtmlUnitDriver(com.gargoylesoftware.htmlunit.BrowserVersion version)             
HtmlUnitDriver(Capabilities capabilities)            Note: There are two configuration modes for the HtmlUnitDriver using this constructor.
 
Method Summary
 voidclose()            Close the current window, quitting the browser if it's the last window currently open.
 java.lang.ObjectexecuteAsyncScript(java.lang.String script, java.lang.Object... args)            Execute an asynchronous piece of JavaScript in the context of the currently selected frame or window.
 java.lang.ObjectexecuteScript(java.lang.String script, java.lang.Object... args)            Executes JavaScript in the context of the currently selected frame or window.
 WebElementfindElement(By by)            Find the first WebElement using the given method.
 WebElementfindElementByCssSelector(java.lang.String using)             
 WebElementfindElementById(java.lang.String id)             
 WebElementfindElementByLinkText(java.lang.String selector)             
 WebElementfindElementByName(java.lang.String name)             
 WebElementfindElementByPartialLinkText(java.lang.String using)             
 WebElementfindElementByTagName(java.lang.String name)             
 WebElementfindElementByXPath(java.lang.String selector)             
 java.util.List<WebElement>findElements(By by)            Find all elements within the current page using the given mechanism.
 java.util.List<WebElement>findElementsByCssSelector(java.lang.String using)             
 java.util.List<WebElement>findElementsById(java.lang.String id)             
 java.util.List<WebElement>findElementsByLinkText(java.lang.String selector)             
 java.util.List<WebElement>findElementsByName(java.lang.String using)             
 java.util.List<WebElement>findElementsByPartialLinkText(java.lang.String using)             
 java.util.List<WebElement>findElementsByTagName(java.lang.String using)             
 java.util.List<WebElement>findElementsByXPath(java.lang.String selector)             
 voidget(java.lang.String url)            Load a new web page in the current browser window.
protected  voidget(java.net.URL fullUrl)            Allows HtmlUnit's about:blank to be loaded in the constructor, and may be useful for other tests?
 CapabilitiesgetCapabilities()             
 java.lang.StringgetCurrentUrl()            Get a string representing the current URL that the browser is looking at.
protected  com.gargoylesoftware.htmlunit.WebWindowgetCurrentWindow()             
 KeyboardgetKeyboard()             
 MousegetMouse()             
 java.lang.StringgetPageSource()            Get the source of the last loaded page.
 java.lang.StringgetTitle()            The title of the current page.
protected  com.gargoylesoftware.htmlunit.WebClientgetWebClient()             
 java.lang.StringgetWindowHandle()            Return an opaque handle to this window that uniquely identifies it within this driver instance.
 java.util.SetgetWindowHandles()            Return a set of window handles which can be used to iterate over all open windows of this webdriver instance by passing them to #switchTo().window(String)
protected
X
implicitlyWaitFor(java.util.concurrent.Callable condition)             
 booleanisJavascriptEnabled()             
protected  com.gargoylesoftware.htmlunit.PagelastPage()             
 WebDriver.Optionsmanage()            Gets the Option interface
protected  com.gargoylesoftware.htmlunit.WebClientmodifyWebClient(com.gargoylesoftware.htmlunit.WebClient client)            Child classes can override this method to customise the webclient that the HtmlUnit driver uses.
 WebDriver.Navigationnavigate()            An abstraction allowing the driver to access the browser's history and to navigate to a given URL.
protected  WebElementnewHtmlUnitWebElement(com.gargoylesoftware.htmlunit.html.HtmlElement element)             
protected  com.gargoylesoftware.htmlunit.WebClientnewWebClient(com.gargoylesoftware.htmlunit.BrowserVersion version)            Create the underlying webclient, but don't set any fields on it.
protected  voidpickWindow()             
 voidquit()            Quits this driver, closing every associated window.
 voidsetAutoProxy(java.lang.String autoProxyUrl)             
 voidsetJavascriptEnabled(boolean enableJavascript)             
 voidsetProxy(java.lang.String host, int port)             
 WebDriver.TargetLocatorswitchTo()            Send future commands to a different frame or window.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Field Detail

INVALIDXPATHERROR

public static final java.lang.String INVALIDXPATHERROR
See Also:
Constant Field Values

INVALIDSELECTIONERROR

public static final java.lang.String INVALIDSELECTIONERROR
See Also:
Constant Field Values
Constructor Detail

HtmlUnitDriver

public HtmlUnitDriver(com.gargoylesoftware.htmlunit.BrowserVersion version)

HtmlUnitDriver

public HtmlUnitDriver()

HtmlUnitDriver

public HtmlUnitDriver(boolean enableJavascript)

HtmlUnitDriver

public HtmlUnitDriver(Capabilities capabilities)
Note: There are two configuration modes for the HtmlUnitDriver using this constructor. The first is where the browserName is "firefox", "internet explorer" and browserVersion denotes the desired version. The second one is where the browserName is "htmlunit" and the browserVersion denotes the required browser AND its version. In this mode the browserVersion could either be "firefox" for Firefox or "internet explorer-7" for IE 7. The Remote WebDriver uses the second mode - the first mode is deprecated and should not be used.
Method Detail

newWebClient

protected com.gargoylesoftware.htmlunit.WebClient newWebClient(com.gargoylesoftware.htmlunit.BrowserVersion version)
Create the underlying webclient, but don't set any fields on it.
Parameters:
version - Which browser to emulate
Returns:
a new instance of WebClient.

modifyWebClient

protected com.gargoylesoftware.htmlunit.WebClient modifyWebClient(com.gargoylesoftware.htmlunit.WebClient client)
Child classes can override this method to customise the webclient that the HtmlUnit driver uses.
Parameters:
client - The client to modify
Returns:
The modified client

setProxy

public void setProxy(java.lang.String host,
int port)

setAutoProxy

public void setAutoProxy(java.lang.String autoProxyUrl)

getCapabilities

public Capabilities getCapabilities()
Specified by:
getCapabilities in interface HasCapabilities
Returns:
The capabilities of the current driver.

get

public void get(java.lang.String url)
Description copied from interface: WebDriver
Load a new web page in the current browser window. This is done using an HTTP GET operation, and the method will block until the load is complete. This will follow redirects issued either by the server or as a meta-redirect from within the returned HTML. Should a meta-redirect "rest" for any duration of time, it is best to wait until this timeout is over, since should the underlying page change whilst your test is executing the results of future calls against this interface will be against the freshly loaded page. Synonym for WebDriver.Navigation.to(String).
Specified by:
get in interface WebDriver
Parameters:
url - The URL to load. It is best to use a fully qualified URL

get

protected void get(java.net.URL fullUrl)
Allows HtmlUnit's about:blank to be loaded in the constructor, and may be useful for other tests?
Parameters:
fullUrl - The URL to visit

pickWindow

protected void pickWindow()

getCurrentUrl

public java.lang.String getCurrentUrl()
Description copied from interface: WebDriver
Get a string representing the current URL that the browser is looking at.
Specified by:
getCurrentUrl in interface WebDriver
Returns:
The URL of the page currently loaded in the browser

getTitle

public java.lang.String getTitle()
Description copied from interface: WebDriver
The title of the current page.
Specified by:
getTitle in interface WebDriver
Returns:
The title of the current page, with leading and trailing whitespace stripped, or null if one is not already set

findElement

public WebElement findElement(By by)
Description copied from interface: WebDriver
Find the first WebElement using the given method. This method is affected by the 'implicit wait' times in force at the time of execution. The findElement(..) invocation will return a matching row, or try again repeatedly until the configured timeout is reached. findElement should not be used to look for non-present elements, use WebDriver.findElements(By) and assert zero length response instead.
Specified by:
findElement in interface SearchContext
Specified by:
findElement in interface WebDriver
Parameters:
by - The locating mechanism
Returns:
The first matching element on the current page
See Also:
ByWebDriver.Timeouts

findElements

public java.util.List<WebElement> findElements(By by)
Description copied from interface: WebDriver
Find all elements within the current page using the given mechanism. This method is affected by the 'implicit wait' times in force at the time of execution. When implicitly waiting, this method will return as soon as there are more than 0 items in the found collection, or will return an empty list if the timeout is reached.
Specified by:
findElements in interface SearchContext
Specified by:
findElements in interface WebDriver
Parameters:
by - The locating mechanism to use
Returns:
A list of all WebElements, or an empty list if nothing matches
See Also:
ByWebDriver.Timeouts

getPageSource

public java.lang.String getPageSource()
Description copied from interface: WebDriver
Get the source of the last loaded page. If the page has been modified after loading (for example, by Javascript) there is no guarantee that the returned text is that of the modified page. Please consult the documentation of the particular driver being used to determine whether the returned text reflects the current state of the page or the text last sent by the web server. The page source returned is a representation of the underlying DOM: do not expect it to be formatted or escaped in the same way as the response sent from the web server. Think of it as an artist's impression.
Specified by:
getPageSource in interface WebDriver
Returns:
The source of the current page

close

public void close()
Description copied from interface: WebDriver
Close the current window, quitting the browser if it's the last window currently open.
Specified by:
close in interface WebDriver

quit

public void quit()
Description copied from interface: WebDriver
Quits this driver, closing every associated window.
Specified by:
quit in interface WebDriver

getWindowHandles

public java.util.Set getWindowHandles()
Description copied from interface: WebDriver
Return a set of window handles which can be used to iterate over all open windows of this webdriver instance by passing them to #switchTo().window(String)
Specified by:
getWindowHandles in interface WebDriver
Returns:
A set of window handles which can be used to iterate over all open windows.

getWindowHandle

public java.lang.String getWindowHandle()
Description copied from interface: WebDriver
Return an opaque handle to this window that uniquely identifies it within this driver instance. This can be used to switch to this window at a later date
Specified by:
getWindowHandle in interface WebDriver

executeScript

public java.lang.Object executeScript(java.lang.String script,
java.lang.Object... args)
Description copied from interface: JavascriptExecutor
Executes JavaScript in the context of the currently selected frame or window. The script fragment provided will be executed as the body of an anonymous function.Within the script, use document to refer to the current document. Note that local variables will not be available once the script has finished executing, though global variables will persist.
If the script has a return value (i.e. if the script contains a return statement), then the following steps will be taken:
  • For an HTML element, this method returns a WebElement
  • For a decimal, a Double is returned
  • For a non-decimal number, a Long is returned
  • For a boolean, a Boolean is returned
  • For all other cases, a String is returned.
  • For an array, return a List with each object following the rules above. We support nested lists.
  • Unless the value is null or there is no return value, in which null is returned
  • Arguments must be a number, a boolean, a String, WebElement, or a List of any combination of the above. An exception will be thrown if the arguments do not meet these criteria. The arguments will be made available to the JavaScript via the "arguments" magic variable, as if the function were called via "Function.apply"

    Specified by:
    executeScript in interface JavascriptExecutor
    Parameters:
    script - The JavaScript to execute
    args - The arguments to the script. May be empty
    Returns:
    One of Boolean, Long, String, List or WebElement. Or null.

    executeAsyncScript

    public java.lang.Object executeAsyncScript(java.lang.String script,
    java.lang.Object... args)
    Description copied from interface: JavascriptExecutor
    Execute an asynchronous piece of JavaScript in the context of the currently selected frame or window. Unlike executing synchronous JavaScript, scripts executed with this method must explicitly signal they are finished by invoking the provided callback. This callback is always injected into the executed function as the last argument.The first argument passed to the callback function will be used as the script's result. This value will be handled as follows:
    • For an HTML element, this method returns a WebElement
    • For a number, a Long is returned
    • For a boolean, a Boolean is returned
    • For all other cases, a String is returned.
    • For an array, return a List with each object following the rules above. We support nested lists.
    • Unless the value is null or there is no return value, in which null is returned
    • Example #1: Performing a sleep in the browser under test.
         long start = System.currentTimeMillis();
      ((JavascriptExecutor) driver).executeAsyncScript(
      "window.setTimeout(arguments[arguments.length - 1], 500);");
      System.out.println(
      "Elapsed time: " + System.currentTimeMillis() - start);
      Example #2: Synchronizing a test with an AJAX application:
         WebElement composeButton = driver.findElement(By.id("compose-button"));
      composeButton.click();
      ((JavascriptExecutor) driver).executeAsyncScript(
      "var callback = arguments[arguments.length - 1];" +
      "mailClient.getComposeWindowWidget().onload(callback);");
      driver.switchTo().frame("composeWidget");
      driver.findElement(By.id("to")).sendKeys("bog@example.com");
      Example #3: Injecting a XMLHttpRequest and waiting for the result:
         Object response = ((JavascriptExecutor) driver).executeAsyncScript(
      "var callback = arguments[arguments.length - 1];" +
      "var xhr = new XMLHttpRequest();" +
      "xhr.open('GET', '/resource/data.json', true);" +
      "xhr.onreadystatechange = function() {" +
      " if (xhr.readyState == 4) {" +
      " callback(xhr.responseText);" +
      " }" +
      "}" +
      "xhr.send();");
      JSONObject json = new JSONObject((String) response);
      assertEquals("cheese", json.getString("food"));

      Specified by:
      executeAsyncScript in interface JavascriptExecutor
      Parameters:
      script - The JavaScript to execute.
      args - The arguments to the script. May be empty.
      Returns:
      One of Boolean, Long, String, List, WebElement, or null.

      getKeyboard

      public Keyboard getKeyboard()
      Specified by:
      getKeyboard in interface HasInputDevices

      getMouse

      public Mouse getMouse()
      Specified by:
      getMouse in interface HasInputDevices

      switchTo

      public WebDriver.TargetLocator switchTo()
      Description copied from interface: WebDriver
      Send future commands to a different frame or window.
      Specified by:
      switchTo in interface WebDriver
      Returns:
      A TargetLocator which can be used to select a frame or window
      See Also:
      WebDriver.TargetLocator

      navigate

      public WebDriver.Navigation navigate()
      Description copied from interface: WebDriver
      An abstraction allowing the driver to access the browser's history and to navigate to a given URL.
      Specified by:
      navigate in interface WebDriver
      Returns:
      WebDriver.Navigation that allows the selection of what to do next

      lastPage

      protected com.gargoylesoftware.htmlunit.Page lastPage()

      findElementByLinkText

      public WebElement findElementByLinkText(java.lang.String selector)
      Specified by:
      findElementByLinkText in interface FindsByLinkText

      newHtmlUnitWebElement

      protected WebElement newHtmlUnitWebElement(com.gargoylesoftware.htmlunit.html.HtmlElement element)

      findElementsByLinkText

      public java.util.List<WebElement> findElementsByLinkText(java.lang.String selector)
      Specified by:
      findElementsByLinkText in interface FindsByLinkText

      findElementById

      public WebElement findElementById(java.lang.String id)
      Specified by:
      findElementById in interface FindsById

      findElementsById

      public java.util.List<WebElement> findElementsById(java.lang.String id)
      Specified by:
      findElementsById in interface FindsById

      findElementByCssSelector

      public WebElement findElementByCssSelector(java.lang.String using)
      Specified by:
      findElementByCssSelector in interface FindsByCssSelector

      findElementsByCssSelector

      public java.util.List<WebElement> findElementsByCssSelector(java.lang.String using)
      Specified by:
      findElementsByCssSelector in interface FindsByCssSelector

      findElementByName

      public WebElement findElementByName(java.lang.String name)
      Specified by:
      findElementByName in interface FindsByName

      findElementsByName

      public java.util.List<WebElement> findElementsByName(java.lang.String using)
      Specified by:
      findElementsByName in interface FindsByName

      findElementByTagName

      public WebElement findElementByTagName(java.lang.String name)
      Specified by:
      findElementByTagName in interface FindsByTagName

      findElementsByTagName

      public java.util.List<WebElement> findElementsByTagName(java.lang.String using)
      Specified by:
      findElementsByTagName in interface FindsByTagName

      findElementByXPath

      public WebElement findElementByXPath(java.lang.String selector)
      Specified by:
      findElementByXPath in interface FindsByXPath

      findElementsByXPath

      public java.util.List<WebElement> findElementsByXPath(java.lang.String selector)
      Specified by:
      findElementsByXPath in interface FindsByXPath

      isJavascriptEnabled

      public boolean isJavascriptEnabled()

      setJavascriptEnabled

      public void setJavascriptEnabled(boolean enableJavascript)

      implicitlyWaitFor

      protected  X implicitlyWaitFor(java.util.concurrent.Callable condition)

      getWebClient

      protected com.gargoylesoftware.htmlunit.WebClient getWebClient()

      getCurrentWindow

      protected com.gargoylesoftware.htmlunit.WebWindow getCurrentWindow()

      manage

      public WebDriver.Options manage()
      Description copied from interface: WebDriver
      Gets the Option interface
      Specified by:
      manage in interface WebDriver
      Returns:
      An option interface
      See Also:
      WebDriver.Options

      findElementByPartialLinkText

      public WebElement findElementByPartialLinkText(java.lang.String using)
      Specified by:
      findElementByPartialLinkText in interface FindsByLinkText

      findElementsByPartialLinkText

      public java.util.List<WebElement> findElementsByPartialLinkText(java.lang.String using)
      Specified by:
      findElementsByPartialLinkText in interface FindsByLinkText