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.
- data/.coveralls.yml +1 -0
- data/.gitignore +1 -0
- data/.rspec +6 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +16 -0
- data/Guardfile +6 -0
- data/README.md +121 -16
- data/Rakefile +36 -12
- data/lib/selenium-connect.rb +3 -82
- data/lib/selenium_connect.rb +49 -0
- data/lib/{selenium-connect → selenium_connect}/configuration.rb +4 -2
- data/lib/selenium_connect/job.rb +102 -0
- data/lib/selenium_connect/report/job_report.rb +17 -0
- data/lib/selenium_connect/report/main_report.rb +17 -0
- data/lib/selenium_connect/report/report_factory.rb +25 -0
- data/lib/{selenium-connect → selenium_connect}/runner.rb +9 -8
- data/lib/{selenium-connect → selenium_connect}/runners/chrome.rb +1 -1
- data/lib/{selenium-connect → selenium_connect}/runners/firefox.rb +1 -1
- data/lib/{selenium-connect → selenium_connect}/runners/ie.rb +1 -1
- data/lib/{selenium-connect → selenium_connect}/runners/no_browser.rb +1 -1
- data/lib/{selenium-connect → selenium_connect}/runners/phantomjs.rb +1 -1
- data/lib/{selenium-connect → selenium_connect}/runners/saucelabs.rb +2 -1
- data/lib/{selenium-connect → selenium_connect}/server.rb +2 -1
- data/selenium-connect.gemspec +9 -4
- data/spec/integration/lib/selenium_connect/runners/chrome_spec.rb +19 -0
- data/spec/integration/lib/selenium_connect/runners/firefox_spec.rb +55 -0
- data/spec/integration/lib/selenium_connect/runners/headless_spec.rb +33 -0
- data/spec/integration/lib/selenium_connect/runners/ie_spec.rb +24 -0
- data/spec/{runners → integration/lib/selenium_connect/runners}/phantomjs_spec.rb +4 -3
- data/spec/integration/lib/selenium_connect/runners/sauce_spec.rb +63 -0
- data/spec/integration/lib/selenium_connect_spec.rb +41 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/{example.yaml → support/example.yaml} +0 -0
- data/spec/{acceptance/helper.rb → support/example_page_object.rb} +1 -1
- data/spec/support/integration_helper.rb +9 -0
- data/spec/unit/lib/selenium-connect_spec.rb +15 -0
- data/spec/{configuration_spec.rb → unit/lib/selenium_connect/configuration_spec.rb} +9 -3
- data/spec/unit/lib/selenium_connect/job_spec.rb +38 -0
- data/spec/unit/lib/selenium_connect/report/job_report_spec.rb +20 -0
- data/spec/unit/lib/selenium_connect/report/main_report_spec.rb +20 -0
- data/spec/unit/lib/selenium_connect/report/report_factory_spec.rb +27 -0
- data/spec/unit/lib/selenium_connect/runners/.gitkeep +0 -0
- data/spec/unit/lib/selenium_connect_spec.rb +58 -0
- metadata +125 -29
- data/spec/acceptance/chrome_spec.rb +0 -21
- data/spec/acceptance/firefox_spec.rb +0 -62
- data/spec/acceptance/headless_spec.rb +0 -29
- data/spec/acceptance/ie_spec.rb +0 -21
- data/spec/acceptance/logging_spec.rb +0 -28
- data/spec/acceptance/sauce_spec.rb +0 -27
- data/spec/quit_and_finish_spec.rb +0 -14
- data/spec/yaml_spec.rb +0 -51
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
|
-
|
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,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 '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
|
10
|
-
|
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
|
data/selenium-connect.gemspec
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'selenium-connect'
|
3
|
-
s.version = '
|
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 = '
|
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
|
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
|
+
|