How to select an option from dropdown select
I can click the selector but my question is how to select one of the options from the dropdown list?
await page.click('#telCountryInput > option:nth-child(4)')
Click the option using CSS selector does not work.
For example, select a country code from a list like below:
Puppeteer v0.13.0 has page.select() method, which does exactly that. You just have to give it the value to select. So, assuming you have an <option value="my-value">
in your <select>
:
await page.select('#telCountryInput', 'my-value')
For dropdown component, I think we should consider 2 situations:
- native HTML
select
element - component written by JS, composed of a button and a list of options, take bootstrap dropdown as example
For the second situation, I think click
can solve the problem.
For the first situation, I just found 2 ways to do this:
page.select
-
elementHandle.type
(notice updated on 27/04/2018)
page.select
is a new feature added in v0.12.0.
For example you have a select element:
<label>Choose One:
<select name="choose1">
<option value="val1">Value 1</option>
<option value="val2">Value 2</option>
<option value="val3">Value 3</option>
</select>
</label>
You have two ways to select second option 'Value 2'.
// use page.select
await page.select('select[name="choose1"]', 'val2');
// use elementHandle.type
const selectElem = await page.$('select[name="choose1"]');
await selectElem.type('Value 2');
Normally elementHandle.type
is used to type in text in input textbox, but since it
Focuses the element, and then sends a keydown, keypress/input, and keyup event for each character in the text.
select
HTML element has input event, so that this method works.
And I personally think elementHandle.type
is better since it's not required to know the option value attribute, only the label/name what man can see.
27/04/2018 Updated
I previously used elementHandle.type
only on Mac OSX. Recently, my colleague reported a bug related to this. He is using Linux/Win. Also, we are both using puppeteer v1.3.0.
After trial and error, we found that this elementHandle.type
can assign the value to the <select>
element, but this won't trigger the change
event of the element.
So I no longer recommend using elementHandle.type
on <select>
.
Finally, we followed this comment to dispatch change event manually. It's like:
// use manually trigger change event
await page.evaluate((optionElem, selectElem) => {
optionElem.selected = true;
const event = new Event('change', {bubbles: true});
selectElem.dispatchEvent(event);
}, optionElem, selectElem);
For native selectboxes, my solution was to execute some JS on the page itself:
await page.evaluate(() => {
document.querySelector('select option:nth-child(2)').selected = true;
})
Turn out this is easier than what I thought because the dropdown list is NOT a native HTML selction&option combination, therefore, I can actually use the code below to select the target I want.
await page.click('#telCountryInput')
await page.click('#select2-telCountryInput-results > li:nth-child(4)')
I landed here from a message where someone was asking how to select the first option from a dropdown. This is how I just worked out how to do it:
await page.click('.select-input');
await page.waitFor(300);
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
The above code first selects the relevant input. I then set a wait because mine wasn't loading quick enough. Then I used keyboard presses to navigate down to the first option.