T-Plan Home
T-Plan Robot Enterprise 4.2.2 Doc Collection
Java API Specification
10/07/17

Developing Java Test Scripts

1. Introduction
2. Setting Up Development Environment
3. Java Test Script Basics
4. Script Body Development
5. Optional Capabilities
6. Important Test Framework Objects
7. Java Test Scripts And TPR
8. Integration With 3rd Party Apps

1. Introduction

T-Plan Robot Enterprise features a programable Java API allowing to write test scripts in the Java language. Compared to the TPR scripting language this approach has numerous advantages such as:
Version 2.1 and 2.2 delivered additional functionality which allows to integrate Java test scripts with the TPR scripting language in order to build hybrid test suites. This includes:
This document is intended to provide basic information on how to write and execute Java test scripts and where to look for detailed information in the T-Plan Robot Enterprise documentation.

2. Setting Up Development Environment

Though the Robot's script editor allows to modify the Java source code there's no advanced development functionality such as method hinting and debugging. That's why it is highly recommended to use a Java Integrated Development Environment (IDE) , such as NetBeans or Eclipse for Java development. Robot 3.0 supports work with these environment as follows:
  1. Robot's project folder is compatible with most IDEs. As the Java classes are placed into the src/ folder it is possible to create a project folder shared by Robot and the IDE.
  2. Robot automatically detects external script file updates on the GUI window activation (focus) and reloads the script editor unless there are unsaved code changes. This behavior allows to work on the same Java class or classes both in the IDE and in Robot.
  3. Java test scripts may be executed both from Robot (using the GUI controls or through the -r CLI option) or from the IDE (through the main() method).
  4. It is recommended to use Robot to create new Java test scripts and to generate the testing code through the GUI tools (Script Recorder, Code Templates, Command Wizard, ...). Use NetBeans for development of any other Java code.
The following instructions show how to set up a project shared between T-Plan Robot Enterprise and NetBeans 6.9.

A. NetBeans Set Up
  1. Download and install NetBeans if you haven't done so.
  2. Start NetBeans.
  3. Create the project in NetBeans first. It will create a path like <project_home>/<project_name> which contains the src/ folder and the build.xml file.
    1. Select File->New Project in the menu.
    2. Highlight Java Application and click Next
    3. Enter a project name and select a folder to store the project to. You may optionally use the default Robot's project path (name=MyAutomation, folder=<user home>).
    4. Select Finish to create the project structure and configuration files.
  4. Right click the MyAutomation node in the project tree and select Properties in the pop up menu to open project configuration.
    1. Select Libraries in the configuration tree.
      1. Check that the Java Platform is JDK 1.6 or higher.
      2. Make sure that the Compile tab is selected and select the Add JAR/Folder button (note that the dialog may be too wide and you may have to scroll to the right to make the button visible).
      3. Navigate to the T-Plan Robot Enterprise installation folder and add all the JAR files listed in the Release Notes file table to the compile-time library list.
      4. Add any 3rd party libraries you are going to use.
    2. Select OK to save the changes.

NOTE: When using Eclipse and exporting a runnable jar file make sure to choose the "Extract required libraries into generated JAR" option under Library Handling. The Robot's plugin functionality will fail otherwise.

B. Robot Set Up
  1. Start Robot.
  2. Make sure that Robot was either started with the java executable from a JDK installation or it is configured properly with the path to the JDK. See the Release Notes for instructions. A failure to configure the JDK access will make Robot to refuse support of Java test scripts later.
  3. To create a shared project:
  4. Put any 3rd party Java libraries you are going to use on the Robot's class path (into the -classpath option in the start command) or copy them to the plugins/ directory under the Robot install folder.
  5. Create a Java test script (see below). Open the same class in NetBeans and start developing the test code in both environments as needed.

3. Java Test Script Basics

A Java test script is a Java class which implements the com.tplan.robot.scripting.JavaTestScript interface. Most Java test scripts simply extend the com.tplan.robot.scripting.DefaultJavaTestScript class which implements the interface and provides a huge framework of automation methods.

A new Java test script can be created in several ways:
  1. Through the New Test Script window in the Robot GUI (File->New Test Script).
  2. Through conversion of a TPR test script into Java. See the Java Converter help topic. This way is suitable for those who migrate from the TPR format to Java.
  3. Manual creation in the IDE.
The most common way is to create test scripts in the New Test Script window. To open it select File->New Test Script in the Robot GUI or press Ctrl+N.

New Script
  1. Set the Test Script Type value to Java test script (*.java)
  2. Set the Test Script Name field to the desired Java class name. The window will suggest a unique default name such as Script<number>.
  3. Customize the Java Package in the  Advanced Options if needed.
  4. It is recommended to leave on the Create the main() method flag because the method has to be added manually otherwise. Existence of the main() method allows to execute the test script from the IDE.
  5. Leave the Script Paths options on the default values. These can be changed through the Paths tab any time later.


Closing the window with OK will create a test script as follows:

package scripts;
import com.tplan.robot.scripting.*;
import com.tplan.robot.*;
import java.io.*;

public class Script1 extends DefaultJavaTestScript {

   public void test() {
      try {
         setTemplateDir(getVariableAsString( "_PROJECT_TEMPLATE_DIR" ));
         setOutputDir(getVariableAsString( "_PROJECT_REPORT_UNIQUE_DIR" ));
         report( new File( "results.xml" ), "" );
         // Develop the automation code in here
      } catch (StopRequestException ex) {
         throw ex;
      } catch (IOException ex) {
         ex.printStackTrace();
         throw new IllegalStateException(ex);
      }
   }

   public static void main(String args[]) {
      Script1 script = new Script1();
      ApplicationSupport robot = new ApplicationSupport();
      AutomatedRunnable runnable = robot.createAutomatedRunnable(
            script, "Script1@" + Integer.toHexString(script.hashCode()), args, System.out, false );

      new Thread(runnable).start();
   }
}

The following rules apply:
If you for some reason can't extend the DefaultJavaTestScript class, an alternative approach is to make your class implement the JavaTestScript interface. Though this is sufficient for T-Plan Robot Enterprise to execute such a test script, you won't have direct access to the DefaultJavaTestScript automation methods. A workaround is to create an instance of this class and call its methods from your code as follows:

import com.tplan.robot.scripting.*;
import com.tplan.robot.scripting.interpret.TestScriptInterpret;
import java.io.IOException;

public class MyCustomTest implements JavaTestScript {
   ScriptingContext context;
   TestScriptInterpret interpret;

   public void setContext(ScriptingContext context) {
      this.context = context;
   }

   public void setInterpret(TestScriptInterpret interpret) {
      this.interpret = interpret;
   }

   public void test() {
      try {
         DefaultJavaTestScript defaultScript = new DefaultJavaTestScript();
         defaultScript.setContext(context);

         defaultScript.setTemplateDir(getVariableAsString( "_PROJECT_TEMPLATE_DIR" ));
         defaultScript.setOutputDir(getVariableAsString( "_PROJECT_REPORT_UNIQUE_DIR" ));
         defaultScript.report( new File( "results.xml" ), "" );
         // Develop the automation code in here
      } catch (StopRequestException ex) {
         throw ex;
      } catch (IOException ex) {
         ex.printStackTrace();
         throw new IllegalStateException(ex);
      }
   }
}

This principle can be used to instantiate and call any other test script. The only requirement is to initialize the test script instance context through setContext() before you start calling its methods.

A Java test script can be executed in several ways:
  1. From the T-Plan Robot Enterprise GUI.  See the Executing Test Scripts help topic.

  2. Through the T-Plan Robot Enterprise CLI. The Java source code (a .java file) can be specified as argument of the -r option.
  3. Through a call of the Run command from a TPR test script. This mechanism is described in the Java Test Scripts And TPR chapter.

  4. Test scripts having the main() method can be also executed as standalone Java programs either from the command line or from the IDE. It is required that the method creates an automation runnable from a script instance through createAutomationRunnable() and runs it through a call of its run() method or starts it as a thread within a Thread class instance.
  5. The code employed by the main() method can be used to start Robot automated processes from any 3rd party Java applications. It can be also reused to start multiple automated processes in parallel, in a sequence or in a combination of both. For an example see the Program Level Execution And Load Testing topic in our online tutorial.

4. Script Body Development

To develop the test script body take advantage of the Robot's GUI tools described in the Script Editor help topic. Release 3.0 has made most of the GUI features support Java the same way as the TPR format except for the ones listed below. These will be addressed gradually in the 3.x and 3.0.x update releases.

Feature
Status
Export Script Comments
Not yet supported for Java test scripts.
Execute Selection
(the ability to select a block of code and execute it)
Supported since the 3.1 release.
Import from T-Plan Professional Supported since the 3.0.1 release.
Var/Eval Commands
There are no GUI components (property windows) allowing to create Java equivalents of the Var/Eval commands. One has to code them manually as getContext().setVariable() or one of the  getContext().setVariableAs...() methods.
View Script Images
(the ability to view component images used by a script in the Project View)
Not yet supported for Java test scripts.


5. Optional Capabilities

Java test scripts may optionally implement two listener interfaces compatible with the Fallback Procedures known from the TPR language:

Listener Interface
Description
com.tplan.robot.scripting.DisconnectListener Declares methods to be called when a connection to the desktop is unexpectedly interrupted during a script execution. This allows to set up central point of I/O error handling and/or eventual custom connection recovery where the standard Connection Recovery mechanism can't be used.
com.tplan.robot.scripting.ComparisonFailureListener Declares methods to be called when an image comparison performed through the compareTo(), waitFor() or screenshot() method fails. This allows to set up central point of handling of comparison errors. For example, the script may rely on a large number of image comparison operations used to locate components on the screen to work with. Instead of testing the result of each comparison for failure the script may set up a central point of failure through this interface.

There's no need to register the class as a listener anywhere. A mere implementation of these interfaces by the test script class is sufficient to receive the specified events.

Java test scripts may receive further information (events) through implementation of various listener interfaces across the test framework. The most important ones are:

Listener Interface
Description
com.tplan.robot.scripting.ScriptListener Receive events of the test script life cycle such as the execution start, stop, pause and regular completion.
Test scripts implementing this interface may register from inside the test() method through getContext().getScriptManager().addScriptListener().
java.beans.PropertyChangeListener Test scripts implementing this interface may register through getContext().getVariables().addPropertyChangeListener() for events of context variable changes.
com.tplan.robot.remoteclient.RemoteDesktopClientListener Receive events of actions performed by the local desktop client, such as sending of mouse and keyboard events to the desktop.
Test scripts implementing this interface may register from inside the test() method through getContext().getClient().addClientListener().
com.tplan.robot.remoteclient.RemoteDesktopServerListener Receive events from the remote desktop, such as desktop screen updates and changes of the remote clipboard.
Test scripts implementing this interface may register from inside the test() method through getContext().getClient().addServerListener().
com.tplan.robot.LicenseListener Receive events about the total/used/available number of licensed seats. This information can be used by test script schedulers to avoid starting of excessive
parallel scripts.
Any Java class may register at any time through a call of the com.tplan.robot.ApplicationSupport.addLicenseListener() method.

Unlike TPR test scripts the Java ones may modify user preference values through the com.tplan.robot.preferences.UserConfiguration class. The following rules apply:
There are two ways of setting of a preference value:
  1. Direct setting through one of the UserConfiguration.getInstance().set...() methods. This way is persistent and the change may get saved to the user configuration file on the hard drive if any other process calls the UserConfiguration.saveConfiguration() method. As there is no synchronization mechanism preventing two independent Robot processes at the OS level from rewriting the user configuration file, setting of preference values in this way is not recommended for environments where there may be multiple Robot instances running under the same user account.
  2. Override setting. The preference framework maintains an override preference key-value map available through UserConfiguration.getInstance().getOverrideTable() which has higher priority than the preferences loaded from the configuration file. This map is valid just withing the single Java process and its values are not saved anywhere. This is a preferred way for test scripts.
The following example show a test script executed through the main() method which wishes to maximize the Robot's GUI window on startup. The corresponding ui.mainframe.maximize preference can be found in the Menu & Tool Bar panel of the Preferences window labeled as "Maximize the GUI on start up".
 
import com.tplan.robot.preferences.UserConfiguration;
...

public class Script1 extends DefaultJavaTestScript {

    public void test() {
        ...
    }

    public static void main(String args[]) {
        Script1 script = new Script1();
        ApplicationSupport robot = new ApplicationSupport();
        UserConfiguration.getInstance().getOverrideTable().put( "ui.mainframe.maximize" , "true" );
        AutomatedRunnable runnable = robot.createAutomatedRunnable(script, "javatest" , args, System.out, false );
        new Thread(runnable).start();
    }
}

The ability to modify preferences allows the test script to control many preference-driven features such as for example:

6. Important Test Framework Objects

T-Plan Robot Enterprise testing framework consists of a set of Java classes concentrated mostly under the com.tplan.robot.scripting package. Understanding their role will help you to develop better test scripts and customize the automation process.

Test scripts are files consisting of automation command calls. Each command is handled through its own command handler. It is a class implementing the CommandHandler interface which defines the command syntax and what is to be done when the command is compiled or executed. Map of available command handlers is maintained by the script manager (see below). As command handlers are shared by the TPR language as well as the Java test scripts, adding of a command  handler through the Plugin API will make it available for both script formats (in case of Java one has to call such custom commands using the generic runScriptCommand() method of DefaultJavaTestScript). As command handlers are in fact plugins, it is very easy to add new commands to the language without having to rebuild the whole product from the source code.

Each test script is encapsulated in a test interpret. It is a class implementing the TestScriptInterpret interface which defines:
Test script interprets are pluggable objects implementing the TestScriptInterpret interface. This makes it eventually possible to implement a custom interpret and make T-Plan Robot Enterprise support another language.

Every time a script is compiled or executed, it gets associated with a unique instance of a script context. It is a map which serves as a storage for all necessary data related to the compilation or execution. It contains many important objects, such as the map of script variables, list of output objects (screenshots, warnings, logs, script/step results etc.), list of compilation errors and references to all important objects such as the test script interpret, desktop client, script manager, script parser and many more. For details see the ScriptingContext interface which defines keys to all objects which may appear in the context as well as many convenience get- methods for the most frequently accessed ones.

The Script Manager acts as the major hub for all objects participating in the testing framework. There's one script manager instance per each automated testing thread. The manager keeps track of all instantiated test script interprets and it also maintains the map of command handlers. It creates all scripting context instances and populates them with the default data (references to important objects and applicable default/implicit variables). Methods like addCommandListener() and addScriptListener() allow to register for various events fired during the test script life cycle. See the ScriptManager interface for more information.

Desktop clients handle communication between T-Plan Robot Enterprise and the connected desktop. Client classes implement the RemoteDesktopClient interface. Though they don't form part of the scripting framework, they play an important role in script execution. Clients are selected depending on the protocol specifed in the connection URL.

References to the currently used client is available through the context and script manager objects (getClient() method). If a script gets executed while a connection to a client already exists, the method provides access to the client. Otherwise it returns null until a connection is established through the connect() method call.

7. Java Test Scripts And TPR

Java test scripts may be easily called from a script in the TPR format. Java test scripts belonging to the same project can be called from the TPR code right away through the Run command. Java classes bundled in a JAR file or located in other folder than the project Java home of <projectHome>/src must be first imported through the Include command.

Let's imagine a simple project consisting of two test scripts, a Java one called Verify.java and a TPR one called TestFile.tpr:

Project View


The Java test script Verify.java verifies existence of the file referenced by the "file" and sets the "exists" context variable to either "true" (file exists) or "false" (file doesn't exist):

package scripts;

import com.tplan.robot.scripting.*;
import com.tplan.robot.*;
import java.io.*;

public class Verify extends DefaultJavaTestScript {

    public void test() {
        try {
            setVariable("exists", new File(getVariableAsString("file")).exists());
        } catch (StopRequestException ex) {
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new IllegalStateException(ex);
        }
    }
}

The TPR test script TestFile.tpr then calls the scripts.Verify class to check existence of the C:\mydata.xls file and populates the report with the passed or failed test step depending on the result:

Var _REPORT_DIR="{_PROJECT_REPORT_UNIQUE_DIR}"
Var _TEMPLATE_DIR="{_PROJECT_TEMPLATE_DIR}"
Report "results.xml"
Var file="C:\mydata.xls"
Run scripts.Verify
if ("{exists}" == "true") {
    Step "File existence" pass
} else {
    Step "File existence" fail
    Exit 1
}

The Run command call can be easily created and modified through its property dialog. To open it simply right click an empty line in the script editor and select Create a Command->Run in the context menu or right click an existing Run command and select Properties.

Run Properties

The example also demonstrates how the Java and TPR scripts can exchange data. The TPR script sets the "file" variable to the target file name and the Java code picks it up later. All variables visible to the TPR script are available to the Java code through the getVariableAs...() methods provided by the DefaultJavaTestScript class. The Java script may also create and/or rewrite the variables through the setVariable() method. Java test scripts which are not subclassing the DefaultJavaTestScript class may manipulate with variables through the same methods provided by the context object (context.getVariableAs...() and context.setVariable()).

There are two additional ways how a TPR script can pass parameters to a Java one:
  1. Undeclared Parameters,
  2. Declared Parameters.
To create an example with undeclared parameters simply replace

Var file="C:\mydata.xls"
Run scripts.Verify

with

Run scripts.Verify file="C:\mydata.xls"

The Run command accepts any number of "name=value" parameters after the Java class name argument. As these values are internally converted to local variables there's no need to modify our Java test script. The only difference is that while the "file" variable used in the original example is global and it exists until the end of the script, the local variables exist just for the time of the Java test script execution and they are removed after the Run command finishes.

The Run property window supports editing of undeclared parameters through the dynamic parameter list at the bottom:

Undeclared Parameters

These parameters are called undeclared because they are not enforced or checked in any way. It is up to the user to specify the correct set of parameters and their values expected by the Java code. This approach has naturally many disadvantages. It is easy to make a mistake and omit a parameter or specify a wrong parameter value. It also requires the programer to write a good documentation of the parameters for each Java test script, especially where the target user is another person or team.

To address these disadvantages the Java test script may declare its parameters. This is done entirely on the Java test script side through implementation of the ParametrizedTestScript interface (or eventually its parent ExtendedParamsObject one). The interface methods make the test script expose its description (in short and long forms), the list of accepted parameter names and the list of Preference objects which encapsulate and describe each parameter. Don't get confused by the Preference class name - the support of test script parameters was built on top of the Preferences framework where a user preference value is in fact a parameter.

To make our Verify.java example declare the "file" parameter update the class in the IDE as follows:

package scripts;

import com.tplan.robot.preferences.Preference;
import com.tplan.robot.scripting.*;
import java.io.*;
import java.util.*;

public class Verify extends DefaultJavaTestScript implements ParametrizedTestScript {

    public void test() {
        try {
            setVariable("exists", new File(getVariableAsString("file")).exists());
        } catch (StopRequestException ex) {
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new IllegalStateException(ex);
        }
    }

    public String getShortDescription() {
        return "Verify existence of a file." ;
    }

    public String getLongDescription() {
        return "Verify existence of a file in the local file system.\n"
                + "The file must be passed as the \"file\" parameter and must be absolute.";
    }

    // Return the "file" parameter name
    public List getParameters() {
        return Arrays.asList(new String[]{"file"});
    }

    // The "file" parameter is not "one of" -> return null
    public List getParameterValues(String parameterName) {
        return null ;
    }

    // For releases 3.5.1 and older this method is not used and may be left empty.
    // Starting with release 3.5.2 it gets called with parameters retrieved
    // from the property window when it is being closed with the OK button.
    // This allows to post-process the parameters and
tweak them or even reject
    // them before the command gets created.

    public void setParameters(Map paramsAndValues) {
    }

    public List getVisualParameters() {
        List l = new ArrayList();
        Preference p = new Preference("file", Preference.TYPE_FILE, "File to verify", null);

        // Make the parameter refuse empty value
        p.setAcceptEmptyValue(false);

        // Make the parameter mandatory (the editor will refuse to close if it is empty)
        p.setMandatory(true);

        l.add(p);
        return l;
    }
}

The Run property window for such a test script then displays with the "file" parameter in the specified format and the GUI chooses the best editor component for its value depending on the declared parameter type. The Preference.TYPE_FILE type is for example represented by an editable text field which may be optionally populated with a file from the local file system selected through the "..." button. As the parameter is declared as mandatory and it is set not to accept an empty value the property window will refuse to close unless the File to verify field is populated.

Declared Parameters

The Preference class supports most common value types. There are also optional mechanisms allowing to check the values or customize the value editor component. For example a number value may be checked against a minimum, a maximum or both.

This framework allows to build well encapsulated libraries of Java scripts that can be called both from Java and TPR test scripts. The scripts are not limited to automation tasks and the test() method may implement any custom feature such as for example database I/O through JDBC. From this point of view the Java test scripts can be considered to be an alternative plug in interface for T-Plan Robot Enterprise.

8. Integration With 3rd Party Apps

To integrate Robot with your Java application you may take advantage of the following Java system properties:

Property
Since
Description
robot.macNativeLayerDir=<dir_containing_librobot.dylib>
4.0.2
Set location of the librobot.dylib native library for Mac OS X. Set the property before the ApplicationSupport class gets instantiated. 
robot.licenseKey=<license_key_path(s)>
4.0.3
Set the path or semicolon separated paths of the license key(s). Set the property before the ApplicationSupport class gets instantiated. 
robot.cleanInstallMode=true
3.5
Ignore the existing user configuration file at <userHome>/tplanrobot.cfg. Only the license key location will be extracted and applied.
Set the property before the ApplicationSupport class gets instantiated.
robot.setWindowSize=<width>x<height>
3.5
Set the Robot's window size. It is typically used to prepare the window for recording of demos. Set the property before the GUI is opened.