DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Trending

  • IntelliJ IDEA Switches to JetBrains YouTrack
  • HashMap Performance Improvements in Java 8
  • How to Load Cypress Chrome Extension
  • File Upload Security and Malware Protection
  1. DZone
  2. Coding
  3. Languages
  4. E2E Test — Use Probe Attribute As Element Locator

E2E Test — Use Probe Attribute As Element Locator

If you have experiences to create an E2E test project on a web application, you should be familiar with codes like this! Check it out!

jian wang user avatar by
jian wang
·
Sep. 08, 20 · Analysis
Like (1)
Save
Tweet
Share
3.66K Views

Join the DZone community and get the full member experience.

Join For Free

If you have experiences to create an E2E test project on a web application, you should be familiar with codes like this.

JavaScript
 




xxxxxxxxxx
1


 
1
// Manipulate browser to enter text to an input box
2
    const fooInput = await getElement('.fooInput');
3
    fooInput.type("user.name@email.com");
4

          
5
    // Manipulate browser to click the submit button
6
    const fooButton = await getElement('button[type=sybmit]');
7
    fooButton.click();
8

          
9
    // Then verify what is happening after form submit



The test actions are quite intuitively — get the references or handlers of specified elements in the view and then interact with them. We can see the CSS selectors are used to locate the target elements. Everything looks pretty good before you write the real test code. Test developers are always bothered by how to locate elements. 

At first, we cannot choose the existed class attributes as element Locator although they exist in most HTML tags. The 'class' of an element is often generated for CSS binding, it is not a surprise when we see the class attributes with strange values as the following HTML snippet.

HTML
 




xxxxxxxxxx
1


 
1
<form class='UserForm__form__34jfdf9r'>
2
    <input type='text' class='UserForm__input__fdfd9%O3' />
3
    <button type='submit' class='d#ere9i2'>
4
        Submit
5
    </button>
6
</form>



I believe no one wants to use these random strings as locators in the test code. But this is not the worst thing, the class value will be changed after each build (refer webpack and CSS module). That means we couldn't use them in test code to locate elements at all.

So we have to choose selectors other than a class attribute, like 'button[type=submit]'. But those selectors are not available for all elements, they are conflict with each other and hard to specify the single element.

How about choose using another type of locator — XPath. All elements in DOM could be retrieved by XPath, and most browser drivers or crawling APIs provide methods for XPath accessing. Sure, it works, but make things worse.

JavaScript
 




xxxxxxxxxx
1


 
1
// Manipulate browser to enter text to an input box
2
    const fooInput = await getElementByXPath('//*[@id="ui — setting-container"]/div[5]/div/div/div[2]/div/input');
3
    fooInput.type("user.name@email.com");
4

          
5
    // Manipulate browser to click the submit button
6
    const fooButton = await getElementByXPath('//*[@id="ui-setting-container"]/div[5]/div/div/button');
7
    fooButton.click();
8

          
9
    // Then verify what is happening after form submit



Lets put the ugly XPath name aside, the important thing is the XPath is fragile because it depends on the HTML hierarchy. The XPath will be crashed after some tags changed. Just think about how many conditional tags and 3-party components exist on a page, the HTML is always changing even after the developing stage.

Anyway, we should add a dedicated Probe to target elements for testing. These probe locators should be readable with easy syntax, and not conflict with others in DOM.

Most developers like to add 'id' attributes as a testing probe. The 'id' is a good probe working in most scenarios.

JavaScript
 




xxxxxxxxxx
1


 
1
// Manipulate browser to enter text to an input box
2
    const fooInput = await getElementById('#Login_Email_Input');
3
    fooInput.type("user.name@email.com");
4

          
5
    // Manipulate browser to click the submit button
6
    const fooButton = await ById('#Login_Submit_Button');
7
    fooButton.click();
8

          
9
    // Then verify what is happening after form submit



However, the 'id' attribute is often used for CSS binding and HTML reference purposes. Sometimes we can not add the id to some elements, or the id will conflict with other components out of control, e.g., some HTML snippets will be generated and insert to the current page.

Another drawback of using 'id' is the 'id' attribute should be unique in the current view. We shouldn't add the same ids to a group of elements. Sometimes we have to add computed ids to target elements, e.g. adding ids to cells of a table. That means extra work in UI coding, and it is not acceptable usually.

The correct solution is choosing a custom attribute as Probe attribute, make sure this attribute is not used for other purposes, for example:

HTML
 




xxxxxxxxxx
1


 
1
<form class='UserForm__form__34jfdf9r'>
2
    <input e2e='Login_Email_Input' type='text' class='UserForm__input__fdfd9%O3' />
3
    <button e2e='Login_Submit_Button' type='submit' class='d#ere9i2'>
4
        Submit
5
    </button>
6
</form>



Locate elements by custom attributes would more verbose than getElementById, but we can add a syntax parser in a test project to keep the coding clean. Then the test code will be:

JavaScript
 




xxxxxxxxxx
1


 
1
// Manipulate browser to enter text to an input box
2
    const fooInput = await getElementByProbe('Login_Email_Input@e2e');
3
    fooInput.type("user.name@email.com");
4

          
5
    // Manipulate browser to click the submit button
6
    const fooButton = await getElementByProbe('Login_Submit_Button@e2e');
7
    fooButton.click();



With the help of the probe syntax parser, we can locate elements sophisticatedly but still with the clean syntax:

JavaScript
 




xxxxxxxxxx
1


 
1
// Get the 4th token in token list
2
const user = await getElementByProbe('Expired_Token@e2e(3)');
3

          
4
// Get the 4th token of tokens with text content "Super Token"
5
const user = await getElementByProbe('Expired_Token@e2e("Super Token", 3)');



The dedicated element locators are used for the E2E test only, we don't want to keep them in the product package. It is easy to do this if you use custom probe attribute, just process the HTML and remove this attribute in the build pipeline.

How is the first E2E test tool implement Probe syntax as CSS selector and XPath? It supports parsing the following probe locator.

  • Locate one element: _"expired-token@e2e"_ by selector or XPath retrieve.
  • Locate all elements: _"expired-token@e2e"_ by selector or XPath retrieve.
  • locate the nth element: _"expired-token@e2e([number])"_ by selector or xpath retrieve..
  • Locate all elements with content: _"expired-token@e2e([string])"_ by xpath retrieve.
  • locate the nth element with content: _"expired-token@e2e([string], \[number\])"_ by xpath retrieve.

Please refer Handow Documentation to see more details.

Here is a Live Demo of a Handow E2E test project.

Element Attribute (computing) Testing XPath Locate (Unix) HTML

Opinions expressed by DZone contributors are their own.

Trending

  • IntelliJ IDEA Switches to JetBrains YouTrack
  • HashMap Performance Improvements in Java 8
  • How to Load Cypress Chrome Extension
  • File Upload Security and Malware Protection

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: