Compare commits

...

8 Commits

Author SHA1 Message Date
John Bintz f698dc7bda Bump version 2015-02-23 14:26:29 -05:00
John Bintz a83023b812 Chrome switch fixes 2015-02-23 14:26:12 -05:00
John Bintz b217fef4ee Add @frame_handles for iframe support 2015-02-23 14:26:00 -05:00
John Bintz 21a622ace0 Bump minor version 2015-01-09 15:06:03 -05:00
John Bintz 2034c864f3 Fixes for modern Capybara versions. 2015-01-09 15:05:44 -05:00
John Bintz ad5d5c5d05 Split up Cucumber and RSpec support 2015-01-09 15:05:05 -05:00
John Bintz e738bab0f4 improve chrome support, add chrome extension option, as well as project dotfile support 2013-08-14 12:08:40 -04:00
John Bintz f6bfa0cf29 add timeout option 2013-05-14 10:57:55 -04:00
10 changed files with 126 additions and 16 deletions

View File

@ -1,3 +1,5 @@
# Persistent Selenium
Now you can keep that precious browser window open when doing continuous integration testing.
Save seconds, and sanity, with every test re-run!
@ -7,7 +9,7 @@ fix your tests and/or code.
Start an instance:
``` bash
persistent_selenium [ --port 9854 ] [ --browser firefox ]
persistent_selenium [ --port 9854 ] [ --browser firefox ] [ --chrome-extensions <file.crx> ... ]
```
Tell Capybara to use it:
@ -36,11 +38,45 @@ these two differences:
The browser's cache is disabled, and cookies are reset before the next test runs, so you still get the state
cleared out before your next set of tests.
### Under the hood
### .persistent_selenium
Configure everything in your app with a `.persistent_selenium` file:
``` ruby
# .persistent_selenium
PersistentSelenium.configure do |c|
c.browser = :chrome
c.chrome_extensions = %w{AngularJS-Batarang.crx}
end
```
### Chrome Extensions
If, for example, you do a lot with AngularJS and want to use [Batarang](https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en),
download the extension, put it in your project's folder somewhere, and call `persistent_selenium` with the path
to the extension:
``` bash
persistent_selenium --browser chrome --chrome-extensions AngularJS-Batarang.crx
```
## Best practice
Use it with Foreman and Guard. Start up your test suite via Guard, configure your test suite to
use persistent_selenium, and run persistent_selenium alongside it:
``` yaml
guard: guard -g wip
ps: persistent_selenium
```
It's an integral part of my [integration testing setup](http://github.com/johnbintz/bintz-integration_testing_setup).
## Under the hood
It's DRb, which mostly Just Works (tm), and has a little reshuffling of the default Capybara Selenium driver's code.
#### When DRb doesn't Just Work (tm)
### When DRb doesn't Just Work (tm)
You're most likely using `all` and invoking an action on one of the nodes within, I'd wager. If you need to find a node
to perform an action on, it's best to stick with `find`, since it's less likely that node will go out of

View File

@ -2,6 +2,10 @@
$: << File.expand_path('../../lib', __FILE__)
require 'persistent_selenium'
PersistentSelenium.load_dotfile
require 'persistent_selenium/cli'
GC.disable

View File

@ -3,7 +3,7 @@ require 'selenium-webdriver'
module PersistentSelenium
class << self
attr_writer :port, :browser
attr_writer :port, :browser, :timeout, :chrome_extensions
def port
@port ||= 9854
@ -13,6 +13,14 @@ module PersistentSelenium
@browser ||= :firefox
end
def timeout
@timeout ||= 120
end
def chrome_extensions
@chrome_extensions ||= []
end
def url
"druby://localhost:#{port}"
end
@ -20,5 +28,11 @@ module PersistentSelenium
def configure
yield self
end
def load_dotfile(file = '.persistent_selenium')
if File.file?(file)
load file
end
end
end
end

View File

@ -5,7 +5,8 @@ require 'base64'
module PersistentSelenium
class Browser < Capybara::Selenium::Driver
def initialize(browser_type)
@browser_type = browser_type
@browser_type = browser_type.to_s.to_sym
@frame_handles = {}
@__found_elements__ = []
end
@ -20,7 +21,13 @@ module PersistentSelenium
options = { :profile => profile }
when :chrome
options = { :switches => %w{--disk-cache-size=1 --media-cache-size=1} }
switches = %w{--disk-cache-size=1 --media-cache-size=1}
PersistentSelenium.chrome_extensions.each do |extension|
switches.push("--load-extension=#{extension}")
end
options = { switches: switches }
end
@browser ||= Selenium::WebDriver.for(@browser_type, options)
@ -30,6 +37,10 @@ module PersistentSelenium
{}
end
def browser_initialized?
false
end
def visit(path)
if !path[/^http/]
path = @app_host + path

View File

@ -10,14 +10,19 @@ module PersistentSelenium
end
desc "start", "Start the server"
method_options :port => PersistentSelenium.port, :browser => PersistentSelenium.browser
method_options :port => PersistentSelenium.port,
:browser => PersistentSelenium.browser,
:timeout => PersistentSelenium.timeout
method_option :chrome_extensions, :type => :array, :default => []
def start
require 'persistent_selenium/browser'
require 'drb'
require 'persistent_selenium/drb'
PersistentSelenium.configure do |c|
c.port = options[:port]
c.browser = options[:browser]
c.browser = options[:browser] if options[:browser]
c.timeout = options[:timeout]
c.chrome_extensions = options[:chrome_extensions] if !options[:chrome_extensions].empty?
end
puts "Starting persistent_selenium on #{PersistentSelenium.port} with #{PersistentSelenium.browser}"

View File

@ -0,0 +1,8 @@
require_relative './driver'
Before do
if Capybara.current_driver == :persistent_selenium
Capybara.server_port ||= '3001'
Capybara.app_host ||= "http://localhost:#{Capybara.server_port}"
end
end

View File

@ -0,0 +1,17 @@
require 'drb'
module DRb
class DRbTCPSocket
alias :_set_sockopt :set_sockopt
def set_sockopt(soc)
_set_sockopt(soc)
optval = [ PersistentSelenium.timeout, 0 ].pack("l_2")
soc.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
soc.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
end
end
end

View File

@ -1,20 +1,25 @@
require 'persistent_selenium'
require 'persistent_selenium/browser'
require 'capybara/selenium/driver'
# make sure these classes exist on this end
[ Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError ]
Before do
if Capybara.current_driver == :persistent_selenium
Capybara.server_port ||= '3001'
Capybara.app_host ||= "http://localhost:#{Capybara.server_port}"
end
end
require 'persistent_selenium/drb'
Capybara.register_driver :persistent_selenium do |app|
require 'drb'
module DRb
class DRbObject
def method(name)
method_missing(:method, name)
end
end
end
DRb.start_service
browser = DRbObject.new nil, PersistentSelenium.url
server = Capybara::Server.new(app)

View File

@ -0,0 +1,10 @@
require_relative './driver'
RSpec.configure do |c|
c.before :each do
if Capybara.current_driver == :persistent_selenium
Capybara.server_port ||= '3001'
Capybara.app_host ||= "http://localhost:#{Capybara.server_port}"
end
end
end

View File

@ -1,3 +1,3 @@
module PersistentSelenium
VERSION = "0.0.2"
VERSION = "0.1.1"
end