Large and complex Single Page Applications (SPAs) might impose significant challenges for test automation tools due to the way the elements are organized. This blog post walks you through a few simple steps to automate SPAs and handle challenging scenarios by enhancing Test Studio’s element find logic.
In a SPA (Single Page [Web] Application), the DOM of the browser can change dramatically without the URL changing at all. This might become a nightmare for testers trying to locate elements in the DOM while recording and executing tests, which causes issues even for Test Studio. Test Studio’s image-based element identification logic can be too generic if you want to uniquely identify elements within a SPA. The result is that in test runtime, an unexpected element may be located instead of the desired one.
This issue is rather common for SPAs due to how the elements are organized in the DOM. With this article I will demonstrate the challenges associated with locating elements within SPAs. The story won’t be complete, though, if we don’t present to you a solution that can help and save you a lot of trouble. In our case, the solution is based on utilizing chained queries to purposefully enhance Test Studio’s element find logic.
In short, the solution is based on assigning IDs to containers instead of single elements. By doing that, we make sure that Test Studio can locate these elements and uniquely identify them. For example, if you have a contact form with input fields (along with the same contact form existing multiple times within the same page), you will not assign IDs to all inputs in the contact form, but only to the container under which these elements (first name, last name, address) are listed.
This way, it is ensured that actions and verifications will be executed on the correct contact form while, at the same time, avoiding the tedious work of assigning IDs to each field in multiple identical contact forms that may appear on the page depending on the circumstances.
When you want Test Studio to identify the field containing last name, you will query for the container based on the ID that you have assigned to that container. Then you can utilize chained find expressions to look for an element within a specific container.
This will make the automated tests not only pass without running into failures, but you can be confident in the final output after executing the test or that Test Studio validates the correct elements.
The demonstration we are going to show represents a use case provided by Test Studio user Mark Claassen and his team based on the challenges they were facing with automating their Kendo UI for Angular–based application.
Mark has been working on UI design for over 20 years, creating highly dynamic interfaces. He has worked on all phases of the design process and has implemented the solutions on all tiers of the application.
Here is the use case description as provided by Mark. In their Kendo UI for Angular–based application, there are two dialogs that may appear after successful login. When they recorded a test and one of these dialogs came up, they selected a button in that component to close the dialog.
Test Studio creates find logic for this button implying something like: “Look for a dialog (by class name) and then look for button 1.” However, on a subsequent run, the other dialog came up. This dialog itself had a matching class and had a “button 1.” However, “button 1” in this dialog was not a “close” button, but a “next” button. When Test Studio executed the test, steps were executed on the unexpected dialog and the whole test was derailed from that point forward. Even worse, the action steps did not fail, which made the test case hard to debug.
The element’s image captured by Test Studio showed that the element was the “close” button, so it looked right in the editor. However, when the annotation feature was turned on, the expected “close” button did not appear—instead, the action was performed on the “next” button from the second dialog.
Mark had been trying to track down why the “close” did not work but missed the fact that it was finding it in the wrong dialog.
When the element find logic in Test Studio breaks down, as in the above example, it can lead to situations that are hard to diagnose. While the above example is simple, there are more complex scenarios that require complex solutions. If we want to make this work in Test Studio, we would need to:
Although that is possible, it is not very efficient. You will end up working closely with development to ensure the appropriate find logic is used to locate elements in the DOM and ultimately you will have to retest all already created tests.
There is an easier way to do it with Test Studio, and it worked perfectly well for Mark’s application, helping him overcome the issue completely. It required him to slightly adapt the application though.
Modifying the original example would entail adding an “automation_id” attribute to each of the dialogs: “automation_id=Dialog 1” and “automation_id=Dialog 2”.
Then, what we need to do in Test Studio is to add the custom attribute “automation_id” to enhance the find logic as part of the project settings.
Doing this will inform Test Studio’s find logic algorithm to always use parent nodes that have this attribute. This would mean for the automatic element find logic for these buttons to use chained queries as follows:
The first element (button:1) would never be accidently found in “Dialog 2” because it is only found when it follows the parent-child logic and is part of the “Dialog 1” container.
This is how setting Find Expressions looks in Test Studio.
The Edit Element pane displays the currently used find expression for the element and allows you to modify it.
Advanced Mode button displays the current find expression in text format and allows you to type in a custom one.
Assigning “automation_id” attributes strategically to containers instead of single elements will enhance the element find logic tremendously and enable the purposeful reuse of elements in a SPA.
It is important that the developers on the team are aware of this approach and follow it by adding such attributes to areas that they know are likely to play a role for the testers, or, in other words—to write code with its testability in mind. This will allow the testers to use these attributes without further and cumbersome analysis of the DOM.
If a QA determines that the find logic is too specific for a particular element, they could always adapt the level of detail. But keep in mind that it is easier to remove levels of specificity than it is to add them.
The find logic screen consists of attribute groups for finding a node in the DOM. These groups together form a path. Adding additional groups below a group is intuitive. To insert a group at the top, you can use the text box in the Advanced Mode of the find expression window.
Large and complex SPAs might be quite challenging for testing tools to automate. The ultimate goal here is to maintain a robust find logic and locate elements easily and uniquely, without changing the code of the application too often as this will create chaos across the entire team or project.
Adding HTML IDs to every single element would be a lot of effort and hard to sustain. On the other hand, using “automation_id” attributes, as described in this article, can help tremendously in finding a good balance between modifying source code as little as possible while enhancing the find logic to an extent that works for us and, ultimately, benefits us.
Asya Ivanova is the Product Marketing Manager for Telerik Test Studio. A passionate technology enthusiast, she has product experience within BIM, Master Data Management and pro audio. Together with the Test Studio team she keeps an eye on ways to make test automation easier for the QA engineer. Asya is a hi fi geek, spending her time with some good old and new album records. Connect on LinkedIn.
Subscribe to be the first to get our expert-written articles and tutorials for developers!