Reputation: 31
I'm trying to get puppeteer to work with antd Select but can't figure out how. Puppeteer keeps timing out because it can't find the selector.
<Select
id="select-whale-type-dropdown"
showSearch
placeholder="Choose one..."
notFoundContent="Whale Type not found"
>
<Select.Option value="Blue Whale" key="Blue Whale">
Blue Whale
</Select.Option>
<Select.Option value="Humpback Whale" key="Humpback Whale">
Humpback Whale
</Select.Option>
<Select.Option value="Pilot Whale" key="Pilot Whale">
Pilot Whale
</Select.Option>
Error message:
1) Frontend crawl test
Whale crawl
Selects Humpback Whale as Whale Type:
Error: waiting for selector "#select-whale-type-dropdown" failed: timeout 30000ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (node_modules/puppeteer/lib/FrameManager.js:845:60)
It worked fine when we were still using react-bootstrap's dropdown, it seems like antd doesn't use the native select element. Any idea how to get antd Select to work with puppeteer?
Thank you :)
Jess
Upvotes: 3
Views: 1923
Reputation: 11
we can use aria-controls
attribute now .
<div class="ant-select-selection
ant-select-selection--single" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="dc58f58e-d287-4a0b-a9aa-d5ce3435102a" aria-expanded="false" data-__meta="[object Object]" data-__field="[object Object]" tabindex="0">
then
document.querySelectorAll('#dc58f58e-d287-4a0b-a9aa-d5ce3435102a')
Upvotes: 1
Reputation: 6087
You are correct, the native <select>
element is not used. AntD <Select>
has a lot more features than it can support.
So you need to take a look at what AntD actually renders, and direct Puppeteer to look for that code. The input field part looks like this:
<div class="ant-select ant-select-enabled">
<div class="ant-select-selection
ant-select-selection--single" role="combobox" aria-autocomplete="list" aria-haspopup="true"
aria-expanded="false" tabindex="0">
<div class="ant-select-selection__rendered">
<div unselectable="unselectable" class="ant-select-selection__placeholder"
style="display: block; user-select: none;">Choose one...
</div>
<div class="ant-select-search ant-select-search--inline" style="display: none;">
<div class="ant-select-search__field__wrap">
<input id="select-whale-type-dropdown" autocomplete="off"
class="ant-select-search__field" value="">
<span class="ant-select-search__field__mirror"> </span>
</div>
</div>
</div>
<span class="ant-select-arrow" unselectable="unselectable" style="user-select: none;"><b></b></span></div>
</div>
Then the dropdown is rendered as an absolutely positioned div on top of the page, looking like this:
<div style="position: absolute; top: 0px; left: 0px; width: 100%;">
<div>
<div class="ant-select-dropdown ant-select-dropdown--single ant-select-dropdown-placement-bottomLeft ant-select-dropdown-hidden"
style="width: 400px; left: 198.5px; top: 1196.08px;">
<div style="overflow: auto;">
<ul class="ant-select-dropdown-menu ant-select-dropdown-menu-root ant-select-dropdown-menu-vertical"
role="menu" aria-activedescendant="" tabindex="0">
<li unselectable="unselectable" class="ant-select-dropdown-menu-item" role="menuitem"
aria-selected="false" style="user-select: none;">Blue Whale
</li>
<li unselectable="unselectable" class="ant-select-dropdown-menu-item" role="menuitem"
aria-selected="false" style="user-select: none;">Humpback Whale
</li>
<li unselectable="unselectable" class="ant-select-dropdown-menu-item" role="menuitem"
aria-selected="false" style="user-select: none;">Pilot Whale
</li>
</ul>
</div>
</div>
</div>
</div>
So Puppeteer should look for the input#select-whale-type-dropdown
field, click it and then look for ul>li menu item tags. If you have several <Select>
on the page, use the dropdownClassName
property to assign different class names to the absolutely positioned divs, in order to make them individually addressable.
Upvotes: 0