Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
Copyright 2007-2009 Selenium committers
Portions copyright 2011 Software Freedom Conservancy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.openqa.selenium.htmlunit;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.CookieManager;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.ProxyConfig;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.TopLevelWindow;
import com.gargoylesoftware.htmlunit.WaitingRefreshHandler;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.WebWindowEvent;
import com.gargoylesoftware.htmlunit.WebWindowListener;
import com.gargoylesoftware.htmlunit.WebWindowNotFoundException;
import com.gargoylesoftware.htmlunit.html.BaseFrameElement;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlHtml;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.host.Location;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLCollection;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
import net.sourceforge.htmlunit.corejs.javascript.NativeObject;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.InvalidCookieDomainException;
import org.openqa.selenium.InvalidSelectorException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.NoSuchFrameException;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.Platform;
import org.openqa.selenium.Point;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UnableToSetCookieException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.browserlaunchers.Proxies;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.Keyboard;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.internal.FindsById;
import org.openqa.selenium.internal.FindsByLinkText;
import org.openqa.selenium.internal.FindsByName;
import org.openqa.selenium.internal.FindsByTagName;
import org.openqa.selenium.internal.FindsByXPath;
import org.openqa.selenium.internal.WrapsElement;
import org.openqa.selenium.logging.Logs;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.SessionNotFoundException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import static org.openqa.selenium.remote.CapabilityType.SUPPORTS_FINDING_BY_CSS;
public class HtmlUnitDriver implements WebDriver, JavascriptExecutor,
FindsById, FindsByLinkText, FindsByXPath, FindsByName, FindsByCssSelector,
FindsByTagName, HasCapabilities, HasInputDevices {
private WebClient webClient;
private WebWindow currentWindow;
// Fictive position just to implement the API
private Point windowPosition = new Point(0, 0);
private Dimension initialWindowDimension;
private boolean enableJavascript;
private ProxyConfig proxyConfig;
private long implicitWait = 0;
private long scriptTimeout = 0;
private HtmlUnitKeyboard keyboard;
private HtmlUnitMouse mouse;
private boolean gotPage;
public static final String INVALIDXPATHERROR = "The xpath expression '%s' cannot be evaluated";
public static final String INVALIDSELECTIONERROR =
"The xpath expression '%s' selected an object of type '%s' instead of a WebElement";
public HtmlUnitDriver(BrowserVersion version) {
webClient = createWebClient(version);
currentWindow = webClient.getCurrentWindow();
initialWindowDimension = new Dimension(currentWindow.getOuterWidth(), currentWindow.getOuterHeight());
webClient.addWebWindowListener(new WebWindowListener() {
public void webWindowOpened(WebWindowEvent webWindowEvent) {
// Ignore
}
public void webWindowContentChanged(WebWindowEvent event) {
if (event.getWebWindow() != currentWindow) {
return;
}
// Do we need to pick some new default content?
switchToDefaultContentOfWindow(currentWindow);
}
public void webWindowClosed(WebWindowEvent event) {
// Check if the event window refers to us or one of our parent windows
// setup the currentWindow appropriately if necessary
WebWindow curr = currentWindow;
do {
// Instance equality is okay in this case
if (curr == event.getWebWindow()) {
currentWindow = currentWindow.getTopWindow();
return;
}
curr = curr.getParentWindow();
} while (curr != currentWindow.getTopWindow());
}
});
// Now put us on the home page, like a real browser
get(webClient.getOptions().getHomePage());
gotPage = false;
resetKeyboardAndMouseState();
}
public HtmlUnitDriver() {
this(false);
}
public HtmlUnitDriver(boolean enableJavascript) {
this(BrowserVersion.getDefault());
setJavascriptEnabled(enableJavascript);
}
/**
* 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.
*/
public HtmlUnitDriver(Capabilities capabilities) {
this(determineBrowserVersion(capabilities));
setJavascriptEnabled(capabilities.isJavascriptEnabled());
if (capabilities.getCapability(CapabilityType.PROXY) != null) {
Proxy proxy = Proxies.extractProxy(capabilities);
String fullProxy = proxy.getHttpProxy();
String pacfile = proxy.getProxyAutoconfigUrl();
if (fullProxy != null) {
int index = fullProxy.indexOf(":");
if (index != -1) {
String host = fullProxy.substring(0, index);
int port = Integer.parseInt(fullProxy.substring(index + 1));
setProxy(host, port);
} else {
setProxy(fullProxy, 0);
}
} else if(pacfile != null && !pacfile.equals("")) {
setAutoProxy(pacfile);
}
}
}
// Package visibility for testing
static BrowserVersion determineBrowserVersion(Capabilities capabilities) {
String browserName = null;
String browserVersion = null;
String rawVersion = capabilities.getVersion();
String[] splitVersion = rawVersion == null ? new String[0] : rawVersion.split("-");
if (splitVersion.length > 1) {
browserVersion = splitVersion[1];
browserName = splitVersion[0];
} else {
browserName = capabilities.getVersion();
browserVersion = "";
}
// This is for backwards compatibility - in case there are users who are trying to
// configure the HtmlUnitDriver by using the c'tor with capabilities.
if (!BrowserType.HTMLUNIT.equals(capabilities.getBrowserName())) {
browserName = capabilities.getBrowserName();
browserVersion = capabilities.getVersion();
}
if (BrowserType.FIREFOX.equals(browserName)) {
return BrowserVersion.FIREFOX_17;
}
if (BrowserType.CHROME.equals(browserName)) {
return BrowserVersion.CHROME;
}
if (BrowserType.IE.equals(browserName)) {
// Try and convert the version
try {
int version = Integer.parseInt(browserVersion);
switch (version) {
case 6:
return BrowserVersion.INTERNET_EXPLORER_6;
case 7:
return BrowserVersion.INTERNET_EXPLORER_7;
case 8:
return BrowserVersion.INTERNET_EXPLORER_8;
case 9:
return BrowserVersion.INTERNET_EXPLORER_9;
default:
return BrowserVersion.INTERNET_EXPLORER_8;
}
} catch (NumberFormatException e) {
return BrowserVersion.INTERNET_EXPLORER_8;
}
}
return BrowserVersion.getDefault();
}
private WebClient createWebClient(BrowserVersion version) {
WebClient client = newWebClient(version);
WebClientOptions options = client.getOptions();
options.setHomePage(WebClient.URL_ABOUT_BLANK.toString());
options.setThrowExceptionOnFailingStatusCode(false);
options.setPrintContentOnFailingStatusCode(false);
options.setJavaScriptEnabled(enableJavascript);
options.setRedirectEnabled(true);
options.setUseInsecureSSL(true);
// Ensure that we've set the proxy if necessary
if (proxyConfig != null) {
options.setProxyConfig(proxyConfig);
}
client.setRefreshHandler(new WaitingRefreshHandler());
return modifyWebClient(client);
}
/**
* Create the underlying webclient, but don't set any fields on it.
*
* @param version Which browser to emulate
* @return a new instance of WebClient.
*/
protected WebClient newWebClient(BrowserVersion version) {
return new WebClient(version);
}
/**
* Child classes can override this method to customise the webclient that the HtmlUnit driver
* uses.
*
* @param client The client to modify
* @return The modified client
*/
protected WebClient modifyWebClient(WebClient client) {
// Does nothing here to be overridden.
return client;
}
public void setProxy(String host, int port) {
proxyConfig = new ProxyConfig(host, port);
getWebClient().getOptions().setProxyConfig(proxyConfig);
}
public void setAutoProxy(String autoProxyUrl) {
proxyConfig = new ProxyConfig();
proxyConfig.setProxyAutoConfigUrl(autoProxyUrl);
getWebClient().getOptions().setProxyConfig(proxyConfig);
}
public Capabilities getCapabilities() {
DesiredCapabilities capabilities = DesiredCapabilities.htmlUnit();
capabilities.setPlatform(Platform.getCurrent());
capabilities.setJavascriptEnabled(isJavascriptEnabled());
capabilities.setCapability(SUPPORTS_FINDING_BY_CSS, true);
return capabilities;
}
public void get(String url) {
// Prevent the malformed url exception.
if (WebClient.URL_ABOUT_BLANK.toString().equals(url)) {
get(WebClient.URL_ABOUT_BLANK);
return;
}
URL fullUrl;
try {
fullUrl = new URL(url);
} catch (Exception e) {
throw new WebDriverException(e);
}
get(fullUrl);
}
/**
* Allows HtmlUnit's about:blank to be loaded in the constructor, and may be useful for other
* tests?
*
* @param fullUrl The URL to visit
*/
protected void get(URL fullUrl) {
try {
getWebClient().getPage(fullUrl);
// A "get" works over the entire page
currentWindow = getCurrentWindow().getTopWindow();
} catch (UnknownHostException e) {
// This should be fine
} catch (ConnectException e) {
// This might be expected
} catch (SocketTimeoutException e) {
throw new TimeoutException(e);
} catch (Exception e) {
throw new WebDriverException(e);
}
gotPage = true;
pickWindow();
resetKeyboardAndMouseState();
}
private void resetKeyboardAndMouseState() {
keyboard = new HtmlUnitKeyboard(this);
mouse = new HtmlUnitMouse(this, keyboard);
}
protected void pickWindow() {
// TODO(simon): HtmlUnit tries to track the current window as the frontmost. We don't
if (currentWindow == null) {
currentWindow = getWebClient().getCurrentWindow();
}
}
public String getCurrentUrl() {
// TODO(simon): Blech. I can see this being baaad
URL url = getRawUrl();
if (url == null) {
return null;
}
return url.toString();
}
public String getTitle() {
Page page = lastPage();
if (page == null || !(page instanceof HtmlPage)) {
return null; // no page so there is no title
}
if (getCurrentWindow() instanceof FrameWindow) {
page = ((FrameWindow) getCurrentWindow()).getTopWindow().getEnclosedPage();
}
return ((HtmlPage) page).getTitleText();
}
public WebElement findElement(By by) {
return findElement(by, this);
}
public List findElements(By by) {
return findElements(by, this);
}
public String getPageSource() {
Page page = lastPage();
if (page == null) {
return null;
}
if (page instanceof SgmlPage) {
return ((SgmlPage) page).asXml();
}
WebResponse response = page.getWebResponse();
return response.getContentAsString();
}
public void close() {
getWebClient(); // check that session is active
WebWindow thisWindow = getCurrentWindow(); // check that the current window is active
if (getWebClient().getWebWindows().size() == 1) {
// closing the last window is equivalent to quit
quit();
} else {
if (thisWindow != null) {
((TopLevelWindow) thisWindow.getTopWindow()).close();
}
if (getWebClient().getWebWindows().size() == 0) {
quit();
}
}
}
public void quit() {
if (webClient != null) {
webClient.closeAllWindows();
webClient = null;
}
currentWindow = null;
}
public Set getWindowHandles() {
final Set allHandles = Sets.newHashSet();
for (final WebWindow window : getWebClient().getTopLevelWindows()) {
allHandles.add(String.valueOf(System.identityHashCode(window)));
}
return allHandles;
}
public String getWindowHandle() {
WebWindow topWindow = getCurrentWindow().getTopWindow();
if (topWindow.isClosed()) {
throw new NoSuchWindowException("Window is closed");
}
return String.valueOf(System.identityHashCode(topWindow));
}
public Object executeScript(String script, final Object... args) {
HtmlPage page = getPageToInjectScriptInto();
script = "function() {" + script + "\n};";
ScriptResult result = page.executeJavaScript(script);
Function func = (Function) result.getJavaScriptResult();
Object[] parameters = convertScriptArgs(page, args);
try {
result = page.executeJavaScriptFunctionIfPossible(
func,
(ScriptableObject) getCurrentWindow().getScriptObject(),
parameters,
page.getDocumentElement());
} catch (Throwable ex) {
throw new WebDriverException(ex);
}
return parseNativeJavascriptResult(result);
}
public Object executeAsyncScript(String script, Object... args) {
HtmlPage page = getPageToInjectScriptInto();
args = convertScriptArgs(page, args);
Object result = new AsyncScriptExecutor(page, scriptTimeout)
.execute(script, args);
return parseNativeJavascriptResult(result);
}
private Object[] convertScriptArgs(HtmlPage page, final Object[] args) {
final Scriptable scope = (Scriptable) page.getEnclosingWindow().getScriptObject();
final Object[] parameters = new Object[args.length];
final ContextAction action = new ContextAction() {
public Object run(final Context context) {
for (int i = 0; i < args.length; i++) {
parameters[i] = parseArgumentIntoJavascriptParameter(context, scope, args[i]);
}
return null;
}
};
getWebClient().getJavaScriptEngine().getContextFactory().call(action);
return parameters;
}
private HtmlPage getPageToInjectScriptInto() {
if (!isJavascriptEnabled()) {
throw new UnsupportedOperationException(
"Javascript is not enabled for this HtmlUnitDriver instance");
}
final Page lastPage = lastPage();
if (!(lastPage instanceof HtmlPage)) {
throw new UnsupportedOperationException("Cannot execute JS against a plain text page");
} else if (!gotPage) {
// just to make ExecutingJavascriptTest.testShouldThrowExceptionIfExecutingOnNoPage happy
// but does this limitation make sense?
throw new WebDriverException("Can't execute JavaScript before a page has been loaded!");
}
return (HtmlPage) lastPage;
}
private Object parseArgumentIntoJavascriptParameter(
Context context, Scriptable scope, Object arg) {
while (arg instanceof WrapsElement) {
arg = ((WrapsElement) arg).getWrappedElement();
}
if (!(arg instanceof HtmlUnitWebElement ||
arg instanceof HtmlElement || // special case the underlying type
arg instanceof Number ||
arg instanceof String ||
arg instanceof Boolean ||
arg.getClass().isArray() ||
arg instanceof Collection> ||
arg instanceof Map, ?>)) {
throw new IllegalArgumentException(
"Argument must be a string, number, boolean or WebElement: " +
arg + " (" + arg.getClass() + ")");
}
if (arg instanceof HtmlUnitWebElement) {
HtmlUnitWebElement webElement = (HtmlUnitWebElement) arg;
assertElementNotStale(webElement.getElement());
return webElement.getElement().getScriptObject();
} else if (arg instanceof HtmlElement) {
HtmlElement element = (HtmlElement) arg;
assertElementNotStale(element);
return element.getScriptObject();
} else if (arg instanceof Collection>) {
List