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
Related
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
I am setting up Cucumber tests in a Rails project. Everything works fine when I use the default driver; but, when I try to use the :selenium_chrome driver, the browser tries to load example.com instead of the local Rails server. Any idea what I'm missing?
My steps look like this:
Before do |scenario|
Capybara.current_driver = :selenium_chrome
end
When(/^I visit the posts page$/) do
visit posts_url
end
When I run the features, I can see that the rails server gets launched:
Using the default profile...
Feature: Posts
Capybara starting Puma...
* Version 3.12.0 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:62056
But, the Chrome window that pops up is attempting to access http://www.example.com/posts instead of http://127.0.0.1:62056/posts
Am I missing a configuration step somewhere?
On a related note: If I want to run all my tests using Selenium, should I have to put the Capybara.current_driver line in a Before block? I tried just adding it to features/support/env.rb, but it didn't seem to have any effect.
I have Chrome 73.0.3683.86 and Rails 5.2.2 running on MacOS 10.14.4.
If you want to use :selenium_chrome as the default driver, you can set Capybara.default_driver = :selenium_chrome.
As to the example.com issue that's because you're visiting posts_url and have your Rails default hostname set to be example.com in your test environment. You can either visit posts_path which will allow Capybara to default the hostname to localhost - or update your test environment config so the url helpers produce the urls you expect.
You need to set Capybara app_host config eg Capybara.app_host = .... See full docs here
Generally, you set Capybara config inside spec_helper.rb so that it's enabled in all specs eg:
Capybara.configure do |config|
config.current_driver = :selenium_chrome
config.app_host = ...
end
Hope that answers your questions?
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.
I have an interesting problem. I'm using Rspec for test driven development and Capybara with Poltergeist for acceptance testing. Oh, and FactoryGirl, too. Rspec and FactoryGirl is operating against the test database, which is what I want. The problem is that acceptance tests are operating against the development database.
This causes simple tests like the following to fail:
my_class = FactoryGirl.create(:my_class)
visit my_classes_path
expect(page).to have_content(my_class.title)
I've even checked screenshots along the way using:
page.save_screenshot("screenshot#{__FILE__}_#{__LINE__}.png")
SOLUTION
So apparently Capybara was attempting to use the same URL and port that is initialized in my local environment when I kickoff "rails server". Specifying a different port in my Capybara configuration did the trick as seen below:
Capybara.configure do |c|
c.run_server = true
c.javascript_driver = :poltergeist
c.default_driver = :poltergeist
c.server_port = 7000
c.app_host = "http://localhost:#{c.server_port}"
end
For normal use you shouldn't have to lock to a specific port or set app_host. If app_host isn't set then Capybara defaults to http://#{Capybara.server_host}:#{Capybara.server_port} which by default is http://127.0.0.1:<the port capybara runs the server on> . If you need to use localhost instead of 127.0.0.1 (because of IPv6 or something) then just set
Capybara.server_host = 'localhost'
instead of app host and fixing the port. app_host is really for when you're trying to test an external site, or you need to access subdomains to test your app - and fixing the port is really intended for issues with firewalls, etc.
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