js_test_core 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/CHANGES +11 -0
  2. data/Rakefile +1 -1
  3. data/lib/js_test_core.rb +10 -2
  4. data/lib/js_test_core/client.rb +85 -18
  5. data/lib/js_test_core/extensions.rb +3 -0
  6. data/lib/js_test_core/extensions/time.rb +6 -0
  7. data/lib/js_test_core/resources.rb +4 -4
  8. data/lib/js_test_core/resources/dir.rb +22 -7
  9. data/lib/js_test_core/resources/file.rb +24 -16
  10. data/lib/js_test_core/resources/file_not_found.rb +11 -0
  11. data/lib/js_test_core/resources/runner.rb +107 -0
  12. data/lib/js_test_core/resources/session.rb +44 -0
  13. data/lib/js_test_core/resources/session_finish.rb +17 -0
  14. data/lib/js_test_core/resources/specs/spec_dir.rb +10 -14
  15. data/lib/js_test_core/resources/specs/spec_file.rb +1 -1
  16. data/lib/js_test_core/resources/web_root.rb +51 -39
  17. data/lib/js_test_core/selenium_server_configuration.rb +48 -0
  18. data/lib/js_test_core/server.rb +3 -64
  19. data/lib/js_test_core/thin/js_test_core_connection.rb +4 -38
  20. data/spec/unit/js_test_core/client_spec.rb +167 -0
  21. data/spec/unit/{js_spec → js_test_core}/rails_server_spec.rb +0 -0
  22. data/spec/unit/js_test_core/resources/dir_spec.rb +52 -0
  23. data/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  24. data/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  25. data/spec/unit/js_test_core/resources/runners/runner_spec.rb +303 -0
  26. data/spec/unit/js_test_core/resources/session_finish_spec.rb +79 -0
  27. data/spec/unit/js_test_core/resources/session_spec.rb +82 -0
  28. data/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +105 -0
  29. data/spec/unit/{js_spec → js_test_core}/resources/specs/spec_file_spec.rb +5 -5
  30. data/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  31. data/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  32. data/spec/unit/{js_spec → js_test_core}/server_spec.rb +18 -32
  33. data/spec/unit/thin/js_test_core_connection_spec.rb +0 -86
  34. data/spec/unit/unit_spec_helper.rb +58 -22
  35. metadata +39 -33
  36. data/lib/js_test_core/resources/runners.rb +0 -15
  37. data/lib/js_test_core/resources/runners/firefox_runner.rb +0 -73
  38. data/lib/js_test_core/resources/suite.rb +0 -24
  39. data/lib/js_test_core/resources/suite_finish.rb +0 -19
  40. data/spec/unit/js_spec/client_spec.rb +0 -137
  41. data/spec/unit/js_spec/resources/dir_spec.rb +0 -42
  42. data/spec/unit/js_spec/resources/file_spec.rb +0 -88
  43. data/spec/unit/js_spec/resources/runner_spec.rb +0 -24
  44. data/spec/unit/js_spec/resources/runners/firefox_runner_spec.rb +0 -161
  45. data/spec/unit/js_spec/resources/specs/spec_dir_spec.rb +0 -79
  46. data/spec/unit/js_spec/resources/suite_finish_spec.rb +0 -94
  47. data/spec/unit/js_spec/resources/suite_spec.rb +0 -44
  48. data/spec/unit/js_spec/resources/web_root_spec.rb +0 -67
@@ -0,0 +1,52 @@
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 - FileNotFound" do
27
+ it "returns a 404 error" do
28
+ mock(connection).send_head(404)
29
+ mock(connection).send_body("")
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 == 3
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
+ end
49
+ end
50
+ end
51
+ end
52
+ 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 FileNotFound 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("")
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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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::SeleniumDriver).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