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.
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>:
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:
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.
expect_value = '3'
select_tag = '#tag'
# extract all options value
option_texts = []
for option_ele in await page.querySelectorAll(f'{select_tag} > option'):
text = await page.evaluate('(element) => ({"value":element.value,"text":element.textContent})', option_ele)
option_texts.append(text)
value = ''
for v in option_texts:
if v.get('text') == expect_value:
value = v.get('value')
break
await page.select(select_tag, value)