Add custom host IP address support - Issue #716

This commit is contained in:
Arturo Isaí Castro Pérpuli 2017-03-27 01:31:03 +00:00
parent 86e783e6fb
commit 97be0eb9e9
14 changed files with 61 additions and 23 deletions

View File

@ -21,6 +21,12 @@ gemfile:
env:
global:
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
- POLTERGEIST_TEST_HOST=poltergeist.test.com
addons:
hosts:
# Used to test custom host driver feature
- poltergeist.test.com
matrix:
include:

View File

@ -1,3 +1,8 @@
### 1.15.0 ###
#### Features ####
* Driver now supports specifying a custom IP address (host) with the :host option (Arturo Castro)
### 1.14.0 ###
#### Features ####

View File

@ -280,8 +280,8 @@ end
to be passed to PhantomJS, e.g. `['--load-images=no', '--ignore-ssl-errors=yes']`
* `:extensions` (Array) - An array of JS files to be preloaded into
the phantomjs browser. Useful for faking unsupported APIs.
* `:port` (Fixnum) - The port which should be used to communicate
with the PhantomJS process. Defaults to a random open port.
* `:port` (Fixnum) - The port which should be used to communicate with the PhantomJS process. Defaults to a random open port.
* `:host` (String) - The name or IP of the PhantomJS host. Default is '127.0.0.1'.
* `:url_blacklist` (Array) - Default session url blacklist - expressed as an array of strings to match against requested URLs.
* `:url_whitelist` (Array) - Default session url whitelist - expressed as an array of strings to match against requested URLs.

View File

@ -91,6 +91,7 @@ module Capybara::Poltergeist
parts << PHANTOMJS_SCRIPT
parts << server.port
parts.concat window_size
parts << server.host
parts
end

View File

@ -1,11 +1,12 @@
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Poltergeist.Connection = (function() {
function Connection(owner, port) {
function Connection(owner, port, host) {
this.owner = owner;
this.port = port;
this.host = host != null ? host : "127.0.0.1";
this.commandReceived = bind(this.commandReceived, this);
this.socket = new WebSocket("ws://127.0.0.1:" + this.port + "/");
this.socket = new WebSocket("ws://" + this.host + ":" + this.port + "/");
this.socket.onmessage = this.commandReceived;
this.socket.onclose = function() {
return phantom.exit();

View File

@ -3,9 +3,9 @@ var Poltergeist, system,
hasProp = {}.hasOwnProperty;
Poltergeist = (function() {
function Poltergeist(port, width, height) {
function Poltergeist(port, width, height, host) {
this.browser = new Poltergeist.Browser(width, height);
this.connection = new Poltergeist.Connection(this, port);
this.connection = new Poltergeist.Connection(this, port, host);
phantom.onError = (function(_this) {
return function(message, stack) {
return _this.onError(message, stack);
@ -226,4 +226,4 @@ phantom.injectJs(phantom.libraryPath + "/browser.js");
system = require('system');
new Poltergeist(system.args[1], system.args[2], system.args[3]);
new Poltergeist(system.args[1], system.args[2], system.args[3], system.args[4]);

View File

@ -1,6 +1,6 @@
class Poltergeist.Connection
constructor: (@owner, @port) ->
@socket = new WebSocket "ws://127.0.0.1:#{@port}/"
constructor: (@owner, @port, @host = "127.0.0.1") ->
@socket = new WebSocket "ws://#{@host}:#{@port}/"
@socket.onmessage = this.commandReceived
@socket.onclose = -> phantom.exit()

View File

@ -1,7 +1,7 @@
class Poltergeist
constructor: (port, width, height) ->
constructor: (port, width, height, host) ->
@browser = new Poltergeist.Browser(width, height)
@connection = new Poltergeist.Connection(this, port)
@connection = new Poltergeist.Connection(this, port, host)
phantom.onError = (message, stack) => @onError(message, stack)
@ -83,4 +83,4 @@ phantom.injectJs("#{phantom.libraryPath}/cmd.js")
phantom.injectJs("#{phantom.libraryPath}/browser.js")
system = require 'system'
new Poltergeist(system.args[1], system.args[2], system.args[3])
new Poltergeist(system.args[1], system.args[2], system.args[3], system.args[4])

View File

@ -37,7 +37,7 @@ module Capybara::Poltergeist
end
def server
@server ||= Server.new(options[:port], options.fetch(:timeout) { DEFAULT_TIMEOUT })
@server ||= Server.new(options[:port], options.fetch(:timeout) { DEFAULT_TIMEOUT }, options[:host])
end
def client

View File

@ -1,10 +1,11 @@
module Capybara::Poltergeist
class Server
attr_reader :socket, :fixed_port, :timeout
attr_reader :socket, :fixed_port, :timeout, :custom_host
def initialize(fixed_port = nil, timeout = nil)
def initialize(fixed_port = nil, timeout = nil, custom_host = nil)
@fixed_port = fixed_port
@timeout = timeout
@custom_host = custom_host
start
end
@ -12,12 +13,16 @@ module Capybara::Poltergeist
@socket.port
end
def host
@socket.host
end
def timeout=(sec)
@timeout = @socket.timeout = sec
end
def start
@socket = WebSocketServer.new(fixed_port, timeout)
@socket = WebSocketServer.new(fixed_port, timeout, custom_host)
end
def stop

View File

@ -18,21 +18,22 @@ module Capybara::Poltergeist
HOST = '127.0.0.1'
attr_reader :port, :driver, :socket, :server
attr_reader :port, :driver, :socket, :server, :host
attr_accessor :timeout
def initialize(port = nil, timeout = nil)
def initialize(port = nil, timeout = nil, custom_host = nil)
@timeout = timeout
@server = start_server(port)
@server = start_server(port, custom_host)
@receive_mutex = Mutex.new
end
def start_server(port)
def start_server(port, custom_host)
time = Time.now
begin
TCPServer.open(HOST, port || 0).tap do |server|
TCPServer.open(custom_host || HOST, port || 0).tap do |server|
@port = server.addr[1]
@host = server.addr[2]
end
rescue Errno::EADDRINUSE
if (Time.now - time) < BIND_TIMEOUT

View File

@ -860,6 +860,25 @@ module Capybara::Poltergeist
end
end
it 'allows the driver to have a custom host' do
begin
# Use custom host "pointing" to localhost, specified by POLTERGEIST_TEST_HOST env var.
# Use /etc/hosts or iptables for this: https://superuser.com/questions/516208/how-to-change-ip-address-to-point-to-localhost
# A custom host and corresponding env var for Travis is specified in .travis.yml
# If var is unspecified, skip test
host = ENV['POLTERGEIST_TEST_HOST']
skip if host.nil?
driver = Capybara::Poltergeist::Driver.new(@driver.app, host: host, port: 12345)
driver.visit session_url('/')
expect { TCPServer.new(host, 12345) }.to raise_error(Errno::EADDRINUSE)
ensure
driver.quit if driver
end
end
it 'lists the open windows' do
@session.visit '/'

View File

@ -2,7 +2,7 @@ require 'spec_helper'
module Capybara::Poltergeist
describe Client do
let(:server) { double(port: 6000) }
let(:server) { double(port: 6000, host: "127.0.0.1") }
let(:client_params) { {} }
subject { Client.new(server, client_params) }

View File

@ -112,7 +112,7 @@ module Capybara::Poltergeist
it 'starts the server with the provided timeout' do
server = double
expect(Server).to receive(:new).with(anything, 3).and_return(server)
expect(Server).to receive(:new).with(anything, 3, nil).and_return(server)
expect(subject.server).to eq(server)
end
end