// Copyright � 2002-2005 Canoo Engineering AG, Switzerland. package com.canoo.webtest.steps.request; import java.io.IOException; import org.apache.log4j.Logger; import com.canoo.webtest.engine.StepFailedException; import com.canoo.webtest.extension.StoreElementAttribute; import com.gargoylesoftware.htmlunit.Page; import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; /** * Clicks an html element determined by its id or xpath.<p> * * @author Marc Guillemot * @author Paul King * @webtest.step category="Extension" * name="clickElement" * alias="click" * description="Clicks an <key>HTML</key> element identified by its <em>id</em> or <em>xpath</em>. If the click triggers the load of a new page, then this page becomes the current one." */ public class ClickElement extends AbstractTargetAction { private static final Logger LOG = Logger.getLogger(ClickElement.class); private String fHtmlId; private String fXPath; public String getHtmlId() { return fHtmlId; } /** * Sets the id attribute of the element to click.<p> * * @param str the new value * @webtest.parameter required="yes/no" * description="The id of the html element to click on. One of <em>htmlId</em> or <em>xPath</em> must be set." */ public void setHtmlId(final String str) { fHtmlId = str; } public String getXpath() { return fXPath; } /** * Sets the XPath used to identify the element to click.<p> * * @param path the new value * @webtest.parameter required="yes/no" * description="The XPath identifying the html element to click on. One of <em>htmlId</em> or <em>xPath</em> must be set." */ public void setXpath(final String path) { fXPath = path; } protected void verifyParameters() { super.verifyParameters(); nullResponseCheck(); paramCheck(getHtmlId() == null && getXpath() == null, "\"htmlId\" or \"xPath\" must be set!"); paramCheck(getHtmlId() != null && getXpath() != null, "Only one from \"htmlId\" and \"xPath\" can be set!"); } protected Page findTarget() throws IOException { return findElement().click(); } protected HtmlElement findElement() { final HtmlPage currentResp = getContext().getCurrentHtmlResponse(this); final HtmlElement element = StoreElementAttribute.findElement(currentResp, getHtmlId(), getXpath(), LOG, this); // does this check make sense? This is a replacement of a check for deprecated HtmlUnit class ClickableElement if ("head".equals(element.getParentNode().getNodeName())) { throw new StepFailedException("Element is not clickable (" + element + ")", this); } // check that element is displayed if needed if (getContext().getConfig().isRespectVisibility() && !element.isDisplayed()) { throw new StepFailedException("Element is not displayed and can't be clicked (" + element + ")"); } return element; } protected String getLogMessageForTarget() { return "by clickElement with " + ((getXpath() == null) ? "id: " + getHtmlId() : "xpath: " + getXpath()); } }