pivotal-screw-unit 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/CHANGES +21 -0
  2. data/README.markdown +354 -0
  3. data/Rakefile +39 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/screw_unit +6 -0
  6. data/bin/screw_unit_server +10 -0
  7. data/core/CHANGES +10 -0
  8. data/core/EXAMPLE.html +68 -0
  9. data/core/LICENSE +22 -0
  10. data/core/README.markdown +307 -0
  11. data/core/example/models/cat.js +5 -0
  12. data/core/example/models/man.js +17 -0
  13. data/core/example/spec/matchers/have.js +8 -0
  14. data/core/example/spec/models/cat_spec.js +31 -0
  15. data/core/example/spec/models/man_spec.js +34 -0
  16. data/core/example/spec/spec_helper.js +5 -0
  17. data/core/example/spec/suite.html +25 -0
  18. data/core/lib/jquery-1.3.2.js +4376 -0
  19. data/core/lib/jquery.fn.js +30 -0
  20. data/core/lib/jquery.print.js +109 -0
  21. data/core/lib/screw.behaviors.js +93 -0
  22. data/core/lib/screw.builder.js +94 -0
  23. data/core/lib/screw.css +90 -0
  24. data/core/lib/screw.events.js +45 -0
  25. data/core/lib/screw.matchers.js +244 -0
  26. data/core/spec/behaviors_spec.js +188 -0
  27. data/core/spec/matchers_spec.js +372 -0
  28. data/core/spec/print_spec.js +158 -0
  29. data/core/spec/spec_helper.js +0 -0
  30. data/core/spec/suite.html +19 -0
  31. data/core/spec/with_screw_context_spec.js +9 -0
  32. data/init.rb +0 -0
  33. data/lib/screw_unit/representations/spec.html.rb +117 -0
  34. data/lib/screw_unit/representations.rb +2 -0
  35. data/lib/screw_unit.rb +19 -0
  36. data/spec/functional/functional_spec.rb +25 -0
  37. data/spec/functional/functional_spec_helper.rb +34 -0
  38. data/spec/functional/functional_spec_server_starter.rb +63 -0
  39. data/spec/functional_suite.rb +10 -0
  40. data/spec/spec_suite.rb +3 -0
  41. data/spec/unit/js_test_core/specs/spec_dir_spec.rb +39 -0
  42. data/spec/unit/js_test_core/specs/spec_file_spec.rb +35 -0
  43. data/spec/unit/unit_spec_helper.rb +119 -0
  44. data/spec/unit_suite.rb +10 -0
  45. data/vendor/js-test-core/CHANGES +25 -0
  46. data/vendor/js-test-core/README +12 -0
  47. data/vendor/js-test-core/Rakefile +73 -0
  48. data/vendor/js-test-core/lib/js_test_core/client.rb +129 -0
  49. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  50. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  51. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +5 -0
  52. data/vendor/js-test-core/lib/js_test_core/rack.rb +2 -0
  53. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +22 -0
  54. data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +23 -0
  55. data/vendor/js-test-core/lib/js_test_core/representations.rb +9 -0
  56. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +67 -0
  57. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +42 -0
  58. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +107 -0
  59. data/vendor/js-test-core/lib/js_test_core/resources/session.rb +44 -0
  60. data/vendor/js-test-core/lib/js_test_core/resources/session_finish.rb +17 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec.rb +32 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +50 -0
  63. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +21 -0
  64. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +66 -0
  65. data/vendor/js-test-core/lib/js_test_core/resources.rb +17 -0
  66. data/vendor/js-test-core/lib/js_test_core/selenium/client/driver.rb +7 -0
  67. data/vendor/js-test-core/lib/js_test_core/selenium.rb +2 -0
  68. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  69. data/vendor/js-test-core/lib/js_test_core/server.rb +50 -0
  70. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
  71. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +8 -0
  72. data/vendor/js-test-core/lib/js_test_core/thin.rb +3 -0
  73. data/vendor/js-test-core/lib/js_test_core.rb +41 -0
  74. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  75. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  76. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  77. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  78. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  79. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  80. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  81. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  82. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
  83. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite.html +9 -0
  84. data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
  85. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  86. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  87. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  88. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  89. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  90. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +192 -0
  91. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +45 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +53 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +303 -0
  96. data/vendor/js-test-core/spec/unit/js_test_core/resources/session_finish_spec.rb +79 -0
  97. data/vendor/js-test-core/spec/unit/js_test_core/resources/session_spec.rb +82 -0
  98. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +104 -0
  99. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +41 -0
  100. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  101. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  102. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +117 -0
  103. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +6 -0
  104. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +161 -0
  105. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  106. data/vendor/js-test-core/vendor/thin-rest/CHANGES +2 -0
  107. data/vendor/js-test-core/vendor/thin-rest/README +0 -0
  108. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/connection.rb +117 -0
  109. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions/object.rb +21 -0
  110. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions.rb +3 -0
  111. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/internal_error.html.rb +19 -0
  112. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/page.html.rb +41 -0
  113. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/resource_not_found.html.rb +18 -0
  114. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations.rb +4 -0
  115. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/internal_error.rb +11 -0
  116. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/resource.rb +105 -0
  117. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/resource_not_found.rb +19 -0
  118. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources.rb +4 -0
  119. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/routing_error.rb +5 -0
  120. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest.rb +10 -0
  121. data/vendor/js-test-core/vendor/thin-rest/spec/spec_suite.rb +5 -0
  122. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/connection_spec.rb +205 -0
  123. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/resource_not_found_spec.rb +16 -0
  124. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/resource_spec.rb +135 -0
  125. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/root_spec.rb +16 -0
  126. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest_spec_helper.rb +133 -0
  127. metadata +184 -0
@@ -0,0 +1,45 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ describe RailsServer do
5
+ it "subclasses Server" do
6
+ RailsServer.superclass.should == Server
7
+ end
8
+
9
+ describe ".run" do
10
+ attr_reader :rails_root
11
+ before do
12
+ @rails_root = "/rails/root"
13
+ Server.instance = nil
14
+ end
15
+
16
+ it "initializes the RailsServer and runs the Thin Handler and sets Server.instance to the RailsServer instance" do
17
+ host = DEFAULT_HOST
18
+ port = DEFAULT_PORT
19
+ server_instance = nil
20
+ mock.proxy(RailsServer).new(
21
+ rails_root,
22
+ host,
23
+ port
24
+ ) do |new_instance|
25
+ server_instance = new_instance
26
+ end
27
+
28
+ mock(EventMachine).run.yields
29
+ mock(EventMachine).start_server(host, port, ::Thin::JsTestCoreConnection)
30
+ RailsServer.run(rails_root)
31
+ Server.instance.should == server_instance
32
+ end
33
+ end
34
+
35
+ describe "#initialize" do
36
+ it "sets the server paths based on the passed in rails root" do
37
+ rails_root = "/rails/root"
38
+ server = RailsServer.new(rails_root)
39
+ server.spec_root_path.should == "#{rails_root}/spec/javascripts"
40
+ server.implementation_root_path.should == "#{rails_root}/public/javascripts"
41
+ server.public_path.should == "#{rails_root}/public"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe Dir do
6
+ attr_reader :dir, :absolute_path, :relative_path
7
+
8
+ describe "GET /stylesheets - Top level directory" do
9
+ it "returns a page with a of files in the directory" do
10
+ mock(connection).send_head()
11
+ mock(connection).send_body(%r(<a href="example.css">example.css</a>))
12
+
13
+ connection.receive_data("GET /stylesheets HTTP/1.1\r\nHost: _\r\n\r\n")
14
+ end
15
+ end
16
+
17
+ describe "GET /javascripts/subdir - Subdirectory" do
18
+ it "returns a page with a of files in the directory" do
19
+ mock(connection).send_head()
20
+ mock(connection).send_body(%r(<a href="bar.js">bar.js</a>))
21
+
22
+ connection.receive_data("GET /javascripts/subdir HTTP/1.1\r\nHost: _\r\n\r\n")
23
+ end
24
+ end
25
+
26
+ describe "GET /javascripts/i_dont_exist - ResourceNotFound" do
27
+ it "returns a 404 error" do
28
+ mock(connection).send_head(404)
29
+ mock(connection).send_body(Regexp.new("File /javascripts/i_dont_exist not found"))
30
+
31
+ connection.receive_data("GET /javascripts/i_dont_exist HTTP/1.1\r\nHost: _\r\n\r\n")
32
+ end
33
+ end
34
+
35
+ describe "#glob" do
36
+ before do
37
+ @absolute_path = spec_root_path
38
+ @relative_path = "/specs"
39
+ @dir = Resources::Dir.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
40
+ end
41
+
42
+ it "returns an array of matching Files under this directory with the correct relative paths" do
43
+ globbed_files = dir.glob("/**/*_spec.js")
44
+ globbed_files.size.should == 4
45
+ globbed_files.should contain_spec_file_with_correct_paths("/failing_spec.js")
46
+ globbed_files.should contain_spec_file_with_correct_paths("/foo/failing_spec.js")
47
+ globbed_files.should contain_spec_file_with_correct_paths("/foo/passing_spec.js")
48
+ globbed_files.should contain_spec_file_with_correct_paths("/custom_dir_and_suite/passing_spec.js")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe ResourceNotFound do
6
+ describe "GET /invalid_path" do
7
+ it "returns a page with a of files in the directory" do
8
+ mock(connection).send_head(404)
9
+ mock(connection).send_body(Regexp.new("File /invalid_path not found."))
10
+
11
+ connection.receive_data("GET /invalid_path HTTP/1.1\r\nHost: _\r\n\r\n")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe File do
6
+ before do
7
+ WebRoot.dispatch_specs
8
+ stub_send_data
9
+ stub(EventMachine).close_connection
10
+ end
11
+
12
+ describe "GET" do
13
+ describe "GET /stylesheets/example.css" do
14
+ it "returns a page with a of files in the directory" do
15
+ path = "#{public_path}/stylesheets/example.css"
16
+ mock(connection).send_head(200, 'Content-Type' => "text/css", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
17
+ mock(connection).send_data(::File.read(path))
18
+
19
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\n\r\n")
20
+ end
21
+ end
22
+
23
+ describe "GET /implementations/foo.js" do
24
+ it "returns a page with a of files in the directory" do
25
+ path = "#{public_path}/javascripts/foo.js"
26
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
27
+ mock(connection).send_data(::File.read(path))
28
+
29
+ connection.receive_data("GET /implementations/foo.js HTTP/1.1\r\nHost: _\r\n\r\n")
30
+ end
31
+ end
32
+
33
+ describe "GET /javascripts/subdir/bar.js - Subdirectory" do
34
+ it "returns a page with a of files in the directory" do
35
+ path = "#{public_path}/javascripts/subdir/bar.js"
36
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
37
+ mock(connection).send_data(::File.read(path))
38
+
39
+ connection.receive_data("GET /javascripts/subdir/bar.js HTTP/1.1\r\nHost: _\r\n\r\n")
40
+ end
41
+ end
42
+
43
+ describe "GET /implementations/large_file.js - Large files" do
44
+ it "returns a page in 1024 byte chunks" do
45
+ chunk_count = 0
46
+ path = "#{public_path}/javascripts/large_file.js"
47
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
48
+ ::File.open(path) do |file|
49
+ while !file.eof?
50
+ chunk_count += 1
51
+ mock(connection).send_data(file.read(1024))
52
+ end
53
+ end
54
+
55
+ chunk_count.should == (::File.size(path) / 1024.0).ceil.to_i
56
+ connection.receive_data("GET /javascripts/large_file.js HTTP/1.1\r\nHost: _\r\n\r\n")
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ describe "==" do
63
+ attr_reader :file, :absolute_path, :relative_path
64
+
65
+ before do
66
+ @absolute_path = "#{implementation_root_path}/foo.js"
67
+ @relative_path = "/implementations/foo.js"
68
+ @file = Resources::File.new(
69
+ :connection => connection,
70
+ :absolute_path => absolute_path,
71
+ :relative_path => relative_path
72
+ )
73
+ end
74
+
75
+ it "returns true when passed a file with the same absolute and relative paths" do
76
+ file.should == Resources::File.new(:absolute_path => absolute_path, :relative_path => relative_path)
77
+ end
78
+
79
+ it "returns false when passed a file with a different absolute or relative path" do
80
+ file.should_not == Resources::File.new(:absolute_path => absolute_path, :relative_path => "bogus")
81
+ file.should_not == Resources::File.new(:absolute_path => "bogus", :relative_path => relative_path)
82
+ end
83
+
84
+ it "when passed a Dir, returns false because File is not a Dir" do
85
+ file.should_not == Resources::Dir.new(:absolute_path => absolute_path, :relative_path => relative_path)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,303 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe Runner do
6
+ attr_reader :request, :driver, :session_id, :selenium_browser_start_command, :body
7
+
8
+ def self.before_with_selenium_browser_start_command(selenium_browser_start_command="selenium browser start command")
9
+ before do
10
+ @driver = FakeSeleniumDriver.new
11
+ @session_id = FakeSeleniumDriver::SESSION_ID
12
+ @selenium_browser_start_command = selenium_browser_start_command
13
+ @body = "selenium_browser_start_command=#{selenium_browser_start_command}"
14
+ stub(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
15
+ driver
16
+ end
17
+ end
18
+ end
19
+
20
+ after do
21
+ Runner.send(:instances).clear
22
+ end
23
+
24
+ describe ".find" do
25
+ attr_reader :runner
26
+ before_with_selenium_browser_start_command
27
+ before do
28
+ @runner = Runner.new(:connection => connection, :selenium_browser_start_command => selenium_browser_start_command)
29
+ stub(runner).driver {driver}
30
+ stub(driver).session_id {session_id}
31
+ Runner.register(runner)
32
+ end
33
+
34
+ context "when passed an id for which there is a corresponding Runner" do
35
+ it "returns the Runner" do
36
+ Runner.find(session_id).should == runner
37
+ end
38
+ end
39
+
40
+ context "when passed an id for which there is no corresponding Runner" do
41
+ it "returns nil" do
42
+ invalid_id = "666666666666666"
43
+ Runner.find(invalid_id).should be_nil
44
+ end
45
+ end
46
+ end
47
+
48
+ describe ".finalize" do
49
+ attr_reader :runner
50
+ before_with_selenium_browser_start_command
51
+ describe "when there is a runner for the passed in session_id" do
52
+ before do
53
+ @runner = Runner.new(:connection => connection, :selenium_browser_start_command => selenium_browser_start_command)
54
+ stub(runner).driver {driver}
55
+ stub(driver).session_id {"DEADBEEF"}
56
+
57
+ Runner.register(runner)
58
+ runner.session_id.should == session_id
59
+ end
60
+
61
+ it "finalizes the Runner that has the session_id and keeps the Runner in memory" do
62
+ mock.proxy(driver).stop
63
+ mock.proxy(runner).finalize("Browser output")
64
+ Runner.find(session_id).should == runner
65
+ Runner.finalize(session_id, "Browser output")
66
+ Runner.find(session_id).should == runner
67
+ end
68
+ end
69
+
70
+ describe "when there is not a runner for the passed in session_id" do
71
+ it "does nothing" do
72
+ lambda do
73
+ Runner.finalize("6666666", "nothing happens")
74
+ end.should_not raise_error
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "POST /runners" do
80
+ before_with_selenium_browser_start_command
81
+ before do
82
+ stub(Thread).start.yields
83
+ stub(connection).send_head
84
+ stub(connection).send_body
85
+ end
86
+
87
+ it "responds with a 200 and the session_id" do
88
+ mock(connection).send_head
89
+ mock(connection).send_body("session_id=#{session_id}")
90
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
91
+ end
92
+
93
+ it "starts the Selenium Driver, creates a SessionID cookie, and opens the spec page" do
94
+ mock(driver).start
95
+ stub(driver).session_id {session_id}
96
+ mock(driver).create_cookie("session_id=#{session_id}")
97
+ mock(driver).open("/")
98
+ mock(driver).open("/specs")
99
+
100
+ mock(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
101
+ driver
102
+ end
103
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
104
+ end
105
+
106
+ describe "when a selenium_host parameter is passed into the request" do
107
+ before do
108
+ body << "&selenium_host=another-machine"
109
+ end
110
+
111
+ it "starts the Selenium Driver with the passed in selenium_host" do
112
+ mock(Selenium::Client::Driver).new('another-machine', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
113
+ driver
114
+ end
115
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
116
+ end
117
+ end
118
+
119
+ describe "when a selenium_host parameter is not passed into the request" do
120
+ before do
121
+ body << "&selenium_host="
122
+ end
123
+
124
+ it "starts the Selenium Driver from localhost" do
125
+ mock(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
126
+ driver
127
+ end
128
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
129
+ end
130
+ end
131
+
132
+ describe "when a selenium_port parameter is passed into the request" do
133
+ before do
134
+ body << "&selenium_port=4000"
135
+ end
136
+
137
+ it "starts the Selenium Driver with the passed in selenium_port" do
138
+ mock(Selenium::Client::Driver).new('localhost', 4000, selenium_browser_start_command, 'http://0.0.0.0:8080') do
139
+ driver
140
+ end
141
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
142
+ end
143
+ end
144
+
145
+ describe "when a selenium_port parameter is not passed into the request" do
146
+ before do
147
+ body << "&selenium_port="
148
+ end
149
+
150
+ it "starts the Selenium Driver from localhost" do
151
+ mock(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
152
+ driver
153
+ end
154
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
155
+ end
156
+ end
157
+
158
+ describe "when a spec_url is passed into the request" do
159
+ it "runs Selenium with the passed in host and part to run the specified spec session in Firefox" do
160
+ mock(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://another-host:8080') do
161
+ driver
162
+ end
163
+ mock(driver).start
164
+ stub(driver).create_cookie
165
+ mock(driver).open("/")
166
+ mock(driver).open("/specs/subdir")
167
+ mock(driver).session_id {session_id}.at_least(1)
168
+
169
+ body << "&spec_url=http://another-host:8080/specs/subdir"
170
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
171
+ end
172
+ end
173
+
174
+ describe "when a spec_url is not passed into the request" do
175
+ before do
176
+ mock(Selenium::Client::Driver).new('localhost', 4444, selenium_browser_start_command, 'http://0.0.0.0:8080') do
177
+ driver
178
+ end
179
+ end
180
+
181
+ it "uses Selenium to run the entire spec session in Firefox" do
182
+ mock(driver).start
183
+ stub(driver).create_cookie
184
+ mock(driver).open("/")
185
+ mock(driver).open("/specs")
186
+ mock(driver).session_id {session_id}.at_least(1)
187
+
188
+ body << "&spec_url="
189
+ connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
190
+ end
191
+ end
192
+ end
193
+
194
+ describe "POST /runners/firefox" do
195
+ before_with_selenium_browser_start_command "*firefox"
196
+
197
+ it "creates a Runner whose #driver started with '*firefox'" do
198
+ stub(Thread).start.yields
199
+ stub(connection).send_head
200
+ stub(connection).send_body
201
+
202
+ mock(connection).send_head
203
+ mock(connection).send_body("session_id=#{session_id}")
204
+
205
+ Runner.find(session_id).should be_nil
206
+ connection.receive_data("POST /runners/firefox HTTP/1.1\r\nHost: _\r\n\r\n")
207
+ runner = Runner.find(session_id)
208
+ runner.class.should == Runner
209
+ runner.driver.should == driver
210
+ end
211
+ end
212
+
213
+ describe "POST /runners/iexplore" do
214
+ before_with_selenium_browser_start_command "*iexplore"
215
+
216
+ it "creates a Runner whose #driver started with '*iexplore'" do
217
+ stub(Thread).start.yields
218
+ stub(connection).send_head
219
+ stub(connection).send_body
220
+
221
+ mock(connection).send_head
222
+ mock(connection).send_body("session_id=#{session_id}")
223
+
224
+ Runner.find(session_id).should be_nil
225
+ connection.receive_data("POST /runners/iexplore HTTP/1.1\r\nHost: _\r\n\r\n")
226
+ runner = Runner.find(session_id)
227
+ runner.class.should == Runner
228
+ runner.driver.should == driver
229
+ end
230
+ end
231
+
232
+ describe "#running?" do
233
+ before_with_selenium_browser_start_command
234
+ context "when the driver#session_started? is true" do
235
+ it "returns true" do
236
+ create_runner_connection = create_connection
237
+ stub(create_runner_connection).send_head
238
+ stub(create_runner_connection).send_body
239
+ create_runner_connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
240
+
241
+ runner = Resources::Runner.find(session_id)
242
+ runner.driver.session_started?.should be_true
243
+ runner.should be_running
244
+ end
245
+ end
246
+
247
+ context "when the driver#session_started? is false" do
248
+ it "returns false" do
249
+ create_runner_connection = create_connection
250
+ stub(create_runner_connection).send_head
251
+ stub(create_runner_connection).send_body
252
+ create_runner_connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
253
+
254
+ runner = Resources::Runner.find(session_id)
255
+ runner.driver.stop
256
+ runner.driver.session_started?.should be_false
257
+ runner.should_not be_running
258
+ end
259
+ end
260
+ end
261
+
262
+ describe "#finalize" do
263
+ attr_reader :runner
264
+ before_with_selenium_browser_start_command
265
+ before do
266
+ create_runner_connection = create_connection
267
+ stub(create_runner_connection).send_head
268
+ stub(create_runner_connection).send_body
269
+ create_runner_connection.receive_data("POST /runners HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
270
+ @runner = Resources::Runner.find(session_id)
271
+ mock.proxy(driver).stop
272
+ end
273
+
274
+ it "kills the browser and stores the #session_run_result" do
275
+ session_run_result = "The session run result"
276
+ runner.finalize(session_run_result)
277
+ runner.session_run_result.should == session_run_result
278
+ end
279
+
280
+ it "sets #session_run_result" do
281
+ runner.finalize("the result")
282
+ runner.session_run_result.should == "the result"
283
+ end
284
+
285
+ context "when passed an empty string" do
286
+ it "causes #successful? to be true" do
287
+ runner.finalize("")
288
+ runner.should be_successful
289
+ runner.should_not be_failed
290
+ end
291
+ end
292
+
293
+ context "when passed a non-empty string" do
294
+ it "causes #successful? to be false" do
295
+ runner.finalize("A bunch of error stuff")
296
+ runner.should_not be_successful
297
+ runner.should be_failed
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe SessionFinish do
6
+ attr_reader :stdout
7
+ before do
8
+ @stdout = StringIO.new
9
+ SessionFinish.const_set(:STDOUT, stdout)
10
+ end
11
+
12
+ after do
13
+ SessionFinish.__send__(:remove_const, :STDOUT)
14
+ end
15
+
16
+
17
+ describe "POST /session/finish" do
18
+ context "when session_id cookie is not set" do
19
+ it "writes the body of the request to stdout" do
20
+ stub(connection).send_head
21
+ stub(connection).send_body
22
+
23
+ text = "The text in the POST body"
24
+ body = "text=#{text}"
25
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
26
+ stdout.string.should == "#{text}\n"
27
+ end
28
+
29
+ it "sends an empty body" do
30
+ text = "The text in the POST body"
31
+ body = "text=#{text}"
32
+
33
+ mock(connection).send_head
34
+ mock(connection).send_body("")
35
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
36
+ end
37
+ end
38
+
39
+ context "when session_id cookie is set'" do
40
+ attr_reader :session_id, :driver
41
+ before do
42
+ @session_id = FakeSeleniumDriver::SESSION_ID
43
+ @driver = FakeSeleniumDriver.new
44
+ stub(Selenium::Client::Driver).new('localhost', 4444, '*firefox', 'http://0.0.0.0:8080') do
45
+ driver
46
+ end
47
+
48
+ firefox_connection = Thin::JsTestCoreConnection.new(Guid.new)
49
+ stub(firefox_connection).send_head
50
+ stub(firefox_connection).send_body
51
+ stub(firefox_connection).close_connection
52
+ firefox_connection.receive_data("POST /runners/firefox HTTP/1.1\r\nHost: _\r\n\r\n")
53
+ end
54
+
55
+ it "calls Runner.finalize" do
56
+ text = "The text in the POST body"
57
+ body = "text=#{text}"
58
+ stub(connection).send_head
59
+ stub(connection).send_body
60
+ mock.proxy(Runner).finalize(session_id.to_s, text)
61
+ mock(driver).stop
62
+ stub(connection).close_connection
63
+
64
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nCookie: session_id=#{session_id}\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
65
+ end
66
+
67
+ it "responds with a blank body" do
68
+ stub(driver).stop
69
+ stub(connection).close_connection
70
+
71
+ mock(connection).send_head
72
+ mock(connection).send_body("")
73
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nCookie: session_id=#{session_id}\r\nHost: _\r\nContent-Length: 0\r\n\r\n")
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe Session do
6
+ describe "GET /sessions/:session_id" do
7
+ attr_reader :driver, :session_id
8
+
9
+ context "when there is no Runner with the :session_id" do
10
+ it "responds with a 404" do
11
+ session_id = "invalid_session_id"
12
+ Runner.find(session_id).should be_nil
13
+
14
+ mock(connection).send_head(404)
15
+ mock(connection).send_body("")
16
+
17
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
18
+ end
19
+ end
20
+
21
+ context "when there is a Runner with the :session_id" do
22
+ attr_reader :session_runner
23
+ before do
24
+ @driver = FakeSeleniumDriver.new
25
+ @session_id = FakeSeleniumDriver::SESSION_ID
26
+ stub(Selenium::Client::Driver).new('localhost', 4444, '*firefox', 'http://0.0.0.0:8080') do
27
+ driver
28
+ end
29
+
30
+ connection_that_starts_firefox = create_connection
31
+ stub(connection_that_starts_firefox).send_head
32
+ stub(connection_that_starts_firefox).send_body
33
+ connection_that_starts_firefox.receive_data("POST /runners/firefox HTTP/1.1\r\nHost: _\r\nContent-Length: 0\r\n\r\n")
34
+ @session_runner = Runner.find(session_id)
35
+ session_runner.should be_running
36
+ end
37
+
38
+ context "when a Runner with the :session_id is running" do
39
+ it "responds with a 200 and status=running" do
40
+ mock(connection).send_head
41
+ mock(connection).send_body("status=#{Resources::Session::RUNNING}")
42
+
43
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
44
+ end
45
+ end
46
+
47
+ context "when a Runner with the :session_id has completed" do
48
+ context "when the session has a status of 'success'" do
49
+ before do
50
+ session_runner.finalize("")
51
+ session_runner.should be_successful
52
+ end
53
+
54
+ it "responds with a 200 and status=success" do
55
+ mock(connection).send_head
56
+ mock(connection).send_body("status=#{Resources::Session::SUCCESSFUL_COMPLETION}")
57
+
58
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
59
+ end
60
+ end
61
+
62
+ context "when the session has a status of 'failure'" do
63
+ attr_reader :reason
64
+ before do
65
+ @reason = "Failure stuff"
66
+ session_runner.finalize(reason)
67
+ session_runner.should be_failed
68
+ end
69
+
70
+ it "responds with a 200 and status=failure and reason" do
71
+ mock(connection).send_head
72
+ mock(connection).send_body("status=#{Resources::Session::FAILURE_COMPLETION}&reason=#{reason}")
73
+
74
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end