jasmine-selenium-sauce 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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