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.
Files changed (27) hide show
  1. data/CHANGES +3 -0
  2. data/Rakefile +1 -1
  3. data/core/JSSpecExtensions.js +5 -11
  4. data/spec/integration/integration_spec_helper.rb +1 -1
  5. data/spec/spec_suite.rb +0 -1
  6. data/spec/unit/js_test_core/resources/spec_dir_spec.rb +6 -6
  7. data/spec/unit/js_test_core/resources/spec_file_spec.rb +4 -4
  8. data/spec/unit/unit_spec_helper.rb +1 -3
  9. data/vendor/js-test-core/CHANGES +4 -0
  10. data/vendor/js-test-core/lib/js_test_core/client.rb +19 -16
  11. data/vendor/js-test-core/lib/js_test_core/resources.rb +2 -2
  12. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +17 -15
  13. data/vendor/js-test-core/lib/js_test_core/resources/{suite.rb → session.rb} +8 -4
  14. data/vendor/js-test-core/lib/js_test_core/resources/{suite_finish.rb → session_finish.rb} +5 -5
  15. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +6 -3
  16. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +22 -21
  17. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +83 -63
  18. data/vendor/js-test-core/spec/unit/js_test_core/resources/{suite_finish_spec.rb → session_finish_spec.rb} +15 -18
  19. data/vendor/js-test-core/spec/unit/js_test_core/resources/session_spec.rb +82 -0
  20. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +3 -3
  21. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +37 -10
  22. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource.rb +4 -0
  23. metadata +84 -87
  24. data/spec/functional/functional_spec_helper.rb +0 -18
  25. data/spec/functional/server_spec.rb +0 -5
  26. data/spec/functional_suite.rb +0 -10
  27. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +0 -86
data/CHANGES CHANGED
@@ -1,3 +1,6 @@
1
+ 0.3.3
2
+ - Fixed for latest version of Selenium, Rack, and Thin
3
+
1
4
  0.3.2
2
5
  - Fixed vendor directory not being included in the gem
3
6
 
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ def run_suite
26
26
  end
27
27
 
28
28
  PKG_NAME = "js_spec"
29
- PKG_VERSION = "0.3.2"
29
+ PKG_VERSION = "0.3.3"
30
30
  PKG_FILES = FileList[
31
31
  '[A-Z]*',
32
32
  '*.rb',
@@ -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 suite_id = JSSpec.suite_id();
96
- if(suite_id) {
97
- var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
98
- xml.open("POST", '/suites/' + suite_id + '/finish', true);
99
- xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
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++) {
@@ -26,7 +26,7 @@ module WaitFor
26
26
  end
27
27
  end
28
28
 
29
- module Spec::Example::ExampleMethods
29
+ class Spec::ExampleGroup
30
30
  include WaitFor
31
31
  attr_reader :spec_root_path, :implementation_root_path, :public_path
32
32
  before(:all) do
@@ -1,4 +1,3 @@
1
1
  dir = File.dirname(__FILE__)
2
2
  raise "Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
3
- raise "Failure" unless system(%Q|ruby #{dir}/functional_suite.rb|)
4
3
  raise "Failure" unless system(%Q|ruby #{dir}/integration_suite.rb|)
@@ -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']").should exist
21
- doc.at("script[@src='/specs/foo/failing_spec.js']").should exist
22
- doc.at("script[@src='/specs/foo/passing_spec.js']").should exist
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']").should exist
27
- doc.at("script[@src='/core/JSSpec.js']").should exist
28
- doc.at("script[@src='/core/JSSpecExtensions.js']").should exist
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']").should exist
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']").should exist
25
- doc.at("script[@src='/core/JSSpec.js']").should exist
26
- doc.at("script[@src='/core/JSSpecExtensions.js']").should exist
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::Example::ExampleGroup
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__)
@@ -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 SuiteNotFound < ClientException
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, :suite_start_response, :last_poll_status, :last_poll_reason, :last_poll
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
- wait_for_suite_to_finish
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
- @suite_start_response = http.post('/runners', query_string)
71
+ @session_start_response = http.post('/runners', query_string)
72
72
  end
73
73
 
74
- def wait_for_suite_to_finish
75
- poll while suite_not_completed?
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::Suite::SUCCESSFUL_COMPLETION
83
+ when Resources::Session::SUCCESSFUL_COMPLETION
81
84
  STDOUT.puts "SUCCESS"
82
85
  true
83
- when Resources::Suite::FAILURE_COMPLETION
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 suite_not_completed?
93
- last_poll_status.nil? || last_poll_status == Resources::Suite::RUNNING
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("/suites/#{suite_id}")
98
- ensure_suite_exists!
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 ensure_suite_exists!
107
+ def ensure_session_exists!
105
108
  if (400..499).include?(Integer(last_poll.code))
106
- raise SuiteNotFound, "Could not find suite with id #{suite_id}"
109
+ raise SessionNotFound, "Could not find session with id #{session_id}"
107
110
  end
108
111
  end
109
112
 
110
- def suite_id
111
- @suite_id ||= parts_from_query(suite_start_response.body)['suite_id']
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/suite"
10
- require "#{dir}/resources/suite_finish"
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 == "" ? spec_suite_url : rack_request['spec_url']
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("suite_id=#{runner.suite_id}")
45
+ connection.send_body("session_id=#{runner.session_id}")
44
46
  end
45
47
 
46
48
  protected
47
- def spec_suite_url
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(suite_id, text)
58
- if runner = find(suite_id)
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.suite_id] = 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, :suite_run_result
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(suite_run_result)
85
+ def finalize(session_run_result)
84
86
  driver.stop
85
- @suite_run_result = suite_run_result
87
+ @session_run_result = session_run_result.to_s
86
88
  end
87
89
 
88
90
  def running?
89
- suite_run_result.nil?
91
+ driver.session_started?
90
92
  end
91
93
 
92
94
  def successful?
93
- !running? && suite_run_result.empty?
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 suite_id
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 Suite < ThinRest::Resource
3
+ class Session < ThinRest::Resource
4
4
  class Collection < ThinRest::Resource
5
5
  route ANY do |env, id|
6
- Suite.new(env.merge(:id => id))
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.suite_run_result}")
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
- SuiteFinish.new(env.merge(:suite => self))
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 SuiteFinish < ThinRest::Resource
4
- property :suite
3
+ class SessionFinish < ThinRest::Resource
4
+ property :session
5
5
 
6
6
  def post
7
- if suite.id == 'user'
8
- STDOUT.puts rack_request['text']
7
+ if session.associated_with_a_runner?
8
+ Runner.finalize(session.id, rack_request['text'])
9
9
  else
10
- Runner.finalize(suite.id, rack_request['text'])
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 "suites", "JsTestCore::Resources::Suite::Collection"
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(301, :Location => "/#{self.class.dispatch_strategy}")
59
- connection.send_body("<script type='text/javascript'>window.location.href='/specs';</script>")
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 suite run in Firefox and polls the status of the suite until the suite is complete" do
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 Suite run ends in 'success'" do
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 Suite run ends in 'failure'" do
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 Suite is not found" do
62
- it "raises a SuiteNotFound error" do
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("/suites/my_suite_id") do
65
- stub(suite_response = Object.new).code {"404"}
66
- suite_response
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::SuiteNotFound)
69
+ lambda {Client.run}.should raise_error(Client::SessionNotFound)
69
70
  end
70
71
  end
71
72
 
72
- context "when the Suite run ends in with invalid status" do
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(start_suite_response = Object.new).body {"suite_id=my_suite_id"}
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
- start_suite_response
84
+ start_session_response
84
85
  end
85
86
  end
86
87
 
87
- def mock_polling_returns(suite_statuses=[])
88
- mock(request).get("/suites/my_suite_id") do
89
- stub(suite_response = Object.new).body {suite_statuses.shift}
90
- stub(suite_response).code {"200"}
91
- suite_response
92
- end.times(suite_statuses.length)
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::Suite::RUNNING}"
97
+ "status=#{Resources::Session::RUNNING}"
97
98
  end
98
99
 
99
100
  def success_status
100
- "status=#{Resources::Suite::SUCCESSFUL_COMPLETION}"
101
+ "status=#{Resources::Session::SUCCESSFUL_COMPLETION}"
101
102
  end
102
103
 
103
104
  def failure_status(reason)
104
- "status=#{Resources::Suite::FAILURE_COMPLETION}&reason=#{reason}"
105
+ "status=#{Resources::Session::FAILURE_COMPLETION}&reason=#{reason}"
105
106
  end
106
107
  end
107
108