33

I am trying to get familiar with the new ruby selenium-webdriver as it appears more intuitive mostly than the previous version of selenium and the ruby driver that went with it. Also, i had trouble getting the old selenium to work with ruby 1.9.1 in windows so I thought i'd look for an alternative. So far i've done this with my script:

require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox
driver.get "https://example.com"

element = driver.find_element(:name, 'username')
element.send_keys "mwolfe"
element = driver.find_element(:name, 'password')
element.send_keys "mypass"
driver.find_element(:id, "sign-in-button").click
driver.find_element(:id,"menu-link-my_profile_professional_info").click
driver.find_element(:id,"add_education_btn").click
country_select = driver.find_element(:name, "address_country")

So basically I'm logging into my site and trying to add an education entry to my user profile.. I have a reference to a select box with options (in the country_select variable) and now i want to select an option with a given value.. I don't see how to do this in the new client.. The only thing I can think of doing is looping through all the options until I find the one I want, and then call execute_script: http://selenium.googlecode.com/svn/trunk/docs/api/rb/Selenium/WebDriver/Driver.html#execute_script-class_method method to set the selectedIndex.

Is there any other way to do this? In the java api for selenium 2.0/webdriver here: http://seleniumhq.org/docs/09_webdriver.html there is an example of doing this

Select select = new Select(driver.findElement(By.xpath("//select")));
select.deselectAll();
select.selectByVisibleText("Edam");

It doesn't appear that the ruby version has this feature though unless I'm missing something. Any help would be appreciated.

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77

10 Answers10

35

Full disclosure here: I have absolutely no working knowledge of Ruby.

However, I'm pretty good with Selenium so I think I can help. I think what you're looking for is the select method. If ruby is anything like the other drivers you can use the select method to tell one of the options it is selected.

In pseudocode/java terms it would look something like this

    WebElement select = driver.findElement(By.name("select"));
    List<WebElement> options = select.findElements(By.tagName("option"));
    for(WebElement option : options){
        if(option.getText().equals("Name you want")) {
            option.click();
            break;
        }
    }

The Select object you have above is actually in a special Support package. It only exists for Java and .Net at the moment (Jan 2011)

Community
  • 1
  • 1
pnewhook
  • 4,048
  • 2
  • 31
  • 49
  • This doesn't seem to work, i tried country_select = driver.find_element(:xpath, "//select[id='address_country']/option = 'Austria'") country_select.select and that didn't do anything. I think the select method is like calling select() in javascript (puts focus in a field and highlights the text) – Matt Wolfe Jan 12 '11 at 23:44
  • Did you try first getting the select element, then iterate through the WebElement options and call the select method on the WebElement you want? – pnewhook Jan 13 '11 at 00:16
  • 1
    pnewhook got it right. Here's the equivalent Ruby code: https://gist.github.com/777516 If Element#select doesn't work, perhaps try Element#toggle. If you think the API is too low level, you may want to check out the watir-webdriver gem as an alternative API to the same technology. – jarib Jan 13 '11 at 07:03
  • 1
    Won't you need `option.getText().equals("Name you want")` instead of `option.getText()=="Name you want"` ? – sarnold Apr 05 '11 at 06:25
  • 4
    option.setSelected(); is deprecated and removed from 2.2 or 2.3 version. Use option.click(); instead – lisak Aug 06 '11 at 14:23
  • [@janderssn in this posting](http://stackoverflow.com/questions/6430462/how-to-select-get-drop-down-option-in-selenium-2#6435526) provided a good answer. – gunalmel Sep 16 '12 at 04:27
  • @Sloin: What if you want to select multiple? Each click will cancel the previous... – Janus Troelsen Oct 09 '12 at 22:27
20

Please note that none of the above will work anymore. Element#select and Element#toggle have been deprecated. You need to do something like:

my_select.click
my_select.find_elements( :tag_name => "option" ).find do |option|
  option.text == value
end.click
Tyson
  • 6,214
  • 3
  • 32
  • 37
14

I don't know what version Selenium this came about, but it looks like there is the Select class that pnewhook mentioned in Selenium 2.20

http://selenium.googlecode.com/svn-history/r15117/trunk/docs/api/rb/Selenium/WebDriver/Support/Select.html

option = Selenium::WebDriver::Support::Select.new(@driver.find_element(:xpath => "//select"))
option.select_by(:text, "Edam")
grumpasaurus
  • 732
  • 1
  • 6
  • 16
  • 3
    This is the best answer! There's no need to iterate through elements on your own, not to mention having to look at :tag_name => 'option' over and over again in your code. Pro tip: for easy access to the Select class (i.e. Select.new instead of Selenium::WebDriver::Support::Select.new), use: include Selenium::WebDriver::Support – Todd Mazierski May 04 '12 at 19:39
  • 4
    If you want to select by value, you can do that too: `option.select_by(:value, "edam")` – chiborg Oct 19 '12 at 12:23
7

pnewhook got it but I'd like to post the ruby version here so everyone can see it:

require "selenium-webdriver"
driver = Selenium::WebDriver.for :firefox
driver.manage.timeouts.implicit_wait = 10
driver.get "https://example.com"  
country_select = driver.find_element(:id=> "address_country")
options = country_select.find_elements(:tag_name=>"option")
options.each do |el|
    if (el.attributes("value") == "USA") 
        el.click()
        break
    end
end
Community
  • 1
  • 1
Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77
6

You can use XPath to avoid looping:

String nameYouWant = "Name you want";
WebElement select = driver.findElement(By.id(id));
WebElement option = 
  select.findElement(By.xpath("//option[contains(text(),'" + nameYouWant + "')]"));
option.click();

or

WebElement option = 
  select.findElement(By.xpath("//option[text()='" + nameYouWant + "']"));
David Carboni
  • 1,556
  • 23
  • 24
3
require "selenium-webdriver"
webdriver = Selenium::WebDriver.for :firefox

driver.navigate.to url

dropdown = webdriver.find_element(:id,dropdownid)
return nil if dropdown.nil?
selected = dropdown.find_elements(:tag_name,"option").detect { |option| option.attribute('text').eql? value}
 if selected.nil? then
  puts "Can't find value in dropdown list"
 else
  selected.click
 end

In my case this is only one working sample.

2

For the latest version of Webdriver (RC3) you should use "click()" instead of setSelected(). Also option.getText().equals("Name you want") should be used instead of option.getText()=="Name you want" in JAVA:

<!-- language: lang-java --> 
WebElement select = driver.findElement(By.name("select"));
List<WebElement> options = select.findElements(By.tagName("option"));
for(WebElement option : options){
    if(option.getText().equals("Name you want"){
        option.click();
        break;
    }
}
DHL
  • 21
  • 1
1

Ruby Code with Example:

require "selenium-webdriver"

driver = Selenium::WebDriver.for :ie

driver.navigate.to "http://google.com"
a=driver.find_element(:link,'Advanced search')

a.click


a=driver.find_element(:name,'num')

options=a.find_elements(:tag_name=>"option")
options.each do |g|
  if g.text == "20 results"
  g.click
  break
  end
end
Jazzezravi
  • 21
  • 3
0
#SELECT FROM DROPDOWN IN RUBY USING SELENIUM WEBDRIVER
#AUTHOR:AYAN  DATE:14 June 2012

require "rubygems"
require "selenium-webdriver"



  begin
    @driver = Selenium::WebDriver.for :firefox
    @base_url = "http://www.yoururl.com"
    @driver.manage.timeouts.implicit_wait = 30

    @driver.get "http://www.yoursite.com"


    #select Urugway as Country
     Selenium::WebDriver::Support::Select.new(@driver.find_element(:id, "country")).select_by(:text, "Uruguay")

        rescue Exception => e
         puts e
         @driver.quit


    end
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Ayan
  • 11
0

The easiest way I found was:

select_elem.find_element(:css, "option[value='some_value']").click
Samsul Islam
  • 2,581
  • 2
  • 17
  • 23
user337620
  • 2,239
  • 3
  • 19
  • 19