Jess
Jess

Reputation: 31

How to get Puppeteer to select item from antd Select (non-native select element)?

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

Answers (2)

nailuoGG
nailuoGG

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

Jesper We
Jesper We

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">&nbsp;</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

Related Questions