As we all know, functional testing scripts that run through the UI need stable locators in order to locate the elements.
Selenium uses the following locator strategies:
• ID
• Name
• Class Name
• XPath
• CSS Selector
• Tag Name
• Link Text
• Partial Link Text
But what happens if none of those locators are stable?
What happens if even the ID is dynamic and changes with each rendering of the page?
Let's say you want to click on the Register button, which has the register_312312312 ID.
The classic way to write the Selenium code would be something like this:
But that won't work, because the next time when you run your test and the page is rendered, it will have a different ID.
We could also write a custom CSS Selector, but our purpose here is to find the ID of that element and use it in our test.
We need to grab on to something that makes that element unique, perhaps an attribute.
But we will need to use JavaScript in order to achieve that.
Luckily, Selenium has the execute_script() method for such cases.
As we can see, the Register button has an attribute named title which has the value Register. This is what makes this element unique on that page.
This is the JavaScript code that you would have to execute in order to find that element and get the ID:
We just have to add that JavaScript code into a variable and execute it in our Selenium code:
Notice how I'm returning that variable which contains the ID to a Python variable. After that, I'm clicking on the element by locating it with the ID from that Python variable.
And voilà, we did it!
We are now handling dynamic locators with Selenium WebDriver.
This can also be executed in Endtest:
Top comments (5)
Hello Klaus,
Recently in the Selenium IDE github, someone asked a valid question about Selectors and modern JS frameworks like react of vue: github.com/SeleniumHQ/selenium-ide...
Relevant for my question is:
At the end, they added:
data-test
anddata-test-id
to select as well elements.Also, in the Selenium/WebDriver website they comment that there is support to select react components, based on their name: webdriver.io/docs/selectors.html#r...
As a passionate for automated testing, what's your view on this? Would you say that using these are a good alternative to use?
Greetings
Hi Daniela,
Thank you for taking the time to write that comment.
Yes, you can easily write a stable CSS Selector or XPath based on a certain attribute and the value of that attribute. It's ideal if you have an attribute like data-test or data-test-id, but very few web applications actually have those.
If someone would start a project from scratch, I would definitely encourage them to implement and use data-test or data-test-id attributes.
Hello Klaus, thanks a lot!
Is this approach faster than searching with xpath? such as
//*[@state = 'active']
I feel like the code in this post doesn't show an example of when you would need to use this technique, however it shows how to use it.
I can imagine a scenario where none of the Selenium selector strategies would apply (perhaps it moves about in the source of the page and shares attributes and classes with other items on the page) but you still need to pin down your element and get an ID for it. This would work in that case.
I'm pretty sure that using Selenium's native selection methods are what you would choose unless you simply can't get your element using them.