Capybara proxy turn on/off while testing - ruby-on-rails

I am using capybara, selenium and geckodriver.
I know that we can configure selenium to launch Firefox with a proxy using a code such as below:
Capybara.register_driver :selenium do |app|
proxy = Selenium::WebDriver::Proxy.new(http: "127.0.0.1:9999", ssl: "127.0.0.1:9999")
desired_caps = Selenium::WebDriver::Remote::Capabilities.firefox({
firefox_profile: "default",
proxy: proxy
})
Capybara::Selenium::Driver.new(app, {:browser => :firefox, :desired_capabilities => desired_caps})
end
Capybara.current_driver = :selenium
#session = Capybara::Session.new(:selenium)
This starts a Firefox instance with the proxy already configured.
Is there a way to turn on/off the proxy after Capybara has started its tests? (ie: I visit url www.xyz.com with proxy. And then, without closing the firefox instance, turn off the proxy, and visit www.abc.com. After that, turn on the proxy and visit www.123.com)
I saw an SO answer that is very close to what I am looking for, instantiate capybara browser and set a proxy, but comments show that it no longer works.
Refs: https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings

Related

Capybara error on HTTP.get: HTTP::ConnectionError Exception: failed to connect: Connection refused - connect(2) for "localhost" port 3000

My app is set to use Capybara and minitest with RackTest driver. This is the main config in test_helper.rb:
require 'capybara/rails'
require 'capybara/minitest'
class ActionDispatch::IntegrationTest
include Capybara::DSL
include Capybara::Minitest::Assertions
fixtures :all
...
Capybara.app_host = "http://localhost:3000"
Capybara.run_server = true
Capybara.server_port = 3000
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new app,
follow_redirects:false
end
...
end
Now, when I perform request directly on my tests they work fine. Such as:
post '/api/v4/login', params: {"email": u.email, "password": u.password }
But in one test I'm calling a class (inside /app) that performs the following method:
HTTP.get(url,params).body
For which i appear to have no server running and get the following Error message in response:
HTTP::ConnectionError Exception: failed to connect: Connection refused - connect(2) for "localhost" port 3000
First, you should not be using post or get in tests that use Capybara (feature/system tests). They should only be used in request/raw integration tests, which don't use Capybara or the server it starts (lazily when the need is detected through a visit call) and are generally used for API tests.
Second, you should not be setting the port (to 3000), or app_host (generally) when having Capybara run the AUT. Port 3000 is generally the port your development server gets run on (rails s) so having Capybara run on the same port in test mode would conflict. If you don't have a really specific need for Capybara to be on a specific port (firewall forwarding, etc) then just let it pick a random port.
Capybara.run_server = true
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new app, follow_redirects:false
end
That will then have Capybara start the app on 127.0.0.1:<random_port>, if you want it specifically on localhost (due to special networking needs, IPv6, etc) then you can set Capybara.server_host = 'localhost'. Also the use of follow_redirects: false is questionable since your tests that use Capybara really shouldn't be checking status codes, but rather what the user sees.
Beyond all that, if you are running a request test that ends up calling app code that does a HTTP::get you'll either need to change that test to be a feature/system test (uses Capybara, starts its own server, uses visit, etc) or mock/stub the request.

Is it possible to set a Selenium::Driver::Proxy after initialization

I am currently using Capybara and Chromedriver to run feature tests in our Rails application. At the moment I can see that it is possible to set the proxy via args when you initialize the driver.
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
args: [
'--window-size=1240,1400',
"--proxy-server=#{s.url}",
'--proxy-bypass-list=127.0.0.1'
]
)
end
However, I only want specific tests to proxy a particular port, because I am also using Capybara::Discoball to boot up a Sinatra app as the application I am proxying external requests to. So I need to be able to change the proxy after it has initialized to the port of the currently booted Sinatra app. Is this possible after initialization?
No but you can register another driver with another name and then specify to use that for the tests that require it. Assuming you're using the default capybara rspec configuration that would be something like
Capybara.register_driver :selenium_chrome do |app|
# register the driver without proxy here
end
Capybara.register_driver :selenium_chrome_proxy do |app|
# register the driver with proxy config here
end
Capybara.javascript_driver = :selenium_chrome # register default JS driver
it "does something that doesn't need proxy", js: true do
# test that doesn't use the proxy config
end
it "does something that needs proxy", driver: :selenium_chrome_proxy do
# test that uses proxy
end

How to get "console.log" from Selenium (with Chrome) in the Rails log files?

In Rails project, I'm using Cucumber, with Capybara, in order to run my tests in a Chrome web browser through Selenium.
My tests are running fine but I would like to get the console.log, console.error and so on in the log files of my Rails application.
I have registered a :chrome capybara driver like this (based on different articles and SO answers):
Capybara.register_driver :chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: {
args: chrome_switches,
},
loggingPrefs: {
browser: 'ALL',
client: 'ALL',
driver: 'ALL',
server: 'ALL'
}
)
Capybara::Selenium::Driver.new(
app,
browser: :remote,
url: "http://selenium:#{ENV['SELENIUM_PORT']}/wd/hub",
desired_capabilities: capabilities
)
end
But I have nothing, from the Chrome browser, in the log files.
How to get "console.log" from Selenium (with Chrome) in the Rails log files?
The logs don't show up automatically, you would need to request them from Selenium and then add then write them out to whatever log you like. To request the logs you need to do something like
page.driver.browser.manage.logs.get(:browser) # :driver, etc.
Generally you'd do something like that in an after step and then write it to the log file you want it to be in.

Cannot specify no_proxy for Capybara with poltergeist

I there, I am a bit stuck with this...
I can't find documentation on how to tell Capybara/Poltergeist with phantomjs to avoid the proxy and go directly to the specified IP.
Host machine (Fedora 20) config? Already tried setting no_proxy
Or, Application config?
A bit of context:
I am making a few web tests using Capybara with Poltergeist/PhantomJS. Unfortunately, my company decided that any request for an internal network that hits the proxy won't be forwarded anymore. So, since I am testing between two different machines in the company's intranet, putting the env variable no_proxy should be enough. But no...
Well... after digging a bit more on the PhantomJS github API Reference page I found the answer.
There is an option --proxy-type=[http|socks5|none] that can be passed to phantomjs command line or in the initialization of Capybara with poltergeist like this:
Capybara.run_server = false
Capybara.javascript_driver = :poltergeist
Capybara.default_wait_time = 60
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, { :phantomjs_options => ['--ignore-ssl-errors=yes', '--proxy-type=none'] })
end

Capybara Poltergeist - Site shows message to enable cookies

I am running Capybara 1.1.2 with Poltergeist 1.0.1 for headless testing. The test runs fine with selenium driver. However with poltergeist, the site snapshot states that cookies are disabled. Am I missing any config. Shouldn't cookies be enabled by default?
You can make sure that the cookies are enabled in Capybara before setting the session.
Capybara.register_driver :my_firefox_driver do |app|
Capybara::Poltergeist::Driver.new(app, {:js_errors => false,
:cookies => true, :window_size => [1280, 1024]})
end
self.session = Capybara::Session.new(:my_firefox_driver)

Resources