Initiate Button click action using Watir Ruby library - ruby

Watir::Browser.default = "firefox"
ie = Watir::Browser.start("http://cars.com")
ie.select_list(:id, 'make_1').set('Chevrolet')
ie.select_list(:id, 'model_1').set('Cobalt')
ie.select_list(:id, 'pricehighnew').set('No Max')
ie.select_list(:id, 'rdnew').set('30 miles')
ie.text_field(:name, "zc").set "44109"
ie.form(:method, "GET").submit #Here is the problem...
URL: http://www.cars.com/
Can anyone help me initiate button click action searching for "New Cars" form on the top left. Seems like they are using JavaScript as well. I appreciate any help.

There's probably a way to do it with JavaScript, but taking just a minute I was able to click the button two different ways:
ie.span(:text=>"Search New").click
ie.link(:href=>"javascript:checkZipFirst(document.newForm, quickSubmitNew, document.newForm.zc.value);").click

Also any of these would work:
browser.a(:class => "button primary zc-submit").click
or
browser.link(:name => "submit").click
or
browser.a(:id => "submit", :index => n).click
where n is the index number

Related

Can Not Click The Same Element Class Using Watir

I have the following screen:
And I use the following Ruby script to click the "Add New" button:
vendorTab = driver.a id: "tab-master-tab-vendor"
vendorTab.wait_until_present
if vendorTab.exists?
vendorTab.click
end
addNewButton = driver.button class: ['btn btn-primary']
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
But, when I move to another tab and try to click the same "Add New" button, the Ruby script doesn't work.
Is there anything wrong with my Ruby code?
buildingTypeTab = driver.a id: "tab-master-tab-building"
buildingTypeTab.wait_until_present
if buildingTypeTab.exists?
buildingTypeTab.click
end
addNewButton = driver.button class: ['btn btn-primary']
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
I Appreciate your help. Thank you very much.
I guess all of these tabs are part of the same web page? I.e., all in the same HTML?
If that is the case, driver.button class: ['btn btn-primary'] is going to stop when it finds the first instance in the HTML, but that isn't the button you are looking for every time (it's the button in the first tab, where your script worked as you expected).
The best options in my mind are
find a way to uniquely identify the button in each tab (for example, use id instead of class if possible), or
pull all the buttons into a collection and click the button using its collection index after you figure out which index aligns with each tab. For example,
button_collection = browser.buttons(:class, ['btn', 'btn-primary'])
button_collection[2].click # Will click the 3rd button in the collection
After reading the suggestions from pjd,
I modified it a bit and got it working like this:
buildingTypeTab = driver.a id: "tab-master-tab-building"
buildingTypeTab.wait_until_present
if buildingTypeTab.exists?
buildingTypeTab.click
end
addNewButton = driver.button(:class => ['btn btn-primary'], :index => 2)
addNewButton.wait_until_present
if addNewButton.exists?
addNewButton.click
end
As pjd said, yes all these tabs are part of the same HTML
Thank you.

ruby watir - get all divs inner contents from search

I am attempting to scrape a website (respectfully). I tried with Nokogiri, then mechanize, then because the website i am scraping is loading a form dynamically, I was forced to use a webdriver. I am currently using ruby's watir.
What i am trying to do, is to fill out the dynamic form with a select, clicking submit, going to the results part of the page (form renders result on same page), and collecting all the divs with the information (traversing through sub-divs looking for hrefs).
def scrape
browser = Watir::Browser.new
browser.goto 'http://www.website-link.com'
browser.select_list(:id => 'city').select('cityName')
browser.link(:id, 'btnSearch').click
# this part; results from search are in this div w/ this ID
# however, iterating through this list does not work the way i expected
browser.div(:id, 'resultsDiv').divs.each do |div|
p div
end
browser.close
end
right now this returns
#<Watir::Div: located: true; {:id=>"resultsDiv", :tag_name=>"div"} --> {:tag_name=>"div", :index=>0}>
#<Watir::Div: located: true; {:id=>"resultsDiv", :tag_name=>"div"} --> {:tag_name=>"div", :index=>1}>
#<Watir::Div: located: true; {:id=>"resultsDiv", :tag_name=>"div"} --> {:tag_name=>"div", :index=>2}>
which looking at the page source looks like there are 3 divs inside of the resultsDiv which is probably what those indexes are. I guess what i was expecting (coming from Nokogiri/Mechanize) is an object to manipulate.
does anyone have any experience doing this that could point me to the right direction?
If you known the order that you want, you can do:
browser.driver.find_elements(:id => 'resultsDiv')[n].click
or
browser.div(:id => 'resultsDiv')[n].click
or
browser.div(:id, 'resultsDiv').div(:id,'id_n').click

Watir WebDriver select list without standard html

Just started using Watir-WebDriver, came across website with and facing an problem.
1) Goto "https://www.smiles.com.br/home"
2) How to get/set values to drop down selections like selecting number of adults in "Adulto"
Selection list initially is hidden but when clicked on the text field it become visible in browser.
But when I tried using to click and check its existence it returning false
1) b.text_field(:id => "inputOrigin").click
2) irb(main):049:0> b.a(:id => 'yui_patched_v3_11_0_1_1467245841395_1777').exist?
=> false
Since its not actually a selection list, how do I set values?
Thanks in advance.
The ID is dynamic so it changes every time. It looks like it might be based on the time, but this should be sufficiently unique:
b.link(id: /^yui_patched_v3_11_0_1_/)
After clicking on <input id="inputOrigin">, you need to perform another click to trigger the "dropdown" list. Otherwise, you'll get a element not visible error. You could do something like this:
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto('https://www.smiles.com.br/home')
b.text_field(:id => "inputOrigin").when_present.click
b.div(:id => "dk_container_qtdAdult").when_present.click #trigger "dropdown" menu
b.div(:class => "adult").link(:text => "02").when_present.click
# b.div(:class => "adult").link(:data_dk_dropdown_value => "02").click #an alternative
Once selected, you can get the option using the .text method:
puts b.div(:id => "dk_container_qtdAdult").link(:class => "dk_toggle dk_label").text
Lastly, you could use regex locators, but you might have more success by trying to identify more discrete (and--ideally--unique) page elements.

Ruby selenium gem: open hyperlinks in multiple tabs

Goal: In irb, open a series of hyperlinks in new tabs and save a screenshot of each.
Code:
require "rubygems"
require "selenium-webdriver"
browser = Selenium::WebDriver.for:firefox
browser.get 'https://company.com'
browser.find_element(:name, "username").send_keys("myUsername")
browser.find_element(:name, "password").send_keys("myPassword")
browser.find_element(:name, "ibm-submit").click
body = browser.find_element(:tag_name => 'body')
body.send_keys(:control, 't')
parent = browser.find_element(:xpath, "//div[#id='someid']")
children = parent.find_elements(:xpath,"//a")
children.each do |i| ;
body.send_keys(:control, 't')
i.click
browser.save_screenshot("{i}")
end
Problem:
Selenium::WebDriver::Error::StaleElementReferenceError: Element not found in the cache - perhaps the page has changed since it was looked up
Question: What am I doing wrong?
Basically you can't share WebElements across pages, yet you're trying to access body across multiple tabs. Try not to think of them as self-contained objects, but as proxies to something on a real page.
The solution is to only ever perform actions on the 'current' page. In your case that means sending the Ctrl-T event on the tab that you've created. Having done that the first time, you're switched to the new tab. You then need to re-perform the lookup:
newTabsBody = browser.find_element(:tag_name => 'body')
and then:
newTabsBody.send_keys(:control, 't')
to create the next one. Continue for each child.

Making a Dialog Box popup when button is clicked (Seesaw)

Im making a simple GUI interface where a user can add/remove a person. I have my GUI set up where there is a table of People with three fields: Name, Age, and Likes.
I have a button called Add Person which I would like to have a dialog box pop up. However, I get the error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: No im
plementation of method: :visible! of protocol: #'seesaw.core/Showable found for
class: guidemo.core$add_person
I don't know where to use the visible! option.
I have the following code for my dialog box:
(defn add-person [person]
;(seesaw/frame :title "Add New Person" :on-close :exit :content
(seesaw/dialog :content
(seesaw/flow-panel :items
["Name:" (seesaw/text :id :title)
;"Age:" (seesaw/text :id :age)
;"Likes:" (seesaw/text :id :likes)
])
:option-type :ok-cancel)
:success-fn (fn [p] (seesaw/text (seesaw/select (seesaw/to-root p) [:#name ] )))
(seesaw/show! add-person))
I got this example off of the seesaw api to start myself with something. I commented out the frame because adding containers on top of another container is not allowed and I commented out the other fields for now. I know the 'success-fn` does not add anything to a table, but I am more concerned with getting a popup window to appear when a button is clicked.
My code of my button is:
(def add-button
(seesaw/button
:text "Add New Person"
:listen [:mouse-pressed add-person]
:popup add-person))
I am able to use seesaw/inputs to create a simple input box with one field, however I want to have one with three fields. Is there a way around this? (and yes I tried 3 input boxes, but they pop up one at a time and its very unintuitive)

Resources