I am playing around with capybara/poltergeist perfect duo, but I am having trouble to properly debugging.
I was testing a simple script:
logger = Logger.new "./log/who-scored-com.log"
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false,
debug: true,
logger: logger)
end
browser = Capybara.current_session
browser.visit 'https://www.whoscored.com/LiveScores'
browser.save_page 'page.html'
I am expecting that the script grap the page normally and saves it, but the page is empty and this is returned:
`Capybara::Poltergeist::StatusFailError: Capybara::Poltergeist::StatusFailError
from /home/vagrant/local/ruby-2.3.0/lib/ruby/gems/2.3.0/gems/poltergeist-1.9.0/lib/capybara/poltergeist/browser.rb:351:in `command'
from /home/vagrant/local/ruby-2.3.0/lib/ruby/gems/2.3.0/gems/poltergeist-1.9.0/lib/capybara/poltergeist/browser.rb:34:in `visit'`
Now, this don't give me nothing about this error. I catch the exception and print it and it gives me:
"Request to 'https://www.whoscored.com/LiveScores' failed to reach server, check DNS and/or server status"
Even if I have no idea why the address do not respond for capybara (and any hint would be appreciate :) ) I don't understand why the :debug options used in configuration doesn't seem to give me no info
You have a couple of issues
the poltergeist logger option is defined as '(Object responding to puts) - The ruby 2.3.0 standard library Logger object doesnt respond to puts so it's not valid.
You're example doesn't have Capybara.current_driver = :poltergeist so I'm not sure if it is actually using the driver you're configuring there or a previously defined one (I would have expected an error on the Logger object if it was)
debug: true will add debugging for poltergeist to the log, but there is also debugging info from phantomjs. That is generated by passing phantomjs_options: ['--debug=true'], phantomjs_logger: <an IO object - again not a Logger object> to the driver
The error you're actually hitting is the connection being refused due to not being able to negotiate an ssl protocol - to fix it add the required ssl protocol as a phantomjs option - `phantomjs_options: ['--ssl-protocol=TLSv1.2']
I'd use something like the following in a standalone ruby script, adjust driver_options to suit your taste.
require 'capybara'
require 'capybara/poltergeist'
class NilLogger
def puts * ; end
end
def setup_session
driver_options = { js_errors: false,
logger: NilLogger.new,
phantomjs_logger: STDOUT,
phantomjs_options: ['--debug=true'],
debug: false }
Capybara.configure do |conf|
conf.run_server = false
conf.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new app, driver_options
end
conf.current_driver = :poltergeist
end
Capybara.current_session
end
browser = setup_session()
browser.visit 'https://www.whoscored.com/LiveScores'
browser.save_page 'page.html'
Have you tried
Capybara.register_driver :poltergeist_debug do |app|
Capybara::Poltergeist::Driver.new(app, :inspector => true)
end
Capybara.javascript_driver = :poltergeist_debug
as shown here?
Related
I'm trying to launch chrome in headless but the browser keeps on launching. Tried several different ways
used chrome options and added arguments
used chrome capabilities as well
My chrome version: 86
OS - ubuntu
capybara - 3.32.2
First Helper file:
spec_helper.rb
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome,
options: Selenium::WebDriver::Chrome::Options.new(args: %w[headless no-sandbox disable-gpu]))
end
Capybara.default_driver = :headless_chrome
Capybara.javascript_driver = :headless_chrome
Second try of Helper file:
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities:Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: {
args: %w[headless disable-gpu disable-popup-blocking no-sandbox]
}
)
)
end
Capybara.default_driver = :headless_chrome
Capybara.javascript_driver = :headless_chrome
Thanks in advance
Simplest way is to not register your own driver and just use the one provided by Capybara
Capybara.default_driver = :selenium_chrome_headless
Capybara.javascript_driver = :selenium_chrome_headless
Note - this will only work if you're not using rails system tests (no indication in your question that you're using rails though) since they override these settings - see the rails/rspec system test docs (driven_by) for that.
Resolved this by adding chromeOptions separately and had to remove -- from all arguments
Apparently, for Selenium >= 3.8, you have to specify goog:chromeOptions instead of chromeOptions.
So in your example:
...
Selenium::WebDriver::Remote::Capabilities.chrome(
"goog:chromeOptions": {
args: %w[headless disable-gpu disable-popup-blocking no-sandbox]
}
)
)
I was experiencing the same issue and this solved it for me.
I know how to create profile for Firefox
require 'watir'
options = Selenium::WebDriver::Firefox::Options.new
options.profile = "default"
#driver = Selenium::WebDriver.for :firefox, options: options
#b = Watir::Browser.new #driver
But when I do same thing for Chrome it's not creating, Infact I realized that options(please look above) object doesn't even have the method profile= so I try adding profile like as given below(I saw how people are creating in Java Selenium Binding so I have done the same but it's not working here)
options = Selenium::WebDriver::Firefox::Options.new
options.add_argument('user-data-dir=C:\Users\user_name\AppData\Local\Google\Chrome\User Data\Default')
#driver = Selenium::WebDriver.for :chrome, options: options
Can someone help me how to create Chrome Profile via Ruby Selenium binding(or WATIR)?
Using an existing or creating a new profile can be done via Chromedrivers user-data-dir argument. In Watir, you can pass the argument via the :args parameter:
browser = Watir::Browser.new :chrome,
args: ['user-data-dir=C:\Users\user_name\AppData\Local\Google\Chrome\User Data']
Note that if you trying to use the existing default profile, you do not want to include the "Default" directory in the path.
I made a function for creating new browser. You can use it.
def new_browser
if Rails.env.production?
chrome_bin = ENV.fetch('GOOGLE_CHROME_SHIM', nil)
Selenium::WebDriver::Chrome.path = "/app/.apt/usr/bin/google-chrome"
Selenium::WebDriver::Chrome.driver_path = "/app/vendor/bundle/bin/chromedriver"
end
profile = Selenium::WebDriver::Chrome::Profile.new
profile['general.useragent.override'] = 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10'
driver = Selenium::WebDriver.for :chrome, :profile => profile
pid = driver.instance_variable_get(:#service).instance_variable_get(:#process).instance_variable_get(:#pid)
begin
browser = Watir::Browser.new driver
rescue => e
system("kill -9 #{#pid}")
end
return {:browser => browser , :pid => pid}
end
Since you asked in the comments for a more detailed explanation for Capybara, I post it as an answer (although you seem to already have a working solution now - sorry for the delayed answer).
In my rails projects I usually configure the Selenium chrome driver as follows:
gem 'chromedriver-helper'
in the Gemfile (or install it locally). Then in a system-test initializer define
Capybara.register_driver :selenium_chrome_headless_no_sandbox do |app|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
browser_options.args << '--headless'
browser_options.args << '--disable-gpu'
browser_options.args << '--no-sandbox'
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
and later (configuring RSpec) I set it as the used driver like:
RSpec.configure do |config|
config.before(:each, type: :system, js: true) do
driven_by :selenium_chrome_headless_no_sandbox
end
end
Maybe this helps someone. Cheers
edit: added chromedriver-helper
I am using Capybara with Selenium driver for my acceptance tests
Versions used:
Selenium 2.53.1
Capybara 2.7.1
cucumber 2.2.0
cucumber-core 1.3.1
According to Selenium/Logging, known log types are browser, client, driver, performance and server. I would like to log all these log types in console output in realtime.
Based on what I understood, to enable full logging I am configuring Capybara as following:
Capybara.configure do |config|
config.run_server = false
config.app_host = ENV['APP_HOST'] # APP HOST from Cucumber.yml file
config.default_driver = :selenium
config.match = :prefer_exact
config.default_max_wait_time = 10
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(
app,
:browser => ENV['BROWSER'].downcase.to_sym,
:desired_capabilities => {
:loggingPrefs => {
:browser => "ALL",
:client => "ALL",
:driver => "ALL",
:server => "ALL"
}
}
)
end
end
Where ENV['BROWSER'] is 'Chrome'.
What I am still unclear is how to print the logs to console. I am looking for a way to print the logs for all scenarios.
I tried adding following code to hooks.rb
After do |scenario|
puts #browser.driver.manage.get_log(:browser)
puts #browser.driver.manage.get_log(:client)
puts #browser.driver.manage.get_log(:server)
puts #browser.driver.manage.get_log(:driver)
end
but #browser is nil.
Also tried following in hooks.rb
After do |scenario|
puts page.driver.browser.manage.logs.get(:browser)
end
But works only for browser logs.
Question: How do I print these logs after each scenario, or even better in realtime?
I have written a small block that will launch Google Chrome when I set a tag #chrome above a scenario within a feature file.
Before ('#chrome') do
Capybara.default_driver = :selenium
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app,
:browser => :chrome,
desired_capabilities: {
'chromeOptions' => {
'args' => %w{ window-size=1920,1080 }
}
}
)
end
end
The problem I have is that all subsequent scenarios within the feature file will also run in Chrome, even when the tag isn't set for them.
Is there a way to add to it to say revert back to Poltergeist once I'm done. I've tried the following but it didn't work:
After do |scenario|
if #chrome == true
Capybara.register_driver = :poltergeist
Capybara::Poltergeist::Driver.new(
app,
phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1'],
window_size: [1280, 1024],
js_errors: false,
debug: false
)
end
end
Thanks in advance for any help you might have
Capybara already provides this behavior here . To use it you just need to require it and register a driver with the tag name you want to use. This would usually be in your env.rb/custom_env.rb
require 'capybara/cucumber'
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app,
browser: :chrome,
...
)
end
The important thing is the name you use to register the driver has to match the tag used (in this case #chrome). It also shows you shouldn't be changing Capybara.default_driver on a test by test basis, that's what Capybara.current_driver is for. You also shouldn't be registering a new driver every scenario, register_driver is meant to be called once for each driver configuration you will need and then referenced by name later.
in env.rb, I have this:
if ENV['BROWSER']
Capybara.default_driver = :selenium
else
# DEFAULT: headless tests with poltergeist/PhantomJS
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(
app,
window_size: [1280, 1024] #,
#debug: true
)
end
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
end
Tests run fine in poltergeist, but if I try to run in firefox, a browser opens, nothing happens, and then the test fails with the first visit statement.
HTTP request path is empty (ArgumentError)
What's wrong with my cucumber/capybara setup? Is there something more I need to do to run tests in a real browser?
In env.rb
ENV['no_proxy'] = '127.0.0.1'