Can someone please give me a example of how to use rspec-retry with the selenium-webdriver. I am trying to get it to reattempt the navigation when there is a Net::ReadTimeout error. I found an example here but I am new to Ruby and don't think I am using it right.
What I have tried.
require 'selenium-webdriver'
require 'rspec/retry'
Selenium::WebDriver::PhantomJS.path = 'phantomjs.exe'
driver = Selenium::WebDriver.for :phantomjs
driver.manage.timeouts.page_load = 300
driver.navigate.to "http://google.com"
RSpec.configure do |config|
# show retry status in spec process
config.verbose_retry = true
# Try five times (retry 4 times)
config.default_retry_count = 5
# Only retry when Selenium raises Net::ReadTimeout
config.exceptions_to_retry = [Net::ReadTimeout]
end
puts(driver.title)
driver.quit
It sounds like you may not be using rspec at all, but just want the retry behavior that is provided by the rspec-retry gem. If that's the case, you could just use ruby's rescue and retry keywords to achieve the same thing.
For example, the following code will retry the navigation 1 time if the navigation throws a Net::ReadTimeout
require 'selenium-webdriver'
Selenium::WebDriver::PhantomJS.path = 'phantomjs.exe'
driver = Selenium::WebDriver.for :phantomjs
driver.manage.timeouts.page_load = 300
attempts = 0 # has to be outside the begin/rescue to avoid infinite loop
begin
driver.navigate.to "http://google.com"
rescue Net::ReadTimeout => e
if attempts == 0
attempts += 1
retry
else
raise
end
end
Related
I'd love to obtain following list in text (screen names) instead of objects using Twitter Api. I am new to Ruby programming language and this's my first attempt using api with ruby especially Twitter api. What I expect is list of screen names instead of objects and I will show you examples bellow:
Results I get currently:
current results
Desired and expected results
I've tried methods such as .full_text and .text appended to the objects and didn't get my desired results.I've searched almost everywhere especially here in Stackoverflow and didn't find my answer yet.
This's my code below:
require 'rubygems'
require 'bundler/setup'
require 'twitter'
require 'json'
require 'yaml'
client = Twitter::REST::Client.new do |config|
config.consumer_key = ""
config.consumer_secret = ""
config.access_token = ""
config.access_token_secret = ""
end
following_list = client.friends('User-exmaple')
begin
for friend in following_list
puts friend
end
rescue Twitter::Error::TooManyRequests => error
# NOTE: Your process could go to sleep for up to 15 minutes but if you
# retry any sooner, it will almost certainly fail with the same exception.
sleep error.rate_limit.reset_in + 1
retry
end
I hope this explains everything, thank you so much.
I solved it by appending screen_name method to friend, example below:
require 'rubygems'
require 'bundler/setup'
require 'twitter'
require 'json'
require 'yaml'
client = Twitter::REST::Client.new do |config|
config.consumer_key = ""
config.consumer_secret = ""
config.access_token = ""
config.access_token_secret = ""
end
following_list = client.friends('User-exmaple')
begin
for friend in following_list
puts friend.screen_name
end
rescue Twitter::Error::TooManyRequests => error
# NOTE: Your process could go to sleep for up to 15 minutes but if you
# retry any sooner, it will almost certainly fail with the same exception.
sleep error.rate_limit.reset_in + 1
retry
end
I hope this explains the solution I found.
I've built a test pack that runs thru hundreds of pages. I'm using find_elements to check the rendering of the page. This should just return an array and continue the test. However I'm getting ReadTimeout after the max client timeout:
Net::ReadTimeout: Net::ReadTimeout
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/default.rb:107:in `response_for'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/default.rb:58:in `request'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:606:in `find_elements_by'
/home/ken/.rvm/gems/ruby-2.2.2/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/common/search_context.rb:84:in `find_elements'
I don't want WebDriver to wait, just continue along.
How can I catch or bypass this so that my test completes?
If you just want to keep cycling through your list of pages, you can use a begin/rescue/end block to recover from the timeout (and possibly print out an appropriate message). Here's a contrived example that looks for a page element that doesn't exist:
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.get 'http://www.iana.org/domains/reserved'
begin
element = driver.find_element(:id, "element_does_not_exist")
rescue => e
puts "element is not found"
end
# a single-line alternative:
# element = driver.find_element(:id, "element_does_not_exist") rescue
driver.quit
i'm really new to Selenium WebDriver. I write a simple code for out of curiousity. I made an spam bot to open a page, shuffle in online users list and click everyone of them in order. Send some message, close the new window and repeat.
I made this work on Selenium Firefox driver. It seems work good. But i want to do it silent, not opening firefox everytime. So i found out i can do that by PhantomJS.
Here is my working code for firefox:
require 'selenium-webdriver'
def setup
#driver = Selenium::WebDriver.for :firefox
#reklam = 'Some testing message.'
end
def run
setup
#driver.get 'http://c2.me/okanb3'
first_window = #driver.window_handle
begin
#driver.switch_to.window(first_window)
#driver.find_element(link_text: "Shuffle").click
sleep 20
elements = #driver.find_elements(:class, 'shufflelink')
elements.each do |x|
x.click
all_windows = #driver.window_handles
new_window = all_windows.select { |this_window| this_window != first_window }
#driver.switch_to.window(new_window)
if #driver.page_source.include? 'The user is not available right now.' or #driver.page_source.include? 'User account is disabled.'
#driver.close
#driver.switch_to.window(first_window)
else
input = #driver.find_element(:id, 'inputbox')
input.send_keys(#reklam)
input.send_keys:return
#driver.close
popup = #driver.switch_to.alert
popup.accept
#driver.switch_to.window(first_window)
end
end
end while TRUE
end
run
But when i switch Webdriver from Firefox to PhantomJS, x.click method doesn't work. I made some tests and program doesnt go further from click method. After a while program ends with (Net::ReadTimeout) error.
Here is my last try to work it proper;
require 'selenium-webdriver'
def setup
#driver = Selenium::WebDriver.for :phantomjs
#reklam = 'http://peyloride.com siteme beklerim.'
end
def teardown
#driver.quit
end
def run
setup
#driver.manage.window.resize_to(1920, 1080)
#driver.get 'http://c2.me/okanb3'
first_window = #driver.window_handle
begin
#driver.switch_to.window(first_window)
#driver.find_element(link_text: "Shuffle").click
puts "Shuffleandı"
sleep 20
elements = #driver.find_elements(:class, 'shufflelink')
elements.each do |x|
puts "click'e geldik"
#driver.save_screenshot "phantomjs.png"
x.click
#driver.save_screenshot "phantomjs2.png"
puts "click yaptı sonunda aq"
all_windows = #driver.window_handles
new_window = all_windows.select { |this_window| this_window != first_window }
#driver.switch_to.window(new_window)
if #driver.page_source.include? 'The user is not available right now.' or #driver.page_source.include? 'User account is disabled.'
#driver.close
#driver.switch_to.window(first_window)
else
input = #driver.find_element(:id, 'inputbox')
input.send_keys(#reklam)
input.send_keys:return
#driver.close
popup = #driver.switch_to.alert
popup.accept
#driver.switch_to.window(first_window)
end
end
end while TRUE
end
run
As you can see i tried to take a screenshot to understand the problem but screenshot seems really fine. Here it is:
EDIT: Versions:
ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
gem list
...
selenium-webdriver (2.48.1)
...
phantomjs -v
1.9.0
I would like a way to take an error generated within a specific test method inside a Test::Unit::TestCase and turn it into a failure with a more friendly generic message. I keep thinking this should be possible with some inheritance but I can't quite get my head around it.
class CalenderTest001 < Test::Unit::TestCase
def testZoneCal001
Fixture.reset
$driver = Selenium::WebDriver.for :firefox
$driver.get "http://myTestSite.com/"
$driver.find_element(:id, "IDthrowsAnError").click
end
end
The effect I would like is to have the entire thing wrapped in a begin rescue end block with the rescue block looking something like this.
rescue Selenium::WebDriver::Error::NoSuchElementError => e
#mark this test as a failure not an error
You can use the assert_nothing_raised construct:
def testZoneCal001
assert_nothing_raised "Something went wrong!" do
Fixture.reset
$driver = Selenium::WebDriver.for :firefox
$driver.get "http://myTestSite.com/"
$driver.find_element(:id, "IDthrowsAnError").click
end
end
I am using webdriver-user-agent mentioned here – http://watirwebdriver.com/mobile-devices/
This is the code I am using when trying out this gem
Browser: FF/Chrome
Ruby: 1.9.3 / Selenium :2.30.0 / Watir : 4.0.2
http_client = Selenium::WebDriver::Remote::Http::Default.new
http_client.timeout = HTTP_TIMEOUT
profile = Selenium::WebDriver::Firefox::Profile.new
device = ENV["DEVICE"]
orientation = ENV["ORIENTATION"]
driver = UserAgent.driver(:browser => :firefox, :agent =>device, :orientation=>orientation)
devices = UserAgent.resolution_for(device,orientation)
UserAgent.resize_inner_window(driver,devices[0],devices[1])
Watir::Browser.new driver
Now when the last statement is executed, i get the following error
(STEP) Launching FIREFOX (using web driver user agent)……
browser:
#
undefined method `to_sym’ for # (NoMethodError)
/Users/user/.rvm/gems/ruby-1.9.3-p194/gems/watir-4.0.2/lib/watir/loader.rb:42:in `load_driver_for’
/Users/user/.rvm/gems/ruby-1.9.3-p194/gems/watir-4.0.2/lib/watir/loader.rb:8:in `new’
Based on some investigation, problem is happening at highlighted line below as its trying to .to_sym on the selenium webdriver object.
def load_driver_for(browser)
if browser && browser.to_sym != :ie && Watir.driver == :classic
Watir.driver = :webdriver
end
Watir.load_driver
end
But if we add a line like given below, this gem is working as expected.
def load_driver_for(browser)
if “#{ENV["BROWSER"]}”.eql?(“chrome_useragent”)||”#{ENV["BROWSER"]}”.eql?(“firefox_useragent”)
Watir.driver = :webdriver
else
if browser && browser.to_sym != :ie && Watir.driver == :classic
Watir.driver = :webdriver
end
Watir.load_driver
end
end
since this is watir code outside of our framework, this is not the right way to do this, any suggestion on how to avoid this situation ?
The problem is reproducible when you do:
require 'watir'
require 'webdriver-user-agent'
driver = Webdriver::UserAgent.driver(:browser => :chrome, :agent => :iphone, :orientation => :landscape)
browser = Watir::Browser.new driver
browser.goto 'tiffany.com'
browser.url.should == 'http://m.tiffany.com/International.aspx'
You can fix the issue by requiring watir-webdriver directly instead of through the watir metagem. Change the first line to:
require 'watir-webdriver'