Finding Locators for React JS Dynamic Drop Downs
Front-end web application development has changed a lot since the 2000's. Clicking links and loading new pages is out. Now we treat the browser as an application run-time, and shift all the processing to the client side with JavaScript.
Popular JavaScript frameworks like React JS, Vue.js, Angular, and Elm all follow the single page, reactive, dynamically-updating-elements architecture pattern. And that means that modern, automated test scenarios will need to handle the behavior of dynamic elements.
The Problem
The usual pattern of writing an automated test is to load a page in the browser, find the element you need to target on the page, and inspect the element (Right Click > Inspect or Command + Option + C on a Mac). The Elements panel of Developer Tools opens up, and from there, you can figure out a selector expression for the element.
For a static element, this process works fine. But for the more dynamic elements that are common in React JS apps, you quickly run into a frustrating problem:
When you interact with a dynamic element such as a drop down menu, the items within the menu change as you interact with it. And if you have the Developer Tools panel open, you can see those changes happen in the element tree (changing elements will flash purple). Then, if you try to expand parts of the element tree to see the code for specific items, the menu suddenly collapses as soon as you click, because the input focus has shifted away from the dynamic element.
The Solution
To overcome this very frustrating problem, you need to use an advanced debugging feature of Developer Tools, DOM Breakpoints:
Before you attempt to interact with the dynamic element, in Developer Tools, find the closest parent element that contains the dynamic element. Open the context menu, look for “Break On”, and “Subtree Modifications” (Right Click > Break On > Subtree Modifications).
With this setting enabled, interact with the dynamic element, and the browser will pause execution and shift to the Sources panel. Switch back to the Elements panel, and you’ll see the dynamic element and its child elements, frozen in time and ready for inspection. You may need to hit the ▶️ button a few times to advance the code, but with the debugger active, you’ll have the opportunity to determine the right selector expression for the target element.
After you figure out your selector expression, look up and to the left of the parent element, and you’ll see a blue dot representing the active DOM breakpoint. Click the blue dot and move through the menus to de-select the break point option. Then click the ▶️ button to resume normal JavaScript execution.
Next Steps
With this debugging technique, you’ll be able to find locators for dynamic elements easily. Then in your test code, you’ll need to write some explicit waits to watch for updates to elements. It’s a good time to get very familiar with the Wait Interface and Expected Conditions in Selenium.