SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.5k stars 8.15k forks source link

Select doesn't work for drop-down menus #5475

Closed MarkDabe closed 4 years ago

MarkDabe commented 6 years ago

Meta -

OS: macOS Sierra 10.12.6

Selenium Version: 3.8.1

Browser: Safari 11.0.3

Browser Version:

Expected Behavior -

select an element from a drop-down menu.

Actual Behavior -

finds the element but doesn't select it.

Steps to reproduce -

            mySelect = Select(webdriver.find_element_by_xpath(xpath/to/element))
            mySelect.select_by_visible_text('visible_text')
t2hv33 commented 6 years ago

Safari not working with Select You must use javascript of DOM Using inject to load javascript Ex:

inject(driver, "document.getElementById('pref').value = '5';");

barancev commented 6 years ago

For issues please provide a concise reproducible test case and describe what results you are seeing and what results you expect.

See CONTRIBUTING.md

craigfowler commented 6 years ago

@barancev: I can contribute that answer, because I have been doing quite a bit of research into it myself.

Reproduction steps

Here's a really simple HTML page with which you can reproduce the problem:

<html>
<body>
<select id="mySelect">
  <option value="1" selected>One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>
</body>
</html>

And now the web driver code (I happen to use C#):

// GetWebDriver: Do whatever you need to do to get a web driver running Safari 11
// I happen to connect to Sauce Labs for it, but whatever is suitable for your test env
var webDriver = GetWebDriver();

var selectWebElement = webDriver.FindElement(By.Id("mySelect"));
var selectElement = new OpenQA.Selenium.Support.UI.SelectElement(selectWebElement);
selectElement.SelectByText("Two");

Expected outcome

The state of the select element should be modified - so that the option with text "Two" is now selected.

Actual outcome

The option "One" is still selected. The state of the select element has not changed.

Additional investigation

I have already performed quite a bit of my own investigation around this issue. Here's what I've found.

Other things tried

Further to the repro steps above, I have also tried:

In all cases above, the attempt to change the selected option silently fails. Via diagnostics/log info (provided to me by Sauce Labs, where I've been running the tests), I can see the 'click' which targets the HTML option element is received on the wire protocol, but Safari's web driver doesn't do anything about it (doesn't change the state of the select element).

Research around the web

In scratching around for a workaround I did come across this SO question (and its incredibly vague replies). I've ruled out the "Use the Safari WebDriver answer" I believe that Sauce Labs is indeed using the Apple WebDriver and not the outdated Selenium one. The other two answers hint that there's some kind of magical mechanism of selecting the options via a SendKeys with an empty string (it's incredibly vague though).

FWIW I did try using optionElement.SendKeys(String.Empty) to no avail. This raised an exception at the remote webdriver (which makes sense to me, sending keys directly to an HTML <option> element is meaningless IMO).

Workaround status

I believe that @t2hv33 has told us the only workaround for now - which is to use JavaScript injection to manipulate the value of the <select> control directly. That's of course sub-optimal because JavaScript does not necessarily expose all of the same mechanisms whereby the select element may be identified. In the example it has an id attribute which makes it easy, but that's not always the case.

Possibly an 'upstream' bug

Given all of the above, I'm not sure whether this is a Selenium bug at all. It seems that it's Apple/Safari's webdriver which is failing to change the state of a select element based on (as far as I'm concerned) perfectly valid wire protocol requests.

The only possibility (in my mind at least) that it's not an Apple/Safari bug is if Apple/Safari have decided to 'change the spec' for how to select/deselect individual options. I have this possibility in mind because Microsoft have done the exact same thing with the Edge browser. In Edge, in order to select/deselect a single option within a <select multiple>, we must now send Ctrl+Click and not just a plain click. I had opened that one as #4490 (and originally I had this symptom in Safari muddled up with that issue).

However, the above said - this problem with Safari affects select elements whether they have the multiple attribute or not. So I now believe that it's unlikely that this is the real cause, and actually more likely an Apple/Safari web driver bug. If people agree on that, I'll try to open a ticket with Apple directly about it; I've tried to get onto their bug tracker and I'm having trouble creating an Apple ID, so I'll have to try again another time (anyone else free to report it to Apple).

Qloriti commented 5 years ago

Year later: Issue still exists...

barancev commented 5 years ago

@Qloriti If you have a super-power to manage Apple you can go and demand them to fix this issue immediately. We don't have.

craigfowler commented 5 years ago

@Qloriti Just to echo what @barancev has said - this is an upstream problem which only Apple can fix. They are responsible for the development of the Safari Webdriver, not Selenium. Unfortunately (at least, when I last checked), Apple don't publish a public bug tracker, so we can't even reference an upstream issue here.

There is a workaround though, which is to inject JavaScript into the page to manipulate the <select> element. Since I wrote the comment above, I actually implemented the workaround in a project of my own. You're free to use that code if you'd like. Here is that JavaScript which I inject for the Safari browser. You can either use it as-is or adapt it for your own purposes.

The parameter to that function is an array of either 2 or 3 items:

  1. A reference to the HTML <select> element
  2. The action to perform. Must be one of selectByIndex, selectByValue, selectByText, deselectByIndex, deselectByValue, deselectByText or deselectAll
  3. The parameter to the action to perform (obviously, deselectAll requires no parameter)
Qloriti commented 5 years ago

@craigfowler Also I was looking for the same issue with chromedriver but most of them are closer with no clear answer. Is it confirmed that same issue have a place to be in chrome?

craigfowler commented 5 years ago

@Qloriti Hmm, I have not seen this issue in Chrome at all.

My Screenlay/Selenium project has CI builds which run via Travis & Sauce Labs. These run on a monthly schedule (at minimum) with settings designed to discover problems with newly-released browser versions. I have explicit tests which work with HTML <select> controls:

As of 8 days ago, these tests passed on both Chrome version 56 and also Chrome "latest". In this context "latest" means the highest version supported by Sauce Labs, which according to their logs of that test-run was version 73.

Based on that, I don't think Chrome suffers the problem described in this Github issue at all.

shukhov88 commented 5 years ago

Looks like issue is fixed for 12th version of safari: I am still unable to select option of dropdown in 11th version of safari, but select DOES work on 12th version.

BenderRodrigez commented 4 years ago

I've got something very close to this case. For me this is a Chrome 79th version running under Grid Hub.

I'm trying to run: new Select(webElement).selectByIndex(5);or new Select(webElement).selectByValue(val);

It hangs on execution of http request to the grid. Like this one:

http://test:test-password@selenoid.qa.domain:4444/wd/hub/session/3992c0293e7c9bff9d31c6f45e0f0c95cc117873f50a5a0a59f6cbba13f82fc0/element/0.5037337135849067-2/click

While it hangs, I can connect to the Chrome node with VNC and click on empty space on the page. If I did so, test is working fine. But if I didn't it will timeout on Grid side and client receives connection error.

diemol commented 4 years ago

Closing as it is reported this works in Safari 12.