Skip to content

Commit e2dcfb0

Browse files
committed
Keep runner from stalling when circular objects are present
1 parent 4ce6783 commit e2dcfb0

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

lib/jasmine/runners/selenium.rb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,32 @@ def get_results
5252
spec_results = []
5353

5454
loop do
55-
slice = driver.execute_script("return jsApiReporter.specResults(#{index}, #{result_batch_size})")
56-
spec_results << Jasmine::Result.map_raw_results(slice)
55+
slice = results_without_circular_references(index)
56+
spec_results << slice
5757
index += result_batch_size
5858
break if slice.size < result_batch_size
5959
end
6060
spec_results.flatten
6161
end
6262

63+
def results_without_circular_references(starting_index)
64+
slice = driver.execute_script(<<-JS)
65+
var specResults = jsApiReporter.specResults(#{starting_index}, #{result_batch_size})
66+
for (var i = 0; i < specResults.length; i++) {
67+
var expectations = specResults[i].failedExpectations;
68+
if (specResults[i].passedExpectations) {
69+
expectations = expectations.concat(specResults[i].passedExpectations);
70+
}
71+
for (var j = 0; j < expectations.length; j++) {
72+
var expectation = expectations[j];
73+
try { JSON.stringify(expectation.expected); } catch (e) { expectation.expected = '<circular expected>'; }
74+
try { JSON.stringify(expectation.actual); } catch (e) { expectation.actual = '<circular actual>'; }
75+
}
76+
}
77+
return specResults;
78+
JS
79+
Jasmine::Result.map_raw_results(slice)
80+
end
6381
end
6482
end
6583
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
it("handles circular references", function() {
2+
var objA = {};
3+
var objB = {back_reference: objA};
4+
objA.back_reference = objB;
5+
6+
expect(objA).not.toBe(objA);
7+
});

spec/jasmine_selenium_runner/configure_jasmine_spec.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
let(:config) { { 'selenium_server' => 'http://example.com/selenium/stuff' }}
1111

1212
it "make a webdriver pointing to the custom server" do
13-
Selenium::WebDriver.should_receive(:for).with(:remote, hash_including(url: 'http://example.com/selenium/stuff'))
13+
expect(Selenium::WebDriver).to receive(:for).with(:remote, hash_including(url: 'http://example.com/selenium/stuff'))
1414
configurer.make_runner
1515
end
1616
end
@@ -20,8 +20,8 @@
2020

2121
it "should create a firebug profile and pass that to WebDriver" do
2222
profile = double(:profile, enable_firebug: nil)
23-
Selenium::WebDriver::Firefox::Profile.stub(:new).and_return(profile)
24-
Selenium::WebDriver.should_receive(:for).with('firefox-firebug'.to_sym, {profile: profile})
23+
allow(Selenium::WebDriver::Firefox::Profile).to receive(:new).and_return(profile)
24+
expect(Selenium::WebDriver).to receive(:for).with('firefox-firebug'.to_sym, {profile: profile})
2525
configurer.make_runner
2626
end
2727
end
@@ -32,17 +32,17 @@ class FakeConfig
3232
end
3333

3434
def configure
35-
Dir.stub(:pwd).and_return(working_dir)
36-
Jasmine.stub(:configure).and_yield(fake_config)
35+
allow(Dir).to receive(:pwd).and_return(working_dir)
36+
allow(Jasmine).to receive(:configure).and_yield(fake_config)
3737
JasmineSeleniumRunner::ConfigureJasmine.install_selenium_runner
3838
end
3939

4040
def stub_config_file(config_obj)
4141
config_path = File.join(working_dir, 'spec', 'javascripts', 'support', 'jasmine_selenium_runner.yml')
42-
File.stub(:exist?).and_call_original
43-
File.stub(:exist?).with(config_path).and_return(true)
44-
File.stub(:read).and_call_original
45-
File.stub(:read).with(config_path).and_return(YAML.dump(config_obj))
42+
allow(File).to receive(:exist?).and_call_original
43+
allow(File).to receive(:exist?).with(config_path).and_return(true)
44+
allow(File).to receive(:read).and_call_original
45+
allow(File).to receive(:read).with(config_path).and_return(YAML.dump(config_obj))
4646
end
4747

4848
let(:working_dir) { 'hi' }
@@ -64,8 +64,8 @@ def make_runner
6464
end
6565

6666
it "should use the custom class" do
67-
Selenium::WebDriver.should_not_receive(:for)
68-
Foo::Bar.any_instance.should_receive(:make_runner)
67+
expect(Selenium::WebDriver).not_to receive(:for)
68+
expect_any_instance_of(Foo::Bar).to receive(:make_runner)
6969
fake_config.runner.call(nil, nil)
7070
end
7171
end

spec/selenium_runner_integration_spec.rb

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,27 @@
2121
`bundle exec jasmine examples`
2222
FileUtils.cp(File.join(project_root, 'spec', 'fixtures', 'is_in_firefox_spec.js'), File.join(dir, 'spec', 'javascripts'))
2323
ci_output = `bundle exec rake -E "require 'jasmine_selenium_runner'" --trace jasmine:ci`
24-
ci_output.should =~ /[1-9][0-9]* specs, 0 failures/
24+
expect(ci_output).to match(/[1-9][0-9]* specs, 0 failures/)
25+
end
26+
end
27+
end
28+
29+
it "allows rake jasmine:ci to retrieve results even though Selenium can't transmit back circular JS objects" do
30+
in_temp_dir do |dir, project_root|
31+
File.open(File.join(dir, 'Gemfile'), 'w') do |file|
32+
file.write <<-GEMFILE
33+
source 'https://rubygems.org'
34+
gem 'jasmine_selenium_runner', :path => '#{project_root}'
35+
gem 'jasmine', :git => 'https://github.com/pivotal/jasmine-gem.git'
36+
GEMFILE
37+
end
38+
Bundler.with_clean_env do
39+
`bundle`
40+
`bundle exec jasmine init`
41+
`bundle exec jasmine examples`
42+
FileUtils.cp(File.join(project_root, 'spec', 'fixtures', 'contains_circular_references_spec.js'), File.join(dir, 'spec', 'javascripts'))
43+
ci_output = `bundle exec rake -E "require 'jasmine_selenium_runner'" --trace jasmine:ci`
44+
expect(ci_output).to match(/[1-9][0-9]* specs, 1 failure/)
2545
end
2646
end
2747
end
@@ -68,13 +88,13 @@
6888
before = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
6989
http.request(job_list_request)
7090
end
71-
JSON.parse(before.body).should == []
91+
expect(JSON.parse(before.body)).to be_empty
7292
ci_output = %x{bundle exec rake -E "require 'jasmine_selenium_runner'" --trace jasmine:ci}
73-
ci_output.should =~ (/[1-9][0-9]* specs, 0 failures/)
93+
expect(ci_output).to match(/[1-9][0-9]* specs, 0 failures/)
7494
after = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
7595
http.request(job_list_request)
7696
end
77-
JSON.parse(after.body).should_not be_empty
97+
expect(JSON.parse(after.body)).not_to be_empty
7898
end
7999
end
80100
end
@@ -107,7 +127,7 @@ def bundle_install
107127
`bundle exec rails g jasmine:examples`
108128
FileUtils.cp(File.join(project_root, 'spec', 'fixtures', 'is_in_firefox_spec.js'), File.join(dir, 'rails-test', 'spec', 'javascripts'))
109129
output = `bundle exec rake jasmine:ci`
110-
output.should =~ /[1-9]\d* specs, 0 failures/
130+
expect(output).to match(/[1-9]\d* specs, 0 failures/)
111131
end
112132
end
113133
end

0 commit comments

Comments
 (0)