js_spec 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +3 -0
- data/Rakefile +1 -1
- data/core/JSSpecExtensions.js +5 -11
- data/spec/integration/integration_spec_helper.rb +1 -1
- data/spec/spec_suite.rb +0 -1
- data/spec/unit/js_test_core/resources/spec_dir_spec.rb +6 -6
- data/spec/unit/js_test_core/resources/spec_file_spec.rb +4 -4
- data/spec/unit/unit_spec_helper.rb +1 -3
- data/vendor/js-test-core/CHANGES +4 -0
- data/vendor/js-test-core/lib/js_test_core/client.rb +19 -16
- data/vendor/js-test-core/lib/js_test_core/resources.rb +2 -2
- data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +17 -15
- data/vendor/js-test-core/lib/js_test_core/resources/{suite.rb → session.rb} +8 -4
- data/vendor/js-test-core/lib/js_test_core/resources/{suite_finish.rb → session_finish.rb} +5 -5
- data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +6 -3
- data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +22 -21
- data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +83 -63
- data/vendor/js-test-core/spec/unit/js_test_core/resources/{suite_finish_spec.rb → session_finish_spec.rb} +15 -18
- data/vendor/js-test-core/spec/unit/js_test_core/resources/session_spec.rb +82 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +3 -3
- data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +37 -10
- data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource.rb +4 -0
- metadata +84 -87
- data/spec/functional/functional_spec_helper.rb +0 -18
- data/spec/functional/server_spec.rb +0 -5
- data/spec/functional_suite.rb +0 -10
- data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +0 -86
data/CHANGES
CHANGED
data/Rakefile
CHANGED
data/core/JSSpecExtensions.js
CHANGED
@@ -92,20 +92,14 @@ function parse_url(url) {
|
|
92
92
|
JSSpec.Logger.prototype.onRunnerEndWithoutServerNotification = JSSpec.Logger.prototype.onRunnerEnd;
|
93
93
|
JSSpec.Logger.prototype.onRunnerEndWithServerNotification = function() {
|
94
94
|
this.onRunnerEndWithoutServerNotification();
|
95
|
-
var
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
xml.send("text=" + encodeURIComponent(this.get_error_message_text()));
|
101
|
-
}
|
95
|
+
var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
|
96
|
+
xml.open("POST", '/session/finish', true);
|
97
|
+
xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
98
|
+
xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
99
|
+
xml.send("text=" + encodeURIComponent(this.get_error_message_text()));
|
102
100
|
}
|
103
101
|
JSSpec.Logger.prototype.onRunnerEnd = JSSpec.Logger.prototype.onRunnerEndWithServerNotification;
|
104
102
|
|
105
|
-
JSSpec.suite_id = function() {
|
106
|
-
return top.runOptions ? top.runOptions.getSessionId() : 'user';
|
107
|
-
}
|
108
|
-
|
109
103
|
JSSpec.Logger.prototype.get_error_message_text = function() {
|
110
104
|
var error_messages = [];
|
111
105
|
for(var i=0; i < JSSpec.specs.length; i++) {
|
data/spec/spec_suite.rb
CHANGED
@@ -17,15 +17,15 @@ module JsTestCore
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "returns script tags for each test javascript file" do
|
20
|
-
doc.at("script[@src='/specs/failing_spec.js']").
|
21
|
-
doc.at("script[@src='/specs/foo/failing_spec.js']").
|
22
|
-
doc.at("script[@src='/specs/foo/passing_spec.js']").
|
20
|
+
doc.at("script[@src='/specs/failing_spec.js']").should_not be_nil
|
21
|
+
doc.at("script[@src='/specs/foo/failing_spec.js']").should_not be_nil
|
22
|
+
doc.at("script[@src='/specs/foo/passing_spec.js']").should_not be_nil
|
23
23
|
end
|
24
24
|
|
25
25
|
it "returns the js specs template" do
|
26
|
-
doc.at("link[@href='/core/JSSpec.css']").
|
27
|
-
doc.at("script[@src='/core/JSSpec.js']").
|
28
|
-
doc.at("script[@src='/core/JSSpecExtensions.js']").
|
26
|
+
doc.at("link[@href='/core/JSSpec.css']").should_not be_nil
|
27
|
+
doc.at("script[@src='/core/JSSpec.js']").should_not be_nil
|
28
|
+
doc.at("script[@src='/core/JSSpecExtensions.js']").should_not be_nil
|
29
29
|
doc.at("body/#js_spec_content").should_not be_nil
|
30
30
|
end
|
31
31
|
end
|
@@ -17,13 +17,13 @@ module JsTestCore
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "returns script tags for the test javascript file" do
|
20
|
-
doc.at("script[@src='/specs/failing_spec.js']").
|
20
|
+
doc.at("script[@src='/specs/failing_spec.js']").should_not be_nil
|
21
21
|
end
|
22
22
|
|
23
23
|
it "returns the screw unit template" do
|
24
|
-
doc.at("link[@href='/core/JSSpec.css']").
|
25
|
-
doc.at("script[@src='/core/JSSpec.js']").
|
26
|
-
doc.at("script[@src='/core/JSSpecExtensions.js']").
|
24
|
+
doc.at("link[@href='/core/JSSpec.css']").should_not be_nil
|
25
|
+
doc.at("script[@src='/core/JSSpec.js']").should_not be_nil
|
26
|
+
doc.at("script[@src='/core/JSSpecExtensions.js']").should_not be_nil
|
27
27
|
doc.at("body/#js_spec_content").should_not be_nil
|
28
28
|
end
|
29
29
|
end
|
@@ -22,7 +22,7 @@ module Spec
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class Spec::
|
25
|
+
class Spec::ExampleGroup
|
26
26
|
class << self
|
27
27
|
def thin_logging
|
28
28
|
@thin_logging = true if @thin_logging.nil?
|
@@ -31,9 +31,7 @@ class Spec::Example::ExampleGroup
|
|
31
31
|
|
32
32
|
attr_writer :thin_logging
|
33
33
|
end
|
34
|
-
end
|
35
34
|
|
36
|
-
module Spec::Example::ExampleMethods
|
37
35
|
attr_reader :spec_root_path, :implementation_root_path, :public_path, :server, :connection
|
38
36
|
before(:all) do
|
39
37
|
dir = File.dirname(__FILE__)
|
data/vendor/js-test-core/CHANGES
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
- Renamed Suite to Session to follow Selenium conventions
|
2
|
+
- Renamed SuiteFinish to SessionFinish to follow Selenium conventions
|
3
|
+
- Added /session, which uses the session_id cookie to derive the current session.
|
4
|
+
- Added /session/finished to be used to simplify client/server interactions.
|
1
5
|
- Remove File caching because it doesn't cause a noticable performance benefit over a local network and because it sometimes doesn't write over stale files.
|
2
6
|
- Client accepts selenium_browser_start_command parameter, which allows the user to parameterize the selenium_browser_start_command
|
3
7
|
- Added support for running specs in Internet Explorer via POST /runners/iexplore
|
@@ -6,7 +6,7 @@ module JsTestCore
|
|
6
6
|
class InvalidStatusResponse < ClientException
|
7
7
|
end
|
8
8
|
|
9
|
-
class
|
9
|
+
class SessionNotFound < ClientException
|
10
10
|
end
|
11
11
|
|
12
12
|
class << self
|
@@ -44,7 +44,7 @@ module JsTestCore
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
attr_reader :parameters, :query_string, :http, :
|
47
|
+
attr_reader :parameters, :query_string, :http, :session_start_response, :last_poll_status, :last_poll_reason, :last_poll
|
48
48
|
def initialize(parameters)
|
49
49
|
@parameters = parameters
|
50
50
|
@query_string = SeleniumServerConfiguration.query_string_from(parameters)
|
@@ -53,7 +53,7 @@ module JsTestCore
|
|
53
53
|
def run
|
54
54
|
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) do |@http|
|
55
55
|
start_runner
|
56
|
-
|
56
|
+
wait_for_session_to_finish
|
57
57
|
end
|
58
58
|
report_result
|
59
59
|
end
|
@@ -68,19 +68,22 @@ module JsTestCore
|
|
68
68
|
|
69
69
|
protected
|
70
70
|
def start_runner
|
71
|
-
@
|
71
|
+
@session_start_response = http.post('/runners', query_string)
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
74
|
+
def wait_for_session_to_finish
|
75
|
+
while session_not_completed?
|
76
|
+
poll
|
77
|
+
sleep 0.25
|
78
|
+
end
|
76
79
|
end
|
77
80
|
|
78
81
|
def report_result
|
79
82
|
case last_poll_status
|
80
|
-
when Resources::
|
83
|
+
when Resources::Session::SUCCESSFUL_COMPLETION
|
81
84
|
STDOUT.puts "SUCCESS"
|
82
85
|
true
|
83
|
-
when Resources::
|
86
|
+
when Resources::Session::FAILURE_COMPLETION
|
84
87
|
STDOUT.puts "FAILURE"
|
85
88
|
STDOUT.puts last_poll_reason
|
86
89
|
false
|
@@ -89,26 +92,26 @@ module JsTestCore
|
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
92
|
-
def
|
93
|
-
last_poll_status.nil? || last_poll_status == Resources::
|
95
|
+
def session_not_completed?
|
96
|
+
last_poll_status.nil? || last_poll_status == Resources::Session::RUNNING
|
94
97
|
end
|
95
98
|
|
96
99
|
def poll
|
97
|
-
@last_poll = http.get("/
|
98
|
-
|
100
|
+
@last_poll = http.get("/sessions/#{session_id}")
|
101
|
+
ensure_session_exists!
|
99
102
|
parts = parts_from_query(last_poll.body)
|
100
103
|
@last_poll_status = parts['status']
|
101
104
|
@last_poll_reason = parts['reason']
|
102
105
|
end
|
103
106
|
|
104
|
-
def
|
107
|
+
def ensure_session_exists!
|
105
108
|
if (400..499).include?(Integer(last_poll.code))
|
106
|
-
raise
|
109
|
+
raise SessionNotFound, "Could not find session with id #{session_id}"
|
107
110
|
end
|
108
111
|
end
|
109
112
|
|
110
|
-
def
|
111
|
-
@
|
113
|
+
def session_id
|
114
|
+
@session_id ||= parts_from_query(session_start_response.body)['session_id']
|
112
115
|
end
|
113
116
|
end
|
114
117
|
end
|
@@ -6,5 +6,5 @@ require "#{dir}/resources/file_not_found"
|
|
6
6
|
require "#{dir}/resources/specs/spec_file"
|
7
7
|
require "#{dir}/resources/specs/spec_dir"
|
8
8
|
require "#{dir}/resources/web_root"
|
9
|
-
require "#{dir}/resources/
|
10
|
-
require "#{dir}/resources/
|
9
|
+
require "#{dir}/resources/session"
|
10
|
+
require "#{dir}/resources/session_finish"
|
@@ -18,7 +18,7 @@ module JsTestCore
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def post
|
21
|
-
spec_url = rack_request['spec_url'].to_s == "" ?
|
21
|
+
spec_url = rack_request['spec_url'].to_s == "" ? full_spec_suite_url : rack_request['spec_url']
|
22
22
|
parsed_spec_url = URI.parse(spec_url)
|
23
23
|
selenium_host = rack_request['selenium_host'].to_s == "" ? 'localhost' : rack_request['selenium_host'].to_s
|
24
24
|
selenium_port = rack_request['selenium_port'].to_s == "" ? 4444 : Integer(rack_request['selenium_port'])
|
@@ -34,17 +34,19 @@ module JsTestCore
|
|
34
34
|
rescue Errno::ECONNREFUSED => e
|
35
35
|
raise Errno::ECONNREFUSED, "Cannot connect to Selenium Server at #{http_address}. To start the selenium server, run `selenium`."
|
36
36
|
end
|
37
|
-
Thread.start do
|
38
|
-
driver.open(spec_url)
|
39
|
-
end
|
40
37
|
runner = Runner.new(:driver => driver)
|
41
38
|
Runner.register(runner)
|
39
|
+
Thread.start do
|
40
|
+
driver.open("/")
|
41
|
+
driver.create_cookie("session_id=#{runner.session_id}")
|
42
|
+
driver.open(parsed_spec_url.path)
|
43
|
+
end
|
42
44
|
connection.send_head
|
43
|
-
connection.send_body("
|
45
|
+
connection.send_body("session_id=#{runner.session_id}")
|
44
46
|
end
|
45
47
|
|
46
48
|
protected
|
47
|
-
def
|
49
|
+
def full_spec_suite_url
|
48
50
|
"#{Server.root_url}/specs"
|
49
51
|
end
|
50
52
|
end
|
@@ -54,14 +56,14 @@ module JsTestCore
|
|
54
56
|
instances[id.to_s]
|
55
57
|
end
|
56
58
|
|
57
|
-
def finalize(
|
58
|
-
if runner = find(
|
59
|
+
def finalize(session_id, text)
|
60
|
+
if runner = find(session_id)
|
59
61
|
runner.finalize(text)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
65
|
def register(runner)
|
64
|
-
instances[runner.
|
66
|
+
instances[runner.session_id] = runner
|
65
67
|
end
|
66
68
|
|
67
69
|
protected
|
@@ -72,7 +74,7 @@ module JsTestCore
|
|
72
74
|
|
73
75
|
include FileUtils
|
74
76
|
property :driver
|
75
|
-
attr_reader :profile_dir, :
|
77
|
+
attr_reader :profile_dir, :session_run_result
|
76
78
|
|
77
79
|
def after_initialize
|
78
80
|
profile_base = "#{::Dir.tmpdir}/js_test_core/#{self.class.name}"
|
@@ -80,24 +82,24 @@ module JsTestCore
|
|
80
82
|
@profile_dir = "#{profile_base}/#{Time.now.to_i}"
|
81
83
|
end
|
82
84
|
|
83
|
-
def finalize(
|
85
|
+
def finalize(session_run_result)
|
84
86
|
driver.stop
|
85
|
-
@
|
87
|
+
@session_run_result = session_run_result.to_s
|
86
88
|
end
|
87
89
|
|
88
90
|
def running?
|
89
|
-
|
91
|
+
driver.session_started?
|
90
92
|
end
|
91
93
|
|
92
94
|
def successful?
|
93
|
-
!running? &&
|
95
|
+
!running? && session_run_result.empty?
|
94
96
|
end
|
95
97
|
|
96
98
|
def failed?
|
97
99
|
!running? && !successful?
|
98
100
|
end
|
99
101
|
|
100
|
-
def
|
102
|
+
def session_id
|
101
103
|
driver.session_id
|
102
104
|
end
|
103
105
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module JsTestCore
|
2
2
|
module Resources
|
3
|
-
class
|
3
|
+
class Session < ThinRest::Resource
|
4
4
|
class Collection < ThinRest::Resource
|
5
5
|
route ANY do |env, id|
|
6
|
-
|
6
|
+
Session.new(env.merge(:id => id))
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -23,7 +23,7 @@ module JsTestCore
|
|
23
23
|
if runner.successful?
|
24
24
|
connection.send_body("status=#{SUCCESSFUL_COMPLETION}")
|
25
25
|
else
|
26
|
-
connection.send_body("status=#{FAILURE_COMPLETION}&reason=#{runner.
|
26
|
+
connection.send_body("status=#{FAILURE_COMPLETION}&reason=#{runner.session_run_result}")
|
27
27
|
end
|
28
28
|
end
|
29
29
|
else
|
@@ -33,7 +33,11 @@ module JsTestCore
|
|
33
33
|
end
|
34
34
|
|
35
35
|
route 'finish' do |env, name|
|
36
|
-
|
36
|
+
SessionFinish.new(env.merge(:session => self))
|
37
|
+
end
|
38
|
+
|
39
|
+
def associated_with_a_runner?
|
40
|
+
id.to_s != ""
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module JsTestCore
|
2
2
|
module Resources
|
3
|
-
class
|
4
|
-
property :
|
3
|
+
class SessionFinish < ThinRest::Resource
|
4
|
+
property :session
|
5
5
|
|
6
6
|
def post
|
7
|
-
if
|
8
|
-
|
7
|
+
if session.associated_with_a_runner?
|
8
|
+
Runner.finalize(session.id, rack_request['text'])
|
9
9
|
else
|
10
|
-
|
10
|
+
STDOUT.puts rack_request['text']
|
11
11
|
end
|
12
12
|
connection.send_head
|
13
13
|
connection.send_body("")
|
@@ -16,7 +16,10 @@ module JsTestCore
|
|
16
16
|
:relative_path => "/implementations"
|
17
17
|
))
|
18
18
|
end
|
19
|
-
route "
|
19
|
+
route "sessions", "JsTestCore::Resources::Session::Collection"
|
20
|
+
route "session" do |env, name|
|
21
|
+
Session.new(env.merge(:id => rack_request.cookies["session_id"]))
|
22
|
+
end
|
20
23
|
route "runners", "JsTestCore::Resources::Runner::Collection"
|
21
24
|
route "specs" do |env, name|
|
22
25
|
if self.class.dispatch_strategy == :specs
|
@@ -55,8 +58,8 @@ module JsTestCore
|
|
55
58
|
property :public_path
|
56
59
|
|
57
60
|
def get
|
58
|
-
connection.send_head(
|
59
|
-
connection.send_body("<
|
61
|
+
connection.send_head(200, :Location => "/#{self.class.dispatch_strategy}")
|
62
|
+
connection.send_body("<html><head></head><body>Welcome to the Js Test Server. Click the following link to run you <a href=/specs>spec suite</a>.</body></html>")
|
60
63
|
end
|
61
64
|
end
|
62
65
|
end
|
@@ -9,19 +9,20 @@ module JsTestCore
|
|
9
9
|
Client.const_set(:STDOUT, stdout)
|
10
10
|
@request = "http request"
|
11
11
|
mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request)
|
12
|
+
stub.instance_of(Client).sleep
|
12
13
|
end
|
13
14
|
|
14
15
|
after do
|
15
16
|
Client.__send__(:remove_const, :STDOUT)
|
16
17
|
end
|
17
18
|
|
18
|
-
it "tells the server to start a
|
19
|
+
it "tells the server to start a session run in Firefox and polls the status of the session until the session is complete" do
|
19
20
|
mock_post_to_runner("*firefox")
|
20
21
|
mock_polling_returns([running_status, running_status, success_status])
|
21
22
|
Client.run
|
22
23
|
end
|
23
24
|
|
24
|
-
context "when the
|
25
|
+
context "when the Session run ends in 'success'" do
|
25
26
|
before do
|
26
27
|
mock_post_to_runner("*firefox")
|
27
28
|
mock_polling_returns([running_status, running_status, success_status])
|
@@ -37,7 +38,7 @@ module JsTestCore
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
context "when the
|
41
|
+
context "when the Session run ends in 'failure'" do
|
41
42
|
attr_reader :failure_reason
|
42
43
|
before do
|
43
44
|
mock_post_to_runner("*firefox")
|
@@ -58,18 +59,18 @@ module JsTestCore
|
|
58
59
|
it "reports the reason for failure"
|
59
60
|
end
|
60
61
|
|
61
|
-
context "when the
|
62
|
-
it "raises a
|
62
|
+
context "when the Session is not found" do
|
63
|
+
it "raises a SessionNotFound error" do
|
63
64
|
mock_post_to_runner("*firefox")
|
64
|
-
mock(request).get("/
|
65
|
-
stub(
|
66
|
-
|
65
|
+
mock(request).get("/sessions/my_session_id") do
|
66
|
+
stub(session_response = Object.new).code {"404"}
|
67
|
+
session_response
|
67
68
|
end
|
68
|
-
lambda {Client.run}.should raise_error(Client::
|
69
|
+
lambda {Client.run}.should raise_error(Client::SessionNotFound)
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
72
|
-
context "when the
|
73
|
+
context "when the Session run ends in with invalid status" do
|
73
74
|
it "raises an InvalidStatusResponse" do
|
74
75
|
mock_post_to_runner("*firefox")
|
75
76
|
mock_polling_returns([running_status, running_status, "status=this is an unexpected status result"])
|
@@ -78,30 +79,30 @@ module JsTestCore
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def mock_post_to_runner(selenium_browser_start_command)
|
81
|
-
mock(
|
82
|
+
mock(start_session_response = Object.new).body {"session_id=my_session_id"}
|
82
83
|
mock(request).post("/runners", "selenium_browser_start_command=#{CGI.escape(selenium_browser_start_command)}&selenium_host=localhost&selenium_port=4444") do
|
83
|
-
|
84
|
+
start_session_response
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
87
|
-
def mock_polling_returns(
|
88
|
-
mock(request).get("/
|
89
|
-
stub(
|
90
|
-
stub(
|
91
|
-
|
92
|
-
end.times(
|
88
|
+
def mock_polling_returns(session_statuses=[])
|
89
|
+
mock(request).get("/sessions/my_session_id") do
|
90
|
+
stub(session_response = Object.new).body {session_statuses.shift}
|
91
|
+
stub(session_response).code {"200"}
|
92
|
+
session_response
|
93
|
+
end.times(session_statuses.length)
|
93
94
|
end
|
94
95
|
|
95
96
|
def running_status
|
96
|
-
"status=#{Resources::
|
97
|
+
"status=#{Resources::Session::RUNNING}"
|
97
98
|
end
|
98
99
|
|
99
100
|
def success_status
|
100
|
-
"status=#{Resources::
|
101
|
+
"status=#{Resources::Session::SUCCESSFUL_COMPLETION}"
|
101
102
|
end
|
102
103
|
|
103
104
|
def failure_status(reason)
|
104
|
-
"status=#{Resources::
|
105
|
+
"status=#{Resources::Session::FAILURE_COMPLETION}&reason=#{reason}"
|
105
106
|
end
|
106
107
|
end
|
107
108
|
|