Test Automation of Natural for Ajax Applications

#### Search Results

Search

# Test Automation of Natural for Ajax Applications

This document covers the following topics:

- General Information

- Enabling the Applications for Test Automation

- Advanced testtoolid Settings in Complex Controls

## General Information

Natural for Ajax is based on running HTML pages in a browser. These pages are designed as XML page layouts.

Test automation tools like Selenium (see http://docs.seleniumhq.org/) need to locate specific HTML elements in an HTML page to either check or adapt the content or to trigger corresponding events. In a Selenium test program, the developer usually passes identifiers using the Selenium Java API which enable Selenium to locate the elements for testing.

For stable automated tests, it is extremely important to use stable identifiers. For instance, rearranging controls in a layout or adding an additional control must not change the identifiers. For the most common controls, Natural for Ajax automatically generates stable identifiers, the so-called "test tool IDs". They are generated as `data-testtoolid` attributes into the HTML page. Test tools like Selenium can use this `data-testtoolid` attribute to locate the element.

The following gives a brief introduction for using stable identifiers in Natural for Ajax applications.

## Enabling the Applications for Test Automation

All Natural for Ajax applications automatically generate stable identifiers for the most common controls. So a developer need not do anything to set them.

Let us have a look at the helloworld.xml page layout of the njxdemos. The most interesting controls for automated tests are the FIELD and BUTTON controls.

#### FIELD Control

In the following example, you see that the `valueprop` property is set in the FIELD control, but the `testtoolid` property is not explicitly set.

If a value for the `testtoolid` property is not explicitly set in a FIELD control, the HTML will contain a `data-testtoolid` attribute with the value of the `valueprop` property. This is shown in the HTML snippet below. You do not need to understand all the HTML details. The snippet just shows that a `data-testtoolid` attribute is automatically generated for a FIELD control; you do not have to do anything.

    ...
    <input id="F_13" name="CC" class='FIELDInputEdit'
    data-testtoolid='yourname' type="text" style="width: 185px;">
    ...

Caution
The above HTML code contains the `id` attribute with the value `F_13`. Do not use this in your test tool. It will break your tests sooner or later because it is not stable. For example, if you add another FIELD control in front of the `yourname` FIELD control, the `id` of the `yourname` FIELD control will change its value to `F_14`.

#### BUTTON Control

In the BUTTON control, the `method` property is set. Again, the `testtoolid` property is not explicitly set.

For a BUTTON control, a `data-testtoolid` attribute with the value of the `method` property is automatically generated as shown in the HTML snippet below. Again, you need not understand all the HTML details, just look at the `data-testtoolid` attribute.

    ...
    <button type="button" id="B_17" data-testtoolid='onHelloWorld'
        	   style="width: 185px; height: 80px;" name="CC"
            class="BUTTONInput">
    ...

#### XPATH Expression

With the Selenium tool, for example, you can locate the FIELD and BUTTON controls using an XPATH expression which contains the `data-testtoolid` value. This XPATH expression can be passed to the Selenium locator `org.openqa.selenium.By.ByXPath`:

    By myfieldlocator = new ByXPath(".//*[@data-testtoolid='yourname"]");
    By mymemthodlocator = new ByXPath(".//*[@data-testtoolid='onHelloWorld"]");

See http://docs.seleniumhq.org/ for more information about the Selenium Java API.

#### Explicit `testtoolid`

In some cases, you may not want to use the `valueprop` property of a control as the `testtoolid`. Instead, you want to specify your own `testtoolid`. Examples for this are layouts in which several controls are bound to the same Natural data field. You can then simply set an explicit `testtoolid` property for each of these controls.

    ...
    <input id="F_13" name="CC" class='FIELDInputEdit'
    testtoolid='myowntesttoolid' type="text" style="width: 185px;">
    ...

## Advanced testtoolid Settings in Complex Controls

For complex controls, a single `testtoolid` is not enough to locate the individual parts of the control. The following table provides examples for the most common XPATH expressions for some complex controls.

Control | `testtoolid` | XPATH
--- | --- | ---
ICONLIST | `testtoolid="myiconlist"` |
    .//*[@data-testtoolid='myiconlist0'],
    .//*[@data-testtoolid='myiconlist1'],...
BUTTONLIST | `testtoolid="mybuttonlist"` |
    .//*[@data-testtoolid='mybuttonlist0'],
    .//*[@data-testtoolid='mybuttonlist1'],...
ROWTABLEAREA2 | `testtoolid="lines"` |
    .//*[@data-testtoolid='lines_table']
Rows/columns:
    .//*[@data-testtoolid=’lines.items[0].<col1testtoolid>’]
    .//*[@data-testtoolid=’lines.items[0].<col2testtoolid>’]...

    .//*[@data-testtoolid=’lines.items[1].<col1testtoolid>’]
    .//*[@data-testtoolid=’lines.items[1].<col2testtoolid>’]...
ROWTABSUBPAGES | `testtoolid="mytabs"` |
    .//*[@data-testtoolid='mytabs0'],
    .//*[@data-testtoolid='mytabs1'],...
MULTISELECT | `testtoolid="mychoice"` | XPATH for entries:
    .//*[@data-testtoolid='mychoice0'],
    .//*[@data-testtoolid='mychoice1'],...
XPATH for buttons:
    .//*[@data-testtoolid='mychoicebutton0'],
    .//*[@data-testtoolid='mychoicebutton1'],
    .//*[@data-testtoolid='mychoicebutton2'],
    .//*[@data-testtoolid='mychoicebutton3']...
BMOBILE:SIMPLEGRID | `testtoolid="lines"` |
    .//*[@data-testtoolid='lines']
Column text:
    .//*[@data-testtoolid='lines']
    1.row/1.column //*[@data-testtoolid='lines']//tr[1]/td[1]
    1.row/2.column.//*[@data-testtoolid='lines']//tr[1]/td[2]
    2.row/1.column .//*[@data-testtoolid='lines']//tr[2]/td[1]
Button to enable editing Select the row/column:
    //*[@data-testtoolid='lines']//tr[1]/td[1]
Use the className `‘SIMPLEGRIDEditbutton’` to select the button. Selenium example:
    driver.findElement(By.xpath(".//*[@data-testtoolid='lines']//tr[1]/td[2]")).findElement(By.className("SIMPLEGRIDEditbutton"));
Input field of editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinput’]
OK Button editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinputok’]
Cancel Button editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinputok’]

In complex controls, you need not explicitly set the `testtoolid` property in the page layout. If you do not specify any `testtoolid`, the corresponding `*prop` properties such as `valueprop`, `griddataprop`, `iconlistprop` or `pagesprop` will be used.

Here is the table from above when not specifying a `testtoolid` explicitly:

Control | `*prop` | XPATH
--- | --- | ---
ICONLIST | `iconlistprop="myiconlist"` |
    .//*[@data-testtoolid='myiconlist0'],
    .//*[@data-testtoolid='myiconlist1'],...
BUTTONLIST | `buttonlistprop="mybuttonlist"` |
    .//*[@data-testtoolid='mybuttonlist0'],
    .//*[@data-testtoolid='mybuttonlist1'],...
ROWTABLEAREA2 | `griddataprop="lines"` |
    .//*[@data-testtoolid='lines_table']
Rows/columns:
    .//*[@data-testtoolid=’lines.items[0].<col1testtoolid>’]
    .//*[@data-testtoolid=’lines.items[0].<col2testtoolid>’]...

    .//*[@data-testtoolid=’lines.items[1].<col1testtoolid>’]
    .//*[@data-testtoolid=’lines.items[1].<col2testtoolid>’]...
ROWTABSUBPAGES | `pagesprop="mytabs"` |
    .//*[@data-testtoolid='mytabs0'],
    .//*[@data-testtoolid='mytabs1'],...
MULTISELECT | `valueprop="mychoice"` | XPATH for entries:
    .//*[@data-testtoolid='mychoice0'],
    .//*[@data-testtoolid='mychoice1'],...
XPATH for buttons:
    .//*[@data-testtoolid='mychoicebutton0'],
    .//*[@data-testtoolid='mychoicebutton1'],
    .//*[@data-testtoolid='mychoicebutton2'],
    .//*[@data-testtoolid='mychoicebutton3']...
BMOBILE:SIMPLEGRID | `gridprop="lines"` |
    .//*[@data-testtoolid='lines']
Column text:
    .//*[@data-testtoolid='lines']
    1.row/1.column //*[@data-testtoolid='lines']//tr[1]/td[1]
    1.row/2.column.//*[@data-testtoolid='lines']//tr[1]/td[2]
    2.row/1.column .//*[@data-testtoolid='lines']//tr[2]/td[1]
Button to enable editing Select the row/column:
    //*[@data-testtoolid='lines']//tr[1]/td[1]
Use the className `‘SIMPLEGRIDEditbutton’` to select the button. Selenium example:
    driver.findElement(By.xpath(".//*[@data-testtoolid='lines']//tr[1]/td[2]")).findElement(By.className("SIMPLEGRIDEditbutton"));
Input field of editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinput’]
OK Button editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinputok’]
Cancel Button editable column:
    .//*[@data-testtoolid='SIMPLEGRIDColinputok’]

### On this page

- General Information
- Enabling the Applications for Test Automation
- Advanced testtoolid Settings in Complex Controls