Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 56416082f761e9f7ac01be7c4af76f619636282b 0 parents
@andrewtimberlake authored
2  .gitignore
@@ -0,0 +1,2 @@
+/chromedriver.log
+/selenium-runner*.gem
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2011 Andrew Timberlake <andrew@andrewtimberlake.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
1  README.rdoc
@@ -0,0 +1 @@
+A new project in it's infancy
8 bin/selenium-runner
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+
+begin
+ require 'selenium-runner'
+rescue LoadError
+ $stderr.puts "Could not find selenium_runner"
+ exit(1)
+end
25 lib/process_formatter.rb
@@ -0,0 +1,25 @@
+class ProcessFormatter
+ def initialize
+ @buffer = ''
+ end
+
+ def example_started(*)
+ end
+
+ def example_passed(*)
+
+ @buffer << 'S' #Succeeded
+ end
+
+ def example_failed(*)
+ @buffer << 'F'
+ end
+
+ def example_pending(*)
+ @buffer << 'P'
+ end
+
+ def result
+ @buffer
+ end
+end
43 lib/process_reporter.rb
@@ -0,0 +1,43 @@
+class ProcessReporter
+ def initialize(reporter)
+ @reporter = reporter
+ @process_formatter = ProcessFormatter.new
+ end
+
+ def report(count)
+ start(count)
+ begin
+ yield self
+ ensure
+ finish
+ end
+ end
+
+ def method_missing(method_name, *args, &block)
+ @reporter.send(method_name, *args, &block) if @reporter.respond_to?(method_name)
+ @process_formatter.send(method_name, *args, &block) if @process_formatter.respond_to?(method_name)
+ end
+
+ def example_failed(example)
+ @reporter.send(:example_failed, example)
+ @process_formatter.send(:example_failed, example)
+ puts example.full_description
+ puts example.execution_result[:exception]
+ end
+
+ def results_of_forked_process
+ @process_formatter.result
+ end
+
+ def parse_forked_result(result)
+ results = result.split(//).group_by{|e| e}
+ results.map{|k, arr| results[k] = arr.size}
+ passed = results['S'].to_i
+ failed = results['F'].to_i
+ pending = results['P'].to_i
+
+ @reporter.instance_variable_set("@example_count", @reporter.instance_variable_get("@example_count") + passed + failed + pending)
+ @reporter.instance_variable_set("@failure_count", @reporter.instance_variable_get("@failure_count") + failed)
+ @reporter.instance_variable_set("@pending_count", @reporter.instance_variable_get("@pending_count") + pending)
+ end
+end
115 lib/selenium-runner.rb
@@ -0,0 +1,115 @@
+require 'rspec'
+require 'selenium-webdriver'
+require_relative 'process_reporter'
+require_relative 'process_formatter'
+
+module RSpec::Core::DSL
+ def visit(url, description, &example_group_block)
+ child = describe description, &example_group_block
+ child.instance_variable_set("@browser_url", url)
+ child
+ end
+end
+
+class SeleniumRunner
+ def self.trap_interrupt
+ RSpec::Core::Runner.trap_interrupt
+ end
+
+ def self.run(args)
+ trap_interrupt
+ options = RSpec::Core::ConfigurationOptions.new(args)
+ options.parse_options
+
+ configuration = RSpec::configuration
+ world = RSpec::world
+ configuration.error_stream = $stderr
+ configuration.output_stream = $stdout
+ options.configure(configuration)
+ configuration.load_spec_files
+ world.announce_filters
+
+ reporter = ProcessReporter.new(configuration.reporter)
+
+ browsers = [:firefox, :chrome]
+ browsers = [:firefox]
+
+ reporter.report(world.example_count) do |reporter|
+ begin
+ configuration.run_hook(:before, :suite)
+ mutex = Mutex.new
+
+ results = []
+ threads = []
+ example_group_indexes = {}
+ browsers.each { |b| example_group_indexes[b] = 0 }
+
+ 4.times do |i|
+ threads << Thread.new do
+ browsers.each do |browser|
+ until RSpec.wants_to_quit
+ group = nil
+ mutex.synchronize do
+ group = world.example_groups[example_group_indexes[browser]]
+ example_group_indexes[browser] += 1
+ end
+ break unless group
+
+ read_end, write_end = IO.pipe
+ pid = fork do
+ read_end.close
+ GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=) #REE memory benefits
+
+ url = group.instance_variable_get("@browser_url")
+ group.metadata[:example_group][:description] = "[#{browser}:#{url}] #{group.description}"
+ before_hook = RSpec::Core::Hooks::BeforeHook.new({}) do
+ capabilities = Selenium::WebDriver::Remote::Capabilities.send(browser)
+ # capabilities.version = 5
+ # capabilities.platform = :XP
+ capabilities[:name] = group.description
+
+ # @driver = Selenium::WebDriver.for(:remote, :url => "http://internuity:235ebfbc-197c-49d2-982e-cc4cb0468f7a@ondemand.saucelabs.com:80/wd/hub", :desired_capabilities => capabilities).tap do |driver|
+ # driver.navigate.to url
+ # end
+ @driver = Selenium::WebDriver.for(browser).tap do |driver|
+ if url
+ driver.navigate.to url
+ end
+ end
+ end
+ group.hooks[:before][:all].unshift before_hook
+ after_hook = RSpec::Core::Hooks::AfterHook.new({}) { @driver.quit if @driver }
+ group.hooks[:after][:all].unshift after_hook
+ group.let(:driver) { @driver }
+
+ results << group.run(reporter)
+ write_end.write reporter.results_of_forked_process
+ write_end.close
+ end
+ write_end.close
+ Process.wait
+ mutex.synchronize do
+ reporter.parse_forked_result(read_end.read)
+ end
+ end
+ end
+ end
+ end
+ threads.each do |t|
+ begin
+ t.join if t.alive?
+ rescue Interrupt
+ end
+ end
+
+ results.all? ? 0 : configuration.failure_exit_code
+ ensure
+ configuration.run_hook(:after, :suite)
+ end
+ end
+ end
+end
+
+at_exit do
+ SeleniumRunner.run(ARGV)
+end
16 selenium-runner.gemspec
@@ -0,0 +1,16 @@
+Gem::Specification.new do |s|
+ s.name = "selenium-runner"
+ s.version = '0.0.2'
+ s.authors = ["Andrew Timberlake"]
+ s.email = "andrew@andrewtimberlake.com"
+ s.description = "A Parallel RSpec runner for running selenium specs in parallel"
+ s.summary = "selenium-runner"
+ s.extra_rdoc_files = ["LICENSE"]
+ s.files = `git ls-files -- lib/*`.split(/\n/) + ["LICENSE"]
+ s.executables = `git ls-files -- bin/*`.split(/\n/).map{ |f| File.basename(f) }
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_path = "lib"
+
+ s.add_runtime_dependency "rspec"
+ s.add_runtime_dependency "selenium-webdriver"
+end
10 spec/test_2_spec.rb
@@ -0,0 +1,10 @@
+describe "Test 2" do
+ before(:all) do
+ print "pid: #{Process.pid}\n"
+ end
+
+ it "should pass" do
+ sleep 3
+ "b".should_not be_false
+ end
+end
13 spec/test_spec.rb
@@ -0,0 +1,13 @@
+visit "http://www.google.com", "A Google search for Clay" do
+ before(:all) do
+ element = driver.find_element(:name, 'q')
+ element.send_keys 'Clay'
+ element.submit
+ wait = Selenium::WebDriver::Wait.new(:timeout => 10)
+ wait.until { driver.find_element(:id => 'rso') }
+ end
+
+ it "should have 'Clay' in the title" do
+ driver.title.should match(/clay/)
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.