Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a real HTML <select>, use your browser-testing framework’s select helper: Selenium’s Select, Playwright’s selectOption(), or Cypress’s .select(). Prefer a stable option value, verify the selected value afterward, and do not use these APIs on a custom dropdown built from buttons or list items.

First confirm the control is a native select

These helpers operate on HTML <select> elements and their <option> children. A control that looks like a dropdown may instead be a custom widget composed of a button, a listbox, and option-like elements. The appearance alone does not tell you which it is.

Inspect the page’s DOM or query the element by a selector you expect to match a select. In browser devtools, a native control will appear as <select>; its choices are typically <option> children. If your framework reports that the target is not a select, do not try to force a native select command onto it. Use the widget’s accessible roles and normal user interactions instead.

Choose a locator that identifies the control

Use a stable ID, test attribute, or other selector tied to the control’s purpose, such as select#country. Avoid locating a dropdown by its position among all page elements unless that position is itself part of the test. A good control locator and a good option identifier solve different problems: first find the right select, then choose the intended option.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose an option by value, label, text, or index

Use the option’s value when it is stable and represents the data your application submits. Use visible text or a label when the user-facing wording is the contract your test needs to protect. Use an index only when the option order is deliberately stable; reordering choices can silently make an index-based test select the wrong item.

  • Value: best when the application’s option values are stable identifiers, such as US.
  • Visible text or label: useful when the exact wording shown to users is what matters, such as United States.
  • Index: useful only when position is meaningful and intentionally maintained. Check the framework’s indexing convention and the order of options before relying on it.

Do not assume a visible option’s text and its submitted value are the same. For example, an option may display “United States” while its value is “US.” If selection fails, inspect the actual option markup and use the identifier that matches your intent.

Select a native option with Selenium

In Python, wrap the located element with Selenium’s Select helper, then choose by value, visible text, or index:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select

country_element = driver.find_element(By.ID, "country")
country = Select(country_element)

country.select_by_value("US")
# Alternatives:
# country.select_by_visible_text("United States")
# country.select_by_index(2)

assert country.first_selected_option.get_attribute("value") == "US"

The helper is specifically for HTML select controls; it validates the target element and raises an error if the requested option cannot be found. Disabled options cannot be selected. Selenium also provides equivalent select and deselect methods in its JavaScript interface. Multi-select behavior is covered below.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When Selenium reports no matching option

A no-such-element error from a selection call generally means the requested option did not match an available choice. Check whether the value is exact, whether visible text differs in spelling or whitespace, and whether the page has populated the options yet. If the page loads choices asynchronously, wait for the expected option to appear before selecting it rather than adding an arbitrary fixed delay.

Select a native option with Playwright

Playwright’s locator method accepts a value, label, index, or an array of choices. For example, in TypeScript:

await page.locator('select#country').selectOption('US');
await expect(page.locator('select#country')).toHaveValue('US');

// Match the option's label instead:
await page.locator('select#country').selectOption({ label: 'United States' });

// Select multiple values from a multiple select:
await page.locator('select#colors').selectOption(['red', 'blue']);

Use the assertion import expected by your test setup; for example, Playwright Test provides expect. The selection method waits for the element, performs actionability checks, and waits until the requested options exist before selecting them. It triggers the input and change events, and returns the values selected. The page-level selectOption API supports matching by value, label, or index as well.

These built-in waits are usually a better fit than sleeping for a guessed number of milliseconds. If the control or option never becomes available, the action will still fail; a wait cannot make a missing option valid.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Select a native option with Cypress

Cypress’s .select() command takes an option value, index, visible text, or an array for a multi-select. It yields the select subject, so chain an assertion to check the result:

cy.get('select#country')
  .select('US')
  .should('have.value', 'US');

// Match visible option text:
cy.get('select#country').select('United States');

// Select multiple values:
cy.get('select#colors')
  .select(['red', 'blue'])
  .should('have.value', 'red');

For a multi-select, asserting only one value is not enough to confirm the complete selection. Assert the selected options or their values explicitly, as shown in the next section. Cypress automatically waits for actionability and retries chained assertions, so a separate arbitrary sleep is generally unnecessary.

Cypress documents { force: true } for hidden or otherwise non-actionable selects. Use it only when the test has a reason to interact with that control despite its normal actionability state. Force does not make a disabled option or disabled optgroup selectable.

Handle multi-select controls and verify results

A native multi-select is marked with the multiple attribute. Select multiple intended values with an array in Playwright or Cypress. With Selenium, select each desired option through the Select wrapper. Verify the full resulting selection instead of assuming the call succeeded because it returned.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Selenium: select and inspect several choices

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select

colors = Select(driver.find_element(By.ID, "colors"))
colors.select_by_value("red")
colors.select_by_value("blue")

selected_values = [
    option.get_attribute("value")
    for option in colors.all_selected_options
]
assert set(selected_values) == {"red", "blue"}

Selenium supports deselection methods only for multi-select controls. Do not call a deselect method on a single-select control.

Playwright: assert the selected values

const colors = page.locator('select#colors');
await colors.selectOption(['red', 'blue']);
await expect(colors).toHaveValues(['red', 'blue']);

Cypress: assert the selected options

cy.get('select#colors')
  .select(['red', 'blue'])
  .find('option:selected')
  .then(($options) => {
    const values = [...$options].map((option) => option.value);
    expect(values).to.have.members(['red', 'blue']);
  });

The application may update other content in response to a selection. If that behavior is under test, assert the resulting page state too; a selected option alone does not prove that dependent application logic ran correctly.

Why a native select command fails on a custom dropdown

A custom dropdown may expose a button that opens a listbox, with choices rendered as elements such as div, li, or ARIA options. It is not a native select, even if it looks identical on screen. Playwright’s select method, Selenium’s Select wrapper, and Cypress’s .select() all require a native select subject.

For a custom widget, interact with the actual control: locate its button or combobox by accessible role and name, open it, then locate and choose an option in its listbox. Follow the widget’s keyboard behavior where relevant, and assert the resulting accessible state or application value. The exact locators depend on the widget’s markup and accessibility implementation, so there is no universal native-select call to substitute.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common selection failures

  • The target is not a select. Inspect the DOM. If the dropdown is custom, switch to role-based interaction rather than using a select helper.
  • No option matches. Check the option’s actual value and displayed text, capitalization, and whether the option exists at the time of selection.
  • The option is disabled. Choose an enabled option or test the disabled-state behavior. Selenium cannot select disabled options; Cypress force mode does not override disabled options or disabled optgroups.
  • The control is not ready yet. Use framework-supported waiting for the select and option to appear. Playwright waits for requested options, and Cypress retries commands and assertions; avoid unexplained fixed sleeps.
  • The value changes but the page does not react. Confirm that you are testing a native select and using the framework API, which dispatches the relevant browser events as documented. Then investigate application handlers or dependent state rather than immediately adding a manual event dispatch.
  • The selection assertion is incomplete. For a multi-select, inspect all selected values; checking only one value can miss an extra or absent selection.
  • An index selects the wrong choice. Re-check option ordering. Replace the index with a stable value or user-facing label when order is not part of the intended contract.

Or skip the browser setup

ScreenshotNeo is a website screenshot API, not a browser-testing framework: it does not select a dropdown or replace Selenium, Playwright, or Cypress. If your workflow also needs a screenshot after your test has navigated the page into the desired state, one GET request can capture that page. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://stripe.com 
  -o shot.webp

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before a capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server lets AI agents use screenshot tools, and the free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Learn about ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Practical selection checklist

  • Confirm that the element is an HTML <select>.
  • Locate the control with a stable selector.
  • Choose by stable value unless visible wording or deliberately fixed order is what the test covers.
  • Use arrays for multi-selects and verify the complete set of selected options.
  • Prefer framework waits and retries over arbitrary sleeps.
  • Treat disabled options and custom dropdowns as separate cases, not as selection-helper edge cases.

Frequently Asked Questions

Do select helpers submit the form?

They select options in the control; form submission is a separate action your test must perform if required.

Can I select a disabled option with force mode?

No. Cypress force mode does not override disabled options or disabled optgroups.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use visible text or the option value?

Use the stable value for data-level behavior, and visible wording when the user-facing label itself is what your test is meant to check.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.