Skip to content
CodeKruPro

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:

  1. Wait until it has loaded: the spinner (a loading icon) is gone or there is at least one row.
  2. Map columns by header text.
  3. Find the row by data, not position: //tr[td[normalize-space()='Ravi']].
  4. Read the cell at the mapped column.
  5. 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 Select on 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

StatusQuestionDifficultyAsked in
Not startedWhich option does select by index 1 choose?EasyAsked in: Accenture, Capgemini, Infosys +3
Not startedXPath for a cell in the row of a known nameMediumAsked in: Accenture, Infosys, TCS +1
Not startedChoose a dropdown option by visible textEasyAsked in: Accenture, Capgemini, Infosys +3
Not startedCount the rows and columns of a web tableEasy-MediumAsked in: Accenture, Infosys, TCS +1
Not startedChoose a dropdown option by valueEasyAsked in: Accenture, Capgemini, Infosys +3
Not startedChoose a dropdown option by indexEasyAsked in: Accenture, Capgemini, Infosys +3
Not startedList every option in a dropdownEasy-MediumAsked in: Accenture, Capgemini, Infosys +3
Not startedSelect and deselect in a multi-select listMediumAsked in: Accenture, Capgemini, Infosys +3
Not startedRead the option that is already selectedEasyAsked in: Accenture, Capgemini, Infosys +3
Not startedDrive a dropdown from a list of choicesMediumAsked in: Accenture, Capgemini, Infosys +3
Not startedRead the header cells of a tableEasy-MediumAsked in: Accenture, Infosys, TCS +1
Not startedRead specific cells from a tableEasy-MediumAsked in: Accenture, Infosys, TCS +1
Not startedRead every row of a tableMediumAsked in: Accenture, Infosys, TCS +1
Pro+Using Select on a dropdown built from divs (Python)MediumAsked in: Accenture, Infosys, TCS
Pro+Handle a custom or auto-suggest dropdownMediumAsked in: Accenture, Infosys, TCS
Pro+Check that a dropdown has no duplicate options (Python)Easy-MediumAsked in: Capgemini
Pro+deselect_all() and is_multiple on a single-choice dropdown (Python)Medium
Pro+Read a dynamic web tableMediumAsked in: Accenture, Infosys, TCS +1
Not startedNot startedIn progressIn progressSolvedSolvedPro+Pro+

The first 2 questions of each topic are free. Pro+ opens every question.

Back to the plan