Skip to content

Commit

Permalink
Add support 4 setting 'no proxy' arg. in drivers
Browse files Browse the repository at this point in the history
Having previously thought we had done enough to support using **Quke** in an environment where a proxy server is in use (PR #47), we found that is not the case. The problem is that a common configuration is to only use the proxy server when making external connections, but not for local ones.

So without the ability to allow **Quke** to configure the drivers in this was, when the **selenium** based drivers attempt to make local connections to the selenium server **Quke** falls over.

This change will add support for specifying this option. In the same manner as PR #47 the user simply has to provide the details in the config file, **Quke** will handle how to configure the drivers with this information when registering them with [Capybara](https://github.com/teamcapybara/capybara).
  • Loading branch information
Cruikshanks committed Dec 2, 2016
1 parent 60fba9b commit e92ab0d
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 26 deletions.
8 changes: 8 additions & 0 deletions .config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ stop_on_error: 1
proxy:
host: '10.10.2.70'
port: 8080
# In some cases you may also need to tell the browser (driver) not to use the
# proxy for local or specific connections. For this simply provide a comma
# separated list of addresses.
#
# IMPORTANT NOTE! phantomjs does not currently support this option. If you
# have to go via a proxy server for external connections, but not local ones
# you will be limited to using either the Chrome or Firefox drivers.
no_proxy: '127.0.0.1,192.168.0.1'

# If you select the browserstack driver, there are a number of options you
# can pass through to setup your browserstack tests, username and auth_key
Expand Down
3 changes: 2 additions & 1 deletion lib/quke/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ def proxy_data(data)
data = {} if data.nil?
data.merge(
'host' => (data['host'] || '').downcase.strip,
'port' => (data['port'] || '0').to_s.downcase.strip.to_i
'port' => (data['port'] || '0').to_s.downcase.strip.to_i,
'no_proxy' => (data['no_proxy'] || '').downcase.strip
)
end

Expand Down
38 changes: 26 additions & 12 deletions lib/quke/driver_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ def phantomjs
# Capybara::Selenium::Driver.new(
# app,
# browser: :chrome,
# switches: ["--proxy-server=localhost:8080"]
# switches: [
# "--proxy-server=localhost:8080",
# "--proxy-bypass-list=127.0.0.1,192.168.0.1"
# ]
# )
#
# Rather than setting the switches manually Quke::DriverConfiguration.chrome
Expand All @@ -131,13 +134,20 @@ def phantomjs
# switches: my_driver_config.chrome
# )
#
# rubocop:disable Metrics/AbcSize
def chrome
if config.use_proxy?
["--proxy-server=#{config.proxy['host']}:#{config.proxy['port']}"]
else
[]
end
result = []

host = config.proxy['host']
port = config.proxy['port']
no_proxy = config.proxy['no_proxy'].tr(',', ';')

result.push("--proxy-server=#{host}:#{port}") if config.use_proxy?
result.push("--proxy-bypass-list=#{no_proxy}") unless config.proxy['no_proxy'].empty?

result
end
# rubocop:enable Metrics/AbcSize

# Returns an instance of Selenium::WebDriver::Remote::Capabilities to be
# used when registering an instance of Capybara::Selenium::Driver,
Expand Down Expand Up @@ -169,12 +179,16 @@ def chrome
def firefox
profile = Selenium::WebDriver::Firefox::Profile.new

if config.use_proxy?
profile.proxy = Selenium::WebDriver::Proxy.new(
http: "#{config.proxy['host']}:#{config.proxy['port']}",
ssl: "#{config.proxy['host']}:#{config.proxy['port']}"
)
end
settings = {}
host = config.proxy['host']
port = config.proxy['port']
no_proxy = config.proxy['no_proxy']

settings[:http] = "#{host}:#{port}" if config.use_proxy?
settings[:ssl] = settings[:http] if config.use_proxy?
settings[:no_proxy] = no_proxy unless config.proxy['no_proxy'].empty?

profile.proxy = Selenium::WebDriver::Proxy.new(settings) if config.use_proxy?

profile
end
Expand Down
6 changes: 6 additions & 0 deletions lib/quke/driver_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def register(driver)
# poltergeist, and we can even pass on options to phantomjs to configure how
# it runs.
def phantomjs
# For future reference the options we pass through to phantomjs appear to
# mirror those you can actually supply on the command line.
# http://phantomjs.org/api/command-line.html
Capybara.register_driver :phantomjs do |app|
# We ignore the next line (and those like it in the subsequent methods)
# from code coverage because we never actually execute them from Quke.
Expand All @@ -65,6 +68,8 @@ def firefox
# object.
# https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings#firefox
# http://www.rubydoc.info/gems/selenium-webdriver/0.0.28/Selenium/WebDriver/Firefox/Profile
# http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
# http://preferential.mozdev.org/preferences.html
Capybara.register_driver :firefox do |app|
# :simplecov_ignore:
Capybara::Selenium::Driver.new(app, profile: config.firefox)
Expand All @@ -81,6 +86,7 @@ def chrome
# Capybara to Selenium-webdriver, which in turn passes it to chromium
# https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings#chrome
# http://peter.sh/experiments/chromium-command-line-switches/
# https://www.chromium.org/developers/design-documents/network-settings
Capybara.register_driver :chrome do |app|
# :simplecov_ignore:
Capybara::Selenium::Driver.new(
Expand Down
2 changes: 1 addition & 1 deletion lib/quke/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Quke #:nodoc:
VERSION = '0.2.6'.freeze
VERSION = '0.2.7'.freeze
end
1 change: 0 additions & 1 deletion spec/data/.as_string.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ pause: '1'
stop_on_error: 'true'

proxy:
host: '10.10.2.70'
port: '8080'
4 changes: 4 additions & 0 deletions spec/data/.proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
proxy:
host: '10.10.2.70'
port: 8080
no_proxy: '127.0.0.1,192.168.0.1'
14 changes: 8 additions & 6 deletions spec/quke/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,19 @@

describe '#proxy' do
context 'when NOT specified in the config file' do
it 'defaults to a blank host and port' do
it 'defaults to a blank values' do
Quke::Configuration.file_location = data_path('.no_file.yml')
expect(subject.proxy).to eq('host' => '', 'port' => 0)
expect(subject.proxy).to eq('host' => '', 'port' => 0, 'no_proxy' => '')
end
end

context 'when specified in the config file' do
it 'matches the config file' do
Quke::Configuration.file_location = data_path('.simple.yml')
Quke::Configuration.file_location = data_path('.proxy.yml')
expect(subject.proxy).to eq(
'host' => '10.10.2.70',
'port' => 8080
'port' => 8080,
'no_proxy' => '127.0.0.1,192.168.0.1'
)
end
end
Expand All @@ -117,8 +118,9 @@
it 'matches the config file' do
Quke::Configuration.file_location = data_path('.as_string.yml')
expect(subject.proxy).to eq(
'host' => '10.10.2.70',
'port' => 8080
'host' => '',
'port' => 8080,
'no_proxy' => ''
)
end
end
Expand Down
39 changes: 34 additions & 5 deletions spec/quke/driver_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,30 @@
end
end

context 'proxy details have been set in the .config.yml' do
it 'returns an array containing proxy settings' do
context 'basic proxy details have been set in the .config.yml' do
it 'returns an array containing basic proxy settings' do
Quke::Configuration.file_location = data_path('.simple.yml')
config = Quke::Configuration.new
expect(Quke::DriverConfiguration.new(config).chrome).to eq(["--proxy-server=#{config.proxy['host']}:#{config.proxy['port']}"])
end
end

context 'proxy details including addresses not to connect via the proxy server have been set in the .config.yml' do
it 'returns an array containing proxy settings including no-proxy details' do
Quke::Configuration.file_location = data_path('.proxy.yml')
config = Quke::Configuration.new
expect(Quke::DriverConfiguration.new(config).chrome).to eq(
[
"--proxy-server=#{config.proxy['host']}:#{config.proxy['port']}",
'--proxy-bypass-list=127.0.0.1;192.168.0.1'
]
)
end
end

end

describe '#firefox' do
describe '#firefox', focus: true do

context 'proxy details have NOT been set in the .config.yml' do
it 'returns a profile where the proxy details are NOT set' do
Expand All @@ -113,8 +126,8 @@
end
end

context 'proxy details have been set in the .config.yml' do
it 'returns a profile where the proxy details are set' do
context 'basic proxy details have been set in the .config.yml' do
it 'returns a profile where the basic proxy details are set' do
Quke::Configuration.file_location = data_path('.simple.yml')
config = Quke::Configuration.new
profile = Quke::DriverConfiguration.new(config).firefox
Expand All @@ -128,6 +141,22 @@
end
end

context 'proxy details including addresses not to connect via the proxy server have been set in the .config.yml' do
it 'returns a profile where the proxy details are set including no-proxy details' do
Quke::Configuration.file_location = data_path('.proxy.yml')
config = Quke::Configuration.new
profile = Quke::DriverConfiguration.new(config).firefox

# See spec/helpers.rb#read_profile_preferences for details of why we
# need to test the profile's properties in this way
preferences = read_profile_preferences(profile)

expect(preferences).to include('user_pref("network.proxy.http", "10.10.2.70")')
expect(preferences).to include('user_pref("network.proxy.http_port", 8080)')
expect(preferences).to include('user_pref("network.proxy.no_proxies_on", "127.0.0.1,192.168.0.1")')
end
end

end

describe '#browserstack_url' do
Expand Down

0 comments on commit e92ab0d

Please sign in to comment.