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.
/*
* Title: SeleniumHTMLUnit
*
* Description:
* This class implements the selenium API (current API as of 20070801) using htmlunit,
* in order to have a suitable load-test engine to be driven by TestMaker.
*
* This component is part of a package allowing TestMaker 5.x
* (http://www.pushtotest.com) to execute Selenium-IDE
* (http://wiki.openqa.org/display/SIDE/Home) recorded test scenarios.
* This extension package will remain accessible from the Open-Source section
* of the Denali web site: http://www.denali.be
*
*/
package com.saucelabs.selenium.client.htmlunit;
/*
* Main author(s): Olivier Dony, Denali
* with contributions from other members of the Denali team
* $Id: SeleniumHTMLUnit.java,v 1.9 2008/06/16 09:02:49 ndaniels Exp $
*/
/*
* Copyright (c) 2007, Denali Consulting SA, Belgium
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Denali Consulting SA nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Denali Consulting SA, Belgium, ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Denali Consulting SA, Belgium BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
import com.gargoylesoftware.htmlunit.AjaxController;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.DomAttr;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
import com.gargoylesoftware.htmlunit.html.HtmlHiddenInput;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlRadioButtonInput;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.thoughtworks.selenium.Selenium;
import java.util.Date;
import java.util.Map;
import java.util.Stack;
/**
* An implementation of the Selenium API (current as of 20070801) with HTMLUnit.
*
* @author Olivier Dony, Denali s.a.
* @version $Id: SeleniumHTMLUnit.java,v 1.9 2008/06/16 09:02:49 ndaniels Exp $
*/
public class SeleniumHTMLUnit implements Selenium {
/** The default timeout for HTTP operations * */
public static final int DEFAULT_HTTP_TIMEOUT = 60000;
public static final int DEFAULT_WAIT_TIMEOUT = 60000;
private static final String CLASS = SeleniumHTMLUnit.class.getName();
protected WebClient webClient;
protected static Logger logger = Logger.getLogger(CLASS);
protected List verificationErrors;
protected String baseUrl;
protected boolean debugPageOnFailure;
protected WebWindow originalWindow;
private boolean verifyActAsAssert;
private static boolean printErrorPage=true;
private Stack history = new Stack ();
static {
logger.setLevel(Level.WARNING);
}
private HtmlPage currentPage;
private HtmlPage oldPage;
public static void setLoglevel(Level l){
logger.setLevel(l);
if (l == l.OFF){
printErrorPage = false;
} else {
printErrorPage = true;
}
}
public SeleniumHTMLUnit() {
this(false,false);
}
public SeleniumHTMLUnit(boolean throwExceptionOnScriptError,
boolean throwExceptionOnFailingStatusCode) {
// defaults to severe as to not slow down the tests by default
// attempt to disable commons-httpclient logging
try {
/* Logger
.getLogger(
"org.apache.commons.httpclient.HttpMethodDirector")
.setLevel(Level.OFF); // java.util.logging
org.apache.log4j.Logger.getLogger(
"org.apache.commons.httpclient.HttpMethodDirector")
.setLevel(org.apache.log4j.Level.OFF); // log4j logging/*/
} catch (Throwable t) {
/*
* ignored, we're just trying to turn off useless commons-http
* logging
*/
}
initWebClient(throwExceptionOnScriptError, throwExceptionOnFailingStatusCode);
}
int delay = 0;
private void sleep(){
if (delay == 0)
return;
try {
Thread.sleep(delay);
} catch (Exception e){
e.printStackTrace();
}
}
public void initWebClient(boolean throwExceptionOnScriptError,
boolean throwExceptionOnFailingStatusCode) {
webClient = new WebClient(BrowserVersion.FIREFOX_2);
webClient.setAjaxController(new AjaxController(){
});
originalWindow = webClient.getCurrentWindow();
webClient.setThrowExceptionOnScriptError(throwExceptionOnScriptError);
webClient.setRedirectEnabled(true);
webClient.setThrowExceptionOnFailingStatusCode(throwExceptionOnFailingStatusCode);
webClient.setPrintContentOnFailingStatusCode(printErrorPage);
verificationErrors = new ArrayList();
verifyActAsAssert = false;
// Set a default timeout on HTTP connect and read, as by default
// WebClient waits forever!
webClient.setTimeout(DEFAULT_HTTP_TIMEOUT);
try {
currentPage = (HtmlPage) webClient.getPage(WebClient.URL_ABOUT_BLANK);
} catch (Exception e){
e.printStackTrace();
}
}
/**
* Returns the baseUrl. Important note: please keep in
* mind that this 'baseUrl' is not combined with relative URLs in the usual
* sense, but always concatenated. That means that whenever you
* {@link #open(String)} a relative URL, the resulting URL will always be
* baseURL+relativeUrl, no matter what.
*
* @return the baseUrl.
*/
public String getBaseUrl() {
return baseUrl;
}
private void setCurrentPage(HtmlPage newPage){
history.push(currentPage.getWebResponse().getRequestUrl());
currentPage = newPage;
}
/**
* Sets the baseUrl to use when a URL passed to {@link #open(String)} is not
* absolute. Important note: please keep in mind that this
* 'baseUrl' is not combined with relative URLs in the usual sense, but
* always concatenated. That means that whenever you {@link #open(String)} a
* URL, the resulting URL will always be baseURL+relativeUrl, no matter
* what. DO NOT SET A BASEURL UNLESS YOU REALLY MEAN IT.
*
* @param baseUrl
* the baseUrl to set.
*/
public void setBaseUrl(String theBaseUrl) {
if (theBaseUrl.endsWith("/"))
baseUrl = theBaseUrl.substring(0,theBaseUrl.length()-1);
else
baseUrl = theBaseUrl;
}
/**
* Set the {@link Level} for the {@link Logger} used by this
* SeleniumHTMLUnit.
*
* @param level
* a String containing the label of the value for a {@link Level}
* (e.g. "INFO" or "800" for
* {@link Level#INFO}).
* @see Level
*/
/* public void setLogLevel(String level) {
logger.setLevel(Level.parse(level));
}*/
/**
* Return the label ({@link Level#getName()}) for the {@link Logger} used
* by this SeleniumHTMLUnit.
*
* @see Level
*/
public String getLogLevel() {
return logger.getLevel().getName();
}
public void setLogLevel(String level) {
logger.setLevel(Level.parse(level));
}
/**
* Returns whether page debugging is enabled when a failure occurs.
*
* @return whether page debugging is enabled when a failure occurs.
*/
public boolean hasDebugPageOnFailure() {
return debugPageOnFailure;
}
/**
* Sets whether page debugging is enabled when a failure occurs.
*
* @param debugPageOnFailure
* true if debugging should be enabled.
*/
public void setDebugPageOnFailure(boolean debugPageOnFailure) {
this.debugPageOnFailure = debugPageOnFailure;
}
/**
* Returns the current page, resulting from the last action, and on which
* the next action will be executed. The current page can also be changed
* indirectly using {@link #selectWindow(String)}.
*
* @return the current page, resulting from the last action, and on which
* the next action will be executed.
* @see #selectWindow(String)
*/
public HtmlPage getPage() {
return currentPage;
}
/**
* Returns the underlying htmlunit webClient.
*
* @return the underlying htmlunit webClient.
*/
public WebClient getWebClient() {
return webClient;
}
public void assertEval(String script,String pattern){
assertEquals(pattern,getEval(script));
}
/**
* Opens an URL in the test frame. This accepts both absolute URLs and URLs
* relative to the {@link #getBaseUrl()}. Important:
* Relative URLs are not combined with the baseURL, but simply concatenated
* with it.
*
* The "open" command waits for the page to load before proceeding, ie. the
* "AndWait" suffix is implicit. Note: The URL must be on the
* same domain as the runner HTML due to security restrictions in the
* browser (Same Origin Policy). If you need to open an URL on another
* domain, use the Selenium Server to start a new browser session on that
* domain.
*
* @param location
* the URL to open; may be relative or absolute
*/
public void open(String location) {
if (!location.startsWith("/")){
try {
new URL(location);
} catch (Exception e){
location = "/"+location;
}
}
// Note: Selenium has a peculiar notion of relative URLs: the relative
// URL
// is appended directly to the base URL, no matter what this
// relative URL is (even if it starts with a forward slash (/) )
try {
URL url = (baseUrl != null) ? new URL(baseUrl + location)
: new URL(location);
setCurrentPage((HtmlPage)webClient.getPage(url));
logger.info("open: opened url = " + location);
} catch (MalformedURLException e) {
throw new RuntimeException(
"open: URL is malformed, maybe the baseURL is incorrect: ",
e);
} catch (IOException e) {
throw new RuntimeException("open: failed to open URL: ", e);
}
sleep();
}
/**
* Sets the value of an input field, as though you typed it in.
*
* Can also be used to set the value of combo boxes, check boxes, etc. In
* these cases, value should be the value of the option selected, not the
* visible text.
*
*
* @param locator
* an element locator
* @param value
* the value to type
*/
public void type(String locator, String value) {
List extends Object> results = getElements(locator);
for (Object elemObj : results) {
HtmlElement elem = (HtmlElement) elemObj;
try {
elem.focus();
if(elem instanceof HtmlFileInput)//Hack because type method is not working on upload input
((HtmlFileInput)elem).setValueAttribute(value);
else
elem.type(value);
} catch (IOException e) {
throw new RuntimeException("type: failed to type on element "+locator, e);
}
logger.info("type: "+value+" typed in element " + elem.getNodeName());
}
sleep();
}
/**
* Clicks on a link, button, checkbox or radio button. If the click action
* causes a new page to load (like a link usually does), call
* waitForPageToLoad.
*
* @param locator
* an element locator
*/
public void clickAndWait(String locator){
click(locator);
}
/**
* Clicks on a link, button, checkbox or radio button. If the click action
* causes a new page to load (like a link usually does), call
* waitForPageToLoad.
*
* @param locator
* an element locator
*/
public void click(String locator) {
try {
HtmlElement elem = getElement(locator);
logger.info("click on " + elem);
setCurrentPage( (HtmlPage)(elem).click());
} catch (IOException e) {
throw new RuntimeException(
"click: failed to perform click on element @ locator "
+ locator, e);
}
sleep();
}
/**
* Returns the title of the current page, or null if there is no title.
*
* @return the title of the current page, or null if there is no title.
*/
public String getTitle() {
try {
return getPage().getTitleText();
} catch (Exception e) {
logger
.log(
Level.WARNING,
"getTitle: could not get page title, maybe there was no page title or head section : "
+ e.getMessage());
return null;
}
}
/**
* Verifies that the specified text pattern appears somewhere on the
* rendered page shown to the user.
*
* @param pattern
* a pattern to match with the text of
* the page
* @return true if the pattern matches the text, false otherwise
*/
public boolean isTextPresent(String pattern) {
return Pattern.compile(pattern).matcher(getPage().asText()).find();
}
/**
* Waits for a new page to load.
*
*
* You can use this command instead of the "AndWait" suffixes,
* "clickAndWait", "selectAndWait", "typeAndWait" etc. (which are only
* available in the JS API).
*
*
* Selenium constantly keeps track of new pages loading, and sets a
* "newPageLoaded" flag when it first notices a page load. Running any other
* Selenium command after turns the flag to false. Hence, if you want to
* wait for a page to load, you must wait immediately after a Selenium
* command that caused a page-load.
*
*
* @param strTimeout
* a timeout in milliseconds, after which this command will
* return with an error
*/
public void waitForPageToLoad(String strTimeout) {
// Selenium is asynchronous but HtmlUnit is synchronous, so this cannot
// be mapped easily.
logger.info("Action ignored: waitForPageToLoad, timeout = "
+ strTimeout);
}
/**
* Select an option from a drop-down using an option locator.
*
* Option locators provide different ways of specifying options of an HTML
* Select element (e.g. for selecting a specific option, or for asserting
* that the selected option satisfies a specification). There are several
* forms of Select Option Locator.
*
*
*
label=labelPattern: matches options
* based on their labels, i.e. the visible text. (This is the default.)
*
*
label=regexp:^[Oo]ther
*
*
*
value=valuePattern: matches options
* based on their values.
*
*
value=other
*
*
*
id=id: matches options based on their
* ids.
*
*
id=option1
*
*
*
index=index: matches an option based
* on its index (offset from zero).
*
*
index=2
*
*
*
*
* If no option locator prefix is provided, the default behaviour is to
* match on label.
*
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @param optionLocator
* an option locator (a label by default)
*/
public void select(final String selectLocator, final String optionLocator) {
setSelectedOption(selectLocator, optionLocator, true);
}
/**
* Add a selection to the set of selected options in a multi-select element
* using an option locator.
*
* @see #select for details of option locators
* @param locator
* an element locator identifying a
* multi-select box
* @param optionLocator
* an option locator (a label by default)
*/
public void addSelection(String locator, String optionLocator) {
setSelectedOption(locator, optionLocator, true);
}
/**
* Remove a selection from the set of selected options in a multi-select
* element using an option locator.
*
* @see #select for details of option locators
* @param locator
* an element locator identifying a
* multi-select box
* @param optionLocator
* an option locator (a label by default)
*/
public void removeSelection(String locator, String optionLocator) {
setSelectedOption(locator, optionLocator, false);
}
/**
* Unselects all of the selected options in a multi-select element.
*
* @param locator
* an element locator identifying a
* multi-select box
*/
public void removeAllSelections(String locator) {
HtmlSelect select = (HtmlSelect) getElement(locator);
List options = select.getOptions();
for (HtmlOption tmp : options) {
HtmlPage newPage = (HtmlPage) select.setSelectedAttribute(tmp, false);
if (newPage != null)
setCurrentPage( newPage);
}
sleep();
}
/**
* Gets all option labels (visible text) for selected options in the
* specified select or multi-select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return an array of all selected option labels in the specified select
* drop-down
*/
public String[] getSelectedLabels(String selectLocator) {
String[] result = null;
List selectedOptions = getSelectedOptions(selectLocator);
result = new String[selectedOptions.size()];
int i = 0;
for (HtmlOption optionItem : selectedOptions) {
result[i++] = optionItem.asText();
}
return result;
}
/**
* Gets option label (visible text) for selected option in the specified
* select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return the selected option label in the specified select drop-down
*/
public String getSelectedLabel(String selectLocator) {
String[] result = getSelectedLabels(selectLocator);
if (result != null && result.length > 0) {
return result[0];
}
return null;
}
/**
* Gets all option values (value attributes) for selected options in the
* specified select or multi-select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return an array of all selected option values in the specified select
* drop-down
*/
public String[] getSelectedValues(String selectLocator) {
String[] result = null;
List selectedOptions = getSelectedOptions(selectLocator);
result = new String[selectedOptions.size()];
int i = 0;
for (HtmlOption optionItem : selectedOptions) {
result[i++] = optionItem.getValueAttribute();
}
return result;
}
/**
* Gets option value (value attribute) for selected option in the specified
* select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return the selected option value in the specified select drop-down
*/
public String getSelectedValue(String selectLocator) {
String[] result = getSelectedValues(selectLocator);
if (result.length > 0) {
return result[0];
}
return null;
}
/**
* Gets all option indexes (option number, starting at 0) for selected
* options in the specified select or multi-select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return an array of all selected option indexes in the specified select
* drop-down
*/
public String[] getSelectedIndexes(String selectLocator) {
String[] result = null;
HtmlSelect select = (HtmlSelect) getElement(selectLocator);
List options = select.getOptions();
List list = new ArrayList();
int i = 0;
for (HtmlOption option : options) {
if (option.isSelected()) {
list.add(String.valueOf(i));
}
i++;
}
result = new String[list.size()];
result = list.toArray(result);
return result;
}
/**
* Gets option index (option number, starting at 0) for selected option in
* the specified select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return the selected option index in the specified select drop-down
*/
public String getSelectedIndex(String selectLocator) {
String[] result = getSelectedIndexes(selectLocator);
if (result.length > 0) {
return result[0];
}
return "-1";
}
/**
* Gets all option element IDs for selected options in the specified select
* or multi-select element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return an array of all selected option IDs in the specified select
* drop-down
*/
public String[] getSelectedIds(String selectLocator) {
String[] result = null;
List selectedOptions = getSelectedOptions(selectLocator);
result = new String[selectedOptions.size()];
int i = 0;
for (HtmlOption optionItem : selectedOptions) {
result[i++] = optionItem.getId();
}
return result;
}
/**
* Gets option element ID for selected option in the specified select
* element.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return the selected option ID in the specified select drop-down
*/
public String getSelectedId(String selectLocator) {
String[] result = getSelectedIds(selectLocator);
if (result.length > 0) {
return result[0];
}
return null;
}
/**
* Determines whether some option in a drop-down menu is selected.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return true if some option has been selected, false otherwise
*/
public boolean isSomethingSelected(String selectLocator) {
HtmlSelect select = (HtmlSelect) getElement(selectLocator);
return select.getSelectedOptions().size() > 0;
}
/**
* Gets all option labels in the specified select drop-down.
*
* @param selectLocator
* an element locator identifying a
* drop-down menu
* @return an array of all option labels in the specified select drop-down
*/
public String[] getSelectOptions(String selectLocator) {
String[] result = null;
HtmlSelect select = (HtmlSelect) getElement(selectLocator);
List options = select.getOptions();
result = new String[options.size()];
int i = 0;
for (HtmlOption option : options) {
result[i++] = option.asText();
}
return result;
}
/**
* Check a toggle-button (checkbox/radio)
*
* @param locator
* an element locator
*/
public void check(String locator) {
HtmlCheckBoxInput checkbox = (HtmlCheckBoxInput) getElement(locator);
setCurrentPage((HtmlPage)checkbox.setChecked(true));
sleep();
}
/**
* Uncheck a toggle-button (checkbox/radio)
*
* @param locator
* an element locator
*/
public void uncheck(String locator) {
HtmlCheckBoxInput checkbox = (HtmlCheckBoxInput) getElement(locator);
setCurrentPage ( (HtmlPage) checkbox.setChecked(false));
sleep();
}
/**
* Gets whether a toggle-button (checkbox/radio) is checked. Fails if the
* specified element doesn't exist or isn't a toggle-button.
*
* @param locator
* an element locator pointing to a
* checkbox or radio button
* @return true if the checkbox is checked, false otherwise
*/
public boolean isChecked(String locator) {
HtmlCheckBoxInput checkbox = (HtmlCheckBoxInput) getElement(locator);
return checkbox.isChecked();
}
/**
* Simulates a user pressing the mouse button (without releasing it yet) on
* the specified element.
*
* @param locator
* an element locator
*/
public void mouseDown(String locator) {
HtmlElement element = getElement(locator);
setCurrentPage ((HtmlPage) element.mouseDown());
sleep();
}
public void mouseDownRight(String locator) {
HtmlElement element = getElement(locator);
setCurrentPage ((HtmlPage) element.mouseDown(false,false,false,1));
sleep();
}
/**
* Simulates a user moving the mouse pointer away from the specified
* element.
*
* @param locator
* an element locator
*/
public void mouseOut(String locator) {
HtmlElement element = getElement(locator);
setCurrentPage ((HtmlPage) element.mouseOut());
sleep();
}
/**
* Simulates a user hovering a mouse over the specified element.
*
* @param locator
* an element locator
*/
public void mouseOver(String locator) {
HtmlElement element = getElement(locator);
setCurrentPage ( (HtmlPage) element.mouseOver());
sleep();
}
/**
* Simulates the event that occurs when the user releases the mouse button
* (i.e., stops holding the button down) on the specified element.
*
* @param locator
* an element locator
*/
public void mouseUp(String locator) {
HtmlElement element = getElement(locator);
setCurrentPage ((HtmlPage) element.mouseUp());
sleep();
}
/**
* Wait for an element to appear on the current page
*
* @param locator
* an element locator
*/
public void waitForElementPresent(String locator) {
logger.info("waitForElementPresent "+locator);
waitForElementPresent(locator, DEFAULT_WAIT_TIMEOUT);
}
/**
* Wait for an element to appear on the current page
*
* @param locator
* an element locator
* @param timeout
* the number of millis to wait before timeout
* @throws InterruptedException
*/
private void waitForElementPresent(String locator, long timeout) {
int count = 0;
for (; count < timeout; count += 500) {
if (isElementPresent(locator)) {
break;
}
synchronized (getPage()) {
try {
getPage().wait(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (count >= timeout) {
System.err.println("Timeout value reached");
}
}
/**
* Runs the specified JavaScript snippet repeatedly until it evaluates to
* "true". The snippet may have multiple lines, but only the result of the
* last line will be considered.
*
* Note that, by default, the snippet will be run in the runner's test
* window, not in the window of your application. To get the window of your
* application, you can use the JavaScript snippet
* selenium.browserbot.getCurrentWindow(), and then run your
* JavaScript in there
*
*
* @param script
* the JavaScript snippet to run
* @param timeout
* a timeout in milliseconds, after which this command will
* return with an error
*/
public void waitForCondition(String script, String timeout)
{
long theTimeout = Integer.parseInt(timeout);
long initialTime = new Date().getTime();
while (true){
if (new Date().getTime()-initialTime > theTimeout)
break;
Object obj = webClient.getJavaScriptEngine().execute(this.getPage(),script,"title",0);
try {
Thread.sleep(100);
Thread.yield();
} catch (InterruptedException e) {
throw new java.lang.RuntimeException ("Thread interrupted",e);
}
if (obj == null)
continue;
if (obj instanceof org.mozilla.javascript.Undefined)
continue;
if (obj instanceof Boolean)
if (((Boolean)obj).booleanValue() == false)
continue;
//not boolean but also not null
// Thread.sleep(1000);
//Sleep some time after aceptance is done
return;
}
throw new java.lang.RuntimeException ("waitForCondition: Timeout reached");
//logger.warning("waitForCondition: action not implemented");
}
/**
* Gets the text of an element. This works for any element that contains
* text. This command uses either the textContent (Mozilla-like browsers) or
* the innerText (IE-like browsers) of the element, which is the rendered
* text shown to the user.
*
* @param locator
* an element locator
* @return the text of the element
*/
public String getText(String locator) {
HtmlElement elem = getElement(locator);
return elem.asText();
}
/*
* (non-Javadoc)
*
* @see com.thoughtworks.selenium.Selenium#getHtmlSource()
*/
public String getHtmlSource() {
return getPage().asXml();
}
/**
* Verifies that the specified element is somewhere on the getPage().
*
* @param locator
* an element locator
* @return true if the element is present, false otherwise
*/
public boolean isElementPresent(String locator) {
try {
return getElement(locator) != null;
} catch (Exception e) {
/*
* ignored: this is one case where it is legal to fail to locate an
* element
*/
}
return false;
}
/**
* Selects a popup window; once a popup window has been selected, all
* commands go to that window. To select the main window again, use null as
* the target.
*
* Note that there is a big difference between a window's internal
* JavaScript "name" property and the "title" of a given window's document
* (which is normally what you actually see, as an end user, in the title
* bar of the window). The "name" is normally invisible to the end-user;
* it's the second parameter "windowName" passed to the JavaScript method
* window.open(url, windowName, windowFeatures, replaceFlag) (which selenium
* intercepts).
*
*
* Selenium has several strategies for finding the window object referred to
* by the "windowID" parameter.
*
*
* 1.) if windowID is null, (or the string "null") then it is assumed the
* user is referring to the original window instantiated by the browser).
*
*
* 2.) if the value of the "windowID" parameter is a JavaScript variable
* name in the current application window, then it is assumed that this
* variable contains the return value from a call to the JavaScript
* window.open() method.
*
*
* 3.) Otherwise, selenium looks in a hash it maintains that maps string
* names to window "names".
*
*
* 4.) If that fails, we'll try looping over all of the known
* windows to try to find the appropriate "title". Since "title" is not
* necessarily unique, this may have unexpected behavior.
*
*
* If you're having trouble figuring out what is the name of a window that
* you want to manipulate, look at the selenium log messages which identify
* the names of windows created via window.open (and therefore intercepted
* by selenium). You will see messages like the following for each window as
* it is opened:
*
*
* debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"
*
*
* In some cases, Selenium will be unable to intercept a call to window.open
* (if the call occurs during or before the "onLoad" event, for example).
* (This is bug SEL-339.) In those cases, you can force Selenium to notice
* the open window's name by using the Selenium openWindow command, using an
* empty (blank) url, like this: openWindow("", "myFunnyWindow").
*
*
* @param windowID
* the JavaScript window ID of the window to select
*/
public void selectWindow(final String windowID) {
// Selenium's "null" windowID designates the original browser window.
if (windowID == null || "null".equals(windowID)) {
webClient.setCurrentWindow(originalWindow);
} else {
// throws WebWindowNotFoundException if not found.
webClient.setCurrentWindow(webClient
.getWebWindowByName(windowID != null ? windowID : ""));
}
logger.info("selectWindow(" + windowID + "): action done");
}
/**
* Selects a frame within the current window. (You may invoke this command
* multiple times to select nested frames.) To select the parent frame, use
* "relative=parent" as a locator; to select the top frame, use
* "relative=top".
*
* You may also use a DOM expression to identify the frame you want
* directly, like this: dom=frames["main"].frames["subframe"]
*
*
* @param locator
* an element locator identifying a
* frame or iframe
*/
public void selectFrame(final String frameID) {
WebWindow frame = null;
// handle selenium's 'special' frameIDs
if (frameID != null) {
if (frameID.startsWith("relative=")) {
String targetFrame = frameID.substring(9);
if ("parent".equals(targetFrame) || "up".equals(targetFrame)) {
if (webClient.getCurrentWindow() instanceof FrameWindow) {
frame = webClient.getCurrentWindow().getParentWindow();
} else {
// ignored, top frame already.
logger
.info("selectFrame("
+ frameID
+ ") seems to reference current frame, using self.");
frame = webClient.getCurrentWindow();
}
} else if ("top".equals(targetFrame)) {
frame = webClient.getCurrentWindow().getTopWindow();
}
} else if (frameID.startsWith("dom=")) {
logger
.warning("selectFrame() with 'dom=' locator not implemented yet!");
throw new ElementNotFoundException("frame", "locator", frameID);
}
}
if (frame == null) {
// No special selenium frame found, locate by id.
try {
// throws WebWindowNotFoundException if not found.
frame = getPage().getFrameByName(frameID != null ? frameID : "");
} catch (ElementNotFoundException e) {
// selenium uses frameID="null" for the default frame, so we
// attempt to
// find a frame without name
if (frameID == null || "null".equals(frameID)) {
List frames = getPage().getFrames();
for (Iterator iter = frames.iterator(); iter
.hasNext();) {
FrameWindow frameElem = (FrameWindow) iter.next();
if (frameElem.getName() == null) {
frame = frameElem;
break;
}
}
}
if (frame == null)
throw e; // rethrow -- still not found
}
}
webClient.setCurrentWindow(frame);
logger.info("selectFrame(" + frameID + "): action done");
}
/**
* Gets the (whitespace-trimmed) value of an input field (or anything else
* with a value parameter). For checkbox/radio elements, the value will be
* "on" or "off" depending on whether the element is checked or not.
*
* @param locator
* an element locator
* @return the element value, or "on/off" for checkbox/radio elements
*/
public String getValue(String locator) {
HtmlElement elem = getElement(locator);
if (elem instanceof HtmlRadioButtonInput) {
HtmlRadioButtonInput input = (HtmlRadioButtonInput) elem;
return input.isChecked() ? "on" : "off";
}
if (elem instanceof HtmlCheckBoxInput) {
HtmlCheckBoxInput input = (HtmlCheckBoxInput) elem;
return input.isChecked() ? "on" : "off";
}
if (elem instanceof HtmlInput) {
HtmlInput input = (HtmlInput) elem;
return input.getValueAttribute();
}
throw new RuntimeException(
"Cannot return value for non-input element with locator :"
+ locator);
}
public void stop(){
List windows = webClient.getWebWindows();
for (WebWindow window: windows){
try {
window.getEnclosedPage().cleanUp();
window.setEnclosedPage(null);
} catch (java.lang.Exception e){
//Stop browser threads
}
}
}
// **** Util selenium-rc equivalent methods **** //
/** Like assertTrue, but fails at the end of the test (during tearDown) */
public void verifyTrue(boolean b) {
try {
Assert.assertTrue(b);
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Like assertTrue, but fails at the end of the test (during tearDown) */
public void verifyTrue(boolean b, String message) {
try {
Assert.assertTrue(message, b);
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Like assertFalse, but fails at the end of the test (during tearDown) */
public void verifyFalse(boolean b) {
try {
Assert.assertFalse(b);
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/**
* Like assertTextPresent, but fails at the end of the test (during
* tearDown)
*/
public void verifyTextPresent(String text) {
try {
verifyTrue(isTextPresent(text), "Text \"" + text + "\" not found");
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Check if the text is present in the current page */
public void assertTextPresent(String text) {
Assert.assertTrue("Text \"" + text + "\" not found",
isTextPresent(text));
logger.info("Text "+text+" found");
}
/** Check the title of the current page */
public void assertTitle(String text) {
String title = getTitle();
Assert.assertTrue("Title is not correct, expecting a title matching \""
+ text + "\" and found \"" + title + "\"", title.matches(text));
}
/** Check if the text is NOT present in the current page */
public void assertTextNotPresent(String text) {
Assert.assertFalse("Text \"" + text + "\" found", isTextPresent(text));
}
public void assertTrue(boolean b) {
Assert.assertTrue(b);
}
public void assertFalse(boolean b) {
Assert.assertFalse(b);
}
public void assertTrue(String msg, boolean b) {
Assert.assertTrue(msg, b);
}
public void assertFalse(String msg, boolean b) {
Assert.assertFalse(msg, b);
}
/** Returns the body text of the current page */
/*
* public String getText() { return
* webClient.getJavaScriptEngine().execute(page,
* "this.page().bodyText()","getText").toString(); }
*/
/** Like assertEquals, but fails at the end of the test (during tearDown) */
public void verifyEquals(Object s1, Object s2) {
try {
assertEquals(s1, s2);
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Like assertEquals, but fails at the end of the test (during tearDown) */
public void verifyEquals(boolean s1, boolean s2) {
try {
assertEquals(new Boolean(s1), new Boolean(s2));
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Like JUnit's Assert.assertEquals, but knows how to compare string arrays */
public void assertEquals(Object s1, Object s2) {
if (s1 instanceof String && s2 instanceof String) {
assertEquals((String) s1, (String) s2);
} else if (s1 instanceof String && s2 instanceof String[]) {
assertEquals((String) s1, (String[]) s2);
} else if (s1 instanceof String && s2 instanceof Number) {
assertEquals((String) s1, ((Number) s2).toString());
} else {
if (s1 instanceof String[] && s2 instanceof String[]) {
String[] sa1 = (String[]) s1;
String[] sa2 = (String[]) s2;
if (sa1.length != sa2.length) {
throw new AssertionFailedError("Expected " + sa1
+ " but saw " + sa2);
}
for (int j = 0; j < sa1.length; j++) {
Assert.assertEquals(sa1[j], sa2[j]);
}
}
}
}
/**
* Like JUnit's Assert.assertEquals, but handles "regexp:" strings like HTML
* Selenese
*/
public void assertEquals(String s1, String s2) {
Assert.assertTrue("Expected \"" + s1 + "\" but saw \"" + s2
+ "\" instead", seleniumEquals(s1, s2));
}
/**
* Like JUnit's Assert.assertEquals, but joins the string array with commas,
* and handles "regexp:" strings like HTML Selenese
*/
public void assertEquals(String s1, String[] s2) {
Assert.assertEquals(s1, stringArrayToSimpleString(s2));
}
/**
* Compares two strings, but handles "regexp:" strings like HTML Selenese
*
* @param expectedPattern
* @param actual
* @return true if actual matches the expectedPattern, or false otherwise
*/
public boolean seleniumEquals(String expectedPattern, String actual) {
if (actual.startsWith("regexp:") || actual.startsWith("regex:")) {
// swap 'em
String tmp = actual;
actual = expectedPattern;
expectedPattern = tmp;
}
if (expectedPattern.startsWith("regexp:")) {
String expectedRegEx = expectedPattern
.replaceFirst("regexp:", ".*")
+ ".*";
if (!actual.matches(expectedRegEx)) {
System.out.println("expected " + actual + " to match regexp "
+ expectedPattern);
return false;
}
return true;
}
if (expectedPattern.startsWith("regex:")) {
String expectedRegEx = expectedPattern.replaceFirst("regex:", ".*")
+ ".*";
if (!actual.matches(expectedRegEx)) {
System.out.println("expected " + actual + " to match regex "
+ expectedPattern);
return false;
}
return true;
}
if (expectedPattern.startsWith("exact:")) {
String expectedExact = expectedPattern.replaceFirst("exact:", "");
if (!expectedExact.equals(actual)) {
System.out.println("expected " + actual + " to match "
+ expectedPattern);
return false;
}
return true;
}
String expectedGlob = expectedPattern.replaceFirst("glob:", "");
expectedGlob = expectedGlob.replaceAll(
"([\\]\\[\\\\{\\}$\\(\\)\\|\\^\\+.])", "\\\\$1");
expectedGlob = expectedGlob.replaceAll("\\*", ".*");
expectedGlob = expectedGlob.replaceAll("\\?", ".");
if (!Pattern.compile(expectedGlob, Pattern.DOTALL).matcher(actual)
.matches()) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("seleniumEquals: expected \"" + actual
+ "\" to match glob \"" + expectedPattern
+ "\" (had transformed the glob into regexp \""
+ expectedGlob + "\")");
}
return false;
}
return true;
}
/**
* Compares two objects, but handles "regexp:" strings like HTML Selenese
*
* @see #seleniumEquals(String, String)
* @return true if actual matches the expectedPattern, or false otherwise
*/
public boolean seleniumEquals(Object expected, Object actual) {
if (expected instanceof String && actual instanceof String) {
return seleniumEquals((String) expected, (String) actual);
}
return expected.equals(actual);
}
/** Asserts that two string arrays have identical string contents */
public void assertEquals(String[] s1, String[] s2) {
String comparisonDumpIfNotEqual = verifyEqualsAndReturnComparisonDumpIfNot(
s1, s2);
if (comparisonDumpIfNotEqual != null) {
throw new AssertionFailedError(comparisonDumpIfNotEqual);
}
}
/**
* Asserts that two string arrays have identical string contents (fails at
* the end of the test, during tearDown)
*/
public void verifyEquals(String[] s1, String[] s2) {
String comparisonDumpIfNotEqual = verifyEqualsAndReturnComparisonDumpIfNot(
s1, s2);
if (comparisonDumpIfNotEqual != null) {
if (verifyActAsAssert) {
throw new AssertionFailedError(comparisonDumpIfNotEqual);
} else {
logger.warning("Verify failed : " + comparisonDumpIfNotEqual);
addToVerificationErrors(new AssertionFailedError(
"Verify failed : " + comparisonDumpIfNotEqual));
}
}
}
private String verifyEqualsAndReturnComparisonDumpIfNot(String[] s1,
String[] s2) {
boolean misMatch = false;
if (s1.length != s2.length) {
misMatch = true;
}
for (int j = 0; j < s1.length; j++) {
if (!seleniumEquals(s1[j], s2[j])) {
misMatch = true;
break;
}
}
if (misMatch) {
return "Expected " + stringArrayToString(s1) + " but saw "
+ stringArrayToString(s2);
}
return null;
}
private String stringArrayToString(String[] sa) {
StringBuffer sb = new StringBuffer("{");
for (int j = 0; j < sa.length; j++) {
sb.append(" ").append("\"").append(sa[j]).append("\"");
}
sb.append(" }");
return sb.toString();
}
private String stringArrayToSimpleString(String[] sa) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < sa.length; j++) {
sb.append(sa[j]);
if (j < sa.length - 1) {
sb.append(',');
}
}
return sb.toString();
}
/** Like assertNotEquals, but fails at the end of the test (during tearDown) */
public void verifyNotEquals(Object s1, Object s2) {
try {
assertNotEquals(s1, s2);
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + s1.toString()
+ " is equal to " + s2.toString());
addToVerificationErrors(e);
}
}
}
/** Like assertNotEquals, but fails at the end of the test (during tearDown) */
public void verifyNotEquals(boolean s1, boolean s2) {
try {
assertNotEquals(new Boolean(s1), new Boolean(s2));
} catch (AssertionFailedError e) {
if (verifyActAsAssert) {
throw e;
} else {
logger.warning("Verify failed : " + e.getMessage());
addToVerificationErrors(e);
}
}
}
/** Asserts that two objects are not the same (compares using .equals()) */
public void assertNotEquals(Object obj1, Object obj2) {
if (obj1.equals(obj2)) {
Assert.fail("did not expect values to be equal (" + obj1.toString()
+ ")");
}
}
/** Asserts that two booleans are not the same */
public void assertNotEquals(boolean b1, boolean b2) {
assertNotEquals(new Boolean(b1), new Boolean(b2));
}
/** Sleeps for the specified number of milliseconds */
public void pause(int millisecs) {
try {
Thread.sleep(millisecs);
} catch (InterruptedException e) {/* ignored */
}
}
// **** A few helper methods... **** //
/**
* Returns a list of selected HtmlOption elements in the Select element
* located with selectLocator.
*/
private List getSelectedOptions(String selectLocator) {
HtmlSelect select = (HtmlSelect) getElement(selectLocator);
if (select == null)
throw new RuntimeException("Could not find