ghostbuster 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -16,53 +16,37 @@ Once installed, you can simply use `ghostbuster [path/to/Ghostfile]` to run your
16
16
 
17
17
  As well, you can install Ghostbuster to run as a rake task. To do this, add this to your `Rakefile`:
18
18
 
19
- ~~~~
20
19
  require 'ghostbuster/install_rake'
21
- ~~~~
22
20
 
23
21
  ### Configuration via Ghostfile
24
22
 
25
23
  Your `Ghostfile` handles your configuration. To set the pattern use:
26
24
 
27
- ~~~~
28
25
  ghost.pattern = "test_*.{js,coffee}" # this is the default
29
- ~~~~
30
26
 
31
27
  To enable (or disable) screenshots use:
32
28
 
33
- ~~~~
34
29
  ghost.take_screenshots! # or #do_not_takescreenshots! defaults to take_screenshots!
35
- ~~~~
36
30
 
37
31
  To set the directory your screenshots will save to use:
38
32
 
39
- ~~~~
40
33
  ghost.screenshot_dir = '.'
41
- ~~~~
42
34
 
43
35
  To set the dimensions for the screenshots use:
44
36
 
45
- ~~~~
46
- ghost.screenshot_dimensions 800, 2000 # x, y
47
- ~~~~
37
+ ghost.screenshot_dimensions 800, 2000 # width, height
48
38
 
49
39
  To set the command for starting your server use:
50
40
 
51
- ~~~~
52
41
  ghost.start_command "./start.sh"
53
- ~~~~
54
42
 
55
43
  To set the command for stopping your server use:
56
44
 
57
- ~~~~
58
45
  ghost.stop_command "./stop.sh"
59
- ~~~~
60
46
 
61
47
  To set the location of your phantomjs binary, use:
62
48
 
63
- ~~~~
64
49
  ghost.phantom_bin = File.join(ENV['HOME'], '.ghostbuster', 'phantomjs')
65
- ~~~~
66
50
 
67
51
  If no Ghostfile is found, it will simply use the defaults.
68
52
 
@@ -70,8 +54,6 @@ If no Ghostfile is found, it will simply use the defaults.
70
54
 
71
55
  You should get some output that looks something like this.
72
56
 
73
- ~~~~
74
-
75
57
  GhostBuster
76
58
  For /Users/joshbuddy/Development/ghostbuster/ghost/test_ghost.coffee
77
59
  ✓ Simple index
@@ -86,8 +68,6 @@ You should get some output that looks something like this.
86
68
  ✓ Simple form
87
69
  ◐ Form should do more things
88
70
 
89
- ~~~~
90
-
91
71
  Your test directory should look something like this:
92
72
 
93
73
  ghost_tests/start.sh # Used to start your web application
@@ -98,8 +78,6 @@ Look inside `ghost` to see some examples of what actual tests would look like. L
98
78
 
99
79
  Here is one in Coffeescript.
100
80
 
101
- ~~~~
102
-
103
81
  phantom.test.root = "http://127.0.0.1:4567" # you must specify your root.
104
82
 
105
83
  phantom.test.add "Simple index", -> # this adds a test
@@ -110,12 +88,8 @@ Here is one in Coffeescript.
110
88
  li.innerHTML == "List item #{idx + 1}"
111
89
  @succeed() # all tests must succeed
112
90
 
113
- ~~~~
114
-
115
91
  Here is the same test in Javascript.
116
92
 
117
- ~~~~
118
-
119
93
  phantom.test.root = "http://127.0.0.1:4567"; // you must specify your root.
120
94
 
121
95
  phantom.test.add("Simple index", function() { // this adds a test
@@ -127,33 +101,82 @@ Here is the same test in Javascript.
127
101
  this.succeed();
128
102
  });
129
103
  });
130
- ~~~~
104
+
105
+ ## Page Controls
106
+
107
+ The following methods are available within your test.
108
+
109
+ ### get
110
+
111
+ *Arguments*: location, [options], callback
112
+
113
+ This location will be relative to your root if it doesn't start with "http". Your callback will be called when the document is ready.
114
+
115
+ ### click
116
+
117
+ *Arguments*: selector, [index]
118
+
119
+ This will click the nth element matching the selector. If no index is specified it uses the first one found.
120
+
121
+ ### input
122
+
123
+ *Arguments*: selector, text
124
+
125
+ This will fill in the matching form elements with the text given.
126
+
127
+ ### wait
128
+
129
+ *Arguments*: seconds, callback
130
+
131
+ This will wait `seconds` secs and then call your callback.
131
132
 
132
133
  ## Assertions
133
134
 
134
135
  Assertions are run in order, and only one assertion at a time can run. An assertion will have at most one second to complete. If you want to change the total amount of time an assertion will take, you can supply that time.
135
136
 
136
- ~~~~
137
137
  @body.assertFirst 'p', total: 3, (p) -> # this asserts the first paragraph's inner text
138
- ~~~~
139
138
 
140
- The available assertions are:
139
+ The options for all assertions currently accepts `total`, which is the total amount of time this assertion will run for in seconds.
140
+
141
+ The available assertion function are available on `body`:
142
+
143
+ ### assertFirst
144
+
145
+ *Arguments*: selector, [options], callback
146
+
147
+ The callback will be called with the first matching DOM element for the selector. The callback must return `true` if this assertion is met.
148
+
149
+ ### assertAll
150
+
151
+ *Arguments*: selector, [options], callback
152
+
153
+ The callback will be called for each matching DOM element for the selector. The arguments supplied to the callback is the DOM element and the index (starting at 0). The callback must return `true` if this assertion is met.
154
+
155
+ ### assertLocation
156
+
157
+ *Arguments*: location, [options]
158
+
159
+ This assertion will attempt to match the current browser location. If your location does not start with `http`, it will be considered relative to the root of your test.
160
+
161
+ ### assertCount
162
+
163
+ *Arguments*: selector, [options], callback
164
+
165
+ This callback will be called with the number of matching DOM elements for this selector. The callback must return `true` if this assertion is met.
166
+
167
+ ### assertCountAndAll
141
168
 
142
- * _assertFirst_ : This asserts for the first matching DOM element
143
- * _assertAll_ : This asserts for the each matching DOM element
144
- * _assertLocation_ : This asserts the current browser location
169
+ *Arguments*: selector, count, [options], callback
145
170
 
146
- The closures passed for matching have access to the real DOM node, however, they do not have any access to the outside context. They must return true if the assertion is passed, anything else will be interpreted as failure.
171
+ The callback will be called for each matching DOM element for the selector. It will only be called if the number of matching elements is equal to `count`. The arguments supplied to the callback is the DOM element and the index (starting at 0). The callback must return `true` if this assertion is met.
147
172
 
148
- ## Before and after
173
+ ## Before and After
149
174
 
150
175
  You can add an arbitrary number of before and after blocks to be run within the context of your test. Simply call `before` and `after` on your test to add them. You have to call @succeed in the before block to continue processing your test.
151
176
 
152
- ~~~~
153
177
  phantom.test.before ->
154
178
  # do some setup
155
179
  @succeed()
156
180
 
157
181
  phantom.test.after ->
158
182
  # do some teardown
159
- ~~~~
data/ghost/config.ru CHANGED
@@ -13,6 +13,11 @@ class App < Sinatra::Base
13
13
  get "/slow" do
14
14
  erb :slow
15
15
  end
16
+
17
+ get "/slow-index" do
18
+ sleep 2
19
+ erb :index
20
+ end
16
21
  end
17
22
 
18
23
  run App
@@ -6,6 +6,12 @@ phantom.test.add "Simple index", ->
6
6
  p.innerHTML == 'This is my paragraph'
7
7
  @body.assertAll 'ul li', (li, idx) ->
8
8
  li.innerHTML == "List item #{idx + 1}"
9
+ @body.assertCountAndAll 'a', 1, (a, idx) ->
10
+ a.href == 'http://127.0.0.1:4567/form'
11
+ @succeed()
12
+
13
+ phantom.test.add "Simple slow index", ->
14
+ @get '/slow-index', total: 3, ->
9
15
  @succeed()
10
16
 
11
17
  phantom.test.add "Form input", ->
@@ -35,4 +41,3 @@ phantom.test.add "Form input not equal", ->
35
41
  @body.assertFirst '#out', (out) ->
36
42
  out.innerHTML == 'this is NOT my input'
37
43
  @succeed()
38
-
@@ -41,10 +41,17 @@ class Test
41
41
  ), 5000
42
42
  runWithFunction: (fn, @callback) ->
43
43
  fn.call(this)
44
- get: (path, getCallback) ->
44
+ get: (path, opts, getCallback) ->
45
+ unless getCallback?
46
+ getCallback = opts
47
+ opts = {}
45
48
  @waitForAssertions ->
46
49
  test = this
50
+ fatalCallback = ->
51
+ test.fail("The request for #{@runner.normalizePath(path)} failed")
52
+ fatal = setTimeout fatalCallback, if opts.total then opts.total * 1000 else 1000
47
53
  loadedCallback = (status) ->
54
+ clearTimeout fatal
48
55
  return if test.seenCallbacks.indexOf(getCallback) != -1
49
56
  test.seenCallbacks.push getCallback # traversing links causes this to get re-fired.
50
57
  switch status
@@ -112,17 +119,16 @@ class Body
112
119
  "
113
120
  @test.page.evaluate(input)
114
121
 
115
- click: (selector) ->
122
+ click: (selector, idx) ->
123
+ idx ||= 0
116
124
  eval "
117
125
  var fn = function() {
118
126
  var targets = document.querySelectorAll('#{selector}'),
119
- evt = document.createEvent('MouseEvents'),
120
- i, len;
127
+ evt = document.createEvent('MouseEvents'),
128
+ idx = #{idx};
121
129
  evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
122
-
123
- for ( i = 0, len = targets.length; i < len; ++i ) {
124
- targets[i].dispatchEvent(evt);
125
- }
130
+ if (idx < targets.length) targets[idx].dispatchEvent(evt);
131
+ else throw('Couldnt find element #{idx} for selector #{selector}');
126
132
  };
127
133
  "
128
134
  @test.page.evaluate(fn)
@@ -229,6 +235,10 @@ class Body
229
235
  "
230
236
  withValue @page.evaluate(evaluator)
231
237
 
238
+ assertCountAndAll: (selector, count, opts, assertionCallback) ->
239
+ @assertCount selector, opts, (c) -> c == count
240
+ @assertAll selector, opts, assertionCallback
241
+
232
242
  class PendingTest
233
243
  constructor: (@runner, @name) ->
234
244
  run: (callback) -> callback('pending')
@@ -1,3 +1,3 @@
1
1
  class Ghostbuster
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
data/test/output CHANGED
@@ -3,6 +3,7 @@ Starting server
3
3
  GhostBuster
4
4
  For test_ghost.coffee
5
5
  ✓ Simple index
6
+ ✓ Simple slow index
6
7
  ✓ Form input
7
8
  ✓ Link traversal
8
9
  ✗ Bad link traversal
@@ -26,5 +27,5 @@ For test_injs.js
26
27
 
27
28
  For test_withoutroot.js
28
29
  ✗ No root is defined
29
- 8 success, 5 failure, 1 pending
30
+ 9 success, 5 failure, 1 pending
30
31
  Stopping server
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghostbuster
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 3
10
- version: 0.2.3
9
+ - 4
10
+ version: 0.2.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Hull