jasmine-selenium-sauce 1.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.
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'jasmine_results'
3
+ require 'sample_results'
4
+
5
+ describe Jasmine::Sauce::CI::JasmineResults do
6
+
7
+ let(:under_test) { Jasmine::Sauce::CI::JasmineResults.new(suites, suite_results) }
8
+
9
+ describe "#suites" do
10
+ subject { under_test.suites }
11
+
12
+ context "when no suites" do
13
+ let(:suites) { {} }
14
+ let(:suite_results) { {} }
15
+ it { should be_empty }
16
+ end
17
+
18
+ context "when suites" do
19
+ include_context "suites sample"
20
+ let(:suite_results) { {} }
21
+ it { should eq(suites) }
22
+ end
23
+ end
24
+
25
+ describe "#for_spec_id" do
26
+ let(:spec_id) { "1" }
27
+ let(:suites) { {} }
28
+ subject { under_test.for_spec_id(spec_id) }
29
+
30
+ context "when unknown spec id" do
31
+ let(:suite_results) { {} }
32
+ it { should be_nil }
33
+ end
34
+
35
+ context "when valid spec id" do
36
+ include_context "suite result sample"
37
+ it { should eq(suite_results["1"]) }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+ require 'sauce_config'
3
+
4
+ describe Jasmine::Sauce::CI::SauceConfig do
5
+
6
+ after do
7
+ ENV.delete('SAUCELABS_URL')
8
+ ENV.delete('JASMINE_URL')
9
+ ENV.delete('SAUCE_BROWSER')
10
+ end
11
+
12
+ describe "#validate" do
13
+ subject { Jasmine::Sauce::CI::SauceConfig.new.validate }
14
+
15
+ context "when valid" do
16
+ before do
17
+ ENV['SAUCELABS_URL'] = 'sauce'
18
+ ENV['JASMINE_URL'] = 'jasmine'
19
+ ENV['SAUCE_BROWSER'] = 'browser'
20
+ end
21
+ specify { expect { subject }.not_to raise_error }
22
+ end
23
+
24
+ context "when saucelabs url is not set" do
25
+ before do
26
+ ENV['JASMINE_URL'] = 'jasmine'
27
+ ENV['SAUCE_BROWSER'] = 'browser'
28
+ end
29
+ specify { expect { subject }.to raise_error(ArgumentError) }
30
+ end
31
+
32
+ context "when jasmine url is not set" do
33
+ before do
34
+ ENV['SAUCELABS_URL'] = 'sauce'
35
+ ENV['SAUCE_BROWSER'] = 'browser'
36
+ end
37
+ specify { expect { subject }.to raise_error(ArgumentError) }
38
+ end
39
+
40
+ context "when browser is not set" do
41
+ before do
42
+ ENV['SAUCELABS_URL'] = 'sauce'
43
+ ENV['JASMINE_URL'] = 'jasmine'
44
+ end
45
+ specify { expect { subject }.to raise_error(ArgumentError) }
46
+ end
47
+ end
48
+
49
+ shared_examples_for "overridable configuration setting" do |env_setting, default|
50
+ context "when not specified" do
51
+ it { should eq(default) }
52
+ end
53
+
54
+ context "when specified" do
55
+ let(:value) { "random value" }
56
+ before { ENV[env_setting] = value }
57
+ after { ENV.delete(env_setting) }
58
+ it { should eq(value) }
59
+ end
60
+ end
61
+
62
+ describe "#saucelabs_server_url" do
63
+ let(:url) { "http://user:password@ondemand.saucelabs.com:80/wd/hub" }
64
+ before { ENV['SAUCELABS_URL'] = url }
65
+ after { ENV.delete('SAUCELABS_URL') }
66
+ its(:saucelabs_server_url) { should eq(url)}
67
+ end
68
+
69
+ describe "#jasmine_server_url" do
70
+ let(:url) { "http://my.host.com/jasmine" }
71
+ before { ENV['JASMINE_URL'] = url }
72
+ after { ENV.delete('JASMINE_URL') }
73
+ its(:jasmine_server_url) { should eq(url)}
74
+ end
75
+
76
+ describe "#sauce_browser" do
77
+ let(:browser) { "Chrome" }
78
+ before { ENV['SAUCE_BROWSER'] = browser }
79
+ after { ENV.delete('SAUCE_BROWSER') }
80
+ its(:browser) { should eq(browser)}
81
+ end
82
+
83
+ describe "#sauce_platform" do
84
+ context "when not specified" do
85
+ its(:platform) { should eq(:VISTA) }
86
+ end
87
+
88
+ context "when specified" do
89
+ let(:platform) { "WIN_7" }
90
+ before { ENV['SAUCE_PLATFORM'] = platform }
91
+ after { ENV.delete('SAUCE_PLATFORM') }
92
+ its(:platform) { should eq(platform.to_sym) }
93
+ end
94
+ end
95
+
96
+ describe "#browser_version" do
97
+ subject { Jasmine::Sauce::CI::SauceConfig.new.browser_version }
98
+ it_behaves_like "overridable configuration setting", 'SAUCE_BROWSER_VERSION', nil
99
+ end
100
+
101
+ describe "#record_screenshots" do
102
+ subject { Jasmine::Sauce::CI::SauceConfig.new.record_screenshots }
103
+ it_behaves_like "overridable configuration setting", 'SAUCE_SCREENSHOTS', false
104
+ end
105
+
106
+ describe "#record_video" do
107
+ subject { Jasmine::Sauce::CI::SauceConfig.new.record_video }
108
+ it_behaves_like "overridable configuration setting", 'SAUCE_VIDEO', false
109
+ end
110
+
111
+ describe "#idle_timeout" do
112
+ subject { Jasmine::Sauce::CI::SauceConfig.new.idle_timeout }
113
+ it_behaves_like "overridable configuration setting", 'SAUCE_IDLE_TIMEOUT', 90
114
+ end
115
+
116
+ describe "#max_duration" do
117
+ subject { Jasmine::Sauce::CI::SauceConfig.new.max_duration }
118
+ it_behaves_like "overridable configuration setting", 'SAUCE_MAX_DURATION', 180
119
+ end
120
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+ require 'selenium_runner'
3
+ require 'jasmine_results'
4
+ require 'sample_results'
5
+
6
+ describe Jasmine::Sauce::CI::SeleniumRunner do
7
+
8
+ let(:driver) { double("Driver") }
9
+ let(:url) { "jasmine.url" }
10
+ let(:under_test) { Jasmine::Sauce::CI::SeleniumRunner.new(driver) }
11
+
12
+ describe "#run" do
13
+ subject { under_test.run(url) }
14
+
15
+ let(:load_timeout) { 0.01 }
16
+ before do
17
+ driver.should_receive(:connect).with(url)
18
+ under_test.should_receive(:load_jasmine_timeout).and_return(load_timeout)
19
+ end
20
+
21
+ context "when loading jasmine times out" do
22
+ before do
23
+ driver.should_receive(:evaluate_js).and_return(false, false)
24
+ end
25
+ specify { expect {subject}.to raise_error("Timed out after #{load_timeout}s waiting for Jasmine to load") }
26
+ end
27
+
28
+ context "when jasmine execution times out" do
29
+ let(:load_result) { true }
30
+ let(:suites) { {} }
31
+ let(:jasmine_finished_result) { false }
32
+ before do
33
+ under_test.should_receive(:jasmine_execution_timeout).and_return(load_timeout)
34
+ driver.should_receive(:evaluate_js).and_return(load_result, suites, jasmine_finished_result, jasmine_finished_result)
35
+ end
36
+ specify { expect {subject}.to raise_error("Timed out after #{load_timeout}s waiting for Jasmine to finish") }
37
+ end
38
+
39
+ context "when there are no suites" do
40
+ let(:load_result) { true }
41
+ let(:suites) { {} }
42
+ let(:jasmine_finished_result) { true }
43
+ let(:suite_results) { {} }
44
+
45
+ before do
46
+ under_test.should_receive(:jasmine_execution_timeout).and_return(load_timeout)
47
+ driver.should_receive(:evaluate_js).and_return(load_result, suites, jasmine_finished_result)
48
+ driver.should_receive(:disconnect)
49
+ end
50
+
51
+ it("should return no suites") { subject.suites.should be_empty }
52
+ it("should return no suite results") { subject.for_spec_id('0').should be_nil }
53
+ end
54
+
55
+ shared_context "selenium runner is successful" do
56
+ include_context "suites sample"
57
+ include_context "suite result sample"
58
+
59
+ let(:load_result) { true }
60
+ let(:jasmine_finished_result) { true }
61
+
62
+ before do
63
+ under_test.should_receive(:jasmine_execution_timeout).and_return(load_timeout)
64
+ driver.should_receive(:disconnect)
65
+ end
66
+
67
+ it("should return suites") { subject.suites.should eq(suites) }
68
+ it("should return suite results") { subject.for_spec_id('0').should eq(suite_results['0']) }
69
+ end
70
+
71
+ context "when there are suites" do
72
+ include_context "selenium runner is successful"
73
+
74
+ before {
75
+ driver.should_receive(:evaluate_js).and_return(load_result, suites, jasmine_finished_result, suite_results)
76
+ }
77
+ end
78
+
79
+ context "when suites exceed batch size" do
80
+ let(:batch_size) { 1 }
81
+ let(:under_test) { Jasmine::Sauce::CI::SeleniumRunner.new(driver, batch_size) }
82
+ include_context "selenium runner is successful"
83
+
84
+ before {
85
+ driver.should_receive(:evaluate_js).and_return(load_result, suites, jasmine_finished_result,
86
+ suite_results.select {|k,_| k == '0'},
87
+ suite_results.select {|k,_| k == '1'},
88
+ suite_results.select {|k,_| k == '2'})
89
+ }
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'sauce_config'
3
+ require 'selenium_saucelabs_driver'
4
+ require 'sample_results'
5
+
6
+ describe Jasmine::Sauce::CI::SeleniumSauceLabsDriver do
7
+
8
+ let(:under_test) { Jasmine::Sauce::CI::SeleniumSauceLabsDriver.new(config) }
9
+ let(:config) { Jasmine::Sauce::CI::SauceConfig.new }
10
+ let(:driver) { double("SeleniumWebDriver") }
11
+
12
+ shared_context "create driver is stubbed" do
13
+ before do
14
+ Jasmine::Sauce::CI::SeleniumSauceLabsDriver.any_instance.should_receive(:create_driver).with(config).and_return(driver)
15
+ end
16
+ end
17
+
18
+ describe "#create_driver" do
19
+ let(:selenium_client) { double("Selenium::WebDriver::Remote::Http::Default") }
20
+ let(:timeout) { "client timeout" }
21
+ let(:sauce_url) { "http://sauce.url" }
22
+ let(:capabilities) { "desired capabilities" }
23
+ subject { under_test }
24
+ before do
25
+ config.should_receive(:selenium_client_timeout).and_return(timeout)
26
+ config.should_receive(:saucelabs_server_url).and_return(sauce_url)
27
+ Selenium::WebDriver::Remote::Http::Default.should_receive(:new).and_return(selenium_client)
28
+ selenium_client.should_receive(:timeout=).with(timeout)
29
+ Jasmine::Sauce::CI::SeleniumSauceLabsDriver.any_instance.should_receive(:generate_capabilities).and_return(capabilities)
30
+ Selenium::WebDriver.should_receive(:for) do | browser, options |
31
+ browser.should eq(:remote)
32
+ options[:http_client].should eq(selenium_client)
33
+ options[:url].should eq(sauce_url)
34
+ options[:desired_capabilities].should eq(capabilities)
35
+ end
36
+ end
37
+
38
+ it("should interact with webdriver correctly") { subject }
39
+ end
40
+
41
+ describe "#connect" do
42
+ include_context "create driver is stubbed"
43
+ let(:url) { "http://jasmine.server.url/jasmine" }
44
+ let(:navigator) { double("SeleniumNavigator") }
45
+ subject { under_test.connect(url) }
46
+ before do
47
+ driver.should_receive(:navigate).and_return(navigator)
48
+ navigator.should_receive(:to).with(url)
49
+ end
50
+
51
+ specify { expect { subject }.not_to raise_error }
52
+ end
53
+
54
+ describe "#disconnect" do
55
+ include_context "create driver is stubbed"
56
+ subject { under_test.disconnect }
57
+ before do
58
+ driver.should_receive(:quit)
59
+ end
60
+
61
+ specify { expect { subject }.not_to raise_error }
62
+ end
63
+
64
+ describe "#evaluate_js" do
65
+ include_context "create driver is stubbed"
66
+ let(:script) { "the javascript" }
67
+ subject { under_test.evaluate_js(script) }
68
+ before do
69
+ driver.should_receive(:execute_script).and_return(script_result)
70
+ end
71
+
72
+ context "when simple result" do
73
+ let(:script_result) { "true" }
74
+ it { should be_true }
75
+ end
76
+
77
+ context "when json result" do
78
+ include_context "suites sample"
79
+ let(:script_result) { suites.to_json }
80
+ it { should eq(JSON.parse(script_result)) }
81
+ end
82
+ end
83
+
84
+ describe "#generate_capabilities" do
85
+ include_context "create driver is stubbed"
86
+ subject { under_test.generate_capabilities(config) }
87
+ before do
88
+ config.should_receive(:platform).and_return("platform")
89
+ config.should_receive(:browser).and_return("browser")
90
+ config.should_receive(:browser_version).and_return("version")
91
+ config.should_receive(:record_screenshots).and_return("screens")
92
+ config.should_receive(:record_video).and_return("video")
93
+ config.should_receive(:idle_timeout).and_return("idle")
94
+ config.should_receive(:max_duration).and_return("duration")
95
+ end
96
+
97
+ it { subject['platform'].should eq "platform" }
98
+ it { subject['browserName'].should eq "browser" }
99
+ it { subject['browser-version'].should eq "version" }
100
+ it { subject['record-screenshots'].should eq "screens" }
101
+ it { subject['record-video'].should eq "video" }
102
+ it { subject['idle-timeout'].should eq "idle" }
103
+ it { subject['max-duration'].should eq "duration" }
104
+ end
105
+
106
+ end
@@ -0,0 +1,54 @@
1
+ require_relative 'spec_helper'
2
+ require_relative 'vcr_helper'
3
+ require 'jasmine-selenium-sauce'
4
+ require 'sauce_config'
5
+ require 'reporter_fake'
6
+
7
+ describe Jasmine::Sauce::CI::Main do
8
+
9
+ describe "#run" do
10
+
11
+ let(:config) { Jasmine::Sauce::CI::SauceConfig.new }
12
+ let(:reporter) { ReporterFake.new }
13
+ subject { Jasmine::Sauce::CI::Main.run(config, reporter) }
14
+
15
+ after do
16
+ ENV.delete('SAUCELABS_URL')
17
+ ENV.delete('JASMINE_URL')
18
+ ENV.delete('SAUCE_BROWSER')
19
+ end
20
+
21
+ context "when there are no failures" do
22
+ use_vcr_cassette 'jasmine_success', record: :none
23
+ before do
24
+ ENV['SAUCELABS_URL'] = 'http://username:password@ondemand.saucelabs.com:80/wd/hub'
25
+ ENV['JASMINE_URL'] = 'http://jasmine.server.com/jasmine'
26
+ ENV['SAUCE_BROWSER'] = 'chrome'
27
+ end
28
+
29
+ describe "passing tests" do
30
+ it { subject[:passed].should eq([0,1,2]) }
31
+ end
32
+ describe "failing tests" do
33
+ it { subject[:failed].should be_empty }
34
+ end
35
+ end
36
+
37
+ context "when there are failures" do
38
+ use_vcr_cassette 'jasmine_failures', record: :none
39
+ before do
40
+ ENV['SAUCELABS_URL'] = 'http://username:password@ondemand.saucelabs.com:80/wd/hub'
41
+ ENV['JASMINE_URL'] = 'http://jasmine.server.com/jasmine'
42
+ ENV['SAUCE_BROWSER'] = 'chrome'
43
+ end
44
+
45
+ describe "passing tests" do
46
+ it { subject[:passed].should eq([0,2]) }
47
+ end
48
+ describe "failing tests" do
49
+ it { subject[:failed].should eq([1]) }
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib', 'jasmine-selenium-sauce'))
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support'))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'fixtures'))
6
+
@@ -0,0 +1,31 @@
1
+
2
+ class ReporterFake
3
+
4
+ def report(jasmine_results)
5
+ results = { passed: [], failed: []}
6
+ jasmine_results.suites.each do |suite|
7
+ child_results = process_children(suite["children"], jasmine_results)
8
+ results[:passed].concat(child_results[:passed]) if child_results[:passed]
9
+ results[:failed].concat(child_results[:failed]) if child_results[:failed]
10
+ end
11
+ results
12
+ end
13
+
14
+ def process_children(children, jasmine_results)
15
+ results = { passed: [], failed: []}
16
+ children.each do |node|
17
+ type = node["type"]
18
+ if type == "suite"
19
+ child_results = process_children(node["children"], jasmine_results)
20
+ results[:passed].concat(child_results[:passed]) if child_results[:passed]
21
+ results[:failed].concat(child_results[:failed]) if child_results[:failed]
22
+ elsif type == "spec"
23
+ spec_result = jasmine_results.for_spec_id(node["id"].to_s)
24
+ results[:passed] << node["id"] if spec_result["result"] == "passed"
25
+ results[:failed] << node["id"] if spec_result["result"] == "failed"
26
+ end
27
+ end
28
+ results
29
+ end
30
+
31
+ end