Package com.canoo.webtest.steps.request

Source Code of com.canoo.webtest.steps.request.ClickLink

// Copyright � 2002-2007 Canoo Engineering AG, Switzerland.
package com.canoo.webtest.steps.request;

import com.canoo.webtest.engine.StepFailedException;
import com.canoo.webtest.util.HtmlConstants;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.html.ClickableElement;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.xml.xpath.XPathException;

/**
* Clicks a link determined by its id or its label and/or its href.
*
* @author Mister Unknown
* @author Marc Guillemot
* @author Matt Raible
* @author Paul King
* @author Denis N. Antonioli
* @webtest.step category="Core"
* name="clickLink"
* alias="clicklink"
* description="This step tries to locate a link (like <a href='thisIsAnotherPage.html'>Follow me</a>) and to click on it. The page where this click leads to will be the current one for further actions."
*/
public class ClickLink extends AbstractIdOrLabelTarget {
  private static final Logger LOG = Logger.getLogger(ClickLink.class);
  private String fHref;

  public String getHref() {
    return fHref;
  }

  /**
   * @webtest.parameter required="yes/no"
   * description="A substring of the <key>HTML</key> anchor tag's HREF attribute for the link of interest. Useful if (part of the <em>href</em>) uniquely identifies a link (for example, a unique parameter/value pair in the <em>href</em>). Also, useful for distinguisking between links with the same labels (in which case, use <em>label</em> and <em>href</em> combined). Either <em>label</em>, <em>href</em> or <em>htmlId</em> is required. Href has the lowest precedence."
   */
  public void setHref(final String href) {
    fHref = href;
  }

  protected Page findTarget() throws XPathException, IOException {
    final HtmlPage currentResp = getContext().getCurrentHtmlResponse(this);
    final HtmlAnchor link = (HtmlAnchor) findClickableElement(currentResp);

    if (link == null)
    {
      final StepFailedException e = new StepFailedException("Link not found in page " + currentResp.getWebResponse().getRequestUrl(), this);

      final StringBuffer sb = new StringBuffer();
      for (final Iterator iter = currentResp.getAnchors().iterator(); iter.hasNext();) {
        final HtmlAnchor webLink = (HtmlAnchor) iter.next();

        sb.append("- label \"").append(webLink.asText());
        sb.append("\" with url \"").append(webLink.getHrefAttribute());
        sb.append("\" and id \"").append(webLink.getIdAttribute());
        sb.append("\"\n");
      }
      e.addDetail("available links", sb.toString());
      throw e;
    }
    LOG.debug("Clicking on link with href: " + link.getHrefAttribute());

    return link.click();
  }

  protected String getLogMessageForTarget() {
    return "by clickLink";
  }

  protected void verifyParameters() {
    super.verifyParameters();
    nullResponseCheck();

    int count = 0;
    if (getXpath() != null) {
      count++;
    }
    if (getHtmlId() != null) {
      count++;
    }
    if (getHref() != null || getLabel() != null) {
      count++;
    }
    paramCheck(count == 0, "\"htmlId\" or \"xpath\" or \"label\" or \"href\" must be set!");
    paramCheck(count > 1, "\"htmlId\", \"xpath\" and \"label\" or \"href\" can't be combined!");
  }

  /**
   * get the link corresponding to the indications defined in the class
   *
   * @param page
   * @return <code>null</code> if no link found
   * @deprecated Use {@link #findClickableElement(com.gargoylesoftware.htmlunit.html.HtmlPage)} .
   */
  protected HtmlAnchor locateWebLink(final HtmlPage page) throws XPathException {
    return (HtmlAnchor) findClickableElement(page);
  }

  protected ClickableElement findClickableElementByAttribute(HtmlPage page) {
    HtmlAnchor link = locateTextLink(page);
    if (link != null) {
      return link;
    }
    return getLinkWithImageText(page, getLabel());
  }


  /**
   * Returns the first link which contains an image with the specified text as its 'alt' attribute.
   *
   * @param htmlPage
   * @param text
   * @return <code>null</code> if none found
   */
  protected static HtmlAnchor getLinkWithImageText(final HtmlPage htmlPage, final String text) {
    final List li = htmlPage.getDocumentElement().getElementsByAttribute(HtmlConstants.IMG, HtmlConstants.ALT, text);

    LOG.debug("Found " + li.size() + " images with alt=\"" + text + "\"");

    // looking for the first enclosing link
    for (final Iterator iter = li.iterator(); iter.hasNext();) {
      final HtmlElement elt = (HtmlElement) iter.next();
      final HtmlAnchor link = (HtmlAnchor) findParent("a", elt);
      if (link != null) {
        return link;
      }
    }
    return null;
  }

  /**
   * Finds the first parent element with the given tag name
   *
   * @param tagName
   * @param elt
   * @return <code>null</code> if none found
   */
  private static HtmlElement findParent(final String tagName, final HtmlElement elt) {
    HtmlElement parent = (HtmlElement) elt.getParentNode();

    while (parent != null) {
      if (tagName.equals(parent.getTagName())) {
        return parent;
      }
      final Object o = parent.getParentNode();
      parent = o instanceof HtmlElement ? (HtmlElement) o : null;
    }
    return null;
  }

  /**
   * @return null if not found
   */
  protected HtmlAnchor locateTextLink(final HtmlPage currentResponse) {
    for (final Iterator iter = currentResponse.getAnchors().iterator(); iter.hasNext();) {
      final HtmlAnchor curLink = (HtmlAnchor) iter.next();

      if (isMatching(curLink)) {
        return curLink;
      }
    }
    return null;
  }

  protected boolean isMatching(final HtmlAnchor link) {
    boolean bRep = true;

    if (getLabel() != null) {
      bRep = link.asText().indexOf(getLabel()) >= 0;
    }

    LOG.debug("labelFound = " + bRep + " in " + link.asText());
    if (getHref() == null) {
      return bRep;
    }

    boolean bHrefFound = link.getHrefAttribute().indexOf(getHref()) >= 0;
    LOG.debug("hrefFound = " + bHrefFound + " in " + link.getHrefAttribute());
    return bRep && bHrefFound;
  }

  ClickableElement checkFoundElement(HtmlElement eltthrows StepFailedException {
    if (elt instanceof HtmlAnchor) {
      return (ClickableElement) elt;
    }
    throw new StepFailedException("Selected element is a " + elt.getTagName() + " tag and not a link", this);
  }


    /**
     * Called by Ant to set the text nested between opening and closing tags.
     * @param text the text to set
     * @webtest.nested.parameter
     *    required="no"
     *    description="Alternative way to set the 'label' attribute."
     */
    public void addText(final String text) {
     setLabel(getProject().replaceProperties(text));
   }
}
TOP

Related Classes of com.canoo.webtest.steps.request.ClickLink

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.