简体   繁体   中英

How to select undisplayed options from dropdown check list in Selenium using Python

I am trying to write a Selenium driver to test a web page that uses drop down (combo) check lists. The following code exhibits the problem.

#!/usr/bin/python

from selenium import webdriver
from selenium.webdriver.support.ui import Select

driver = webdriver.Firefox()

driver.get("http://dropdown-check-list.googlecode.com/svn/trunk/doc/ddcl-tests.html")

selector = driver.find_element_by_id("s1")

allOptions = selector.find_elements_by_tag_name("option")

for option in allOptions:
    print "Value is", option.get_attribute("value")
    option.click()

When I run it, I get the following output:

Value is Low
Traceback (most recent call last):
  File "./ddcl-test.py", line 24, in <module>
option.click()
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 51, in click
self._execute(Command.CLICK_ELEMENT)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 225, in _execute
return self._parent.execute(command, params)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 160, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 149, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: u'Element is not currently visible and so may not be interacted with' ; Stacktrace: Method fxdriver.preconditions.visible threw an error in file:///var/folders/d4/qbgb29wx7z7fpr15t___x24h0000gn/T/tmpBzUUcu/extensions/fxdriver@googlecode.com/components/command_processor.js 

It can't click on the element(s) because it's not displayed.

How can I resolve this? Or is this an untestable case in Selenium?

The problem is that the <SELECT> you're trying to access is deliberately hidden by jQuery:

<select id="s1" class="s1" tabindex="8" multiple="" style="display: none;">
    <option>Low</option>
    <option>Medium</option>
    <option>High</option>
</select>

WebDriver won't click on a hidden element. Period. It's deliberate, because an end user can't click on it either. WebDriver doesn't want to let you do things humans can't do.

Instead, you have to interact with the browser the same way a human would: by clicking on whatever element jQuery exposes to the human. For this example, the human UI is:

<span id="ddcl-s1" class="ui-dropdownchecklist ui-dropdownchecklist-selector-wrapper ui-widget" style="display: inline-block; cursor: default; overflow: hidden;">
    <span class="ui-dropdownchecklist-selector ui-state-default" style="display: inline-block; overflow: hidden; white-space: nowrap; width: 85px;" tabindex="8">
        <span class="ui-dropdownchecklist-text" style="display: inline-block; white-space: nowrap; overflow: hidden; width: 81px;" title=" "> 
        </span>
    </span>
</span>
<div id="ddcl-s1-ddw" class="ui-dropdownchecklist ui-dropdownchecklist-dropcontainer-wrapper ui-widget" style="position: absolute; left: -33000px; top: -33000px; height: 74px; width: 91px;">
    <div class="ui-dropdownchecklist-dropcontainer ui-widget-content" style="overflow-y: auto; height: 74px;">
        <div class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">
            <input id="ddcl-s1-i0" class="active" type="checkbox" tabindex="8" disabled="" index="0" value="Low">
            <label class="ui-dropdownchecklist-text" for="ddcl-s1-i0" style="cursor: default;">Low</label>
        </div>
        <div class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">
            <input id="ddcl-s1-i1" class="active" type="checkbox" tabindex="8" disabled="" index="1" value="Medium">
            <label class="ui-dropdownchecklist-text" for="ddcl-s1-i1" style="cursor: default;">Medium</label>
        </div>
        <div class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">
            <input id="ddcl-s1-i2" class="active" type="checkbox" tabindex="8" disabled="" index="2" value="High">
            <label class="ui-dropdownchecklist-text" for="ddcl-s1-i2" style="cursor: default;">High</label>
        </div>
    </div>
</div>

So it looks like the thing to interact with is one of the <input id="ddcl-s1-i*" ...> elements, but it's really not easy to be sure.

This is why some of us think JavaScript frameworks that reconstruct existing HTML capabilities from spans and divs are a Really Bad Idea.

I've tried endless times to click on elements that are not visible and it's just not doable with selenium, or at least I haven't found a way yet. It doesn't look like you're trying to click on the drop down button first so I would suggest to click on the drop down menu button first to expose the menu and I think that should get you past your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM