Purpose of WebAppProfile
WebAppProfile serves as an instruction to Rapise on how to record XPath locators for elements in a given application.
Adding WebAppProfile to a Test
To create WebAppProfile.json
file in your test navigate to Files tab, right click Scripts folder and choose Create... > WebAppProfile.json
.
The default profile looks like this:
{
record:
{
attributes: [
{ name: "id", notEmpty: true, exclude: "\\d" },
{ name: "title" },
{ name: "role" }
],
classes: [
{ name: "content" }
],
anchors: [
{ xpath: "//div[@class='content-wrapper']" }
]
}
}
WebAppProfile Format
record.attributes
array contains definition of attributes to record.
name
is the only required property for an attribute. It is case insensitive.
notEmpty
is 'false' by default. If set to 'true' then the attribute will be recorded only if it has non empty value.
exclude
is a regular expression. If attribute value matches the regexp then the attribute is not recorded.
record.classes
array lists class names that are meaningful for element identification and should be recorded.
name
is the only required property for a class. It is case sensitive.
record.anchors
array lists anchors.
xpath
is the only required property for an anchor.
Anchors
When element XPath is recorded and an element belongs to a DOM sub-tree of an anchor then anchor XPath is always appended to element XPath,
Let's look at the example. Here we have a table built with DIVs and ARIA roles.
<div id="Customers" role="grid">
<div role="row">
<span role="cell" title="Contoso"></span>
...
</div>
...
</div>
If we record just using title
attribute and it's value is unique for the page we'll end up with a locator
//span[@title='Contoso']
However if we define an anchor
//div[@id='Customers']
we'll get the locator as
//div[@id='Customers']//span[@title='Contoso']
The locator is now bound to the table. If another element with 'Contoso' title appears somewhere on the page (outside the table) we'll find the correct element.
Here is more complex and real-life example. In Microsoft Dynamics 365 Business Central application when you navigate through the forms they are loaded into the DOM tree inside DIV elements with spa-view
class. When you move from one form to another - old forms are not unloaded an continue to sit in the DOM tree. They just have lower z-index
then currently active form.
It means that when Rapise searches for an element during test playback it should work with the topmost spa-view
.
To achieve this goal we define an anchor in WebAppProfile for the application
//div[contains(concat(' ', @class, ' '), ' spa-view ') and position()=last()]
Here is an example of automatically recorded XPath
//div[contains(concat(' ', @class, ' '), ' spa-view ') and position()=last()]//span[@aria-label='Customers']
The anchor prevents us from finding elements that are not visible to user and ensure that if we find an element it belongs to an active form.
XPath Minimization
Rapise always tries to build the minimal XPath locator possible with a given set of attributes, classes and anchors. Full XPath is not an option.
Let's assume we have a page
<div>
<div>
<span title="Account"></span>
...
</div>
...
</div>
and XPath
//span[@title='Account']
finds a single node, then it is a good minimal locator for the element.
Compare with full XPath
/div[1]/div[1]/span[@title='Account']
that may easily become broken with page layout changes.
Conclusion
WebAppProfile addresses one of the challenges in web UI test automation: generation of resilient XPath locators during test recording. Other challenges include dealing with asynchronous loading of data and working with complex controls (like grids, trees, menus, etc.).