HtmlUnitHelper.java from Jameleon at Krugle
Show HtmlUnitHelper.java syntax highlighted
/*
Jameleon HtmlUnit plug-in - A plug-in that uses HtmlUnit to drive web sites
Copyright (C) 2006 Christian W. Hargraves (engrean@hotmail.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111AssertLevel.NO_FUNCTION07 USA
*/
package net.sf.jameleon.plugin.htmlunit.util;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import net.sf.jameleon.util.JameleonUtility;
import org.jaxen.JaxenException;
import org.jaxen.Navigator;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.ClickableElement;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
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.gargoylesoftware.htmlunit.html.HtmlTextArea;
import com.gargoylesoftware.htmlunit.html.xpath.HtmlUnitXPath;
/**
* This class is used as a facade around the HtmlUnit API and is used by both
* the HtmlUnitSessionTag and the HtmlUnitFunctionTag.
*/
public class HtmlUnitHelper {
protected HtmlUnitDelegate delegate;
public HtmlUnitHelper(HtmlUnitDelegate delegate) {
this.delegate = delegate;
}
/**
* Clicks on an HtmlElement (ClickableElement) defined by the provided XPath expression
* @param xpath - The XPath expression to locate the element to click on.
*/
public void clickElementWithXPath(String xpath) {
HtmlElement element = getHtmlElementByXPath(xpath);
if ( element != null && element instanceof ClickableElement ) {
try {
((ClickableElement)element).click();
} catch ( IOException ioe ) {
throw new RuntimeException(ioe.getMessage(), ioe);
}
} else {
String errMsg;
if ( element == null ) {
errMsg = "No element found to click on that matches the given XPath '"+xpath+"'";
} else {
errMsg = "The element returned ("+element.getTagName()+") can not be clicked on";
}
throw new RuntimeException(errMsg);
}
}
/**
* Gets the HtmlUnitDelegate that this object uses to communicate with the
* existing session.
*
* @return The HtmlUnitDelegate that this object uses to communicate with the
* existing session.
*/
public HtmlUnitDelegate getDelegate() {
return delegate;
}
/**
* Gets the current page in the currently active WebWindow
*
* @return The current page in the currently active WebWindow
*/
public Page getCurrentPage() {
Page page = null;
WebWindow window = delegate.getCurrentWebWindow();
if ( window != null ) {
page = window.getEnclosedPage();
}
return page;
}
/**
* Gets the HTML source from the currently active window
*
* @return The HTML source used in the current window
*/
public String getCurrentPageContent() {
String content = null;
WebResponse res = getCurrentWebResponse();
if ( res != null ) {
content = res.getContentAsString();
}
return content;
}
/**
* Gets the currnet WebResponse
*
* @return The current WebResponse
*/
public WebResponse getCurrentWebResponse() {
WebResponse res = null;
Page page = getCurrentPage();
if ( page != null ) {
res = page.getWebResponse();
}
return res;
}
/**
* Gets an HtmlElement matching the provided xpath expression
* @param xpath - An XPath expression that matches the desired HtmlElement
*
* @return The matching HtmlElement
*/
public HtmlElement getHtmlElementByXPath(String xpath) {
HtmlElement element = null;
if ( xpath != null ) {
element = getHtmlElementByXPath((HtmlPage)getCurrentPage(), xpath);
} else {
throw new RuntimeException("xpath was null! Supply an xpath expression.");
}
return element;
}
/**
* Gets an HtmlElement matching the provided xpath expression
* @param container - The DOM to start at
* @param xpath - An XPath expression that matches the desired HtmlElement
*
* @return The matching HtmlElement
*/
public HtmlElement getHtmlElementByXPath(DomNode container, String xpath) {
HtmlElement element = null;
if ( xpath != null && container != null ) {
Navigator nav = HtmlUnitXPath.buildSubtreeNavigator(container);
try {
HtmlUnitXPath xp = new HtmlUnitXPath(xpath, nav);
element = (HtmlElement)xp.selectSingleNode(getCurrentPage());
} catch ( JaxenException je ) {
throw new RuntimeException("Problem processing XPath '"+xpath+"'", je);
}
} else {
throw new RuntimeException("Neither xpath nor container can be null! Supply an xpath expression and the container to execute it in.");
}
return element;
}
/**
* Gets an HTMLElement by the tag name, attribute name and the attribute value.
* This then in turn gets translated to an XPath expression.
* An example of this might be to get a form with its id='ten'.
* @param tagname - The name of the tag to get back. In the above example, the value would be 'form'
* @param attributeName - The name of attribute to check against. In the above example, the value would be 'id'
* @param attributeValue - The value of the attribute to check against. In the above example, the value would be 'ten'
*
* @return HtmlElement - An element that matches the criteria.
*/
public HtmlElement getHtmlElementByAttributeNameAndValue(String tagname, String attributeName, String attributeValue) {
HtmlElement element = null;
if ( tagname != null && attributeName != null && attributeValue != null ) {
String xpath = "//"+tagname+"[@"+attributeName+"='"+attributeValue+"']";
element = getHtmlElementByXPath(xpath);
} else {
throw new RuntimeException("The 'tagname', 'attributeName' and 'attributeValue' parameters must all be set!");
}
return element;
}
/**
* Gets a form element back by its id attribute.
* @param id - the value of the id attribute.
*
* @return HtmlForm
*/
public HtmlForm getHtmlFormById(String id) {
HtmlForm form = null;
if ( id != null ) {
HtmlPage page = (HtmlPage)getCurrentPage();
HtmlElement elmnt = null;
try {
elmnt = page.getHtmlElementById(id);
if ( elmnt instanceof HtmlForm ) {
form = (HtmlForm) elmnt;
}
} catch ( ElementNotFoundException enfe ) {
//Do nothing. We will instead return null
}
} else {
throw new RuntimeException("The 'id' parameter was null!");
}
return form;
}
/**
* Gets a form element back by its index or location on the page.
* For the first form on the page, pass in '1'
* @param index - the nth form on the page
*
* @return HtmlForm
*/
public HtmlForm getHtmlFormByIndex(int index) {
return(HtmlForm)getHtmlElementByXPath("//form["+index+"]");
}
/**
* Gets a form element back by its name attribute.
* @param formName - the value of the name attribute.
*
* @return HtmlForm
*/
public HtmlForm getHtmlFormByName(String formName) {
HtmlForm form = null;
if ( formName != null ) {
HtmlPage page = (HtmlPage)getCurrentPage();
try {
form = page.getFormByName(formName);
} catch ( ElementNotFoundException enfe ) {
//Do nothing here. We will return null instead of throwing an exception
}
} else {
throw new RuntimeException("The 'formName' parameter was null!");
}
return form;
}
/**
* Gets a form element back by an XPath expression
* @param xpath - The XPath expression matching the desired form
*
* @return HtmlForm
*/
public HtmlForm getHtmlFormByXPath(String xpath) {
HtmlForm form = null;
HtmlElement e = getHtmlElementByXPath(xpath);
if ( e instanceof HtmlForm ) {
form = (HtmlForm) e;
}
return form;
}
/**
* Gets an HtmlInput tag based on the current workingForm or the currently active page if the workingForm is not set.
* @param fieldName - The name of the input field
*
* @return HtmlForm
*/
public HtmlInput getHtmlInputByName(String fieldName) {
HtmlInput input = null;
HtmlForm form = delegate.getWorkingForm();
if ( form != null ) {
input = form.getInputByName(fieldName);
} else {
HtmlElement element = getHtmlElementByXPath("//input[@name='"+fieldName+"']");
if ( element != null && element instanceof HtmlInput ) {
input = (HtmlInput)element;
}
}
return input;
}
/**
* Gets an HtmlInput tag based on the current workingForm or the currently active page if the workingForm is not set.
* @param fieldName - The name of the input field
* @param fieldValue - The value of the input field
*
* @return HtmlForm
*/
public HtmlInput getHtmlInputByNameAndValue(String fieldName, String fieldValue) {
HtmlInput input = null;
HtmlForm form = delegate.getWorkingForm();
String xpath = "//input[@name='"+fieldName+"' and @value='"+fieldValue+"']";
if ( form != null ) {
input = (HtmlInput) getHtmlElementByXPath(form, xpath);
} else {
input = (HtmlInput) getHtmlElementByXPath(xpath);
}
return input;
}
/**
* Navigates to the provided URL
* @param url - the url to navigate to.
*/
public void navigate(String url) {
try {
WebClient client = delegate.getWebClient();
URL u = new URL(url);
client.getPage(u);
} catch ( MalformedURLException mfue ) {
throw new RuntimeException("The provided url '"+url+"' is not valid.", mfue);
} catch ( IOException ioe ) {
throw new RuntimeException("Could not coneect to '"+url+"'.", ioe);
}
}
/**
* Checks or unchecks the checkbox that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param checked - set to <code>true</code> to check the checkbox and to <code>false</code> to uncheck it
*/
public void setCheckBox(String fieldName, boolean checked) {
HtmlInput input = getHtmlInputByName(fieldName);
if ( input != null ) {
if ( input instanceof HtmlCheckBoxInput ) {
((HtmlCheckBoxInput)input).setChecked(checked);
} else {
throw new RuntimeException("expected checkbox, but was a '"+input.getTypeAttribute()+"' field!");
}
} else {
throw new RuntimeException("No checkbox named '"+fieldName+"' was found!");
}
}
/**
* Checks or unchecks the checkbox that either exists in the workingForm or in the current page.
* This method is used for pages that contain several checkboxes with the same name, but different values
* @param fieldName - The name of the checkbox to check
* @param fieldValue - The value of the input field to check
* @param checked - set to <code>true</code> to check the checkbox and to <code>false</code> to uncheck it
*/
public void setCheckBox(String fieldName, String fieldValue, boolean checked) {
HtmlInput input = getHtmlInputByNameAndValue(fieldName, fieldValue);
if ( input != null ) {
if ( input instanceof HtmlCheckBoxInput ) {
((HtmlCheckBoxInput)input).setChecked(checked);
} else {
throw new RuntimeException("expected checkbox, but was a '"+input.getTypeAttribute()+"' field!");
}
} else {
throw new RuntimeException("No checkbox named '"+fieldName+"' with the value '"+fieldValue+"' was found!");
}
}
/**
* Sets the file field that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param value - The value to set the input field to
*/
public void setFileField(String fieldName, String value) {
HtmlInput input = getHtmlInputByName(fieldName);
setHtmlInputValue(input, value, "file");
}
/**
* Sets the hidden field that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param value - The value to set the input field to
*/
public void setHiddenField(String fieldName, String value) {
HtmlInput input = getHtmlInputByName(fieldName);
setHtmlInputValue(input, value, "hidden");
}
/**
* Sets the password field that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param value - The value to set the input field to
*/
public void setPasswordField(String fieldName, String value) {
HtmlInput input = getHtmlInputByName(fieldName);
setHtmlInputValue(input, value, "password");
}
/**
* Checks or unchecks the radio button that either exists in the workingForm or in the current page.
* @param fieldName - The name of the radio button to check
* @param fieldValue - The value of the radio button to check
* @param checked - set to <code>true</code> to check the radio button and to <code>false</code> to uncheck it
*/
public void setRadioButton(String fieldName, String fieldValue, boolean checked) {
HtmlInput input = getHtmlInputByNameAndValue(fieldName, fieldValue);
if ( input != null ) {
if ( input instanceof HtmlRadioButtonInput ) {
((HtmlRadioButtonInput)input).setChecked(checked);
} else {
throw new RuntimeException("expected radio, but was a '"+input.getTypeAttribute()+"' field!");
}
} else {
throw new RuntimeException("No radio button named '"+fieldName+"' with the value '"+fieldValue+"' was found!");
}
}
/**
* Selects or unselects the option by its index order that either exists in the workingForm or in the current page.
* @param fieldName - The name of the select field to select
* @param index - The nth option in the list. 1st option = 1
* @param selected - set to <code>true</code> to select and to <code>false</code> to unselect it
*/
public void setSelectFieldByIndex(String fieldName, int index, boolean selected) {
HtmlOption option = null;
HtmlForm form = delegate.getWorkingForm();
String xpath = "//select[@name='"+fieldName+"']/option["+index+"]";
HtmlElement element = null;
if ( form != null ) {
element = getHtmlElementByXPath(form, xpath);
} else {
element = getHtmlElementByXPath(xpath);
}
if ( element != null && element instanceof HtmlOption ) {
option = (HtmlOption)element;
option.setSelected(selected);
} else {
throw new RuntimeException("select field with the name '"+fieldName+"' and option was not found!");
}
}
/**
* Selects or unselects the option with the displayed text that either exists in the workingForm or in the current page.
* @param fieldName - The name of the select field to select
* @param optionText - The text displayed in the drop-down
* @param selected - set to <code>true</code> to select and to <code>false</code> to unselect it
*/
public void setSelectFieldByOptionText(String fieldName, String optionText, boolean selected) {
HtmlOption option = null;
HtmlForm form = delegate.getWorkingForm();
String xpath = "//select[@name='"+fieldName+"']/option[text()='"+optionText+"']";
HtmlElement element = null;
if ( form != null ) {
element = getHtmlElementByXPath(form, xpath);
} else {
element = getHtmlElementByXPath(xpath);
}
if ( element != null && element instanceof HtmlOption ) {
option = (HtmlOption)element;
option.setSelected(selected);
} else {
throw new RuntimeException("select field with the name '"+fieldName+"' was not found!");
}
}
/**
* Selects or unselects the option with the given attribute value that either exists in the workingForm or in the current page.
* @param fieldName - The name of the select field to select
* @param valueAttribute - The value of option field to select
* @param selected - set to <code>true</code> to select and to <code>false</code> to unselect it
*/
public void setSelectFieldByValue(String fieldName, String valueAttribute, boolean selected) {
HtmlSelect select = null;
HtmlForm form = delegate.getWorkingForm();
if ( form != null ) {
select = form.getSelectByName(fieldName);
} else {
HtmlElement element = getHtmlElementByXPath("//select[@name='"+fieldName+"']");
if ( element != null && element instanceof HtmlSelect ) {
select = (HtmlSelect)element;
}
}
if ( select != null ) {
select.setSelectedAttribute(valueAttribute, selected);
} else {
throw new RuntimeException("select field with the name '"+fieldName+"' was not found!");
}
}
/**
* Selects or unselects the option defined by XPath.
* @param xpath - The XPath expression that matches an HtmlOption (not a select) to be selected
* @param selected - set to <code>true</code> to select and to <code>false</code> to unselect it
*/
public void setSelectFieldByXPath(String xpath, boolean selected) {
HtmlOption option = null;
HtmlElement element = null;
element = getHtmlElementByXPath(xpath);
if ( element != null && element instanceof HtmlOption ) {
option = (HtmlOption)element;
option.setSelected(selected);
} else {
throw new RuntimeException("select field defined by '"+xpath+"' was not found!");
}
}
/**
* Sets the text area that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param value - The value to set the input field to
*/
public void setTextArea(String fieldName, String value) {
HtmlTextArea textArea = null;
HtmlForm form = delegate.getWorkingForm();
if ( form != null ) {
List textAreas = form.getTextAreasByName(fieldName);
if ( textAreas.size() > 0 ) {
textArea = (HtmlTextArea)textAreas.get(0);
}
} else {
HtmlElement element = getHtmlElementByXPath("//textarea[@name='"+fieldName+"']");
if ( element != null && element instanceof HtmlTextArea ) {
textArea = (HtmlTextArea)element;
}
}
if ( textArea != null ) {
textArea.setText(value);
} else {
throw new RuntimeException("textarea with the name '"+fieldName+"' was not found!");
}
}
/**
* Sets the text field that either exists in the workingForm or in the current page
* @param fieldName - The name of the input field to set the value of
* @param value - The value to set the input field to
*/
public void setTextField(String fieldName, String value) {
HtmlInput input = getHtmlInputByName(fieldName);
setHtmlInputValue(input, value, "text");
}
/**
* Sets an input field type's value
* @param input - The HtmlInput to set the value on
* @param value - The value to set the input element to.
* @param type - The input type. If this does not match the given field, then this method will fail
*/
public void setHtmlInputValue(HtmlInput input, String value, String type) {
if ( input != null ) {
String elementType = input.getAttributeValue("type");
if ( type.equalsIgnoreCase(elementType) ) {
input.setValueAttribute(value);
} else {
throw new RuntimeException("input field defined '"+input.getTagName()+"' of type '"+elementType+"' was not expected '"+type+"'!");
}
} else {
throw new RuntimeException("input field was null!");
}
}
/**
* Sets an input field type's value
* @param xpath - An XPath expression that matches the desired HtmlInput Element.
* @param value - The value to set the input element to.
* @param type - The input type. If this does not match the given field, then this method will fail
*/
public void setHtmlInputValueByXPath(String xpath, String value, String type) {
HtmlElement element = getHtmlElementByXPath(xpath);
if ( element != null && element instanceof HtmlInput ) {
HtmlInput input = (HtmlInput) element;
setHtmlInputValue(input, value, type);
} else {
throw new RuntimeException("Could not find the input element defined by '"+xpath+"'");
}
}
/**
* Store the contents of the currently active window
* @param fName - The name of the file to store the source to.
*/
public File store(String fName) throws IOException{
WebResponse res = getCurrentWebResponse();
File stateFile = null;
if ( res != null ) {
String html = res.getContentAsString();
String charset = res.getContentCharSet();
String filename = fName+".html";
if ( html != null && html.length() > 0 ) {
stateFile = new File(filename);
if ( charset != null && charset.length() > 0 ) {
JameleonUtility.recordResultsToFile(stateFile, html, charset);
} else {
JameleonUtility.recordResultsToFile(stateFile, html);
}
}
}
return stateFile;
}
/**
* Checks that the the provided XPath expression matches something on the current page.
* @param xpath - The XPath expression to evaulate
*
* @return boolean - true if the XPath expresssion matches
*/
public boolean xPathMatches(String xpath) {
boolean matches = (getHtmlElementByXPath(xpath) != null);
return matches;
}
}
See more files for this project here