selenium-connect 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/.coveralls.yml +1 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +6 -0
  4. data/.travis.yml +1 -0
  5. data/CHANGELOG.md +16 -0
  6. data/Guardfile +6 -0
  7. data/README.md +121 -16
  8. data/Rakefile +36 -12
  9. data/lib/selenium-connect.rb +3 -82
  10. data/lib/selenium_connect.rb +49 -0
  11. data/lib/{selenium-connect → selenium_connect}/configuration.rb +4 -2
  12. data/lib/selenium_connect/job.rb +102 -0
  13. data/lib/selenium_connect/report/job_report.rb +17 -0
  14. data/lib/selenium_connect/report/main_report.rb +17 -0
  15. data/lib/selenium_connect/report/report_factory.rb +25 -0
  16. data/lib/{selenium-connect → selenium_connect}/runner.rb +9 -8
  17. data/lib/{selenium-connect → selenium_connect}/runners/chrome.rb +1 -1
  18. data/lib/{selenium-connect → selenium_connect}/runners/firefox.rb +1 -1
  19. data/lib/{selenium-connect → selenium_connect}/runners/ie.rb +1 -1
  20. data/lib/{selenium-connect → selenium_connect}/runners/no_browser.rb +1 -1
  21. data/lib/{selenium-connect → selenium_connect}/runners/phantomjs.rb +1 -1
  22. data/lib/{selenium-connect → selenium_connect}/runners/saucelabs.rb +2 -1
  23. data/lib/{selenium-connect → selenium_connect}/server.rb +2 -1
  24. data/selenium-connect.gemspec +9 -4
  25. data/spec/integration/lib/selenium_connect/runners/chrome_spec.rb +19 -0
  26. data/spec/integration/lib/selenium_connect/runners/firefox_spec.rb +55 -0
  27. data/spec/integration/lib/selenium_connect/runners/headless_spec.rb +33 -0
  28. data/spec/integration/lib/selenium_connect/runners/ie_spec.rb +24 -0
  29. data/spec/{runners → integration/lib/selenium_connect/runners}/phantomjs_spec.rb +4 -3
  30. data/spec/integration/lib/selenium_connect/runners/sauce_spec.rb +63 -0
  31. data/spec/integration/lib/selenium_connect_spec.rb +41 -0
  32. data/spec/spec_helper.rb +37 -0
  33. data/spec/{example.yaml → support/example.yaml} +0 -0
  34. data/spec/{acceptance/helper.rb → support/example_page_object.rb} +1 -1
  35. data/spec/support/integration_helper.rb +9 -0
  36. data/spec/unit/lib/selenium-connect_spec.rb +15 -0
  37. data/spec/{configuration_spec.rb → unit/lib/selenium_connect/configuration_spec.rb} +9 -3
  38. data/spec/unit/lib/selenium_connect/job_spec.rb +38 -0
  39. data/spec/unit/lib/selenium_connect/report/job_report_spec.rb +20 -0
  40. data/spec/unit/lib/selenium_connect/report/main_report_spec.rb +20 -0
  41. data/spec/unit/lib/selenium_connect/report/report_factory_spec.rb +27 -0
  42. data/spec/unit/lib/selenium_connect/runners/.gitkeep +0 -0
  43. data/spec/unit/lib/selenium_connect_spec.rb +58 -0
  44. metadata +125 -29
  45. data/spec/acceptance/chrome_spec.rb +0 -21
  46. data/spec/acceptance/firefox_spec.rb +0 -62
  47. data/spec/acceptance/headless_spec.rb +0 -29
  48. data/spec/acceptance/ie_spec.rb +0 -21
  49. data/spec/acceptance/logging_spec.rb +0 -28
  50. data/spec/acceptance/sauce_spec.rb +0 -27
  51. data/spec/quit_and_finish_spec.rb +0 -14
  52. data/spec/yaml_spec.rb +0 -51
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'yaml'
4
4
 
5
- module SeleniumConnect
5
+ # selenium connect
6
+ class SeleniumConnect
6
7
  # Encapsulates the configuration
7
8
  class Configuration
8
9
 
@@ -18,10 +19,11 @@ module SeleniumConnect
18
19
  attr_accessor :sauce_username, :sauce_api_key,
19
20
  :os, :browser_version, :description
20
21
 
21
- def initialize
22
+ def initialize(opts = {})
22
23
  @host = 'localhost'
23
24
  @port = 4444
24
25
  @browser = 'firefox'
26
+ populate_with_hash opts unless opts.empty?
25
27
  end
26
28
 
27
29
  def populate_with_hash(hash)
@@ -0,0 +1,102 @@
1
+ # Encoding: utf-8
2
+ require 'selenium_connect/runner'
3
+ require 'sauce/client'
4
+ require 'rest_client'
5
+ require 'selenium-webdriver'
6
+ require 'json'
7
+ require 'sauce_whisk'
8
+ require 'curb'
9
+
10
+ # selenium connect
11
+ class SeleniumConnect
12
+ # encapsulates the creation of a driver and a run
13
+ class Job
14
+
15
+ def initialize(config, report_factory)
16
+ @config = config
17
+ @report_factory = report_factory
18
+ end
19
+
20
+ # Creates and returns the driver, using options passed in
21
+ def start(opts = {})
22
+
23
+ # TODO this could be refactored out into an options parser of sorts
24
+ @config.description = opts[:name] if opts.has_key? :name
25
+
26
+ @driver = Runner.new(@config).driver
27
+ end
28
+
29
+ # Finishes the driver run, taking any data to help, returning report
30
+ def finish(opts = {})
31
+
32
+ # extracted from the earlier main finish
33
+ begin
34
+ @driver.quit
35
+ job_id = @driver.session_id
36
+ if @config.host == 'saucelabs'
37
+ if opts.has_key?(:failed) && opts[:failed]
38
+ fail_job job_id
39
+ if opts.has_key?(:failshot) && opts[:failshot]
40
+ save_last_screenshot job_id
41
+ end
42
+ end
43
+ if opts.has_key?(:passed) && opts[:passed]
44
+ pass_job job_id
45
+ end
46
+ data = fetch_logs(job_id)
47
+ report_data = symbolize_keys sauce_data: data
48
+ end
49
+ # rubocop:disable HandleExceptions
50
+ rescue Selenium::WebDriver::Error::WebDriverError
51
+ # rubocop:enable HandleExceptions
52
+ end
53
+
54
+ @report_factory.build :job, report_data
55
+ end
56
+
57
+ private
58
+
59
+ # TODO all this sauce stuff needs to be pulled out of the job class
60
+ # TODO need to put error handling around the sauce api requests
61
+ def save_last_screenshot(job_id)
62
+ begin
63
+ # Seemingly need to wait slightly for the images to be processed
64
+ sleep(2)
65
+ image = SauceWhisk::Jobs.fetch_asset job_id, 'final_screenshot.png'
66
+ image_file = File.join(Dir.getwd, @config.log, "failed_#{job_id}.png") if @config.log
67
+ File.open(image_file, 'w') { |f| f.write image }
68
+ rescue RestClient::ResourceNotFound
69
+ puts 'Unable to download image!'
70
+ end
71
+ end
72
+
73
+ def fail_job(job_id)
74
+ SauceWhisk::Jobs.fail_job job_id
75
+ end
76
+
77
+ def pass_job(job_id)
78
+ SauceWhisk::Jobs.pass_job job_id
79
+ end
80
+
81
+ def fetch_logs(job_id)
82
+ sauce_job = Sauce::Job.find(job_id)
83
+ # Seemingly need to wait slightly for the images to be processed
84
+ sleep(2)
85
+ server_log = SauceWhisk::Jobs.fetch_asset job_id, 'selenium-server.log'
86
+ log_file = File.join(Dir.getwd, @config.log, "sauce_job_#{job_id}.log") if @config.log
87
+ File.open(log_file, 'w') { |f| f.write server_log }
88
+ JSON.parse(sauce_job.to_json)
89
+ end
90
+
91
+ # TODO this should be pulled out into a generic report... or something
92
+ def symbolize_keys(hash)
93
+ hash.reduce({}) do |result, (key, value)|
94
+ new_key = key.class == String ? key.to_sym : key
95
+ new_value = value.class == Hash ? symbolize_keys(value) : value
96
+ result[new_key] = new_value
97
+ result
98
+ end
99
+ end
100
+ end
101
+ end
102
+
@@ -0,0 +1,17 @@
1
+ # Encoding: utf-8
2
+
3
+ # selenium connect
4
+ class SeleniumConnect
5
+ module Report
6
+ # report for a specific job
7
+ class JobReport
8
+
9
+ attr_reader :data
10
+
11
+ def initialize(data)
12
+ @data = data
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # Encoding: utf-8
2
+
3
+ # selenium connect
4
+ class SeleniumConnect
5
+ module Report
6
+ # report for a connection
7
+ class MainReport
8
+
9
+ attr_reader :data
10
+
11
+ def initialize(data)
12
+ @data = data
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'selenium_connect/report/job_report'
4
+ require 'selenium_connect/report/main_report'
5
+
6
+ # selenium connect
7
+ class SeleniumConnect
8
+ module Report
9
+ # creates report objects
10
+ class ReportFactory
11
+
12
+ def build(type, data)
13
+ # resource locator for report
14
+ case type
15
+ when :main
16
+ SeleniumConnect::Report::MainReport.new data
17
+ when :job
18
+ SeleniumConnect::Report::JobReport.new data
19
+ else
20
+ raise ArgumentError, "Report type \"#{type.to_s}\" unknown!"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,13 +1,14 @@
1
1
  # Encoding: utf-8
2
2
 
3
- require 'selenium-connect/runners/firefox'
4
- require 'selenium-connect/runners/ie'
5
- require 'selenium-connect/runners/chrome'
6
- require 'selenium-connect/runners/phantomjs'
7
- require 'selenium-connect/runners/no_browser'
8
- require 'selenium-connect/runners/saucelabs'
9
-
10
- module SeleniumConnect
3
+ require 'selenium_connect/runners/firefox'
4
+ require 'selenium_connect/runners/ie'
5
+ require 'selenium_connect/runners/chrome'
6
+ require 'selenium_connect/runners/phantomjs'
7
+ require 'selenium_connect/runners/no_browser'
8
+ require 'selenium_connect/runners/saucelabs'
9
+
10
+ # selenium connect
11
+ class SeleniumConnect
11
12
  # Initializes the driver
12
13
  class Runner
13
14
  attr_reader :driver, :config
@@ -1,6 +1,6 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ class SeleniumConnect
4
4
  # Runner
5
5
  class Runner
6
6
  # Chrome browser runner
@@ -1,6 +1,6 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ class SeleniumConnect
4
4
  # Runner
5
5
  class Runner
6
6
  # Firefox browser runner
@@ -1,6 +1,6 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ class SeleniumConnect
4
4
  # Runner
5
5
  class Runner
6
6
  # IE Browser Runner
@@ -1,6 +1,6 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ class SeleniumConnect
4
4
  # Runner
5
5
  class Runner
6
6
  # No Browser Runner
@@ -1,6 +1,6 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ class SeleniumConnect
4
4
  # Runner
5
5
  class Runner
6
6
  # PhantomJS browser runner
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'sauce'
4
4
 
5
- module SeleniumConnect
5
+ # selenium connect
6
+ class SeleniumConnect
6
7
  # Runner
7
8
  class Runner
8
9
  # Sauce runner
@@ -1,6 +1,7 @@
1
1
  # Encoding: utf-8
2
2
 
3
- module SeleniumConnect
3
+ # selenium connect
4
+ class SeleniumConnect
4
5
  # Creates a server connection
5
6
  class Server
6
7
  attr_reader :configuration, :current_dir_path
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'selenium-connect'
3
- s.version = '2.3.0'
3
+ s.version = '3.0.0'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = ['Dave Haeffner', 'Jason Fox']
6
6
  s.email = ['dave@arrgyle.com', 'jason@arrgyle.com']
7
7
  s.homepage = 'https://github.com/arrgyle/selenium-connect'
8
8
  s.summary = 'A stupid simple way to run your Selenium tests on localhost, against a Selenium Grid, or in the cloud (e.g. SauceLabs).'
9
- s.description = 'Added return data to a finish call to pass back relevent job details'
9
+ s.description = 'Major refactoring of the public api which now includes correct updating of sauce lab job status and fetching screenshots on failure'
10
10
  s.license = 'MIT'
11
11
 
12
12
  s.files = `git ls-files`.split($/)
@@ -17,8 +17,13 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency 'selenium-webdriver'
18
18
  s.add_dependency 'rake'
19
19
  s.add_dependency 'sauce', '~> 2.4.4'
20
+ s.add_dependency 'sauce_whisk', '~> 0.0.8'
21
+ s.add_dependency 'curb', '~> 0.8.4'
20
22
 
21
- s.add_development_dependency 'rspec'
22
- s.add_development_dependency "rubocop", "~> 0.9.0"
23
+ s.add_development_dependency 'rspec', '~> 2.14.1'
24
+ s.add_development_dependency 'mocha', '~> 0.14.0'
25
+ s.add_development_dependency 'rubocop', '~> 0.9.0'
26
+ s.add_development_dependency 'guard-rspec', '~> 3.0.2'
27
+ s.add_development_dependency 'coveralls', '~> 0.6.7'
23
28
 
24
29
  end
@@ -0,0 +1,19 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'selenium_connect'
5
+
6
+ describe 'Chrome', selenium: true do
7
+
8
+ it 'localhost' do
9
+ config = SeleniumConnect::Configuration.new browser: 'chrome'
10
+ sc = SeleniumConnect.start config
11
+ job = sc.create_job
12
+ driver = job.start
13
+
14
+ execute_simple_test driver
15
+
16
+ job.finish
17
+ sc.finish
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'selenium_connect'
5
+
6
+ describe 'Firefox', selenium: true do
7
+
8
+ it 'blank config' do
9
+ @config = SeleniumConnect::Configuration.new
10
+ end
11
+
12
+ it 'localhost' do
13
+ @config = SeleniumConnect::Configuration.new host: 'localhost'
14
+ end
15
+
16
+ it 'local jar file specified' do
17
+ opts = {
18
+ host: 'localhost',
19
+ jar: "#{Dir.pwd}/bin/selenium-server-standalone-2.33.0.jar"
20
+ }
21
+ @config = SeleniumConnect::Configuration.new opts
22
+ end
23
+
24
+ it 'profile name' do
25
+ pending 'requires machine setup to run, and need a public example'
26
+ @config = SeleniumConnect::Configuration.new profile_name: 'YourProfileNameGoesHere'
27
+ end
28
+
29
+ it 'profile path' do
30
+ pending 'need to add a profile to the repo'
31
+ @config = SeleniumConnect::Configuration.new profile_path: "#{Dir.pwd}/path/to/profile"
32
+ end
33
+
34
+ it 'browser path' do
35
+ # example only works on Mac
36
+ opts = {
37
+ browser: 'firefox',
38
+ browser_path: '/Applications/Firefox.app/Contents/MacOS/firefox'
39
+ }
40
+ @config = SeleniumConnect::Configuration.new opts
41
+ end
42
+
43
+ after(:each) do
44
+ # execute a simple test with the configuration
45
+ unless @config.nil?
46
+ sc = SeleniumConnect.start @config
47
+ job = sc.create_job
48
+ driver = job.start
49
+ execute_simple_test driver
50
+ job.finish
51
+ sc.finish
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,33 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'selenium_connect'
5
+
6
+ describe 'Headless', selenium: true do
7
+
8
+ let(:google) { Google.new(SeleniumConnect.start) }
9
+ let(:quit) { SeleniumConnect.finish }
10
+
11
+ before(:each) do
12
+ config = SeleniumConnect::Configuration.new browser: 'phantomjs'
13
+ @sc = SeleniumConnect.start config
14
+ @job = @sc.create_job
15
+ @driver = @job.start
16
+ end
17
+
18
+ it 'should run a basic test with phantom js' do
19
+ execute_simple_test @driver
20
+ end
21
+
22
+ it 'should not find something on a page' do
23
+ google = ExamplePageObject.new @driver
24
+ google.visit
25
+ google.page_title.should_not include('Poogle')
26
+ end
27
+
28
+ after(:each) do
29
+ @job.finish
30
+ @sc.finish
31
+ end
32
+
33
+ end
@@ -0,0 +1,24 @@
1
+ # Encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'selenium_connect'
5
+
6
+ describe 'IE', selenium: true do
7
+
8
+ it 'with Selenium Grid' do
9
+ pending 'not yet implemented'
10
+ opts = {
11
+ host: '192.168.1.139',
12
+ browser: 'ie'
13
+ }
14
+ config = SeleniumConnect::Configuration.new opts
15
+ sc = SeleniumConnect.start config
16
+ job = sc.create_job
17
+ driver = job.start
18
+ execute_simple_test driver
19
+ job.finish
20
+ sc.finish
21
+ end
22
+
23
+ end
24
+