Using Capybara and Selenium test suite fail switching from Firefox to Chrome - ruby

Using capybara (2.4.4) to test a non Rails application. I have write some tests, I run the tests using selenium with default firefox web browser and all tests are green.
Today I have tried to run same tests against chrome with this configuration:
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.javascript_driver = :selenium
Capybara.default_driver= :selenium
Capybara.app_host = ENV['WEB_SERVER_URL']
When I start the tests they fail becouse Chrome it seems too quick, infact with Firefox to complete the form it took several seconds, instead with Chrome is very very quick but then the tests fails with random errors:
"email" field not found (??)
current_url is not the expected url (?? in the browser I see the correct url!! )
ect ect..
Errors in my opinion have no sense and is very strange because with Firefox all tests are green.
Have you ever noticed this problem?

Chromedriver with Chrome 44 returns from actions much faster than before (incorrectly apparently) so visit is basically fully asynchronous. There have been numerous issues filed against Chromedriver for this such as https://code.google.com/p/chromedriver/issues/detail?id=1158&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
What this means for test stability is potentially needing to specify a longer wait on finds for the first element you're looking for after a visit, and checking for content that should be on the page before checking the current url (because content checks will use capybaras waiting behavior while capybara doesn't provide a waiting url matcher currently). You could also revert to Chrome 43 which will probably fix your issues

In accordance with the link provided by Tom Walpole I have switch from Chrome 44 to Chromium 43. I prefer use Chromium becouse I use chrome during my working day and I want to always have the latest version.
In my Ubuntu 14.04:
$sudo apt-get install chromium-browser
Then:
#spec/spec_helper.rb
require 'selenium/webdriver'
if ENV["USE_CHROME_BROWSER"]
Capybara.register_driver :selenium do |app|
Selenium::WebDriver::Chrome.path = ENV["CHROME_PATH"] if ENV["CHROME_PATH"]
Capybara::Selenium::Driver.new app, browser: :chrome
end
end
Capybara.default_driver = Capybara.javascript_driver = :selenium
Capybara.app_host = ENV['WEB_SERVER_URL']
With this configuration I can easily switch from Firefox (default) to Chromium.
I use dotenv gem to manage the configurations:
#./.env
...
USE_CHROME_BROWSER = true
CHROME_PATH = "/usr/bin/chromium-browser"
...

Based on what you have provided, I cannot tell if Chrome actually does load faster than Firefox. However, the following may be of some help. Wherever you define your Capybara conditions, I suggest replacing them with the following:
Capybara.configure do |config|
config.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
config.default_wait_time = 5 # default is 2 seconds
end
config.javascript_driver = :selenium
config.default_driver= :selenium
config.app_host = ENV['WEB_SERVER_URL']
end
Not only can you change the default wait time for Capybara to search for an element, but your code will be a little DRYer!
You may want to test other JavaScript drivers, like Capybara-Webkit. If this works for Chrome, I would suggest editing the config above, so capybara-webkit is set only when using a Chrome browser.

Related

How do I open a chrome browser using ruby, cucumber, capybara and bddfire gem?

I am very new at BDD testing and I am trying to figure out how to open a chrome browser in a specific URL using these technologies. I already installed bddfire gem and already ran it.
Now I have a feature:
#openingChrome
Scenario: Opening Chrome on facebook page
Given I open chrome and write "url"
bddfir_steps.rb
Given(/^I open chrome and write "([^"]*)"$/) do |arg1|
$session.visit("https://www.facebook.com.br")
end
In the hooks file I wrote
Before do
$session = Capybara::Session.new(:selenium, browser: :chrome)
end
And in the env.rb file that came with bddfire gem there is this
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
So chrome is already added and I already installed chrome webdriver. Unfortunately this line of code is not working: $session = Capybara::Session.new(:selenium, browser: :chrome)
it throws this error: The second parameter to Session::new should be a rack app if passed. (TypeError)
does anyone know why?
Session#new takes the name of the driver and optionally a rack app instance to start. Since you don't seem to be starting an app and you're registering your driver with a name of :chrome you want
Before do
$session = Capybara::Session.new(:chrome)
end

Disable Javascript for Chrome using Capybara Selenium

I'm wondering if there is a way to disable Javascript for some tests using Selenium-webdriver in Chrome with Capybara.
I have the following:
Capybara.register_driver :selenium do |app|
opts = Selenium::WebDriver::Chrome::Options.new
opts.add_argument '--start-maximized'
opts.add_argument '--disable-infobars'
opts.add_argument '--disable-features'
Capybara::Selenium::Driver.new(app, browser: :chrome, options: opts)
end
Capybara.default_driver = :selenium
But I don't think that --disable-javascript works now.
I've tried to find an alternative but to no joy.
Would anyone have the solution?
I think it is not possible to disable js for selenium-webdriver, however, you can just use :rack_test. driver instead.
From Capybara documentation:
By default, Capybara uses the :rack_test driver, which is fast but
limited: it does not support JavaScript,
So in your case it can be:
it "test description", driver: :rack_test do
...
end

chrome browser closes automatically after the program finishes in ruby using watir

I am using chrome 56, chrome driver 2.27(latest release) with selenium web driver 3.1.0. Referring to the issue(https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/1811) where chrome closes all the instances once the program finishes and it does not give me a chance to debug. I just want to know if this is fixed then why it is still happening ? or i am missing something ?
I am using the following code. Any help is appreciated.
require "uri"
require "net/http"
require 'watir-webdriver'
require 'selenium-webdriver'
#b = Watir::Browser.new :chrome
#b.goto 'http://www.google.com'
Firstly, watir-webdriver gem is deprecated. The updated code is in the watir gem. Also, you shouldn't need to require any of those other gems directly.
The chromedriver service is stopped when the ruby process exits. If you do not want the browsers that were started by chromedriver to close as well, you need to use the detach parameter. Currently this is done like so:
require 'watir'
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps[:chrome_options] = {detach: true}
#b = Watir::Browser.new :chrome, desired_capabilities: caps
Declare these
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => true})
browser = Watir::Browser.new :chrome, desired_capabilities: caps
On a side note! this might give a problem when you are running multiple scenario tests, chromedriver will actively refuse connection in case an other test initiates in the same chrome session. Ensure you have browser.close whenever required.

Unsupported command-line flag: --ignore-certificate-errors (in Ruby)

Using Ruby 2.0.0 p481 in RubyMine and chromedriver 2.10
When Chrome starts it displays a message in a yellow popup bar: "You are using an unsupported command-line flag: --ignore-certificate-errors. Stability and security will suffer." This simple example reproduces the problem.
require "selenium-webdriver"
driver = Selenium::WebDriver.for :chrome
driver.navigate.to login_url
This question has been answered for Java and Python. I have looked everywhere for a Ruby analog. Does anyone have a suggestion or know how to translate the Python answer (Unsupported command-line flag: --ignore-certificate-errors) to Ruby? Thank you!
The Ruby selenium-webdriver API doesn't expose a separate Chrome options object like Java/Python but you can set the options via "Capabilities".
The Capabilities web page provides a Ruby example and the table of recognized capabilities that you can inject. Plugging those together with excludeSwitches:
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"excludeSwitches" => [ "--ignore-certificate-errors" ]})
driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps
Take a look at Watir too, it's a front end for WebDriver.
Their examples show how you can send a :switches array which is passed straight through to the web driver so you can do the same. That makes adding other switches a bit easier rather than going through capabilities.
There is a chromedriver issue on the topic as well. There are posts detailing that you can add a --test-type argument to work around the certificate issue and ruby code examples like above.
I adjusted:
driver = Selenium::WebDriver.for :chrome
to read:
driver = Selenium::WebDriver.for :chrome, :switches => %w[--test-type]
...and the script ran successfully without the yellow flag. Clearly, other command-line switches could be added.
Thank you to Nguyen Vu Hoang and mtm.
I donot know ruby, however my approach is set mode "test-type" to ChromeDriver capabilities
Here's my sample code in Java
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities = DesiredCapabilities.chrome();
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type", "start-maximized",
"no-default-browser-check");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
With Capybara:
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome, switches: ['--test-type'])
end
This error caused my rspec tests to fail. I think it was causing Chrome to slow down so the above fixes did remove the error messages but did not resolve my problem of my tests failing.
If you are using chromedriver-helper then this should fix the problem. Run this from the command line
chromedriver-update
This is described more in chromedriver-helper, "This might be necessary on platforms on which Chrome auto-updates, which has been known to introduce incompatibilities with older versions of chromedrive"
Once I ran this I was able to remove the fixes described elsewhere and Chrome ran with out warnings.

How to use same browser window for automated test using selenium-webdriver (ruby)?

I am automating test cases for a website using selenium-webdriver and cucumber in ruby. I need each feature to run in a particular order and using the same browser window. Atm each feature creates a new window to run test in. Though in some test cases this behavior is desired- in many cases it is not. From my research so far it seems there are mixed answers about whether or not it is possible to drive the same browser window with selenium throughout test cases. Most answers I have run into were for other languages and were work arounds specific to a browser (I am developing my test while testing IE but will be expected to run these test in other browsers). I am working in Ruby and from what I have read it seems as though I'd have to make a class for the page? I'm confused as to why I would have to do this or how that helps.
my env.rb file:
require 'selenium-webdriver'
require 'rubygems'
require 'nokogiri'
require 'rspec/expectations'
Before do
#driver ||= Selenium::WebDriver.for :ie
#accept_next_alert = true
#driver.manage.timeouts.implicit_wait = 30
#driver.manage.timeouts.script_timeout = 30
#verification_errors = []
end
After do
##driver.quit
##verification_errors.should == []
end
Some information I've gathered so far of people with similar problems:
https://code.google.com/p/selenium/issues/detail?id=18
Is there any way to attach an already running browser to selenium webdriver in java?
Please ask me questions if anything about my question is not clear. I have many more test to create but I do not want to move on creating test if my foundation is sloppy and missing requested capabilities. (If you notice any other issues within my code please point them out in a comment)
The Before hook is run before each scenario. This is why a new browser is opened each time.
Do the following instead (in the env.rb):
require "selenium-webdriver"
driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []
Before do
#driver = driver
end
at_exit do
driver.close
end
In this case, a browser will be opened at the start (before any tests). Then each test will grab that browser and continue using it.
Note: While it is usually okay to re-use the browser across tests. You should be careful about tests that need to be run in a specific order (ie become dependent). Dependent tests can be hard to debug and maintain.
I had a similar problem in creating a spec_helper file. I did the following (simplified for locally-run firefox) for my purposes and it works very, very reliably. RSpec will use the same browser window for all it blocks in your _spec.rb file.
Rspec.configure do |config|
config.before(:all) do
#driver = Selenium::WebDriver.for :firefox
end
config.after(:all) do
#driver.quit
end
end
If you switch to :each instead of :all, you can use a separate browser instance for each assertion block... again, with :each RSpec will give a new browser instance for each it. Both are useful depending on the circumstance.
As the answers solve the problem but do not answer the question "How to connect to an existing session".
I managed to do this with the following code since it is not officially supported.
# monkey-patch 2 methods
module Selenium
module WebDriver
class Driver
# Be able to set the driver
def set_bridge_to(b)
#bridge = b
end
# bridge is a private method, simply create a public version
def public_bridge
#bridge
end
end
end
end
caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")
driver = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
used_bridge = driver.bridge
driver.get('https://www.google.com')
# opens a new unused chrome window
driver2 = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
driver2.close() # close unused chrome window
driver2.set_bridge_to(used_bridge)
driver2.title # => "Google"
Sadly this did not test work between 2 rescue jobs, will update this in the future when I made it work for my own use case.

Resources