AI QA Automation Hub

Tutorial on single and multi-select dropdowns in Playwright

Tutorial on single and multi-select dropdowns in Playwright

Playwright Dropdown Handling

Key Questions

When should I prefer user-like interactions over select_option()?

Use select_option() for native <select> elements. For custom-styled dropdowns or components rendered via JS/CSS (no native <select>), prefer user-like interactions (click triggers, choose visible text, keyboard navigation) because they replicate actual user behavior and respect component logic and event handlers.

How do I avoid flaky dropdown tests when options load asynchronously?

Use explicit waits before interacting: wait_for_selector() with appropriate selector and state (attached/visible), wait_for_response() for known network calls, or wait_for_function() to assert expected DOM state. Combine waits with Playwright’s auto-waiting and retries to stabilize tests.

What's the best way to verify multi-select selections?

Query the element state rather than relying solely on UI text. For native multi-selects, evaluate el.selectedOptions and assert their values. For custom controls, inspect the DOM region that shows selected tokens/labels or use accessible attributes (aria-checked, aria-selected) to confirm selections.

Should I test keyboard interactions for dropdowns?

Yes. Keyboard navigation and activation are critical for accessibility. Test focus behavior, Enter/Space to open/select, Arrow keys to navigate, and typing/search within the control where supported. These tests help ensure compliance and catch issues keyboard-only users would face.

Are AI tools safe to use for generating dropdown tests?

AI tools can accelerate test creation but require careful review. Validate generated tests for robustness (explicit waits, error handling), maintainability, and alignment with accessibility practices. Combine AI-assisted generation with manual code reviews and add targeted assertions to avoid brittle or incorrect tests.

Enhancing UI Test Automation in 2024: Mastering Single and Multi-Select Dropdowns with Playwright

Web automation continues to evolve at a rapid pace in 2024, and handling dropdown controls remains a fundamental aspect of reliable UI testing. Whether dealing with native <select> elements or complex, custom-styled dropdowns, testers need robust, adaptable strategies to ensure their tests are both accurate and resilient. Building on the foundational tutorial "Playwright with Python & Pytest | How to Handle Single & Multi Select Dropdowns (Session 6)," recent developments this year have significantly expanded Playwright’s capabilities, enabling QA engineers to tackle modern web app challenges with greater confidence and efficiency.

This article synthesizes the latest insights, best practices, and emerging tools to provide a comprehensive update on dropdown automation, highlighting how Playwright’s features now support a broader spectrum of controls, dynamic content, and accessibility considerations.


Recap of Core Dropdown Handling in Playwright

Historically, Playwright's select_option() method has been the primary means to interact with dropdowns. It facilitates selecting options based on value, label, or visible text, and works seamlessly with both single-select and multi-select <select> elements. Typical patterns include:

  • Waiting for options to be loaded
  • Selecting options by their attributes
  • Verifying the selections via assertions

For example:

# Select options in a multi-select dropdown
await page.wait_for_selector('select#multi option')
await page.select_option('select#multi', ['value1', 'value2'])
# Verify selections
selected_values = await page.eval('select#multi', 'el => Array.from(el.selectedOptions).map(opt => opt.value)')
assert set(selected_values) == {'value1', 'value2'}

While these techniques remain vital, the 2024 landscape introduces new challenges—such as dynamically loaded options, custom-styled controls, and accessibility needs—that require more advanced strategies.


Recent Developments and Best Practices in 2024

1. Handling Dynamic Dropdowns with Explicit Waiting Strategies

Modern web applications often load dropdown options asynchronously via AJAX or client-side rendering. Flaky tests caused by timing issues are now mitigated through Playwright's improved waiting mechanisms:

# Wait explicitly for options to be attached
await page.wait_for_selector('select#multi option', state='attached')
# Proceed with selection
await page.select_option('select#multi', ['value1', 'value2'])

This ensures options are fully available before interaction, increasing test stability.

2. Interacting with Custom and Styled Dropdowns

A significant trend in 2024 is replacing native <select> controls with custom HTML/CSS components for enhanced styling and functionality. Playwright now advocates simulating user interactions on these controls:

# Open custom dropdown
await page.click('.custom-dropdown-trigger')
# Select an option by its visible text
await page.click('text="Option Label"')

This user-like approach is more reliable than DOM manipulation, especially when dealing with complex JavaScript-driven controls that rely heavily on event handling.

3. Enhanced Verification and Assertion Techniques

To confirm the UI reflects the correct state post-interaction, explicit verification methods are recommended:

# Single select
selected_value = await page.eval('select#single', 'el => el.value')
assert selected_value == 'expected_value'
# Multi-select
selected_options = await page.eval('select#multi', 'el => Array.from(el.selectedOptions).map(opt => opt.value)')
assert set(selected_options) == {'value1', 'value2'}

These methods provide definitive confirmation, reducing false positives and increasing confidence in test results.

4. Keyboard and Accessibility Interactions

Accessibility testing has gained prominence. In 2024, simulating keyboard interactions ensures not only functionality but also compliance with accessibility standards:

await page.focus('.custom-dropdown-trigger')
await page.keyboard.press('Enter')
await page.keyboard.type('Option Label')
await page.keyboard.press('Enter')

This approach verifies that dropdowns are navigable and operable via keyboard, supporting users relying on assistive technologies.

5. Leveraging Cross-Browser and Shadow DOM Support

Playwright’s native support for Shadow DOM, along with its cross-browser consistency, has been further strengthened. According to the recent comparative article "Playwright vs Selenium vs Cypress: Which One Should QA Engineers Choose in 2024?", Playwright excels in:

  • Handling Shadow DOM components seamlessly
  • Interacting with complex custom controls
  • Providing auto-retry and built-in waits that significantly reduce flaky tests
  • Ensuring consistent behavior across Chrome, Firefox, Safari, and Edge

This makes Playwright particularly suitable for testing modern UIs with intricate dropdown controls.

6. AI-Assisted Testing and Community Resources

AI-powered tools have become integral in 2024:

  • AutoQA, an AI browser testing agent powered by Gemini 2.5, automates the generation of test cases—including complex dropdown interactions—accelerating test creation and maintenance.
  • Community plugins and visual validation tools now support testing custom dropdowns for visual correctness and accessibility compliance.

Recent articles, like "I Built Karpathy's AutoResearch for Playwright Testing (Here's What Happened)," demonstrate how AI can augment manual testing efforts, making dropdown automation faster and more reliable.


Practical Patterns and Updated Code Snippets

Handling Native <select> Elements

# Waiting for options to load dynamically
await page.wait_for_selector('select#multi option')
# Selecting multiple options
await page.select_option('select#multi', ['value1', 'value2'])
# Verifying selections
selected_values = await page.eval('select#multi', 'el => Array.from(el.selectedOptions).map(opt => opt.value)')
assert set(selected_values) == {'value1', 'value2'}

Handling Custom-Styled Dropdowns

# Open the custom dropdown
await page.click('.custom-multiselect-trigger')

# Select multiple options by visible text
await page.click('text="Option 1"')
await page.click('text="Option 2"')

# Verify selected options in the UI
selected_texts = await page.eval(
    '.custom-multiselect-selected',
    'el => Array.from(el.children).map(child => child.innerText)'
)
assert "Option 1" in selected_texts and "Option 2" in selected_texts

Deselecting Options in Multi-Selects

# Deselect an option by clicking again if toggle behavior exists
await page.click('text="Option 1"')
# Or reset the control if supported
await page.click('.reset-multiselect')

Accessibility and Keyboard Interaction Example

await page.focus('.custom-dropdown-trigger')
await page.keyboard.press('Enter')
await page.keyboard.type('Option Label')
await page.keyboard.press('Enter')

This ensures the dropdowns are accessible and functional via keyboard navigation, aligning with best practices.


Implications and Current Status

As of 2024, Playwright remains the premier framework for handling dropdown interactions in modern web applications. Its continual enhancements—like improved waiting strategies, support for custom controls, Shadow DOM handling, and cross-browser consistency—empower testers to build more reliable, maintainable test suites.

Key takeaways:

  • Use explicit waits to handle asynchronously loaded options
  • Prefer user-like interactions for custom controls
  • Verify selections explicitly to confirm UI correctness
  • Incorporate keyboard and accessibility testing to meet standards
  • Leverage AI and community tools to accelerate test development and coverage

In conclusion, mastering dropdown automation with Playwright in 2024 not only improves test robustness but also aligns with the evolving landscape of web development. Ensuring your tests are resilient against dynamic content, custom controls, and accessibility requirements is essential for delivering high-quality web applications in today’s fast-changing environment.

Sources (7)
Updated Mar 18, 2026
When should I prefer user-like interactions over select_option()? - AI QA Automation Hub | NBot | nbot.ai