How To Handle Dropdowns In Selenium WebDriver Using Python?
Harshit Paul
Posted On: March 8, 2021
93786 Views
13 Min Read
This article is a part of our Content Hub. For more in-depth resources, check out our content hub on Selenium Python Tutorial.
Dropdowns are an integral part of modern websites. And like any other HTML element, these need to be tested as well, especially when you are performing automated browser testing. UI/UX designers love dropdown elements, but it’s the automation testing engineers who get to play with it. Therefore, it becomes important to know how to handle dropdowns in Selenium WebDriver when you are handling access forms or testing websites.
Designers prefer using aesthetically appealing dropdown menus or boxes. Mostly because dropdowns tend to utilize the available screen space frugally. It is useful when you want only specific inputs from users and not some crap data. However, dropdown design bloopers could be a serious turn-off for users.
I have come across websites with poorly implemented navigational dropdown menus, where I had no way to exit the menu without clicking on an option. It’s an erroneously irritating experience! In mobile browsers, it gets even trickier, where ideally, dropdown options have to be optimized for the thumb interface. To ensure a seamless user experience across the application or website, test automation engineers are often required to investigate any possible flaw with the dropdowns thoroughly.
This insight aims to be your go-to destination for dealing with how to handle dropdowns in Selenium WebDriver using Python. You may consider bookmarking this page and subscribing to our blog (if you haven’t already) for future automation testing tutorials and LambdaTest’s offer updates.
Starting your journey with Selenium WebDriver? Check out this step-by-step guide to perform Automation testing using Selenium WebDriver.
TABLE OF CONTENT
- Different Types of Dropdowns, an Automation Test Engineer Must Know
- How to Handle Dropdowns in Selenium Webdriver
- Using LambdaTest to perform an automated Select Deselect test operation in the cloud using Selenium Grid
- Common Error While Working with Dropdowns: Handling ElementNotInteractable Exception
Different Types of Dropdowns, an Automation Test Engineer Must Know
In HTML, we encounter four types of dropdown implementations:
- Dropdown Navigation Options :
- Dropdown Command Options :
- Attribute Selection Dropdown Options :
- Form Filling Dropdowns Options :
These are usually encountered in NavBar of a website with dropdown links to other webpages.
Like navigation dropdown options, these are found at the top, but these are meant to perform some action on the active page itself. Example – Google Docs Menu Bar.
These are commonly used to implement search filtering features and customization options like changing the color-template or language of a website.
These sort of dropdown options are used for registration forms or product/service booking forms.
This certification is for professionals looking to develop advanced, hands-on expertise in Selenium automation testing with Python and take their career to the next level.
Here’s a short glimpse of the Selenium Python 101 certification from LambdaTest:
How to Handle Dropdowns in Selenium Webdriver
Using CSS and/or XPATH selectors in Selenium Python can test a variety of dropdown components. However, Selenium WebDriver includes the SELECT class as an extra functionality. It can be used to automate interactions with dropdown menus created with the html tag “select”.
What is ‘Select’ Class in Selenium WebDriver
Selenium provides the Select class to implement the HTML Select elements. The Select class in Selenium is an ordinary Java class that you can create as a new object using the keyword New and specifying a web element’s location. In this tutorial on how to handle dropdowns in Selenium WebDriver, we shall see different SELECT class functions:
class selenium.webdriver.support.select.Select(webelement)
Under the hood, the Selenium select class checks if the HTML web element we are using it with is a <select> tag or not. If not, Selenium WebDriver throws UnexpectedTagNameException
.
Note: Selenium ‘Select’ is only meant to be used with html <select> tag and none else.”
The selenium SELECT class comprises of following sub-functions:
options(self)
all_selected_options(self)
first_selected_option(self)
select_by_value(self, value)
select_by_index(self, index)
select_by_visible_text(self, text)
This function finds all <options> tags within the target <select> tag.
This function loops over all the options and checks if selected using is_selected() method and returns a list of selected “options.”
This is similar to the above function, loops over all available options under the <select> tag but returns as soon as it finds the first is_selected() <option>.
This function makes use of CSS selector to evaluate value attributes of web elements. It returns all the <options> with matching values.
This SELECT class function of Selenium evaluates the index of <option> tags by using get_attribute(“index”) and returns the matching option.
This function is implemented using XPATH and multiple if-else. Selects the option elements which contain string equal to text attribute between opening and closing option tags i.e, <option>dummy_text_attribute</option>.
Similarly, there are functions to deselect the selected options too –
deselect_by_index(self, index)
deselect_by_value(self, value)
deselect_all(self)
deselect_by_visible_text(self, text)
The two functions which are internally used by Selenium WebDriver’s SELECT class to implement above functions for “selecting or deselecting” options are:
1 2 3 |
def _setSelected(self, option): if not option.is_selected(): option.click() |
1 2 3 |
def _unsetSelected(self, option): if option.is_selected(): option.click() |
For all the below demonstrations, we shall be using a webpage with three different dropdown elements hosted on the demo page as shown below:
Selecting a Dropdown option in Selenium WebDriver with matching text
To automate testing of <option> selection, based on the criteria whether it matches a particular text string or not, we use the select_by_visible_text(self, text)
method of a SELECT class in Selenium.
Example
Under “Demo for individual select” section in the aforementioned webpage, we have four options – “Python, Java, C#, PHP”. To select “Java” using string match:
1 2 |
dropdown1 = Select(driver.find_element_by_id('lang1')) dropdown1.select_by_visible_text('Java') |
1 |
Selecting a Dropdown option in Selenium WebDriver using the value attribute |
Often, <select> and <options> tags when used inside a form are implemented by assigning a “value” attribute to options. The text between opening and closing <option> tags is visible to the users, but it is the value assigned to the “value” attribute sent to the server on form submit. As said before, Selenium WebDriver provides an API for automation test engineers to select options based on option values too, i.e., select_by_value(self, value)
.
On our demo page, the first “Select your lang:” section is a form element implemented using select & option with value attribute. To select python using select_by_value
method –
1 2 |
dropdown = Select(driver.find_element_by_id('lang')) dropdown.select_by_value('python') |
Selecting a Dropdown option in Selenium WebDriver using index
Javascript provides a DOM property to select <options> using index –
1 |
document.getElementById("myCourses").selectedIndex = "3"; |
Similarly, Selenium Python provides a method i.e., select_by_index(self, index)
to automate selection of option(s). In “Demo for individual select” section on our test webpage, we can select C# by passing an index of ‘3’.
1 2 |
dropdown = Select(driver.find_element_by_id('lang1')) dropdown.select_by_index(3) |
Using Selenium WebDriver for handling Dropdowns with multiple select options enabled
Multiple option selection is enabled by adding an attribute named “multiple” to <select> elements. To check if a <select> dropdown allows multiple selection, we can use xpath or get attribute or both. Internally, Selenium in its __init__() constructor use following approach to evaluate if drop-down list allow multiple option selection –
1 2 3 |
self._el = webelement multi = self._el.get_attribute("multiple") self.is_multiple = multi and multi != "false" |
We first identify a <select> webElement using xpath or CSS selectors and then evaluate if it contains a “multiple” attribute using the get_attribute() method.
1 2 3 4 5 |
dropdown = driver.find_element_by_tag_name('select') if dropdown.get_attribute("multiple"): print("multiple select options can be chosen") else: print("only one select option can be selected") |
Selecting multiple Dropdown options in Selenium WebDriver
Once you know that multiple options can be selected in a dropdown, we can iterate over options and choose them using Selenium WebDriver’s “select” class methods. Alternatively, we can also use the “actionchains” class of Selenium WebDriver to select multiple choices. The strategy is first to get the <select> web element and then perform chained click actions on it with “ctrl” key pressed. For our demo test page, we demonstrate both approaches to select multiple options in Selenium Python.
For the “action chains” demo, we first evaluate if the <select> element with id “lang2” is having a “multiple” attribute. If yes, then we select webelements with “PHP” and “C#” options respectively –
1 2 |
myOption = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'C#')]") myOption1 = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'PHP')]") |
and then we can execute chained actions on it using the following code –
1 2 |
ActionChains(driver).key_down(Keys.CONTROL).click(myOption).key_up(Keys.CONTROL).perform() ActionChains(driver).key_down(Keys.CONTROL).click(myOption1).key_up(Keys.CONTROL).perform() |
For the Selenium SELECT class demo, we first find the <select> element with id “lang2” having a “multiple” attribute. If yes, then we select options with “Java,” “PHP,” and “Python” using select_by_index, select_by_value, select_by_visible_text
, respectively.
1 2 3 4 |
dropdown = Select(driver.find_element_by_id('lang2')) dropdown.select_by_index(3) dropdown.select_by_value('php') dropdown.select_by_visible_text('Python') |
Selecting all the Dropdown options in Selenium WebDriver
To choose all options, we can loop over available options and select using Selenium WebDrivers SELECT APIs. For our example demo, to select all options of webelement with id “lang2” –
1 2 3 |
dropdown = Select(driver.find_element_by_id('lang2')) for opt in dropdown.options: dropdown.select_by_visible_text(opt.get_attribute("innerText")) |
Deselecting or clearing already selected Dropdown options in Selenium WebDriver
To deselect an option we can use any of :
deselect_by_index(self, index)
deselect_by_value(self, value)
deselect_by_visible_text(self, text)
And to deselect all, we have the method deselect_all(self)
In our example, we can deselect python from multiple selected options using –
1 2 |
dropdown = Select(driver.find_element_by_id('lang2')) dropdown.deselect_by_visible_text('Python') |
Using LambdaTest to perform an automated Select Deselect test operation in the cloud using Selenium Grid
Now, we shall run an automated test in the cloud using Selenium and Python to see how to handle dropdowns in Selenium using the Selenium SELECT class. If you’re new to LambdaTest, it is an affordable, efficient & scalable testing platform, compatible with all major testing frameworks, CI/CD tools, and languages. Intuitive documentation, in-depth insights & testing tutorials makes it pretty easy for even beginners to test across 3000+ browsers seamlessly, OS and devices combination.
Please read comments in the following test script to understand the program flow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# import the packages we would be using to automate this test from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys import time # Username, Access Token and grid URL can be obtained through automation dashboard - username = "user_name" accessToken = "access_key" gridUrl = "hub.lambdatest.com/wd/hub" # environment configs, for simplicity we have only two configs. You can have more than 3000 if required browsers = [ { "browser":"Chrome", "version":"88.0", "OS" : "windows 10", "resolution" : "1024x768" }, { "browser":"Firefox", "OS" : "windows 10", "version":"71.0", "resolution" : "1024x768" } ] # looping over environment to perform cross-browser testing for cap in browsers: desired_cap = { # operating system 'platform' : cap["OS"], # Browser 'browserName' : cap["browser"], 'version' : cap["version"], # Resolution of machine "resolution": cap["resolution"], "name": "Select Option in selenium webdriver", "build": "Select Option in selenium webdriver", "network": True, "video": True, "visual": True, "console": True, } url = "https://"+username+":"+accessToken+"@"+gridUrl print("Initiating remote driver on platform: "+desired_cap["platform"]+" browser: "+desired_cap["browserName"]+" version: "+desired_cap["version"]) # driver instance creation driver = webdriver.Remote( desired_capabilities=desired_cap, command_executor= url ) # maximizing the browser window to fit the screen resolution driver.maximize_window() # loading the passed url into browser driver.get('https://pynishant.github.io/dropdown-selenium-python-select.html') # identifying select element with id="lang2" using selectors and checking if attribute "multiple" is present in it. dropdown = driver.find_element_by_id('lang2') if dropdown.get_attribute("multiple"): # xpath selector to find the element with text "C#" and "PHP" respectively myOption = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'C#')]") myOption1 = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'PHP')]") # using actionchains to select multiple options ActionChains(driver).key_down(Keys.CONTROL).click(myOption).key_up(Keys.CONTROL).perform() # pausing program execution for few seconds time.sleep(2) ActionChains(driver).key_down(Keys.CONTROL).click(myOption1).key_up(Keys.CONTROL).perform() try: # creating a selenium Select webelement of html <select> tag dropdown = Select(driver.find_element_by_id('lang2')) # using selenium webdriver's select class methods to find all selected options and printing it's text. Ideally, here output should be "PHP, C#" print("All selected options using ActionChains : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) # clearing the php selection we performed in last step dropdown.deselect_by_visible_text('PHP') # Again printing the active selections, this time output should be only c# print("Remaining selected options after deselecting PHP : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) time.sleep(2) # Using selenium select class method to deselect all options dropdown.deselect_all() time.sleep(2) # Using different select class methods, to select multiple options # selecting by index, Java dropdown.select_by_index(3) time.sleep(2) # selecting by value - php dropdown.select_by_value('php') time.sleep(2) # selecting by text - python dropdown.select_by_visible_text('Python') # printing active selections - output should include all three php, python, java print("All selected options after selecting using different select class methods : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) dropdown.deselect_all() # to select all possible options dropdown = Select(driver.find_element_by_id('lang2')) for opt in dropdown.options: dropdown.select_by_visible_text(opt.get_attribute("innerText")) # all four selected options should be output print("Selected option lists after selecting all of them : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) driver.quit() except Exception as e: print(e) print("error") else: print("get_attribute didn't work!") |
Output:
You can check the status of your successful test runs or builds on your LambdaTest Automation dashboard. For the above program, here is the dashboard’s screenshot:
Common Error While Working with Dropdowns: Handling ElementNotInteractable Exception
When you’re interacting with dropdowns, make sure:
- The element is clickable.
- The element is visible.
- The element is enabled.
- Use the try-except-finally approach in Python.
ElementNotInteractable exception arises when the element is either not accessible (hindered by another element) or inactive. Certain elements are not clickable. If you try click operation on them, it results in an error.
If you target element is AJAX rendered or depends on another event to turn clickable then following approach might help :
1 2 3 4 5 6 7 8 9 10 11 |
rom selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome(path_to_your_chrome_driver) driver.maximize_window() # some code... element = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "id_of_your_target_element")) ) # some code... |
Here, you explicitly wait for a duration before your target element becomes clickable.
You may also check if a target element is enabled using:
1 |
element.is_enabled() |
Or if target element is visible
1 |
element.is_displayed() |
Let’s demonstrate why checking an element’s visibility is important before interacting with it.
This time we use a slight different version of above demo url: pynishant.github.io/dropdown-visibility-demo.html
Output on execute this in the command line using:
python demo-visibility.py
In the above code, we try interacting with an invisible element and it throws JS error:
1 2 3 4 5 6 |
try: # try clicking invisible element langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]') ActionChains(driver).click(langDropdown).perform() except Exception as e: print(e) |
Next we try selecting an element in <select id=”lang”> tag with <select id=”lang1”> tag expanded and hovering over <select id=”lang”>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# try clicking visible element langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]') ActionChains(driver).click(langDropdown).perform() # try clicking an element with another element overflowing it myOption = driver.find_element_by_xpath('//select[@id="lang"]/option[@value="python"]') ActionChains(driver).click(myOption).perform() time.sleep(3) # Get the selected value of element under target and element hovering target selectedOption = Select(driver.find_element_by_xpath('//select[@id="lang"]')) try: selected_option = selectedOption.first_selected_option.text except Exception as e: print(e) selected_option = "None" try: selected_option1 = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]').text except Exception as e: print(e) selected_option1 = "None" |
As apparent from the output, we instead end up selecting “Java,” an element from <select id=”lang1”>. This could lead to incorrect testing at times. So, do observe the behavior of elements.
You can also refer to the below video tutorial on how to handle Windows and Frames in selenium.
Conclusion
In this Selenium WebDriver tutorial, we demonstrated how to handle dropdowns in Selenium WebDriver using the methods provided by selenium.webdriver.support.select.Select(webelement) class of Selenium WebDriver. We explored ways to select/deselect an option from a dropdown. We also detailed on “checking if multiple selections are allowed, and selecting multiple options if required.” The article also shares tac for automation testers to avoid ElementNotInteractable error when automating interactions with dropdown elements. For scalable automation needs, adhere to best test automation practices, and consider testing in the cloud to cut costs.
That’s all folks, I hope you liked this Selenium WebDriver tutorial for Selenium test automation. For any clarification, please comment. If you found this helpful, please share it in your circle and on social media.
Happy Testing!!!
Frequently Asked Questions
How does selenium handle multiple dropdowns?
You need to use the Select class to handle drop-down and multi-select lists using Selenium WebDriver. The Select class provides the implementation of the HTML SELECT tag. Besides, it also reveals many “Select By” and “Deselect By” type methods.
How do you handle dynamic elements?
You can handle Dynamic Web Elements in Selenium using any of the following ways:
- Absolute Path method.
- Use Relative XPath
- Identify by index
- Use Multiple attributes
How do you handle the submenu in selenium?
You can Mousehover on your menu item using the Actions class and then click on the submenu option. To get an overview of the methods, refer to the Actions class available and understand how to use these interactions.
Got Questions? Drop them on LambdaTest Community. Visit now