Selenium can't find anything after clicking link and updating frame - ruby

I am trying to make a script that will mass-apply to jobs on LinkedIn. It is able successfully log in and search for jobs, collect elements that contain the special 'linkedIn-apply' icon, and this is where the problems begin. Once it clicks on one of those, it successfully loads the job posting's page, but after that it CANNOT seem to locate anything.
To add more information, when a job posting is clicked, LinkedIn automatically opens up the posting in a new tab. Is it possible that the driver is still on the main page and doesn't see what is on the other tab?
Entire file:
require 'selenium-webdriver'
require 'byebug'
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"excludeSwitches" => [ "--ignore-certificate-errors" ]})
driver = Selenium::WebDriver.for :chrome, :switches => %w[--test-type]
driver.navigate.to("https://www.linkedin.com/uas/login?goback=&trk=hb_signin")
# driver.switch_to.frame(0)
driver.find_element(:name, "session_key").send_keys("someuser")
driver.find_element(:name, "session_password").send_keys("somepassword")
driver.find_element(:name, "signin").click()
driver.switch_to.frame(0)
sleep 2
driver.find_element(:link_text, "Jobs").click()
sleep 2
e = driver.find_elements(:class, "in-apply-icon")
if e.empty?
driver.find_element(:class, "expand-button").click
else
e.each do |posting|
posting.click
sleep 10
driver.switch_to.frame(0)
sleep 10
# THIS is where it gets stuck. It cannot find the 'apply button'. I have tried
using :id and alas, no luck. I have tried finding other things and no luck.
driver.find_element(:class, "apply-button").click
sleep 5
driver.find_element(:id, "file-browse-input").send_keys(somepath)
sleep 5
driver.find_element(:id, "send-application-button").click
#find and click on apply
#upload resume
#submit
#hit x button/leave
#hit back button
end
end
The code towards the bottom is not complete, I am aware of that. I can't even get past clicking the apply button, so it is not important at this time.

Make sure if there is a frame , you are switching to the correct frame and then find the element. Switching to frame indexed to Zero takes you to the default frame.

Related

verify scroller button works with preloaded data with watir-webdriver

I am trying to verify that a scroller button is working correctly. The button is an arrow image that slides a row of images/links, showing 5 out of the 10 images that are all loaded at page load. Whats making it difficult is that images are populated from a 3rd party provided so the urls change all the time. The only other identifier is by its class and text, the class is the same for all of them.
Since they are all loaded at the same time its hard to determine if the images are changing.
If you go to http://www.hayneedle.com/product/curiousgeorgepeelstickgiantmural.cfm and scroll to "Suggestions For You" you can see the on the right to scroll to a new set of suggestions. This button has broke before so need a simple way to regression it.
Any suggestions?
You can check if an image is actually visible to the user by using the present? method. You could also use the visible? method, but it throws an exception if the element does not exist. You can see a comparison of these and the .exists? method in the blog post, "Checking for an element – exists?, visible?, present?".
Knowing this, you could click the scrolling arrow and then check if last image is present (ie actually visible).
# Go to the page
browser = Watir::Browser.new :firefox
browser.goto 'http://www.hayneedle.com/product/curiousgeorgepeelstickgiantmural.cfm'
# This is the scroller control
scroller = browser.div(:id => 'HN_PP_RelatedCats')
# (optional) Check that the last image is *not* displayed
puts browser.div(:class => 'HN_Scroller_Cont').link(:index => 9).present?
#=> false
# Click the right scroller
scroller.div(:class => 'HN_Scroller_R').click
# Check that the last image is displayed
puts browser.div(:class => 'HN_Scroller_Cont').link(:index => 9).when_present.present?
#=> true
Note that the check for the last link/image is using when_present.present?. The when_present allows the scrolling to finish. Without it, you might end up checking the element before the scrolling is done (ie you false negative). The present? is there to return a true/false result.

Unable to find buttons of system popup using rautomation

I'm writing tests using Selenium WebDriver and rautomation to handle system popup. I tried it on irb like following:
require 'selenium-webdriver'
require 'rautomation'
driver = Selenium::WebDriver.for :firefox
driver.get "http://rubygems.org/gems/rautomation-0.9.2.gem"
window = RAutomation::Window.new :title => "Opening rautomation-0.9.2.gem"
ok_button = window.button(:text => "&OK")
ok_button.exists?
cancel_button = window.button(:text => "&Cancel")
cancel_button.exists?
ok_button.exists? and cancel_button.exists? are returning false. Hence I can't click on the buttons.
I also tried:
window.buttons.length
to find number of buttons, but it's returning 0.
Could someone please help me why the buttons aren't detected using rautomation? Please correct me if I'm doing something wrong.
Here is a popup:
For my condition, I have to send two :tab key and then send :enter to save the file. like:
driver.get "http://rubygems.org/gems/rautomation-0.9.2.gem"
window = RAutomation::Window.new :title => /Opening/i
if window.exist?
window.activate
window.send_keys :tab;
sleep 2;
window.send_keys :tab;
sleep 2;
window.send_keys :enter
end
I don't know why I can't just save the file with:
window.activate; sleep 1; window.send_keys :enter
The problem with this dialog is that it does not use native Windows controls. When you use Spy++ or AutoIt Window Info Tool then they do not show you any controls in that window either.
When using RAutomation you can check if it has native controls on it or not like this:
win = RAutomation::Window.new :title => /Opening rautomation/
p win.present?
p win.controls.length
p win.text
win.close
The output of this script will be:
true
0
""
In other words - window was present, it had zero controls of any kind and text was an empty string. Also, closing the window really closed it which you can verify visually - this means that we were interacting with the correct window and not accidentally with some other empty window (beware: this might sometimes happen too).
This all means that you cannot interact with the controls directly with AutoIt, RAutomation or many other automation tools. There might be some specific automation tools available for handling these kind of dialogs - i'm not sure.
There is however a workaround how to work with these kind of windows - send needed keystrokes to the window. In this case, sending a return/enter key would do the trick since that is the same as clicking on the "OK" button - you can try that manually.
Here is example code, which works the same as clicking on the "OK" button:
win = RAutomation::Window.new :title => /Opening rautomation/
win.activate
sleep 1
win.send_keys :enter
I'm not sure why, but for some reason you have to activate the window manually by calling Window#activate and wait a second before sending that enter key.
After doing that a new dialog will pop up, which uses native Windows controls - you can handle that as you would have expected RAutomation to work in the first place.
However, if you would use a :ms_uia adapter instead of the default :win32 then you don't need to activate and sleep.
Here is a fully working example with :ms_uia adapter:
win = RAutomation::Window.new :title => /Opening rautomation/, :adapter => :ms_uia
win.send_keys :enter
file_dialog = RAutomation::Window.new :title => /Enter name of file/
file_dialog.button(:value => "&Save").click
To click "Cancel" on the first dialog instead of "OK" you can just use Window#close as i was using to test the window above.
I would recommend you to use :ms_uia adapter instead of :win_32 since it is getting more stable every day and will be a new default one in the far future.
To set :ms_uia adapter for default one you can use environment variable RAUTOMATION_ADAPTER before loading RAutomation itself like this:
ENV["RAUTOMATION_ADAPTER"] ||= :ms_uia
require "rautomation"
I do not see any popup when I click that link. Chrome just downloads a file. :) This could help: http://watirwebdriver.com/browser-downloads/
This code worked for me:
window = RAutomation::Window.new(:title => /Opening rautomation-0.9.2.gem/i)
window.activate
p window.exists? # => true
sleep 2
window.send_keys(:down)
window.send_keys(:enter)

how to scroll a web page using watir

I am trying to scroll a web page to find and click on a content that is lazily loaded when the page is scrolled. I am using following command
require 'watir-webdriver'
#browser = Watir::new :firefox
#browser.send_keys :space
I am using web-driver with firefox and I am on ubuntu but it is not working. In the following ruby code I am trying to scroll the page down until I don't find the element with :id. The element is loading lazily.
I am getting timeout after few seconds, any idea what is wrong with the following code.
When /^deal (\d+) is loaded$/ do |id|
(0..5).each do |click|
#browser.send_keys :space
end
end
What is the best way to scroll a page using watir-driver ?
If you have JavaScript enabled, you can access the underlying driver and execute some JavaScript to scroll on the page.
#browser.driver.executeScript("window.scrollBy(0,200)")
will scroll down the page 200 pixels along the y axix.
See here for documentation of the method:
http://www.w3schools.com/jsref/met_win_scrollby.asp
I use a gem called "watir-scroll" to assist me with this. Though it usually needs places to scroll to, it also will scroll to coordinates.
https://github.com/p0deje/watir-scroll
Since Watir v6.16 watir-scroll gem merged into watir
You can either scroll to a specific element
button1 = #browser.input(:class => "mileage_rate")
#browser.scroll.to button1
Or just scroll to the top middle or center
#browser.scroll.to :top
#browser.scroll.to :center
#browser.scroll.to :bottom
Or scroll to a coordinate
browser.scroll.to [0, 200]
This saved me a bunch of time:
browser.div(:id => 'start-date-holder').wd.location_once_scrolled_into_view
Sorry I could not comment on the last answer since I am new here and do not have enough rep pts yet so I just created a new answer. Anyways, if anyone is having issues with scrolling multiple times try this (add a loop and sleep):
maximum_times_needed = max # of times you need the page to scroll down
maximum_times_needed.each do
#browser.driver.executeScript("window.scrollBy(0,200)")
sleep 0.15
end
0.15 may vary depending on how long it takes the page to load. 0.15 is 0.15 seconds so adjust as needed to allow for enough time for the page to load. The 200 may also need to be adjusted to a larger pixel amount.
300.times do
#browser.driver.execute_script("window.scrollBy(0,200)")
sleep 0.05
end
You can access the underlying driver and execute some javascript. For instance if you wanted to scroll to the bottom of the page you would use
#browser.driver.execute_script( "window.scrollBy(0,document.body.scrollHeight)" )
which scrolls to the bottom of the page on the y-axis.
It works
evaluate_script("document.getElementsByTagName('body')[0].scrollTop=0;")

How to set WATIR focus on new window

I'm new to WATIR testing (and do I love it!) and have run into a wall on how to refocus my WATIR script to a newly opened window.. Here's my (simplified) script....
#!/usr/bin/ruby
require 'rubygems'
require 'watir-webdriver'
browser=Watir::Browser.new
browser.goto("http://0:3050")
browser.text_field(:name,"userkey300203830").set("OKJHNB")
browser.button(:id, "interview48").click
puts "Expected Result:"
puts "A successful display of cars"
if browser.window(:title=>"300203830").exists?
puts " Test passed. New window opened!"
else
puts " Test Failed! No window found"
end
It all works right up to the end. After the key "interview48" is clicked, a new window is opened with the title "300203830". Looks like I find it but I just don't know how to now focus on that window.
browser.window(:title => "300203830").use do
# do something
end
More information: http://watir.github.io/docs/browser-popups/
Additionally for more than 2 windows you can use the following:
browser.windows[n].use
#n is variable for which window. n will access them in order of opened or tabs from left to right
browser.windows.last.use
browser.windows.first.use
You can use the above commands if you open a new window from first browser instance and would like to toggle between the two.
There are 3 primary selectors for windows:
:title - typically the easiest
:url - often used with a Regexp value
:element - a unique element might be the least brittle (new as of Watir 6.18!)
browser.window(title: 'new window')
browser.window(url: /my_page.html/)
browser.window(element: browser.div(id: 'my-element'))
Locating by index is no longer supported
More information: Watir Browser Windows
If there is only one other window you want to use, so as of Watir 6.18, the easiest way to work with that window is with Browser#switch_window. It can only be used if there are only 2 windows, and all it does is switch to the other one, no additional locating required.
browser.switch_window

How can I automate a slider using watir-webdriver and ruby?

I am trying to automate a Jquery UI slider using watir-webdriver and ruby but am having no luck. I want to be able to manipulate the slider to either increase or decrease the value. I have searched everywhere and asked a few of my colleagues but no one has an answer. I am attaching a piece of HTML code for the slider. Any help would be much appreciated.
URL link: http://www.whatcar.com/new-car-deals/ (price range slider)
I haven't done any coding for the slider as I have no idea how to go about it. If I could be set on the right path that would be fantastic. Also it seems the HTML code doesn't seem to be showing on the question I am asking.
it's a Jquery widget that appears (looking at the scripts) to respond to key presses once one of the handles has been clicked on. the handles are link objects, inside a pair of divs, the outer one has the ID value 'slider-range'
You should be able to address them via browser.div(:id => 'slider-range').link(:index => n) where n = 0 for the lefthand one and n=1 for the right hand one.
Try this manually first
Click on the left handle for the slider
Then press arrow keys on the keyboard.. it will move 1K(pounds) up or down with each right or left arrow keypress.
Once you have moved it right, click the Home key and it should reset to its min value
repeat above for the right handle but reset it to far right using the End key.
In theory you could fire a click event at the right slider to get focus, then fire off some keypress events to first set it far right (end) followed by enough left arrows to move it down to the top value you want.
Repeat for the left handle, setting it to the left end with the home key, and moving it with right arrow keypresses
I don't have the time right now to experiment further and develop an exact script, but I think you could probably create two little functions even that took an upper and lower range value and did the required number of keypresses to move the lower up from 5K to the right amount, and the upper down from 100k
Note that this thing is very very event driven, it responds (at least when watching the dev tools while playing with it) to being moused over, mousedown, mouseup, etc.. if using click does not work to 'get the attention' of the control so it will respond to keypresses, try using the onmousedown event instead.
Using the code from your answer, to move the left slider to 12K I'd try
browser.div(:id => 'slider-range').link(:index => 0).click #make sure it has focus
browser.div(:id => 'slider-range').link(:index => 0).send_keys :home #set to 5K
7.times do
browser.div(:id => 'slider-range').link(:index => 0).send_keys :arrow_right
end
Thank you very much Chuck. I got it working. Here is the script I used:
#browser.link(:xpath, "/html/body/div/div[3]/div[4]/div/div/div/a").send_keys :arrow_right
Still needs a bit of tweaking, but I should be ok now.
This worked great. We just added these sliders to our website and my first thought was "how are we going to automate that!?"
I wanted to add an example will full code that is available publicly for people to experiment with. The following interacts with an example on jqueryui.com.
require "watir-webdriver"
#browser = Watir::Browser.new :chrome
#browser.goto "http://jqueryui.com/slider/#default"
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").click
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").send_keys :home
puts "clicked home"
7.times do
#browser.frame(:class => "demo-frame").span(:class =>"ui-slider-handle").send_keys :arrow_right
end
To achieve this using Rspec and Watir-Webdriver with Page-Object gem I used:
div(:slider, id: "slider-range") #in page file
#then in spec file
browser.slider_element.input.send_keys :home
This answer comes from http://watir.com/guides/special-keys/

Resources