js_test_core 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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