Are you tired of writing tests which have a lot of boilerplate code? If so, get started with Spock Framework >>

Adding Input and Output Parameters to TestProject Actions

When we use TestProject addons in a real software project, the odds are that we want to write actions which have input and output parameters. This blog post helps us to solve that problem.

After we have finished this blog post, we:

  • Know how we can add input and output parameters to TestProject actions.
  • Understand how we can write a TestProject action that has input parameters.
  • Can write a TestProject action that has output parameters.

Let’s start by finding out how we can add input and output parameters to TestProject actions.

This blog post is the sixth part of my TestProject tutorial that is sponsored by TestProject.io. However, the views and opinions expressed in this tutorial are mine.

This blog post assumes that:

By the way, you might want to read the other parts of my TestProject tutorial.

Adding Input and Output Parameters to a TestProject Action

When we want to add an input or an output parameter to a TestProject action, we have to follow these steps:

First, we have to add a private field to our action class. This field contains the value of our input or output parameter.

When we specify the type of the parameter field, we must use either primitive types or primitive wrapper classes.

Second, we have to annotate our field with the @Parameter annotation. This annotation has three attributes which allow us to configure our parameter. These attributes are:

  • The description attribute contains the description of our parameter.
  • The direction attribute specifies the direction of our parameter. If we want to create an input parameter, the value of this attribute must be: ParameterDirection.INPUT. This is also the default value of this attribute. On the other hand, if we want to create an output parameter, the value of this attribute must be: ParameterDirection.OUTPUT.
  • The defaultValue attribute contains the default value of our parameter.
We should always specify the description of our input parameter by using the description attribute because this description is shown on the app.testproject.io website when we run tests which use our action. If we use a human-friendly description, our tests are easier to run. However, if we don’t specify the description of our parameter, the app.testproject.io website will use the field name of the parameter field.

Next, we will take a look at two examples that demonstrate how we can add an input and an output parameter to an action class.

Example 1:

After we have added an input parameter to our action class, its source code looks as follows:

import io.testproject.java.annotations.v2.Action;
import io.testproject.java.annotations.v2.Parameter;
import io.testproject.java.sdk.v2.addons.WebAction;

@Action(name = "This action has a parameter")
public class ParameterAction implements WebAction {

    @Parameter(description = "Contains the value of our input parameter",
            defaultValue = "Hello Action!"
    )
    private String inputParameter;
}

Example 2:

After we have added an output parameter to our action class, its source code looks as follows:

import io.testproject.java.annotations.v2.Action;
import io.testproject.java.annotations.v2.Parameter;
import io.testproject.java.enums.ParameterDirection;
import io.testproject.java.sdk.v2.addons.WebAction;

@Action(name = "This action has a parameter")
public class ParameterAction implements WebAction {

    @Parameter(description = "Contains the value of our output parameter",
            direction = ParameterDirection.OUTPUT,
            defaultValue = "Hello World!"
    )
    private String outputParameter;
}

We can now add input and output parameters to our action classes. Let’s move on and find out how we can write TestProject actions which use input and output parameters.

Writing TestProject Actions Which Use Input And Output Parameters

Earlier we wrote a custom TestProject action which clears the search field found from the sidebar of my blog. Next, we will write two actions which will help us to write tests for the search function. We can write these actions by following these steps:

First, we have to write an action which enters the specified search term in the search field and submits the search form. We can write this action by following these steps:

  1. Create a new action class and configure the name of the created action.
  2. Add a new input parameter called searchTerm to the our action class.
  3. Implement the execute() method. Our implementation simply enters the search term in the search field and submits the search form.

After we have implemented our actions class, its source code looks as follows:

import io.testproject.java.annotations.v2.Action;
import io.testproject.java.annotations.v2.Parameter;
import io.testproject.java.sdk.v2.addons.WebAction;
import io.testproject.java.sdk.v2.addons.helpers.WebAddonHelper;
import io.testproject.java.sdk.v2.enums.ExecutionResult;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

@Action(name = "Enter the search term and submit the search form")
public class BlogSearchAction implements WebAction {

    @Parameter(description = "Contains the submitted search term")
    private String searchTerm;

    @Override
    public ExecutionResult execute(WebAddonHelper webAddonHelper) {
        WebDriver browser = webAddonHelper.getDriver();

        WebElement searchField = browser.findElement(By.id("s"));
        if (!searchField.isDisplayed()) {
            return ExecutionResult.FAILED;
        }

        searchField.sendKeys(searchTerm);
        searchField.sendKeys(Keys.ENTER);

        return ExecutionResult.PASSED;
    }
}

Second, we have to write an action which counts (and returns) the number of search results found from the search result page. We can write this action by following these steps:

  1. Create a new action class and configure the name of the created action.
  2. Add a new output parameter called actualSearchResultCount to the our action class.
  3. Implement the execute() method. Our implementation counts the number of search results found from the search result page and stores this value in the actualSearchResultCount field.

After we have implemented our actions class, its source code looks as follows:

import io.testproject.java.annotations.v2.Action;
import io.testproject.java.annotations.v2.Parameter;
import io.testproject.java.enums.ParameterDirection;
import io.testproject.java.sdk.v2.addons.WebAction;
import io.testproject.java.sdk.v2.addons.helpers.WebAddonHelper;
import io.testproject.java.sdk.v2.enums.ExecutionResult;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.util.List;

@Action(name = "Finds the number of search results")
public class BlogSearchResultFinderAction implements WebAction {

    @Parameter(description = "Contains the number of actual search results",
            direction = ParameterDirection.OUTPUT
    )
    private long actualSearchResultCount;

    @Override
    public ExecutionResult execute(WebAddonHelper webAddonHelper) {
        WebDriver browser = webAddonHelper.getDriver();

        List<WebElement> searchResults = browser.findElements(
                By.cssSelector(".template-search .content .post_box")
        );
        actualSearchResultCount = searchResults.size();

        return ExecutionResult.PASSED;
    }
}

We have now written two action classes which have input and output parameters. Let’s summarize what we learned from this blog post.

Summary

This blog post has taught us three things:

  • We can store our parameter values in private fields which are added to our action classes.
  • When we specify the type of the parameter field, we must use either primitive types or primitive wrapper classes.
  • We can configure our input and output parameters by annotating the relevant field with the @Parameter annotation.

P.S. You can get the example application of this blog post from Github.

1 comment… add one

    Leave a Comment