UI Development Standards for Test Automation
Web Pages
Page Elements
- Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
- Set a unique HTML "ID" attribute for primary identification
- The "ID" attribute must be unique, so never duplicate an "ID" attribute
- This resolves to
getElementByID()
to locate the element
- Set a unique HTML "Name" attribute for secondary identification
- If an "ID" attribute cannot be used to uniquely identify an element, then the "Name" attribute must be unique, and not used by another element
- The "Name" attribute is helpful for locating groups of elements
- This resolves to
getElementsByName()
to locate the element
- Set a unique HTML "Class" attribute as an alternative
- If an "ID" or "Name" attribute cannot be used to uniquely identify an element, then the "Class" attribute must be unique, and not used by another element
- The "Class" attribute is helpful for locating groups of elements
- This resolves to
getElementsByClassName()
andquerySelectorAll()
to locate the element
- Set a unique HTML 5 custom data attribute as an alternative
- If an "ID", "Name", or "Class" attribute cannot be used to uniquely identify an element, then an HTML 5 custom data attribute must be unique, and not used by another element
- This resolves to
querySelectorAll()
to locate the element
- Do not create an element that requires the use of an XPath expression to locate the element
- On web applications XPath is the slowest expression type to parse by test automation tools and browsers
- This is not true for iOS and Android native applications
- Do not create an element where it can only be uniquely identified by it's text node
- Example:
<span>John</span>
<span>Smith</span> - This requires an XPath expression to locate the element by it's text node
- Instead add an 'ID' attribute to identify the elements
<span id='firstName'>John</span>
<span id='lastName'>Smith</span>
- Example:
Wrapping Elements
- If the content of an element will change, then wrap the element with a unique parent element
- Examples are buttons, links, images, and hybrids:
<button class="..." />
<input type="button" value="save" onclick="..." />
<input type="image" value="save" onclick="..." />
<img name="save" src="..." onclick="..." />
<a class="button" alt="save" href="..." />
<a href="..." > <img src="..." /> </a>
<div class="button" onclick="..." />
- Examples are buttons, links, images, and hybrids:
- It is common in content-driven applications to frequently change the content on a page, and this includes the element structure
- Content Management Systems (CMS) let Marketing teams manipulate the content of an element and publish it to production on-demand
- This is a common failure point for automated tests that locate an element by it's attributes
Web Input Fields
- Always use the "ID" attribute
- Always set the "type" attribute
Web Radio Buttons
- Always use the "ID" attribute
- If the radio button is selected, then always set the "checked" attribute
- When grouping mutually exclusive radio buttons:
- Give each element a unique "ID" and "value" attribute
- Each element can have a common "name" or "class" attribute
Web Check Boxes
- Always use the "ID" attribute
- If the check box is checked, then always set the "checked" attribute
- When grouping mutually exclusive radio buttons:
- Give each element a unique "ID" and "value" attribute
- Each element can have a common "name" or "class" attribute
Web Select Dropdowns
- Always use the "ID" attribute
- Always set the "selected" attribute on Option elements
- Always set the "selected" attribute on the default Option
Web Links
- Ideally all links would have an "ID" attribute
- If an "ID" attribute is not used, then query string in the "href" attribute
must contain a constant page name that can be used in a CSS Selector
-
<a href="/index.html">Home</a>
- Now the element can be uniquely identified and located by
querySelectorAll("a[href*='/index.html']");
-
Web Labels
- Each label needs a "for" attribute that references another element's "ID" attribute
Web Text
- If the text content needs to be evaluated or verified for testing, then always give it a unique attribute such as an ID, Name, or Class
- Do not let the text content elements stand alone without an attribute, as this makes evaluations, verifications, and assertions very difficult - if not impossible to perform
Structures
Web Tables and Grids
- Every row and column should be attributed by a unique identifier, and a common class
- Example table:
<tr id="row_id_101" class="row_style">
<td id="column_id_101" class="column_style">...</td>
<td id="column_id_102" class="column_style">...</td>
</tr>
<tr id="row_id_102" class="row_style">
<td id="column_id_201" class="column_style">...</td>
<td id="column_id_202" class="column_style">...</td>
</tr> - Automation will search for all rows by CSS Selector using "class" attribute
querySelectorAll(".row_style");
- A new object will be generated for each row
- The "ID" attribute will be used to uniquely identify each row
- Example table:
- Do not nest the unique identifier in a child element of the row
- Example list with divisions:
<li>
<div>
<div item_id="101">...</div>
</div>
<div>
<div id="price_0">...</div>
<div id="quantity_0">...</div>
</div>
<div>
<input id="textbox_01">...</input>
<select id="dropdown_01">...</select>
</div>
</li>
<li>
<div>
<div item_id="102">...</div>
</div>
<div>
<div id="price_1">...</div>
<div id="quantity_1">...</div>
</div>
<div>
<input id="textbox_02">...</input>
<select id="dropdown_02">...</select>
</div>
</li> - It is incredibly difficult to uniquely identify and locate the child elements for each row
- Example list with divisions:
- If an "ID" attribute cannot be used to uniquely identify a row or column, then a unique "name", "class", or HTML 5 custom data attribute should be used
Web Tabs
Web Inline Frames
- If possible, do not use them
- iframes can cause problems on mobile browsers
- Do not nest iframes inside of another iframe
Web Pop-up Windows
- Always give a constant, unique name for each pop-up window
URI
Web Page URL
- Pages should have a unique name for validation purposes
- Examples:
index.html
home.jsp
home.ftl
home.aspx
- Examples:
- Validating page titles and headers is not a good practice, because of Content Management Systems (CMS) the content can change frequently, so verifying title and headers is not a robust approach to validation
Native Apps
Android Elements
- Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
- Set a unique resource ID attribute for primary identification
- The "resource-id" attribute must be unique, so never duplicate a "resource-id" attribute
- Set a unique accessibility ID attribute for secondary identification
- If an "resource-id" attribute cannot be used to uniquely identify an element, then the "content-desc" attribute must be unique, and not used by another element
- XPath expressions should be used as an alternative to search for views
iOS Elements
- Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
- Set a unique "Name" attribute for primary identification
- The "Name" attribute must be unique, so never duplicate a "Name" attribute
- Set a unique accessibility ID attribute for secondary identification
- If an "Name" attribute cannot be used to uniquely identify an element, then the "Label" attribute must be unique, and not used by another element
- XPath expressions should be used as an alternative to search for views