Nexial Automation

Test Automation Platform for everyone!

X

web

Nexial supports browser automation via the popular Selenium/ WebDriver automation framework. In effect, Nexial translates the commands in the Nexial script (spreadsheet) to Selenium- or WebDriver- specific API calls, along with other automation work such as error handling and browser lifecycle management. Similar to web cookie and JavaScript alert automation, Nexial acts as the translator to mediate between the automation script and the underlying Selenium/WebDriver framework. As part of the overall approach to building an automation platform, the Nexial development team tries to keep up the latest official releases of its third-party libraries. Selenium is no exception. As of July 2018 Nexial uses Selenium 3.1.13 and the latest releases of related webdrivers.


Locators

For effective automation of Web application, there are several critical technical knowledge and techniques to apply. The most important of which is the right technique of writing locators. Locators are a collections of ways (7 in total) to identify elements of a web page. It is by such mechanism one can effectively identify elements on a web page, interact with them and perform automation upon them.

Note: Most of the information on the Web about locators are not created from the standpoint of a codeless or hybrid framework like Nexial. This applies to the links in this page. Reader’s discretion is advised…

Here’s a summary of the various locators (click on tab to view):

Syntax/Example Pros Cons
id=id-of-target-element
id=username
id=section1
  • Low to zero impact by page structural changes
  • Generally faster than other methods
  • Not every web element is associated with an ID
  • Poorly coded web page may cause multiple matches

This strategy instructs Nexial (webdriver behind the scene) to look for an element in the current page with an id attribute corresponding to the specified one. Hence, <div id="section1">...</div> can be referenced via locator id=section1.

Typically the ID of a web element is assigned by the web developer. At the discretion of the developer, not every element might be assigned an ID, much less meaningful ones. Hence the success of using this approach is largely dependent on the developer, and to some extent the collaboration between engineers. Another issue is that, while ID should be unique on the same web page, many browsers allow violation of this rule such that an ID-based locator might match more than 1 element. Such anomaly occurs more frequently with generated ID stemmed from JavaScript front-end framework, the likes of React, Angular, Dojo, etc.

In terms of performance, this approach is generally recognized as one of the faster ones.

Syntax/Example Pros Cons
name=name-of-target-element
name=Password
name=SubmitOrder
  • Works well with forms or simpler web applications
  • Not many HTML elements are associated with name attribute
  • The name attribute is not designed to be unique within the same page.

This strategy is similar to that of ID (above), with the exception that the target attribute is "name" instead of "id". The name attribute is commonly found with form elements such as textbox, select (dropdown), checkbox, radio box, buttons and text area (like textbox, but supports multi-line input). Consider the following web snippet and its HTML:

Enter username:
Enter password:
<form id="login_form" method="post" action="...">
     Enter username: <input type="text" name="username"/><br/>
     Enter password: <input type="password" name="password"/>
     <input type="submit" name="submit" value="Log In"/>
</form>
To access the textbox for username, one could use a locator as name=username. To reference the "Log In" button, one could specify name=submit.

Due to how such attribute is used, this strategy is best suited to referencing form elements. Some forms are generated dynamically or programmed to behave differently based on user interaction. Such might be difficult for the name-based strategy.

By specification, the name attribute is not expected to be unique within the same web page. At times one may use this to one's advantage. For example, a select (dropdown) element that contains a list of 50 items can be referred by one single name=... locator.

Syntax/Example Pros Cons
partialLinkText=partial-link-text or partial=partial-link-text
partialLinkText=Forgot My
partial=Click here to
  • automatically limits to <A> (hyperlink) element
  • best for testing navigation
  • guarded against stylistic or page structure changes
  • partial match can be easier to maintain than exact match (as in Link Text)
  • Not suitable when link text is generated dynamically
  • Unintended consequences of matching to multiple elements

This strategy is intended to select hyperlink element(s) (denoted via the <A> tag) that contains the specified text. This strategy is similar to that of Link Text, except that only partial match on the link text is required. As a convenience, Nexial supports both the use of partialLinkText= or partial= prefix for this locator strategy. For example, these 2 locators yield the same outcome:
partialLinkText=Submit
partial=Submit

This strategy has potentially some advantages and some disadvantages. On one hand, partial match would remove the need for exact match thus simplify the automation work a bit. However, partial match could result in erroneous automation. Partial match could result in multiple matches and an unintended link could be invoked as a result. As with most web commands, when there are multiple matches to the specified partial text match, only the first matched element is considered.

Not all web applications use the <A> tag to represent its navigation (inasmuch as this is the recommended approach by all major search and SEO engines to improve search hits). If a web application opted to use another tag, such as <DIV> tag, then this locator strategy would not work.

Syntax/Example Pros Cons
tag=tag-name-of-element
tag=select
tag=table
  • Simple to create, to understand and to maintain
  • Fast
  • Limited in usefulness; best suited for simple web pages

This is another simple way to located element(s) on a web page. The idea is to filter to element(s) of the same "tag" so that interactions can be made to all the elements of the same tag. There is no hierarchy support so only 1 tag can be referenced at one time. This is designed for simplistic use cases where tags are not used by overlapping purposes.

Syntax/Example Pros Cons
class=css_class_name
class=nav-item
class=required_input
  • Simple, easy to maintain and to understand
  • Not powerful enough for more complex web pages.

This type of locator matches elements with an attribute named as class that contains the specified value. One should recognize that this type of locator is just a simplification of the CSS selector based locator (next). The CSS selector based locator is much more powerful and offers a wide range of capabilities for selecting web elements.

This type of locator focused on the style class(es) set to web element. While only 1 style class can be specified in the locator, it is capable of matching web element that contains multiple style classes (including the target class). For example, suppose the following HTML snippet:

  <li name="item1" class="style1">Item 1</li>
  <li name="item2" class="style1 style2">Item 2</li>
  <li name="item3" class="style1 style3">Item 3</li>
  <li name="item4" class="style1 style2">Item 4</li>
  <li name="item5" class="style1 style2 style3">Item 5</li>
In this case,
  • The locator class=style1 would match all 5 elements.
  • The locator class=style2 would match the 2nd, 4th, and 5th elements.
  • The locator class=style3 would match the 3rd and 5th elements.
  • The locator class=style1 style2 would NOT match any element since it is not a valid class-based locator.
The reason that the last locator would not match any element is that each style class is treated as independent entity and is matched as such. To match multiple style classes, one would need to consider the use of CSS selector based locator (next).

This type of locator is simple, highly readable and easy to maintain. However, it only deals with one style class at a time and does not consider other HTML attributes.

Syntax/Example Pros Cons
css=css-selector
css=form#login > input.username
css=input[name='login'][type='submit']
css=#records li:nth-of-type(4)
css=a[id^='id_prefix_']
  • Very powerful; supports a wide range of selection criteria
  • Can be independent to page structure or element hierarchy
  • Seems more consistent between browsers
  • Noticeable faster than XPATH
  • Syntax can be difficult to decipher
  • Steeper learning curve

Unlike the ID locator, name locator, link text locator and style class locator, which are designed for more specific cases, the CSS locator is designed for general-purpose use. Using the appropriate CSS selector, one can pinpoint to the element or elements with precision. A CSS Selector is a combination of an element selector and a value which identifies the web element within a web page. They represent HTML tags, attributes, ID and Classes as patterns that match against elements in their respective hierarchical structure tree.

The W3C CSS-Selector provides a wide range of capabilities to reference web elements, of which most are implemented in Selenium 3.x. In general, the CSS selectors can be divided into the following categories:

  • HTML tag
  • ID via the #id syntax
  • Classname via the .class syntax
  • Attribute via the [attrib...] syntax
  • String matches: equals (=), start with (^=), ends with ($=), contains (*=)
  • Inward hierarchy: descendant, direct child (>), first child (:first-child), last child (:last-child), nth child (:nth-child(n))
  • Outward hierarchy: immediate after (+), before (~).
  • Pseudo Class: active element (:active), enabled (:enabled), disabled (:disabled), etc.
The topic and discussion about CSS selectors is a substantial one. Many great resources are widely available. Here are some of the popular ones:
Syntax/Example Pros Cons
xpath=xpath-to-target
xpath=//div[@id='d1']//a[text()='Best Price']
xpath=//footer
//span[contains(text(),'Complete']
  • Precision
  • Supports both hierarchy-aware and hierarchy-agnostic reference
  • One of the slowest locators
  • Inconsistent amongst browsers
  • Can be difficult to read and to maintain

XPATH is a W3C standard to reference nodes and fragments of an XML/xHTML document. It has sufficiently descriptive syntax for precise element referencing while not bound to the underlying DOM structure. It is commonly known as an effective alternative where id, name or similar attributes are not available on the target web element(s). This is because XPath is flexible enough to describe element(s) based on its absolute or relative position in the containing document, and it can also be used to filter via element attributes and pseudo-classes. In general, XPath is the "catch-all" for locators.

However, with great power comes great responsibility. XPath based locator can be easily misused where the locators can become difficult to read and maintain. Deciphering and maintaining XPaths like /child::library/child::book/child::title[position()=2]/child::text or //report//author[text()=../../following-sibling::report//author/text()] are certainly not a walk in the park. XPath designer must take special care in designing locators, or they might end up as technical debts! What further the complication is the interoperability of these XPath across browsers. There is to date no feature parity amongst the popular browsers in terms of XPath implementation (particularly with IE). This adds additional burden in designing cross-browser XPath. Also, XPATH based locators are not the most ideal locator for performance (again, particularly with IE).

There are lots of tutorial and learning material on the Internet regarding XPath. Here are some that might be helpful:

Syntax/Example Pros Cons
text=element-text
text=Welcome
text=CONTAIN:order complete
text=START_ANY_CASE:This request is submitted
  • Low to zero impact by page structure changes
  • Highly readable, easily to maintain
  • PolyMatcher for added flexibility
  • Not every web element has text
  • Problematic when specified text isn't unique

The "text" locator is uniquely crafted within Nexial to provide an efficient and easy-to-maintain strategy for text-centric components. Consider the following example with multiple labels (highlighted) and how we can reference them via text locators:
  
The ability to create locators without examining the underlying DOM structure can be a huge time saver.

In addition, we can also apply PolyMatcher for added flexibility. With PolyMatcher, we can use any of the following partial match strategies:

CONTAIN: Reference a web element that contains the specified text.
For example,text=CONTAIN:logged in successfully.
CONTAIN_ANY_CASE: Reference a web element that contains the specified text,case-insensitively.
For example, text=CONTAIN_ANY_CASE:matches found in los angeles
START: Reference a web element that starts with the specified text.
For example, text=START:Welcome,
START_ANY_CASE: Reference a web element that starts with the specified text, case-insensitively.
For example, text=START_ANY_CASE:the time now is
LENGTH: Reference a web element that contains text of specified length.
For example,text=LENGTH:12
EMPTY:true|false Reference a web element (the first matched) that contains text or no text.
For example,text=EMPTY:true means elements with no text; text=EMPTY:false means elements containing at least 1 character.
Usually, this specific PolyMatcher makes more sense when applied within the context of layer locator.
BLANK:true|false Reference a web element (the first matched) that contains only blanks.
For example,text=BLANK:true means elements with only blank/space characters; text=BLANK:false means elements that contain characters other than blank/space.
Usually this specific PolyMatcher makes more sense when applied within the context of layer locator.

While its convenience is undeniable, this locator strategy is not a cure-all. Here are some reasons why you might not want to rely on this locator strategy too much:
  1. When the specified text might reference multiple web elements (test flakiness).
  2. When the specified text might be hidden or its visibility is event-bound.
  3. When the specified text is insufficient to pinpoint or to assert the target element. For example, "find an element with text "Click here to register" and background color is blue."
  4. When the specified text is too long (as in a paragraph, for example), and using other attributes might be more efficient.
This strategy is most effective for a simpler DOM structure or simpler page layout. It is similar to web » clickByLabel(label), except it can be applied to any web element.

In terms of performance, this approach is around the same speed as that of the XPATH-based locators.

Syntax/Example Pros Cons
layer={locator}{locator}{...}
layer={css=dialog.toast}{text=Transaction Complete}
layer={css=.error}{text=CONTAIN:Invalid}
  • Scalable for complex DOM structure
  • Combining best locator strategy per layer
  • Slower than XPATH or CSS
  • Less like to be reused

This is another Nexial-only locator. In essence, this approach allows the mix-and-match of any locator per "DOM layer" to reference the target element(s). One can think of a "DOM layer" as the parent-child concept of a web page, where web element capable of containing one or more web (child) elements. At each hierarchy (or layer), a web element can be constructed very differently than its parent or its children elements. As such, there might not be an optimal locator to reference a specific element and its parent elements. Suppose we want to reference the SPAN element with the text "Items" in the following HTML snippet:

<nav class="navbar navbar-light bg-light">
  <i class="fa fa-shopping-cart fa-lg m-2" aria-hidden="true"></i>
  <span class="badge badge-pill badge-info m-2" style="width: 50px;">1</span>
  <span>Items</span>
</nav>
XPATH would seem to be the obvious choice since it is the only locator that can reference element text. However, XPATH isn't ideal to reference CSS classes. With layer locator we can reference the same web element. Consider the difference between these locators:
XPATH layer
//*[contains(@class,'navbar')]/*[text()='Items'] layer={css=.navbar}{text=Items}
The layer locator (right) reads
find a web element that contains a "navbar" CSS class, then under such element, find a child or descendent element that has text "Item".
In this case, the end result is the same as that of the XPATH locator. However, the layer locator has this {...} syntax, which represents 1 layer, that allows us to use different locator at each layer. We can select the best locator strategy - in terms of performance, maintainability, etc. - at every layer to create a so-called compound locator. This can lead to productivity gain, performance gain, and improved readability.

Consider a different example below,

Suppose the objective is to find all the computer names that
  • start with the letter HP, AND
  • do not have an associated "Introduced" value
The image above shows 5 highlighted computer names that match the above criterion. To achieve this via the layer locator, we would first break things down into 3 successive filters:
  1. find the table that contains the data in question, THEN
  2. find the rows that do not have a corresponding "Introduced" value (second columns with -), THEN
  3. find the cell that contains text that starts with HP
Here's the layer locator that would satisfy the above requirements:
layer={css=.computers}{.//tr[td[2][text()='-']]}{text=START:HP}

Note that the second layer uses a relative XPATH (a dot in front) because we are filtering within the previous "layer" (the TABLE). The last layer will automatically be converted into a relative locator by Nexial. The START: syntax is part of PolyMatcher. Check out the "Text" locator tab for more details on this.

Now we can put this layer locator to good use:


Using the web » saveTextArray(var,locator) command we can capture the text of each referenced web element. Then using the LIST expression, we can convert the captured list into a newline-separated text, like this:

One critical thing to note is that the flexibility of the layer locator can easily lead to abuse. One should still hold to all the good practices of writing effective locators.
Using the layer locator, we can circumvent some shortcomings of other locators when dealing with either a complex or inconsistent DOM structure.


Additional Help on Locators

Here are a few tutorials on locators (please feel free to send more links so we can add to this list):

One might consider converting XPaths to CSS locators since CSS locators are generally faster and more readable. Here’s an online app to help converting XPath to CSS locator:

https://cssify.appspot.com/
https://cssify.appspot.com/


Google Chrome comes with a sleuth of useful features to perform common tasks such as selecting and inspecting DOM elements, and monitoring DOM events. This is available from the Chrome DevTools (aka Console):

Command Line API Reference
developers.google.com

Browser Support

Nexial currently supports the following browsers (recent versions only):

Enabling Firefox automation is straightforward:
  1. Make sure a recent version of Firefox suitable to your platform is installed locally. For Linux and Mac OS, firefox or firefox-bin is expected to be found in the $PATH environment variable. The order of paths in $PATH determines the precedence in being selected as the target executable for automation. For Windows, Firefox is expected to be installed in either %ProgramFiles%\Mozilla Firefox or%ProgramFiles(x86)%\Mozilla Firefox.
  2. Set nexial.browser to firefox.
  3. Begin scripting...
Follow the same instruction as Firefox, except setting nexial.browser to firefox.headless.
Enabling Chrome automation requires the following steps:
  1. Make sure a recent version of Chrome suitable to your platform is installed locally. Linux installation differs based on distro - check distribution vendor website or Google for more details. Be sure that google-chrome can be found in $PATH environment variable. For Mac, Google Chrome is expected to be installed either in the standard /Applications/Google Chrome.app or in the home directory of the current user (give precedence).
  2. Set nexial.browser to chrome.
  3. Begin scripting...
Mobile Device Emulation
It is possible to emulate mobile devices during automation via the Chrome webdriver (i.e. nexial.browser as chrome).
There are 2 ways of enabling mobile device emulation:
  1. via the nexial.browser.emulation.deviceName data variable
  2. via the nexial.browser.emulation.userAgent data variable.
The first approach is simpler. Simply specify a mobile device name that is supported by the Chrome browser to enable such emulation. For example,


The second approach offers finer controls. Along with the "User Agent" string to match the target mobile device, one can also specify the width (via nexial.browser.emulation.width data variable), the height (nexial.browser.emulation.height data variable), the pixel ratio (via the nexial.browser.emulation.pixelRatio data variable) and touch activation (via the nexial.browser.emulation.touch data variable). For example,

Note that nexial.browser.emulation.pixelRatio defaults to 3.0 and nexial.browser.emulation.touch defaults to true.

For a list of supported mobile devices and their respective "user-agent" string, visit the following link: Chrome's Emulated Devices JSON


For more information about mobile device emulation, visit ChromeDriver's Mobile Emulation page. While it is cost-effective to use the emulation capability of ChromeDriver, it is noteworthy that there are known issues and limitations of using ChromeDriver's mobile emulation.

Note that uring device emulation, the screen capturing might cause a sudden "grow-and-shrink" behavior as shown below:


Emulators cannot accurately reflect the real devices in terms of hardware and OS-specific nuances. For more accurate testing, consider using BrowserStack or CrossBrowserTesting services (both commercial) instead.
Follow the same instruction as Chrome, except setting nexial.browser to chrome.headless.
Chrome Embedded Framework, or CEF for short, is an open-source framework for embedding chrome browser (technically chromium) in a desktop application. The ability to do so opens up a wide range of possibilities in application development.

To enable CEF automation, follow these steps:
  1. Make sure the Chrome-embedded application (AUT) is properly installed. In most cases, one should find a libcef.dll or libcef.so in the same location as the CEF-enabled application.
  2. Set nexial.browser to chrome.embedded.
  3. Set nexial.browser.embedded.appLocation to the full path of the application executable program.
  4. Begin scripting...
Electron is an open-source framework to create desktop applications using JavaScript. It combines the use of Node.js runtime as the backend and Chromium as the frontend engine to create a compelling, cross-platform desktop GUI framework that powers popular applications such as Atom, Microsoft team, Microsoft Visual Studio Code, WhatsApp, Slack and Cycligent.

To enable Electron application automation, follow these steps:
  1. Make sure the target Electron application is properly installed.
  2. Set nexial.browser to electron.
  3. Set nexial.browser.electron.appLocation to the full path of the executable program. For MacOS, the executable is usually found under $APPLICATION/Contents/MacOS/.
  4. Begin scripting...
Enabling Safari automation requires the following steps:
  1. Make sure a recent version of Safari is installed locally. Only MacOS is supported for safari automation at this time.
  2. Set nexial.browser to safari.
  3. Begin scripting...
Enabling Safari Technology Preview automation requires the following steps:
  1. Make sure a recent version of Safari Technology Preview is installed locally. Only MacOS is supported for Safari automation at this time.
  2. Set nexial.browser to safari.
  3. Set nexial.browser.safari.useTechPreview to true.
  4. Begin scripting...
Enabling IE automation requires the following steps:
  1. Make sure a recent version of Internet Explorer suitable to your platform is installed locally. Only Windows 7 and above is supported at this time.
  2. Set nexial.browser to ie.
  3. Be sure to read through and follow the recommendations listed in Web Automation On IE.
  4. Begin scripting...
Enabling Edge automation requires the following steps:
  1. Make sure a recent version of Microsoft Edge Browser suitable to your platform is installed locally. Only Windows 10 is supported at this time.
  2. Set nexial.browser to edge.
  3. Be sure to read through and follow the recommendations listed in Improving IE Automation (these recommendations apply to Edge as well!).
  4. Begin scripting...
Enabling Chromium Based Edge automation requires the following steps:
  1. Make sure a recent version of Microsoft Edge Chromium Browser suitable to your platform is installed locally. Only Windows is supported at this time. To find out browser version locally, please go through How to check Edge version
  2. Set nexial.browser to edgechrome.
  3. Be sure to read through and follow the recommendations listed in Improving IE Automation (these recommendations apply to Edge as well!).
  4. Begin scripting...
BrowserStack is a popular cloud, web and mobile testing platform that enables developers to test their websites and mobile applications across on-demand browsers, operating systems, and real mobile devices. This is a paid service.

To enable BrowserStack integration, be sure to read up on the BrowserStack Integration page.
excerpts from CrossBrowserTesting.com:
... Browser testing is a method of quality assurance for web applications across multiple browsers. ... It’s implemented to ensure a website’s functionality and design and includes testing a range of devices and operating systems being used in the market and customer base.
CrossBrowserTesting is a popular cloud, web and mobile testing platform that enables developers to test their websites and mobile applications across on-demand browsers, operating systems, and real mobile devices. And, much like BrowserStack, this is also a paid service.

To enable CrossBrowserTesting integration, be sure to read up on the CrossBrowserTesting Integration page.



WebDriver Support

Nexial automatically downloads required webdriver, during runtime as needed. Webdrivers are downloaded to the user’s home directory, under the .nexial folder. For example, C:\Users\MY_USER_ID\.nexial\chrome or /Users/USERID/.nexial/firefox. Also, a .manifest file with the driver details is maintained in the same directory. The .manifest file is used to check and download the latest version available based on the current OS. If there should be any reason not to update to the newer/latest webdriver (e.g. due to compatibility with older browser), one can disable the automatic webdriver update by setting "neverCheck": true in .manifest file.

See Forcefully update or omit webdriver updates for more details.


Browser Performance Metrics

As of v2.7, Nexial supports the collection of browser performance metrics during execution. One can configure an execution to collect browser performance metrics without the need to modify automation script. The collected metrics will be presented as a web page at the end of the execution. To read more about this, visit Browser Performance Metrics.


Browser Metadata

As of Nexial v2.9, Nexial exposes a set of metadata concerning the browser in execution. Such metadata provides further insight concerning the browser in used for automation, such as the browser version and if it is running in a desktop or mobile platform. This can be useful towards conditional execution and reporting.

To open a URL via Nexial, one would utilize one of the following commands:

Within each of these commands, Nexial will ensure that the browser metadata is also captured and stored to a System variable named nexial.browser.meta. This means that the browser metadata will not be available for use until one of the above commands is invoked.

When the browser is closed via the web » closeAll() command or via the web » close() command on the last window/tab, the same nexial.browser.meta System variable will be removed. This allows one to utilize a different browser thereafter and for Nexial to capture the relevant browser metadata accordingly.

One can inspect the browser metadata via the nexial.browser.meta System variable. The browser metadata has nested structure to expose information about the browser, the underlying operation system and device classification. Below is a graphical depiction of the metadata available during execution:

  • ${nexial.browser.meta}.name - the name of the browser currently in execution.
  • ${nexial.browser.meta}.version - the full version string of the browser currently in execution.
  • ${nexial.browser.meta}.userAgent - the full identifier of the browser currently in execution. See User agent for more details.
  • ${nexial.browser.meta}.os.name - the (marketing) name of the underlying operation system. For example, iOS 8, macOS 10.14 Mojave, Windows 10.
  • ${nexial.browser.meta}.os.code - the code name of the underlying operation system. For example, ios_8, macos_10_14, windows_10.
  • ${nexial.browser.meta}.os.family - the product family of the underlying operation system. For example, Windows, iOS, macOS.
  • ${nexial.browser.meta}.device.type - the detected device type for the browser currently in execution. For example, desktop, table, smartphone.
  • ${nexial.browser.meta}.device.brand - the name of the device for the browser currently in execution. May be empty. For example, Apple.
  • ${nexial.browser.meta}.device.name - the name of the device for the browser currently in execution. May be empty. For example, Mac, iPad.
Note: Nexial uses Userstack for browser metadata detection.

The “web” command type represents a series of automation commands regarding web operations. See below for a list of available commands.

Available Commands