diff --git a/README.md b/README.md index 5b8bd21..7d250c4 100644 --- a/README.md +++ b/README.md @@ -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 ... ] ``` 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 diff --git a/bin/persistent_selenium b/bin/persistent_selenium index 7f790e6..a69a5e6 100755 --- a/bin/persistent_selenium +++ b/bin/persistent_selenium @@ -2,6 +2,10 @@ $: << File.expand_path('../../lib', __FILE__) +require 'persistent_selenium' + +PersistentSelenium.load_dotfile + require 'persistent_selenium/cli' GC.disable diff --git a/lib/persistent_selenium.rb b/lib/persistent_selenium.rb index 65b4091..5d5c281 100644 --- a/lib/persistent_selenium.rb +++ b/lib/persistent_selenium.rb @@ -3,7 +3,7 @@ require 'selenium-webdriver' module PersistentSelenium class << self - attr_writer :port, :browser, :timeout + attr_writer :port, :browser, :timeout, :chrome_extensions def port @port ||= 9854 @@ -17,6 +17,10 @@ module PersistentSelenium @timeout ||= 120 end + def chrome_extensions + @chrome_extensions ||= [] + end + def url "druby://localhost:#{port}" end @@ -24,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 diff --git a/lib/persistent_selenium/browser.rb b/lib/persistent_selenium/browser.rb index b71f54f..e385ff4 100644 --- a/lib/persistent_selenium/browser.rb +++ b/lib/persistent_selenium/browser.rb @@ -5,7 +5,7 @@ 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 @__found_elements__ = [] end @@ -20,7 +20,13 @@ module PersistentSelenium options = { :profile => profile } when :chrome - options = { :switches => %w{--disk-cache-size=1 --media-cache-size=1} } + profile = Selenium::WebDriver::Chrome::Profile.new + + PersistentSelenium.chrome_extensions.each do |extension| + profile.add_extension extension + end + + options = { :profile => profile, :switches => %w{--disk-cache-size=1 --media-cache-size=1} } end @browser ||= Selenium::WebDriver.for(@browser_type, options) diff --git a/lib/persistent_selenium/cli.rb b/lib/persistent_selenium/cli.rb index 625c85c..06a8c38 100644 --- a/lib/persistent_selenium/cli.rb +++ b/lib/persistent_selenium/cli.rb @@ -10,15 +10,19 @@ module PersistentSelenium end desc "start", "Start the server" - method_options :port => PersistentSelenium.port, :browser => PersistentSelenium.browser, :timeout => PersistentSelenium.timeout + 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 '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}" diff --git a/lib/persistent_selenium/driver.rb b/lib/persistent_selenium/driver.rb index d01b11f..8e81bcd 100644 --- a/lib/persistent_selenium/driver.rb +++ b/lib/persistent_selenium/driver.rb @@ -1,4 +1,5 @@ require 'persistent_selenium' +require 'persistent_selenium/browser' require 'capybara/selenium/driver' # make sure these classes exist on this end diff --git a/lib/persistent_selenium/version.rb b/lib/persistent_selenium/version.rb index e21d94e..50718b2 100644 --- a/lib/persistent_selenium/version.rb +++ b/lib/persistent_selenium/version.rb @@ -1,3 +1,3 @@ module PersistentSelenium - VERSION = "0.0.2" + VERSION = "0.0.3" end