Automation tool (Selenium) · Python
Dropdowns and tables
Selecting options and reading web tables.
Learn: Dropdowns and web tables in Selenium Python7 minute read
A dropdown lets a user pick a value from a list; a web table shows data in rows and columns. Both are everywhere, so interview tasks use them constantly: pick a country, list every option, find the right row and read a cell. Python makes the checking part short. The Selenium part needs care.
Native dropdowns with Select
A native dropdown is a real <select> element. Wrap it in the Select helper (a class made for dropdowns):
from selenium.webdriver.support.ui import Select
country = Select(driver.find_element(By.ID, "country"))
country.select_by_visible_text("India")
country.select_by_value("IN")
country.select_by_index(2) # counts from 0
chosen = country.first_selected_option.text
labels = [o.text for o in country.options]
options, first_selected_option and all_selected_options are properties. Visible text reads well in tests. Value is the hidden value attribute and stays the same when labels are translated. Index counts from 0, includes any placeholder such as "Choose one", and breaks when the list changes. A missing text or value raises NoSuchElementException.
Multi-select lists
A multi-select list has the multiple attribute. Then is_multiple is true, and you can select several options and remove them with deselect_by_visible_text, deselect_by_value, deselect_by_index or deselect_all(). On a single-choice select, deselect_all() raises NotImplementedError, and is_multiple can be None rather than False, so test it with if select.is_multiple:.
Custom and auto-suggest dropdowns
Dropdowns built from div and li elements are not select elements, and Select raises UnexpectedTagNameException on them. Use user-like steps:
driver.find_element(By.ID, "country-picker").click()
WebDriverWait(driver, 5).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "ul.options")))
driver.find_element(By.XPATH, "//ul[@class='options']/li[normalize-space()='India']").click()
An auto-suggest box shows matches as you type. Type a few letters, wait for the list, click the suggestion whose text matches exactly, then check the value the input shows.
Checking the options
labels = [o.text.strip() for o in Select(driver.find_element(By.ID, "country")).options]
seen, duplicates = set(), []
for label in labels:
if label in seen:
duplicates.append(label)
seen.add(label)
assert not duplicates, f"Duplicate options: {duplicates}"
body = labels[1:] # skip the placeholder
assert body == sorted(body), "options are not in alphabetical order"
A set holds each value once, so a label already in it is a repeat. Decide with the team whether case matters before comparing.
Web tables
A table is rows (tr) of cells (td, or th for headers):
headers = [th.text for th in driver.find_elements(By.CSS_SELECTOR, "#orders thead th")]
rows = driver.find_elements(By.CSS_SELECTOR, "#orders tbody tr")
for row in rows:
cells = [td.text for td in row.find_elements(By.TAG_NAME, "td")]
print(cells[0], "-", cells[1])
Calling find_elements on a row searches only inside that row. headers.index("Status") gives the column number by name, so a new column does not break the test.
Dynamic tables, step by step
A dynamic table loads late, gets sorted or spreads over pages:
- Wait until it has loaded: the spinner (a loading icon) is gone or there is at least one row.
- Map columns by header text.
- Find the row by data, not position:
//tr[td[normalize-space()='Ravi']]. - Read the cell at the mapped column.
- Page with a bounded loop: if the row is missing and Next is enabled, click it, wait for the old first row to go stale (
EC.staleness_of: the page replaced that row, so the old reference no longer works; see Selenium exceptions and debugging), and search again.
A helper that returns each row as a dict from header to cell text makes assertions read like the requirement (a dict is a Python dictionary of name and value pairs):
def table_rows(driver, table_locator):
table = driver.find_element(*table_locator)
names = [th.text for th in table.find_elements(By.CSS_SELECTOR, "thead th")]
return [dict(zip(names, [td.text for td in tr.find_elements(By.TAG_NAME, "td")]))
for tr in table.find_elements(By.CSS_SELECTOR, "tbody tr")]
How to answer in an interview
For dropdowns, first ask whether it is a real select element, then name the approach. For tables, walk the five steps and mention that a search box or filter beats paging when the app has one.
Common mistakes
- Using
Selecton a div-based dropdown. - Clicking the first suggestion: "Ind" may list Indonesia first.
- Selecting by index when options can change.
- Reading the table before it finishes loading.
- Keeping row elements, sorting the table, and then using the now stale rows (the old references no longer work).
Recap
Select for real select elements; clicks and waits for custom ones. Sets for duplicate checks, sorted() for order checks. Read tables by header name and row data, and page with a loop that always ends.
18 questions0/18 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Which option does select by index 1 choose? | Easy | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | XPath for a cell in the row of a known name | Medium | Asked in: Accenture, Infosys, TCS +1 |
| Not started | Choose a dropdown option by visible text | Easy | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Count the rows and columns of a web table | Easy-Medium | Asked in: Accenture, Infosys, TCS +1 |
| Not started | Choose a dropdown option by value | Easy | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Choose a dropdown option by index | Easy | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | List every option in a dropdown | Easy-Medium | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Select and deselect in a multi-select list | Medium | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Read the option that is already selected | Easy | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Drive a dropdown from a list of choices | Medium | Asked in: Accenture, Capgemini, Infosys +3 |
| Not started | Read the header cells of a table | Easy-Medium | Asked in: Accenture, Infosys, TCS +1 |
| Not started | Read specific cells from a table | Easy-Medium | Asked in: Accenture, Infosys, TCS +1 |
| Not started | Read every row of a table | Medium | Asked in: Accenture, Infosys, TCS +1 |
| Pro+ | Using Select on a dropdown built from divs (Python) | Medium | Asked in: Accenture, Infosys, TCS |
| Pro+ | Handle a custom or auto-suggest dropdown | Medium | Asked in: Accenture, Infosys, TCS |
| Pro+ | Check that a dropdown has no duplicate options (Python) | Easy-Medium | Asked in: Capgemini |
| Pro+ | deselect_all() and is_multiple on a single-choice dropdown (Python) | Medium | |
| Pro+ | Read a dynamic web table | Medium | Asked in: Accenture, Infosys, TCS +1 |
The first 2 questions of each topic are free. Pro+ opens every question.