selectOption() funciona apenas em elementos nativos : chame-o em um React Select ou combobox do Material UI construído com divs e o Playwright lança um erro. Dropdowns customizados precisam de uma abordagem diferente: clicar para abrir, depois clicar na opção por role ou texto visível.
Elementos nativos
O caso mais simples: um elemento HTML padrão.
<label for="country">Country</label>
<select id="country">
<option value="">Select a country</option>
<option value="us">United States</option>
<option value="de">Germany</option>
<option value="pl">Poland</option>
</select>// Seleciona pelo texto visível
await page.getByLabel('Country').selectOption('Germany');
// Seleciona pelo atributo value
await page.getByLabel('Country').selectOption({ value: 'de' });
// Seleciona por índice (base 0, evite — frágil)
await page.getByLabel('Country').selectOption({ index: 2 });
// Verifica a seleção
await expect(page.getByLabel('Country')).toHaveValue('de');
// Seleciona múltiplos (para <select multiple>)
await page.getByLabel('Tags').selectOption(['playwright', 'typescript']);selectOption() funciona apenas em elementos . Para dropdowns customizados, você precisa de uma abordagem diferente.
Componentes dropdown customizados
A maioria dos apps modernos usa componentes dropdown customizados (React Select, Headless UI, Material UI) em vez de nativo. Eles parecem dropdowns, mas se comportam de forma diferente por baixo.
Padrão 1: Clicar para abrir, depois clicar na opção
O padrão mais comum de dropdown customizado:
// Dropdown customizado: clicar para abrir, clicar para selecionar
await page.getByRole('combobox', { name: 'Country' }).click();
await page.getByRole('option', { name: 'Germany' }).click();
// Verificar
await expect(page.getByRole('combobox', { name: 'Country' })).toHaveText('Germany');Se o dropdown usa o role listbox:
await page.getByRole('button', { name: 'Country' }).click();
await page.getByRole('listbox').getByRole('option', { name: 'Germany' }).click();Padrão 2: Digitar para filtrar, depois selecionar
Muitos dropdowns customizados suportam busca/filtro:
// Digitar para filtrar
await page.getByRole('combobox', { name: 'Country' }).fill('Ger');
// Aguardar os resultados filtrados aparecerem
await page.getByRole('option', { name: 'Germany' }).waitFor();
// Clicar na opção
await page.getByRole('option', { name: 'Germany' }).click();Padrão 3: Navegação por teclado
Alguns dropdowns são controlados por teclado:
await page.getByLabel('Country').focus();
await page.keyboard.press('ArrowDown'); // Abre o dropdown
await page.keyboard.press('ArrowDown'); // Move para a primeira opção
await page.keyboard.press('ArrowDown'); // Move para a segunda opção
await page.keyboard.press('Enter'); // SelecionaOu digitar para pular para opções correspondentes:
await page.getByLabel('Country').focus();
await page.keyboard.type('G'); // Pula para Germany
await page.keyboard.press('Enter');Inspecionando a implementação real do dropdown
Antes de escrever o teste, inspecione o elemento no DevTools:
1. Clique com o botão direito no dropdown e selecione Inspecionar
2. Verifique o tipo do elemento: 3. Se for customizado, interaja com ele manualmente e observe as mudanças no DOM 4. Verifique o atributo A abordagem certa de teste depende inteiramente da implementação. Não assuma. O React Select é uma das bibliotecas de dropdown mais utilizadas. Tem comportamento específico: O React Select usa classes CSS específicas. Se sua versão gera nomes de classe diferentes, adapte conforme necessário. Prefira Inputs de data com dropdowns separados para mês, dia e ano: Para ou um ?
role ou os roles ARIAReact Select (uma biblioteca comum)
// Combobox do React Select
const dropdown = page.locator('.react-select__control');
await dropdown.click();
// Digitar para filtrar
await dropdown.locator('input').fill('Ger');
await page.locator('.react-select__option', { hasText: 'Germany' }).click();
// Verificar
await expect(page.locator('.react-select__single-value')).toHaveText('Germany');
// Limpar a seleção
await page.locator('.react-select__clear-indicator').click();getByRole quando possível:// Melhor — usa roles semânticos
await page.getByRole('combobox', { name: 'Country' }).click();
await page.getByRole('option', { name: 'Germany' }).click();Dropdowns multi-select
// <select multiple> nativo
await page.getByLabel('Skills').selectOption(['playwright', 'typescript', 'cicd']);
// Multi-select customizado: clicar em múltiplas opções
await page.getByRole('button', { name: 'Skills' }).click();
await page.getByRole('option', { name: 'Playwright' }).click();
await page.getByRole('option', { name: 'TypeScript' }).click();
await page.getByRole('option', { name: 'CI/CD' }).click();
// Fechar o dropdown
await page.keyboard.press('Escape');
// Verificar seleções
await expect(page.getByTestId('selected-skills')).toContainText('Playwright');
await expect(page.getByTestId('selected-skills')).toContainText('TypeScript');Dropdowns de data (seletores de dia, mês, ano)
await page.getByLabel('Month').selectOption('June');
await page.getByLabel('Day').selectOption('15');
await page.getByLabel('Year').selectOption('1990');:// Funciona cross-browser
await page.getByLabel('Date of birth').fill('1990-06-15');
// Verificar
await expect(page.getByLabel('Date of birth')).toHaveValue('1990-06-15');Verificando as opções do dropdown
// Verifica que todas as opções estão presentes
const options = await page.getByLabel('Country').locator('option').allTextContents();
expect(options).toContain('Germany');
expect(options).toContain('Poland');
// Verifica que uma opção específica está desabilitada
await expect(page.getByRole('option', { name: 'Out of stock item' })).toBeDisabled();
// Verifica a quantidade de opções
const optionCount = await page.getByLabel('Category').locator('option').count();
expect(optionCount).toBeGreaterThan(0);Erros comuns
Usar selectOption() em um dropdown customizado. Funciona apenas em . Dropdowns customizados exigem interações de clique ou teclado.
Não aguardar as opções aparecerem. Após abrir um dropdown que carrega opções de forma assíncrona, espere a opção ficar visível antes de clicar.
Selecionar por índice. Frágil: uma nova opção adicionada antes da sua quebra o teste. Use texto ou value em vez disso.
Não verificar o que o dropdown mostra após a seleção. Faça assertion no valor selecionado, não apenas que o clique não lançou um erro.
→ Veja também: Locators do Playwright: getByRole, getByLabel, getByText, getByTestId Comparados | Assertions no Playwright: O Guia Completo | Múltiplas Abas, Janelas e iFrames no Playwright