Extracting Value from an Auto-Suggestive Dropdown with Javascript in Selenium

Blog Post: Smoothly Navigating Autosuggest Dropdowns with Selenium and JavaScriptExecutor in Java

Hello everyone! Today, I’m excited to share my journey on how I mastered the art of automating autosuggestive dropdowns using Selenium’s JavaScriptExecutor. This post is designed to help anyone who might be struggling with manipulating and testing UI components that are a bit more dynamic than your typical form elements. I recently faced a challenge with an autosuggest dropdown where typical Selenium methods were falling short, prompting me to dive deeper into the JavaScriptExecutor and its powerful capabilities.

Summary

Dealing with autosuggest dropdowns can be tricky. Recently, while working on a project, I encountered a particularly stubborn dropdown. The dropdown did not interact well with Selenium’s standard sendKeys method followed by keys navigation to select an option. In this blog post, I narrate my solution to tackle this using JavaScriptExecutor to directly interact with JavaScript elements, providing a deeper level of control over the DOM elements.

The Problem

I was working on a test script for a web page with an autosuggestive dropdown. The HTML structure of the dropdown looked quite standard, with an input tag for the text field and a corresponding unordered list (<ul>) that populated the suggestions. Here is a glimpse of the HTML setup:

<input type="text" id="autocomplete" class="inputs ui-autocomplete-input">
<ul id="ui-id-1" class="ui-menu ...">
    <li class="ui-menu-item"><div id="ui-id-81">British Indian Ocean Territory</div></li>
    <li class="ui-menu-item"><div id="ui-id-82">India</div></li>
    <li class="ui-menu-item"><div id="ui-id-83">Indonesia</div></li>
</ul>

Essentially, I needed to input “ind” into the text field, move through the dropdown list, and select “India”. Simple enough, but the sendKeys followed by Keys.DOWN to navigate was unreliable due to asynchronous loading of the suggestions and id nuances.

JavaScriptExecutor to the Rescue

The native Selenium interactions weren’t cutting it, so I turned to JavascriptExecutor for a more direct approach. Here’s the step-by-step solution using JavaScriptExecutor:

  1. Sending Keys to the Input Field

Instead of using sendKeys, I opted to directly set the value using JavaScript.

JavascriptExecutor js = (JavascriptExecutor) driver;
   WebElement autocomplete = driver.findElement(By.id("autocomplete"));
   js.executeScript("arguments[0].value='ind';", autocomplete);

  1. Simulating the Down Arrow Key Press

To trigger the dropdown list after setting the input value.

js.executeScript("var e = new KeyboardEvent('keydown', {'keyCode':40, 'which':40}); arguments[0].dispatchEvent(e);", autocomplete);

  1. Retrieve and Click the Desired Option

The challenge here was to interact with DOM elements using JavaScript to find the right option.

String script = "return Array.from(document.querySelectorAll('#ui-id-1 .ui-menu-item div')).find(el => el.textContent === 'India');";
   WebElement indiaOption = (WebElement) js.executeScript(script);
   if (indiaOption != null) {
       indiaOption.click();
   }

This approach ensured that I could reliably trigger the dropdown, navigate the options, and select the desired entry without worrying about the timing issues associated with asynchronous content loading.

Conclusion

Using JavaScriptExecutor unlocked a new level of control in handling complex UI elements, especially when traditional Selenium methods fall short. It was an enlightening and empowering experience, and I urge those facing similar challenges not to shy away from delving into JavaScriptExecutor for more intricate interactions.

Navigating through JavaScript-driven components can be daunting, but with the right approach, it’s another powerful tool in your automation arsenal. Hopefully, this solution not only resolves the dropdown selection issue but also enhances your testing strategy with Selenium. Thank you for reading!


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *