Client Scripting

Requires Platform 4.2.2+

Test Script API

Nexaweb Platform 4.2.2 includes the Test Script API which you can you use to write automated functional tests. The Test Script API exposes the UI components of your Nexaweb application as scriptable objects that simplify the building of automated functional tests. The Test Script API provides you with the ability to:

  • Identify components
  • Interact with components without relying on mouse clicks and coordinates
  • Easily retrieve meaningful values from components
  • Write a useful test script without using record

The examples in this document focus on using the Test Script API with Quick Test Professional (QTP) from Mercury; however, the use of this API is not limited to that product.

Getting Started

In Nexaweb 4.2.2 to 4.5.6, because the test script API is built into the unobfuscated test jars, there is no additional setup required to use them.  

In Nexaweb 4.5.7 and later, the testscript classes are packaged in the plugin JAR file, PluginTestScript.jar. You can use the testscript classes with both debug (unobfuscated) and non-debug (obfuscated) JARs. You specify which type of JARs to use with the testclasses by editing the <ui-test> parameter in the nexaweb-client.xml configuration file. The <ui-test> parameter is set to true by default for use with debug (unobfuscated) JARs. To use non-debug (obfuscated) JARs, edit the nexaweb-client.xml configuration file to set the <ui-test> parameter to false.

To use the test script API, follow these steps:

1. Locate the PluginTestScript.jar file in your platform\dist\plugins folder.

2. Copy this file to your application's WEB-INF\client\plugins\pre-loaded directory.

How to get a test script object

The test scripts that the QTP record mechanism generates use QTP's object wrapper of the actual UI component (for example, Label or Button). QTP stores the object wrappers in its object repository. By default, QTP names objects in this repository based on their actual class (for example, NRichLabel or NButton).  However, you can rename objects in the repository by right clicking on the object name as it appears in the object repository dialog. The name of the object as it appears in the object repository, is the the name that the method inside the QTP script uses to locate the QTP object wrapper.


The following script demonstrates how to obtain the Test Script Object from the QTP Wrapper object named "Some Label".

Set labelObj = Browser("Welcome To Nexaweb").Page("Welcome To Nexaweb").JavaApplet("DefaultJvmDetector").JavaObject("Some 
Label").Object.getScriptObject()

Set labelObj =
Stores the test script object in a variable for later use within a script.

Browser("Welcome To Nexaweb")
Browser is a QTP method for locating a QTP Browser Object for testing. In this example,  Welcome To Nexaweb represents the name of the Browser Object as defined in the Object Repository.

Page("Welcome To Nexaweb")
Page is a QTP method for locating a QTP Page Object for testing. In this example, Welcome To Nexaweb represents the name of the Page Object as defined in the Object Repository.

JavaApplet("DefaultJvmDetector")
JavaApplet is a QTP method for locating a QTP Applet Object for testing. In this example, DefaultJvmDetector represents the name of the Applet Object as defined in the Object Repository.

JavaObject("Some Label")
JavaObject is a QTP method for locating a QTP JavaObject Wrapper for testing. In this example, Some Label represents the name of the Applet Object as defined in the Object Repository.

.Object
The Object property of the QTP JavaObject Wrapper accesses the underlying Nexaweb UI Component (for example, Label).

getScriptObject()
The getScriptObject() method returns the Test Script Object associated with the underlyingNexaweb UI Component. Test Script API methods are applied to this Test Script Object on which the .

You can also use the findObjectById(), findObject() and findObjects() methods of the Application Script Object to obtain test script objects for UI components. The findObjectById() finds the UI component with the matching id attribute, and the findObject() and findObjects() methods locate objects based on an XPath query.
For example, the following script locates a button whose text is Test Button and then clicks the button:

Set appObj = Browser("Welcome To Nexaweb").Page("Welcome To Nexaweb").JavaApplet("DefaultJvmDetector").Object.getScriptObject()
Set buttonObj = appObj.findObject("\\button[@text='Test Button']" )
buttonObj.click

Using the findObject() method, you do not have to add the button object to the object repository in order to run this script.  However, you still need to add the applet to the repository, because the script is using the QTP method JavaApplet() to locate the applet and the .Object to access the applet object.
 

Using the Test Script API

Once you obtain a test script object, you can then use it to interact with and test the contents of the underlying UI component.

The Test Script API includes test script objects for the following composite components

  • ComboBox
  • ListBox
  • Table
  • Tree
  • TreeTable

In addition, you can perform the following tasks with a single API call.

  • Selecting an item in a combobox
  • Editing a cell in a table
  • Retrieving the items of a listbox
  • Typing a string into a textfield
  • Dragging an object and dropping it on another

For more information on the Test Script API, select the Test API tab in the API and XML Reference section of the DevCenter.

Example:

This example tests an application that sets the value of a label based on the value of an item selected from a combobox. The text of the label is set within a MCO call that handles the onCommand() event of the combobox. The test first verifies the intial state of the combobox and the label. It then selects each item of the combobox.  After each selection it tests the text of the combobox against the text of the item being selected.  It then also tests the text of the label against the value of the item being selected.

The XML UI

<nxml>
   <mco:declarations xmlns:mco="http://nexaweb.com/mco">
      <mco:mco id="eventMco" src="ComboBoxHandler"/>
   </mco:declarations>
   <rootPane>
     <comboBox id ="combobox" text="ComboBox"
       onCommand="mco://eventMco.handleComboBoxOnCommand( mylabel )">
       <listBox>
         <listItem text="Tree Item 1" value="one"/>
         <listItem text="Tree Item 2" value="two"/>
         <listItem text="Tree Item 3" value="three"/>
        </listBox>
     </comboBox>
     <label id = "mylabel" text="Label to Change"/>
   </rootPane>
</nxml>

The MCO

import com.nexaweb.client.ClientEvent;
import com.nexaweb.client.ClientSession;
import com.nexaweb.client.mco.AbstractMco;
import com.nexaweb.client.mco.McoContainer;
import com.nexaweb.xml.Document;
import com.nexaweb.xml.Element;

public class ComboBoxHandler extends AbstractMco
{
   public void handleComboBoxOnCommand( Element label )
   {
      ClientSession clientSession = 
           McoContainer.getClientSessionFromMco(this);
      Document uiDocument = 
           clientSession.getDocumentRegistry().getUiDocument();
      ClientEvent clientEvent = 
           clientSession.getEventHandler().getClientEvent();
      synchronized ( uiDocument.getDomSynchronizationObject())
      {
         String value = clientEvent.getParameter( "value" );
         label.setAttribute( "text", value );
      }
   }
} 

The Test

' get the applet script object
Set appObj = Browser("Welcome To Nexaweb").
Page("Welcome To Nexaweb").JavaApplet("DefaultJvmDetector").
Object.getScriptObject()

'get the combobox script object
Set comboBox = appObj.findObjectById("combobox")

' get the label script object
Set label = appObj.findObjectByid("mylabel")

'test inital state of combo
text = comboBox.getText()

if( text <>"ComboBox") then
   result = "Expected 'ComboBox' Actual was '" + text + "'"
   Reporter.ReportEvent micFail,"ComboBox", result

Else

   Reporter.ReportEvent micDone,"ComboBox", 
   "Intial Text passed. was 'ComboBox'"
End If

'test intiial state of label
text = label.getText()
if( text <>"Label to Change") then
   result = "Expected 'Label to Change' Actual was '" + text + "'"
   Reporter.ReportEvent micFail,"Label", result
Else
   Reporter.ReportEvent micDone,"Label", 
   "Intial Text passed. was 'Label to Change'"
End If

' get the count of the items in the combobox
itemCount = comboBox.getItemCount()

' get the vector of the items and the size of the return
Set itemobjs = comboBox.getItems()
sizeItems = itemobjs.size()

' verify the size of the return is correct
if( itemCount <> sizeItems ) then
   result = "Expected " +itemCount + 
            " tiems Actual was '" + sizeItems + "'"
   Reporter.ReportEvent micFail,"Label", result
Else
   Reporter.ReportEvent micDone,"ComboBox", 
   "Number of Items was "+itemCount
End If

' select each item and test the combobox and label text
' to ensure selection and onStateChange() event has fied correctly

For i = 0 to itemCount - 1
   ' select the tiem
   comboBox.selectItemAt( i )

   ' check the text of the combobox against the 
   '  text of the item being selected
   tag = "Selected Item #" + CStr(i) + " - ComboBox"
   expectedText = itemobjs.elementAt(i).getText()
   text = comboBox.getText()

   if( text <> expectedText ) then
      result = "Expected '" + expectedText +
      "' Actual was '" + text + 
      "'"Reporter.ReportEvent micFail,tag, result
   Else
      Reporter.ReportEvent micDone, tag, 
      "ComboBox text was '" + expectedText +"'"
   End If

   ' check the text of the label against the value of 
   ' the item being selected
   tag = "Selected Item #" + CStr(i) + " - Label"
   expectedText = itemobjs.elementAt(i).getValue()
   text = label.getText()

   if( text <> expectedText) then
      result = "Expected '" + expectedText + "' Actual was '" + 
      text + "'" Reporter.ReportEvent micFail,tag, result
   Else
      Reporter.ReportEvent micDone,tag, 
      "Label Text passed. was '" + expectedText +"'"
   End If

Next