Search code examples
pythoncssseleniumselenium-webdriversplinter

splinter: visible dropdown is clickable but not selectable


I am trying to select something from a dropdown on a modal via splinter. I have no problem finding this dropdown, e.g. :

(Pdb) dropdown = next(i for i in my_browser.find_by_xpath('//select[@name="existing.widgets.user:list"]') if i.visible)

(the page I'm dealing with actually has multiple, identical modals, so I have to get the current, visible one. Sigh..)

The dropdown can be clicked:

(Pdb) dropdown.visible
True
(Pdb) dropdown.click()  //succeeds and displays menu
(Pdb)

...but trying to select on it fails, even though it's supposedly visible!

(Pdb) dropdown.select('my_val')
*** ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
    at fxdriver.preconditions.visible (file:///tmp/tmp6tSmOc/extensions/fxdriver@googlecode.com/components/command-processor.js:9587)
    at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmp6tSmOc/extensions/fxdriver@googlecode.com/components/command-processor.js:12257)
    at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmp6tSmOc/extensions/fxdriver@googlecode.com/components/command-processor.js:12274)
    at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmp6tSmOc/extensions/fxdriver@googlecode.com/components/command-processor.js:12279)
    at DelayedCommand.prototype.execute/< (file:///tmp/tmp6tSmOc/extensions/fxdriver@googlecode.com/components/command-processor.js:12221)
(Pdb) dropdown.visible
True  // what???
(Pdb)

I'm pretty sure the argument to select is correct, so I'm at a loss about what's going on here.

If all else fails, is there something clever I can do with xpaths? Or do I need to try finding/interacting with the element another way?

A partial screenshot of the HTML situation: http://pasteboard.co/1I30ljRl.png


Solution

  • As it turns out, the multiple modals are what did me in.

    Given my dropdown with name 'existing.widgets.user:list' and the desired my_val, the failing select call, at its source, has:

    find_by_xpath('//select[@name="%s"]/option[@value="%s"]' % (dropdown['name'], my_val).click()

    Now, it turns out that this find_by_xpath actually returns multiple/duplicate options, probably from the multiple modals!

    (Pdb) blah=my_browser.find_by_xpath('//select[@name="%s"]/option[@value="%s"]' % (dropdown['name'], my_val)
    (Pdb) blah
    [<splinter.driver.webdriver.WebDriverElement object at 0x7f7205ff3750>, <splinter.driver.webdriver.WebDriverElement object at 0x7f7205ff39d0>, <splinter.driver.webdriver.WebDriverElement object at 0x7f7205ff38d0>, <splinter.driver.webdriver.WebDriverElement object at 0x7f7205ff3610>]
    (Pdb) [bl.value for bl in blah]
    [u'my_val', u'my_val', u'my_val', u'my_val']
    (Pdb) [bl.visible for bl in blah]
    [False, True, False, False]
    

    I thought I could fix this by accessing the options via the correct modal (e.g, with the specific form class) instead of through the whole page; i.e., starting with something like

    form = my_browser.find_by_xpath('//form[@id="{0}"]'.format(my_current_modal))
    

    ...and THEN trying

    dropdown = form.find_by_xpath(...)
    dropdown.select(...)
    etc.
    

    But it led to the same problem; still multiple elements being found, and still failing! So, I resorted to visibility checks, which actually worked:

    opts = form.find_by_xpath('//select[@name="%s"]/option[@value="%s"]' % (dropdown['name'], my_val)
    next(opt for opt in opts if opt.visible).click()
    

    Perhaps something I'm still missing here...or even something buggy with Splinter, but at least it works!