Package com.canoo.webtest.steps.control

Source Code of com.canoo.webtest.steps.control.RepeatStep

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

import java.util.List;
import java.util.ListIterator;

import javax.xml.namespace.QName;
import javax.xml.xpath.XPathException;

import org.apache.log4j.Logger;
import org.apache.tools.ant.Task;

import com.canoo.webtest.engine.StepExecutionException;
import com.canoo.webtest.engine.xpath.XPathHelper;

/**
* A RepeatStep accepts one or more nested step elements and executes
* them as many times as defined in the count attribute.
* <p/>
* Before it actually starts the execution of contained steps, the contained
* steps are "expanded", i.e. cloned so that each invocation has
* a dedicated step object. This is required since the step object serves
* also as history element for logging results and execution times.
* <p/>
* As soon as one of the nested steps fails, the RepeatStep fails as
* well (simply by propagating the TestStepFailed exception).
* <p/>
* It also updates a property #{count} with the current number of the
* current repetition which can be accessed as a dynamic property if desired.
*
*
* @author Carsten Seibert
* @webtest.step
*   category="Core"
*   name="repeat"
*   description="This step encapsulates one or more test steps that shall be repeated a certain number of times.
*   Any kind of step can be nested."
*/
public class RepeatStep extends MultipleExecutionStepContainer {
  private static final Logger LOG = Logger.getLogger(RepeatStep.class);
  private static final String DEFAULT_COUNTERNAME = "count";
  private Integer fCount;
  private int fStartCount;
    private Integer fEndCount;
    private int fStep = 1;
    private String fCounterName = DEFAULT_COUNTERNAME;
    private String fXpath;

    /**
     * @param count
     * @webtest.parameter
     *   required="yes/no"
     *   description="The number of times that the included steps shall be executed. Specify either count or endCount. Counter values start at <em>startCount</em> and go up to <em>startCount + count - 1</em>."
     */
    public void setCount(final Integer count) {
        fCount = count;
    }

    public Integer getCount() {
    return fCount;
  }

  /**
   * @param count
   * @webtest.parameter
   *   required="no"
     *   default="0"
     *   description="The initial value of the count. Doesn't affect the number of iterations, just the value appearing in the counter."
     */
    public void setStartCount(final int count) {
        fStartCount = count;
    }

  public int getStartCount() {
    return fStartCount;
  }

    /**
   * @param count
   * @webtest.parameter
   *   required="yes/no"
   *   description="The final value of the count.
   *   Specify either count or endCount.  Counter values start at <em>startCount</em> and go up to <em>endCount</em>."
   */
  public void setEndCount(final Integer count) {
        fEndCount = count;
  }

  public Integer getEndCount() {
    return fEndCount;
  }

    /**
   * @param step
   * @webtest.parameter
   *   required="no"
     *   default="1"
   *   description="The step size of the count.
   *   Doesn't affect the number of iterations, just the value appearing in the counter."
   */
  public void setStep(final int step) {
        fStep = step;
  }

  public int getStep() {
    return fStep;
  }

  /**
   * @param counterName
   * @webtest.parameter
   *   required="no"
   *   default="count"
   *   description="The name that shall be used to reference the current repetition counter."
   */
  public void setCounterName(final String counterName) {
    fCounterName = counterName;
  }

  public String getCounterName() {
    return fCounterName;
  }

    protected void verifyParameters() {
        super.verifyParameters();
        if (getStep() < 1) {
            throw new StepExecutionException("Step must be greater than or equal to 1!", this);
        }
        if (getCount() != null) {
            if (getCount().intValue() < 0) {
                throw new StepExecutionException("Repeat count must be greater than or equal to 0!", this);
            }
        }
        else if (getEndCount() != null) {
            if (getEndCount().intValue() < fStartCount) {
                throw new StepExecutionException("endCount ("+fEndCount+") must be greater than or equal to startCount (" + fStartCount + ")!", this);
            }
        }
        else if (getXpath() == null) {
            throw new StepExecutionException("You must specify a count, a endCount or a XPath attribute.", this);
        }
    }

  public void doExecute() throws XPathException
  {
    if (getXpath() != null)
      doExecuteWithXPath();
    else
    {
      final int first = getStartCount();
      final int last;
      if (getCount() != null)
        last = first + getCount().intValue();
      else
        last = getEndCount().intValue() + 1;
     
      for (int i=first; i<last; i+=getStep())
      {
              setWebtestProperty(getCounterName(), Integer.toString(i));
              executeContainedTasks(String.valueOf(i));
      }
    }
    // TODO: generate report for not executed steps too
  }
 
  protected List getNodesByXPath() throws XPathException
  {
    return getContext().getXPathHelper().selectNodes(getContext().getCurrentResponse(), getXpath());
  }

  protected void doExecuteWithXPath() throws XPathException
  {
    LOG.debug("repeat with xpath " + getXpath());
    final XPathHelper xpathHelper = getContext().getXPathHelper();
    final List nodes = getNodesByXPath();

    final int nbNodes = nodes.size();
    LOG.debug("Iterating over " + nbNodes + " nodes");
    for (final ListIterator iter = nodes.listIterator(); iter.hasNext();)
    {
      final Object node = iter.next();
      final String loopLabel = iter.nextIndex() + "/" + nbNodes;
      LOG.debug("Iteration " + loopLabel + ": placing current node >"
          + node + "< as >" + getCounterName() + "< in variable context");
      xpathHelper.getVariableContext().setVariableValue(new QName(getCounterName()), node);

      executeContainedTasks(loopLabel);
    }
  }

  protected void executeContainedTasks(final String loopLabel)
  {
        LOG.debug("creating wrapper for current iteration (" + getCounterName() + "): " + loopLabel);
    final Task iterationWrapper = createIterationWrapper("Iteration " + loopLabel);

    LOG.debug("execution wrapper for current iteration (" + getCounterName() + "): " + loopLabel);
    iterationWrapper.perform();
  }

  public String getXpath() {
    return fXpath;
  }

  /**
   * @webtest.parameter
   *   required="yes/no"
   *  description="Specifies the <key>XPATH</key> expression which evaluation gives the results on which to iterate"
   */
  public void setXpath(final String xpath)
  {
    fXpath = xpath;
  }

}
TOP

Related Classes of com.canoo.webtest.steps.control.RepeatStep

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.