Have you ever tried selecting an option from a dropdown in Playwright and felt like it just wasn’t working the way you expected?
I’ve been there. When I first automated forms with Playwright, I ran into a few frustrating moments where selectOption didn’t behave consistently across different browsers.
Sometimes the wrong option got selected, and other times the test failed without a clear reason.
I tried different approaches and explored Playwright’s features until I found techniques that make dropdown selections reliable and tests much more stable.
Overview
Playwright lets you choose options from a dropdown () using the selectOption() method. You can pick an option in different ways depending on what is easiest for your test.
1. By Visible Text (Label)
Select an option using the text that appears in the dropdown:
await page.selectOption(‘select#dropdownId’, { label: ‘Option 2’ });
// or
await page.locator(‘select#dropdownId’).selectOption({ label: ‘Option 2’ });2. By Value Attribute
Use the option’s value attribute, which is usually unique:
await page.selectOption(‘select#dropdownId’, { value: ‘optionValue’ });
// or
await page.locator(‘select#dropdownId’).selectOption({ value: ‘optionValue’ });3. By Index
Pick an option based on its position in the list (zero-based):
await page.selectOption(‘select#dropdownId’, { index: 1 }); // selects the second option4. Selecting Multiple Options
For multi-select dropdowns (), provide an array of values, labels, or indices:
// By values
await page.selectOption(‘#multiSelect’, [‘value1’, ‘value2’]);// By labels
await page.selectOption(‘#multiSelect’, [‘Option 1’, ‘Option 3’]);// By indices
await page.selectOption(‘#multiSelect’, [{ index: 0 }, { index: 2 }]);
In this article, I’ll walk you through how to reliably select options using Playwright, share the pitfalls I ran into, and show practical tips to make your automation smoother and more predictable.
How to Use Playwright selectOption
Playwright provides the selectOption() method to choose options from a dropdown (). Depending on your test scenario, you can select options by label, value, or index. For multi-select dropdowns, you can select multiple options at once.
1. By Visible Text (Label)
Sometimes the easiest way to select an option is by the text that appears in the dropdown. This is useful when the value attribute is dynamic or unknown, but the visible text is consistent.
await page.selectOption(‘select#dropdownId’, { label: ‘Option 2’ });
// or using locator
await page.locator(‘select#dropdownId’).selectOption({ label: ‘Option 2’ });2. By Value Attribute
Many dropdowns use a value attribute as a unique identifier for each option. Selecting by value ensures that your test works even if the visible text changes slightly.
await page.selectOption(‘select#dropdownId’, { value: ‘optionValue’ });
await page.locator(‘select#dropdownId’).selectOption({ value: ‘optionValue’ });3. By Index
Sometimes you may want to select an option based on its position in the list, especially when neither the label nor value is consistent. Remember that the index is zero-based.
await page.selectOption(‘select#dropdownId’, { index: 1 }); // selects the second option4. Selecting Multiple Options
For multi-select dropdowns (), you can select several options at once by providing an array of labels, values, or indices. This is particularly useful for filters or multi-choice forms.
// By labels
await page.selectOption(‘#multiSelect’, [‘Option 1’, ‘Option 3’]);// By values
await page.selectOption(‘#multiSelect’, [‘value1’, ‘value2’]);// By indices
await page.selectOption(‘#multiSelect’, [{ index: 0 }, { index: 2 }]);
Handling Custom or Dynamic Dropdowns
Not all dropdowns are simple <select> elements. Many modern web applications use custom dropdowns built with <div>, <ul>, or other HTML structures, often with dynamic options loaded via JavaScript or API calls. These dropdowns don’t work with selectOption(), so you need a different approach.
1. Clicking to Open and Selecting an Option
For custom dropdowns, the usual method is to click the dropdown to reveal the options and then click the option you want.
// Open the dropdown
await page.click(‘#customDropdown’);// Select the desired option
await page.click(‘text=Option 2’);
2. Using Locators for Dynamic Options
If the options load asynchronously, you should wait for them to appear before selecting. Playwright’s locator with waitFor or first can help:
const option = page.locator(‘.dropdown-option’, { hasText: ‘Option 2’ });
await option.waitFor({ state: ‘visible’ });
await option.click();3. Handling Multi-Select Custom Dropdowns
For multi-select dropdowns, repeat the click for each desired option. If the options are dynamic, always wait for them to appear to avoid flaky tests:
const options = [‘Option 1’, ‘Option 3’];
for (const label of options) {
const optionLocator = page.locator(‘.dropdown-option’, { hasText: label });
await optionLocator.waitFor({ state: ‘visible’ });
await optionLocator.click();
}
How to Ensure Reliable Option Selection in Playwright
Even when your dropdown locator seems correct, tests can still fail due to timing issues, dynamic content, or browser inconsistencies. To make your option selection reliable, follow these best practices.
1. Wait for the Dropdown to Be Ready
Always ensure the dropdown is fully rendered and visible before interacting. Use Playwright’s locator.waitFor() or built-in await checks:
const dropdown = page.locator(‘select#dropdownId’);await dropdown.waitFor({ state: ‘visible’ });
await dropdown.selectOption({ label: ‘Option 2’ });2. Use Explicit Locators
Target the element or option precisely using IDs, classes, or text. Avoid generic selectors like select or div that might match multiple elements.
await page.locator(‘select#countryDropdown’).selectOption({ value: ‘IN’ });3. Handle Dynamic or Lazy-Loaded Options
If options appear after an API call or animation, wait for them explicitly before selection:
const option = page.locator(‘option’, { hasText: ‘Option 2’ });await option.waitFor({ state: ‘visible’ });
await option.click();Read More: What is Lazy loading?
4. Use Assertions to Confirm Selection
After selecting, always verify the value to catch silent failures:
await expect(page.locator(‘select#dropdownId’)).toHaveValue(‘optionValue’);
Also Read: What is Assertion Testing?
5. Consider Alternative Approaches for Custom Dropdowns
For non-standard dropdowns (<div>, <ul>, or dynamic components), simulate user interactions:
- Click to open
- Wait for options to appear
- Click the desired option
await page.click(‘#customDropdown’);
await page.locator(‘.dropdown-item’, { hasText: ‘Option 2’ }).click();
Even if selectOption() passes on a local machine, dropdown behavior can vary across real browsers. BrowserStack lets you test on thousands of devices to ensure selections work consistently everywhere.
Troubleshooting Playwright selectOption()
Even with correct locators and proper waits, selecting options in Playwright can sometimes fail. Understanding common issues and their fixes can save a lot of debugging time.
1. Dropdown Not Found or Not Visible
If Playwright cannot find the element or it is hidden, selectOption() will fail. Always ensure the element is present and visible:
const dropdown = page.locator(‘select#dropdownId’);
await dropdown.waitFor({ state: ‘visible’ });
await dropdown.selectOption({ label: ‘Option 2’ });
2. Wrong Option Selected
This can happen if the label or value does not match exactly. Check for leading/trailing spaces, casing, or dynamic values. Using exact strings or trimming input can help:
await dropdown.selectOption({ label: ‘Option 2’.trim() });3. Multi-Select Misbehaving
For single-select dropdowns, passing multiple options will only select the last one. For multi-select dropdowns, ensure the element has the multiple attribute:
await page.selectOption(‘#multiSelect’, [‘Option 1’, ‘Option 3’]); // works only if
4. Dynamic or Lazy-Loaded Options
If options load asynchronously, the selection may fail because the option isn’t in the DOM yet. Wait explicitly for the option before selecting:
const option = page.locator(‘option’, { hasText: ‘Option 2’ });
await option.waitFor({ state: ‘visible’ });
await option.click();Read More: Understanding Playwright waitForResponse
5. Custom Dropdowns
selectOption() works only on <select> elements. For custom dropdowns built with <div> or <ul>, simulate a user click:
await page.click(‘#customDropdown’);
await page.locator(‘.dropdown-item’, { hasText: ‘Option 2’ }).click();
6. Assertion Failures
Even after selection, tests can fail if the value doesn’t match expectations. Always verify with a Playwright assertion:
await expect(dropdown).toHaveValue(‘optionValue’);
Pro Tip: If tests still fail intermittently, add small delays or use locator.first() for repeated elements to make selections more stable.
Best Practices for Selecting Options in Playwright
Selecting options in dropdowns might seem simple, but small mistakes can lead to flaky or unreliable tests. Following these best practices helps ensure your tests are stable, maintainable, and resilient across different browsers and dynamic web environments.
- Use Precise Locators: Always target the dropdown and its options with unique identifiers such as IDs, classes, or exact text. This prevents accidental interactions with similar elements elsewhere on the page and reduces flakiness.
- Wait for Elements to Be Ready: Dropdowns and options may load asynchronously due to JavaScript or API calls. Ensure that the dropdown and its options are fully visible and interactable before attempting a selection.
Read More: Understanding Playwright waitforloadstate
- Verify Selections: Confirm that the selected option is applied correctly using assertions. This avoids silent test failures where the test passes, but the wrong option is actually selected.
- Consider Multi-Select Scenarios: For multi-select dropdowns, ensure the element supports multiple selections and verify each selected option individually. Selecting multiple options in a single-select dropdown will only select the last one.
- Handle Custom or Dynamic Dropdowns Carefully: For non-standard dropdowns built with <div> or <ul> elements, simulate real user interactions by opening the dropdown, waiting for options to appear, and clicking the desired option. This approach handles dynamic content reliably.
- Keep Tests Readable and Maintainable: Organize repetitive selection logic in helper functions, use descriptive labels or values instead of indexes, and avoid hard-to-read selectors. This makes your tests easier to maintain as the application evolves.
- Avoid Hardcoded Waits: Do not rely on fixed delays (sleep or waitForTimeout) as they can slow tests and still fail unpredictably. Use Playwright’s built-in waiting mechanisms to wait for visibility, enablement, or specific conditions instead.
Testing Playwright Select Option on Real Browsers with BrowserStack
Select-option tests usually fail for reasons that do not show up locally. UI frameworks replace the native <select> with custom components, so Playwright interacts with a simulated dropdown instead of a real one. These components rely on animations, delayed rendering, or hidden DOM nodes that load at slightly different times on different browsers.
As a result, selectOption() passes in Chromium but fails in Firefox, selects the wrong item when the list scrolls incorrectly, or clicks the overlay instead of the actual option.
Testing on real browsers can help uncover these inconsistencies. Platforms like BrowserStack let you run your Playwright tests across multiple browsers and engines, exposing differences in rendering, event timing, and focus behaviour that local or headless runs often miss.
Here is how BrowserStack helps make Playwright tests more reliable:
- Real Device Cloud: Run tests on thousands of real desktop and mobile browsers to ensure consistent behavior across platforms.
- Parallel Testing: Execute multiple Playwright tests at the same time across different browsers and devices to speed up validation.
- Test Reporting and Analytics: Access video recordings, console logs, and network traces to quickly identify and fix issues with dropdown selections or other interactions.
- Local Testing Support: Securely test local or staging environments on real browsers without deploying publicly.
- CI/CD Integration: Integrate with existing pipelines to automatically run Playwright tests on real browsers during builds and deployments.
Conclusion
Selecting options with Playwright can be tricky when dropdowns are dynamic, multi-select, or custom-styled. Using precise locators, waiting for elements, and validating selections helps ensure reliable and consistent tests.
Running these tests on real browsers and devices reveals issues that local tests might miss. Platforms like BrowserStack allow you to validate dropdown interactions across thousands of environments, catch issues that local tests might miss, and provide debugging tools such as video recordings and logs to quickly resolve failures.

