One of the keys to creating Experience scripts is to uniquely and robustly identify the web page elements the script commands operate on. For a script to be robust, it should continue to work even after the web pages it is accessing change in minor ways. Ideally, it can withstand a web page being rearranged or having elements removed or added. If the script is not robust, any change to a web page accessed by the script requires changes to the script.

A locator identifies a web element on a web page. It identifies the web element based on the element’s HTML properties. Some of the common web elements used when scripting include:

  • Buttons
  • Hyperlinks
  • Dropdowns
  • Check boxes
  • Radio Buttons
  • Text boxes

The HTML properties associated with a web element determine the type of locator to use. You can find these properties using the Inspect feature in Chrome. The locator types and when they are used include:

  • ID - Can be used if an “id” attribute is available.
  • Name - Can be used if a “name” attribute is available.
  • Link Text - Can be used if link text is available.
  • XPath - Used when the simpler locator types above are not available. Recommended.
  • CSS Selector - Used when the simpler locator types above are not available. Similar to XPath in capability.

Using Inspect

The Inspect feature in Chrome is the recommended way of finding a web element’s HTML properties to be used in a locator.

To use Inspect:

  1. In Chrome, navigate to the page you are interested in.
  2. Right-click the element you are interested in and click Inspect.
    • The Inspect pane appears with the Elements tab selected.
    • The HTML for the selected element is highlighted.

For example, selecting the “English” link on the Wikipedia homepage displays the following:

inspect-wikipedia.png

Locators using ID

If an “id” attribute is available in a web element’s HTML, it can be used as the locator for the element. Because an ID is supposed to be unique, it is a great choice as a locator.

For example, using Inspect in Chrome to view the HTML for the “English” link on the Wikipedia homepage we see ... id="js-link-box-en" ....

The syntax for the ID locator is:

id=<element-id>

So, for our example, the ID locator is:

id=js-link-box-en

Notice that there are no double-quotes in the locator.

To confirm the locator is valid and unique you can test it.

Note: ID’s that contain a long string of numbers are typically dynamic and should not be used directly with an ID locator as they will continue to change and cause your script to fail.

Locators using Name

If a “name” attribute is available in a web element’s HTML, it can be used as the locator for the element.

For example, using Inspect in Chrome to view the HTML for the search box on the Wikipedia homepage we see ... name="search" ....

The syntax for the name locator is:

name=<element-name>

So, for our example, the name locator is:

name=search

Notice that there are no double-quotes in the locator.

To confirm the locator is valid and unique you can test it.

If link text is available in a web element’s HTML, it can be used as the locator for the element.

For example, using Inspect in Chrome to view the HTML for the “Wikimedia Foundation” link on the Wikipedia homepage we see <a href="//wikimediafoundation.org/">Wikimedia Foundation</a>. The link text is “Wikimedia Foundation”.

The syntax for the link text locator is:

link=<element-link-text>

So, for our example, the link text locator is:

link=Wikimedia Foundation

Notice that there are no double-quotes in the locator.

To confirm the locator is valid and unique you can test it.

Locators using XPath

XPath is a powerful language for selecting nodes in an XML document. For our purposes it allows us to select a particular HTML element on a web page. The hierarchical nature of the HTML in a web page (similar to the hierarchical nature of a file system’s directory structure) allows it to be navigated easily. For example, the absolute path to a given element might look as follows: /html/body/footer/div/nav/div/div[7]/ul/li. However, if we use this path in a script, the slightest modification to the page could change this path and cause the script to fail. Our goal is to create robust XPath locators that are resilient to web page changes.

To create a robust XPath locator, you need to look for features of an element that make it unique and are not likely to change. The XPath language provides great flexibility in this regard.

The subsections that follow use the following XML snippet to provide examples of this flexibility. Note that XPath locators are case sensitive.

<?xml version="1.0" encoding="UTF-8"?>

<recordstore>

<album>
  <title id="abbeyr" lang="en" class="60s" funattribute="reallyfun">Abbey Road</title>
  <price class="cheap">22.99</price>
</album>

<album>
  <title id="rattleh" lang="en" class="80s">Rattle and Hum</title>
  <price class="expensive">39.95</price>
</album>

</recordstore>

Selecting based on element text

Text-based XPath locators use the following syntax:

//<element-type>[contains(text(), '<element-text>')]

For example, to select the title element containing “Abbey Road”, we could use the following XPath locator:

//title[contains(text(), 'Abbey Road')]

Note: Any substring of text can be used.

Selecting based on attributes

You can select an element based on an arbitrary attribute using the following syntax:

//<element-type>[@<attribute-name>='<attribute-value>']

For example, to select the title element for “Abbey Road” using the “funattribute” attribute, we could use the following XPath locator:

//title[@funattribute='reallyfun']

Selecting based on a substring of an attribute value

You can select an element based on an substring of an arbitrary attribute using the following syntax:

//<element-type>[contains(@<attribute-name>, '<attribute-value>')]

For example, to select the title element for “Abbey Road” using a substring of the “funattribute” attribute, we could use the following XPath locator:

//title[contains(@funattribute, 'lyfun')]

Selecting using any element type

Examples in the sections above specify the <element-type> explicitly, but you can use a wild-card (“*”) to indicate “any element type”. For example, to select elements that contain the “funattribute” attribute with a value of “reallyfun”, we could use the following XPath locator:

//*[@funattribute='reallyfun']

Note that the change from the previous examples was to change “title” to “*”.

Handing multiple returned elements

If you create an XPath locator that identifies more than one element, you can indicate which of the elements you want by specifying an index.

For example, let’s say we use the following XPath locator:

//title[@lang='en']

This returns an array containing two title elements - the ones containing “Abbey Road” and “Rattle and Hum”. The element that appears first in the array is the one that appears first on the web page when traversed from top to bottom. In this case, “Abbey Road” is first.

To identify which of the two we want, we need to use an index. The syntax for specifying an index is as follows:

(<locator>)[<index>]

As array indexing begins at 1 for Xpath locators, to select the title element containing “Abbey Road”, the XPath is:

(//title[@lang='en'])[1]

If we wanted to select “Learning XML” we would use:

(//title[@lang='en'])[2]

Selecting on multiple conditions

To avoid situations where multiple elements are returned, you can specify more than one condition in the XPath locator. The syntax for this is:

//<element-type>[<expression-1> and <expression-2>]

For example, to modify the previous example so that it returns a single element, we can select based on the “lang” attribute and the “Abbey Road” text:

//title[@lang='en' and contains(text(), 'Abbey Road')]

The previous subsections touched on some of the most useful XPath expressions for use when creating Experience scripts, but the XPath language is more extensive. Additional references include:

Locators using CSS Selectors

CSS Selectors, like XPaths, provide a powerful way to select elements on a web page. One disadvantage is that you are not able to select elements based on text that is not an attribute value.

As with XPaths, our goal is to create robust CSS Selectors that are resilient to web page changes. To create a robust CSS Selector, you need to look for features of an element that make it unique and are not likely to change.

The subsections that follow use the following XML snippet to provide examples how to create CSS Selectors. Note that CSS Selectors are case sensitive.

<?xml version="1.0" encoding="UTF-8"?>

<recordstore>

<album>
  <title id="abbeyr" lang="en" class="60s" funattribute="reallyfun">Abbey Road</title>
  <price class="cheap">22.99</price>
</album>

<album>
  <title id="rattleh" lang="en" class="80s">Rattle and Hum</title>
  <price class="expensive">39.95</price>
</album>

</recordstore>

Selecting based on ID

CSS Selectors that use the element ID (indicated by “#”) have the following syntax:

css=<element-type>#<ID-attribute-value>

For example, to select the title element with an ID of “abbeyr”, we could use the following CSS Selector:

css=title#abbeyr

Selecting based on class

CSS Selectors that use the element’s class attribute (indicated by “.”) have the following syntax:

css=<element-type>.<class-attribute-value>

For example, to select the price element with a class of “expensive”, we could use the following CSS Selector:

css=price.expensive

Selecting based on arbitrary attributes

CSS Selectors that use arbitrary attributes have the following syntax:

css=<element-type>[<attribute-name>='<attribute-value>']

For example, to select the title element for “Abbey Road” using the “funattribute” attribute, we could use the following CSS Selector:

css=title[funattribute='reallyfun']

Selecting based on ID or Class and arbitrary attributes

It is possible to combine CSS Selectors using ID or Class with those that use arbitrary attributes.

CSS Selectors that use ID and an arbitrary attribute have the following syntax:

css=<element-type>#<ID-attribute-value>[<attribute-name>='<attribute-value>']

For example, to select the title element for “Abbey Road” using the ID (abbeyr) and the “funattribute” attribute, we could use the following CSS Selector:

css=title#abbeyr[funattribute='reallyfun']

CSS Selectors that use class and an arbitrary attribute have the following syntax:

css=<element-type>.<class-attribute-value>[<attribute-name>='<attribute-value>']

For example, to select the title element for “Abbey Road” using the class (60s) and the “funattribute” attribute, we could use the following CSS Selector:

css=title.60s[funattribute='reallyfun']

Selecting with multiple arbitrary attributes

To make the previous example even more explicit, we could include additional attributes. For example:

css=title.60s[funattribute='reallyfun'][lang='en']

Selecting based on substrings within attributes

The previous examples used complete attribute value strings, but CSS Selectors can also be created using substrings of attribute values. The substring can be at the beginning of the string (Prefix), at any point in the string (Substring), or at the end of the string (Suffix).

Prefix

CSS Selectors that use prefixes (indicated by “^”) have the following syntax:

css=<element-type>[<attribute-name>^='<attribute-value-prefix>']

For example, to select the title element for “Abbey Road” using the a prefix in the “funattribute” attribute (“reallyfun”), we could use the following CSS Selector:

css=title[funattribute^='reall']

Substring

CSS Selectors that use a general substring (indicated by “*”) have the following syntax:

css=<element-type>[<attribute-name>*='<attribute-value-substring>']

For example, to select the title element for “Abbey Road” using the a substring in the “funattribute” attribute (“reallyfun”), we could use the following CSS Selector:

css=title[funattribute*='llyf']

Suffix

CSS Selectors that use a suffix (indicated by “$”) have the following syntax:

css=<element-type>[<attribute-name>$='<attribute-value-suffix>']

For example, to select the title element for “Abbey Road” using the a substring in the “funattribute” attribute (“reallyfun”), we could use the following CSS Selector:

css=title[funattribute$='yfun']

The previous subsections touched on some of the most useful CSS Selector expressions for use when creating Experience scripts, but more are available. Additional references include:

Testing a locator

Once you create a locator, you should confirm that it works before using it in a script. There are dedicated testers available, but you can also use the Inspect feature in Chrome (recommended) or Kantu.

Test a locator using Inspect in Chrome

If you are already using Chrome’s Inspect feature to find a web element’s HTML properties, it makes sense to use it to test the locators you create. It can be used for testing XPath locators and CSS Selectors. In either case, there are a number of possible response types.

To test a locator using Chrome’s Inspect feature:

  1. Open Inspect in Chrome.
    • The Console tab in the bottom pane should be selected.
      inspect-console.png
  2. To test an XPath locator, see Test an XPath locator.
  3. To test a CSS Selector, see Test a CSS Selector.

Test an XPath locator

To test an XPath locator, use the following syntax:

$x("<locator>")

For example, to test XPath locator //a[@id='js-link-box-en'], you would enter the following at the Console command prompt:

$x("//a[@id='js-link-box-en']")

Several response types are possible.

Test a CSS Selector

To test a CSS Selector, use the following syntax:

$$("<locator>")

For example, to test CSS Selector a#js-link-box-en you would enter the following at the Console command prompt:

$$("a#js-link-box-en")

Several response types are possible.

Response types

When you test a locator using the Console within Chrome’s Inspect feature, a number of response types are possible. The goal is to have the locator return a single match. In other words, the locator identifies a unique element on the web page.

Single match

This is an example of a locator (//a[@id='js-link-box-en']) that matches a single element:

inspect-console-success.png

Only one element is returned. This is what you want. The locator can be used in your script.

Multiple matches

This is an example of a locator (//a[contains(@class, 'link-box')]) that matches multiple (10 in this case) elements:

inspect-console-multiple.png

Multiple elements are returned. You need to refine the locator until it matches a single element.

No match

This is an example of a locator (//a[@class='link-box-xxx']) that fails to match an element:

inspect-console-none.png

An empty set is returned. You need to refine the locator until it matches a single element.

Bad syntax

This is an example of a command that is specified incorrectly. In this case, a valid XPath locator (//a[@id='js-link-box-en']) is specified but the wrong command ($$) is used to evaluate it:

inspect-console-fail.png

An error message is returned. You need to refine the locator to use the correct command or the correct syntax.

Test a locator using Kantu

If you are using the Kantu Selenium IDE as a script recorder, you can also use it to evaluate locators that you want to use in your script using the Find button.

For example, to evaluate XPath locator //a[@id='js-link-box-en'] on the Wikipedia home page, you would enter the locator text in the Target field of a script command and click Find.

kantu-find.png

If successful, the matched element on the web page will be briefly highlighted.

Note: For locators that match multiple elements, only the first on the page will be highlighted. You will have no indication that the selector actually matched multiple elements as you do using the Inspect feature in Chrome.