Package com.canoo.webtest.extension

Source Code of com.canoo.webtest.extension.ScriptStep

// Copyright � 2004-2005 ASERT. Released under the Canoo Webtest license.
package com.canoo.webtest.extension;

import java.io.File;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import com.canoo.webtest.boundary.ResetScriptRunner;
import com.canoo.webtest.engine.Context;
import com.canoo.webtest.engine.StepExecutionException;
import com.canoo.webtest.engine.StepFailedException;
import com.canoo.webtest.steps.Step;
import com.canoo.webtest.util.ConversionUtil;
import com.canoo.webtest.util.FileUtil;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.xml.XmlPage;

/**
* Wrapper class for the ant script command.<p>
*
* @author Paul King
* @webtest.step
*    category="Extension"
*    name="scriptStep"
*    description="Provides the ability to use scripting code in your tests."
*/
public class ScriptStep extends Step {
  private static final Logger LOG = Logger.getLogger(ScriptStep.class);
  private String fLanguage;
    private String fKeep;
  private File fSrc;
  private String fScriptText = "";

  /**
   * Perform the step's actual work.
   *
   * @throws Exception if a problem occurred
   */
  public void doExecute() throws Exception {
        final ResetScriptRunner runner; // delegate pattern
        final Context context = getContext();
        if (context.getRunner() == null) {
            runner = new ResetScriptRunner();
            runner.setLanguage(getLanguage());
            context.setRunner(runner);
            LOG.debug("Creating new Script Runner with language: " + fLanguage);
        }
        else {
            runner = context.getRunner();
            runner.reset();
        }
    buildScript();
    getProject().addReference("step", this);
    if (context.getCurrentResponse() == null) {
      LOG.warn("No response found. Previous invoke missing? Related scripting variables not created");
    }
    else {
      setupResponseScriptingVariables(context);
    }

    try {
      executeByRunner(runner, getProject().replaceProperties(fScriptText), this, getProject());
            // languages like groovy can throw assert errors which are useful to fail test
            // but what about an assert in groovy's implementation that has failed - this should
            // probably be configurable to potentially throw StepExecutionError
        } catch (AssertionError ae) {
            final String msg = "Assertion error during scriptStep: " + ae.getMessage();
            LOG.debug(msg, ae);
            throw new StepFailedException(msg, this);
        } catch (BuildException be) {
            LOG.debug(be.getMessage(), be);
            throw new StepExecutionException("Error invoking script: " + be.getMessage(), this);
    } finally {
            if (!isKeep()) {
                context.setRunner(null);
            }
        }
  }

    public static String evalScriptExpression(final Context context, final String expression, final Step step) {
        final ResetScriptRunner runner = context.getRunner();
        if (runner == null) {
            throw new StepExecutionException("Can't evaluate script property because no previous <scriptStep> with keep=true.", step);
        }
        runner.reset();
        try {
            return evalByRunner(runner, expression, step);
        } catch (BuildException be) {
            throw new StepExecutionException("Error invoking script: " + be.getMessage(), step);
        }
    }

    public static void executeByRunner(final ResetScriptRunner runner, final String script, final Step step, final Project project) throws BuildException {
        runner.addText(script);
        runner.addBeans(project.getProperties());
        runner.addBeans(project.getUserProperties());
        runner.addBeans(project.getTargets());
        runner.addBeans(project.getReferences());
        runner.addBean("project", project);
        runner.addBean("self", step);
        runner.executeScript("WebTest");
    }

    public static String evalByRunner(final ResetScriptRunner runner, final String script, final Step step) throws BuildException {
        runner.addText(script);
        runner.addBean("self", step);
        return runner.evalScript("WebTest");
    }

    private void buildScript() {
    if (fSrc != null) {
      fScriptText += FileUtil.readFileToString(fSrc, this);
    }
  }

  private void setupResponseScriptingVariables(final Context context) {
    getProject().addReference("response", context.getCurrentResponse().getWebResponse());
    if (context.getCurrentResponse() instanceof HtmlPage) {
      getProject().addReference("document", ((HtmlPage) context.getCurrentResponse()).getDocumentElement());
    } else if (context.getCurrentResponse() instanceof XmlPage) {
      getProject().addReference("document", ((XmlPage) context.getCurrentResponse()).getXmlDocument());
    }
  }

  /**
   * Verify that language is set
   *
   * @throws StepExecutionException if a mandatory attribute is not set
   */
  protected void verifyParameters() {
    super.verifyParameters();
        final ResetScriptRunner runner = getContext().getRunner();
        if (runner == null) {
            emptyParamCheck(fLanguage, "language");
        } else {
            paramCheck(fLanguage != null && !fLanguage.equals(runner.getLanguage()),
                    "You may not change 'language' to '" + fLanguage +
                    "' after previously using the 'keep' attribute (was: " + runner.getLanguage() + ")");
        }
    paramCheck(fSrc == null && StringUtils.isEmpty(fScriptText),
       "Either \"src\" attribute or nested script text must be given.");
  }

  /**
   * override to add actual attribute values to the reporting
   */
  protected void addComputedParameters(final Map map) {
    map.put("language", fLanguage); // cannot be null (mandatory)
    if (fSrc == null) {
      map.put("script", fScriptText);
    } else {
      map.put("src", fSrc); // (optional)
    }
  }

  /**
   * Defines the language (required).
   *
   * @param language Sets the scripting language.
   * @webtest.parameter
   *    required="yes/no"
   *   description="The scripting language to use. Required unless using the <em>keep</em> attribute in which case the value is optional but must agree with the original language if used. The value can be any language supported by the <key>BSF</key>, e.g. javascript, jacl, netrexx, java, javaclass, bml, vbscript, jscript, perlscript, perl, jpython, jython, lotusscript, xslt, pnuts, beanbasic, beanshell, ruby, judoscript, groovy."
   */
  public void setLanguage(final String language) {
    fLanguage = language;
  }

  public String getLanguage() {
    return fLanguage;
  }

  /**
   * Defines the src file containing scripting code (optional).
   *
   * @param fileName Sets the name of the file containing script code.
   * @webtest.parameter
   *   required="yes/no"
   *  description="The name of the file containing the scripting code. You may omit this parameter if you have embedded script code."
   */
  public void setSrc(final File fileName) {
    fSrc = fileName;
  }

  public File getSrc() {
    return fSrc;
  }

    /**
     * Flag to indicate that the scripting engine should be kept after the step completes and re-used for future script steps.
     *
     * @param keep Indicates that the script engine should be kept for future steps.
     * @webtest.parameter
     *    required="no"
     *   default="false"
     *   description="Indicates that the script engine should be kept for future steps. Variables created during one script step will remain available."
     */
    public void setKeep(final String keep) {
        fKeep = keep;
    }

    public String getKeep() {
        return fKeep;
    }

    public boolean isKeep() {
        return ConversionUtil.convertToBoolean(fKeep, false);
    }

  /**
   * The script text if inlined.
   *
   * @param text The nested scripting code.
     * @webtest.nested.parameter
     *    required="yes/no"
     *    description="The nested script code. You may omit this if you use the parameter src."
     */
  public void addText(final String text) {
    fScriptText += text;
  }

}
TOP

Related Classes of com.canoo.webtest.extension.ScriptStep

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.