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 +61 -38
- data/ghost/config.ru +5 -0
- data/ghost/test_ghost.coffee +6 -1
- data/lib/ghostbuster.coffee +18 -8
- data/lib/ghostbuster/version.rb +1 -1
- data/test/output +2 -1
- metadata +3 -3
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
|
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
|
-
*
|
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
|
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
|
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
data/ghost/test_ghost.coffee
CHANGED
@@ -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
|
-
|
data/lib/ghostbuster.coffee
CHANGED
@@ -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
|
-
|
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
|
-
|
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')
|
data/lib/ghostbuster/version.rb
CHANGED
data/test/output
CHANGED
@@ -3,6 +3,7 @@ Starting server
|
|
3
3
|
GhostBuster
|
4
4
|
For [1mtest_ghost.coffee[0m
|
5
5
|
[32m✓[0m Simple index
|
6
|
+
[32m✓[0m Simple slow index
|
6
7
|
[32m✓[0m Form input
|
7
8
|
[32m✓[0m Link traversal
|
8
9
|
[31m✗[0m Bad link traversal
|
@@ -26,5 +27,5 @@ For [1mtest_injs.js[0m
|
|
26
27
|
|
27
28
|
For [1mtest_withoutroot.js[0m
|
28
29
|
[31m✗[0m No root is defined
|
29
|
-
|
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:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 4
|
10
|
+
version: 0.2.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Josh Hull
|