ghostbuster 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +31 -1
- data/Rakefile +28 -1
- data/ghost/Ghostfile +4 -0
- data/lib/ghostbuster.coffee +18 -3
- data/lib/ghostbuster.rb +7 -6
- data/lib/ghostbuster/config.rb +38 -0
- data/lib/ghostbuster/rake.rb +2 -2
- data/lib/ghostbuster/runner.rb +4 -4
- data/lib/ghostbuster/version.rb +1 -1
- data/test/output +23 -0
- metadata +9 -6
data/README.md
CHANGED
@@ -8,7 +8,37 @@ To install first `gem install ghostbuster`. Once you've done that, you can run `
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
-
Once installed, you can simply use `ghostbuster path/to/
|
11
|
+
Once installed, you can simply use `ghostbuster [path/to/Ghostfile]` to run your tests.
|
12
|
+
|
13
|
+
## `Ghostfile`
|
14
|
+
|
15
|
+
Your `Ghostfile` handles your configuration. To set the pattern use:
|
16
|
+
|
17
|
+
~~~~
|
18
|
+
ghost.pattern = "test_*.coffee" # this is the default
|
19
|
+
~~~~
|
20
|
+
|
21
|
+
To enable (or disable) screenshots use:
|
22
|
+
|
23
|
+
~~~~
|
24
|
+
ghost.take_screenshots! # or #do_not_takescreenshots! defaults to take_screenshots!
|
25
|
+
~~~~
|
26
|
+
|
27
|
+
To set the directory your screenshots will save to use:
|
28
|
+
|
29
|
+
~~~~
|
30
|
+
ghost.screenshot_dir = '.'
|
31
|
+
~~~~
|
32
|
+
|
33
|
+
To set the dimensions for the screenshots use:
|
34
|
+
|
35
|
+
~~~~
|
36
|
+
ghost.screenshot_dimensions 800, 2000 # x, y
|
37
|
+
~~~~
|
38
|
+
|
39
|
+
If no Ghostfile is found, it will simply use the defaults.
|
40
|
+
|
41
|
+
You should get some output that looks something like this.
|
12
42
|
|
13
43
|
~~~~
|
14
44
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,30 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
$: << 'lib'
|
3
|
-
require 'ghostbuster/install_rake'
|
3
|
+
require 'ghostbuster/install_rake'
|
4
|
+
|
5
|
+
def test_output
|
6
|
+
out = `bundle exec rake test:ghostbuster`
|
7
|
+
$?.success? ? out.gsub(/server .*?\n/m, "server\n") : raise("there was a problem")
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Run tests"
|
11
|
+
task :test do
|
12
|
+
out = test_output
|
13
|
+
if File.read(File.join(File.dirname(__FILE__), 'test', 'output')) == out
|
14
|
+
puts "Everything is great!"
|
15
|
+
else
|
16
|
+
puts out
|
17
|
+
raise "Things aren't great."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Update tests"
|
22
|
+
task :'test:update' do
|
23
|
+
File.open(File.join(File.dirname(__FILE__), 'test', 'output'), 'w') {|f| f << test_output}
|
24
|
+
puts "Test output updated"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Show output"
|
28
|
+
task :"test:output" do
|
29
|
+
puts test_output
|
30
|
+
end
|
data/ghost/Ghostfile
ADDED
data/lib/ghostbuster.coffee
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
class Test
|
2
2
|
constructor: (@runner, @name, @testBody) ->
|
3
3
|
@page = new WebPage()
|
4
|
+
if @runner.useScreenshots()
|
5
|
+
@page.viewportSize = @runner.viewportDimensions()
|
4
6
|
@page.onConsoleMessage = (msg) ->
|
5
7
|
console.log "PAGE CONSOLE: #{msg}"
|
6
8
|
@page.onAlert = (msg) => @setLastError(msg)
|
7
9
|
@lastError = null
|
8
10
|
@assertions = []
|
9
11
|
@seenCallbacks = []
|
12
|
+
@assertionIndex = 0
|
13
|
+
nameForRender: -> "#{@runner.suite.screenshot_dir}/#{@runner.nameForRender()}-#{@name.toLowerCase()}".replace(///\s///g, '_').replace(///'///g, '')
|
10
14
|
getLastError: -> @runner.lastErrors[@name]
|
11
15
|
resetLastError: -> delete @runner.lastErrors[@name]
|
12
16
|
setLastError: (error) ->
|
@@ -43,17 +47,18 @@ class Test
|
|
43
47
|
fail: (msg) ->
|
44
48
|
@callback(false, msg)
|
45
49
|
assert: (opts, valueFetcher) ->
|
46
|
-
@assertions.push(new Assertion(this, opts, valueFetcher))
|
50
|
+
@assertions.push(new Assertion(this, ++@assertionIndex, opts, valueFetcher))
|
47
51
|
@assertions[0].start() if @assertions.length == 1
|
48
52
|
wait: (time, callback) ->
|
49
53
|
test = this
|
50
54
|
setTimeout (-> callback.call(test)), time * 1000
|
51
55
|
|
52
56
|
class Assertion
|
53
|
-
constructor: (@test, @opts, @fetcher) ->
|
57
|
+
constructor: (@test, @idx, @opts, @fetcher) ->
|
54
58
|
@count = 0
|
55
59
|
@totalTime = if @opts['total'] then @opts['total'] * 1000 else 1000
|
56
60
|
@everyTime = if @opts['every'] then @opts['every'] else 75
|
61
|
+
nameForRender: -> "#{@test.nameForRender()}-#{@idx}.png"
|
57
62
|
start: ->
|
58
63
|
test = @test
|
59
64
|
assertion = this
|
@@ -69,6 +74,8 @@ class Assertion
|
|
69
74
|
test.resetLastError()
|
70
75
|
test.assertions.splice(test.assertions.indexOf(assertion), 1)
|
71
76
|
clearTimeout assertion.fatal
|
77
|
+
if test.runner.useScreenshots()
|
78
|
+
test.page.render assertion.nameForRender()
|
72
79
|
if test.assertions.length > 0
|
73
80
|
test.assertions[0].start()
|
74
81
|
else
|
@@ -180,12 +187,16 @@ class PendingTest
|
|
180
187
|
constructor: (@runner, @name) ->
|
181
188
|
run: (callback) -> callback('pending')
|
182
189
|
actuallyRun: -> false
|
190
|
+
|
183
191
|
class TestFile
|
184
192
|
constructor: (@suite, @name) ->
|
185
193
|
@tests = []
|
186
194
|
@lastErrors = {}
|
187
195
|
@befores = []
|
188
196
|
@afters = []
|
197
|
+
nameForRender: -> @name.toLowerCase()
|
198
|
+
useScreenshots: -> @suite.screenshots
|
199
|
+
viewportDimensions: -> width: @suite.screenshot_x, height: @suite.screenshot_y
|
189
200
|
normalizePath: (path) -> if path.match(/^http/) then path else "#{@root}#{path}"
|
190
201
|
addPending: (name, body) -> @tests.push new PendingTest(this, name)
|
191
202
|
before: (body) -> @befores.push(body)
|
@@ -257,7 +268,11 @@ class TestSuite
|
|
257
268
|
@failure += failure
|
258
269
|
@pending += pending
|
259
270
|
run: ->
|
260
|
-
|
271
|
+
@screenshots = @args[0] == 'true'
|
272
|
+
@screenshot_x = @args[1]
|
273
|
+
@screenshot_y = @args[2]
|
274
|
+
@screenshot_dir = @args[3]
|
275
|
+
count = 4
|
261
276
|
suite = this
|
262
277
|
runNextTest = ->
|
263
278
|
if suite.args.length == count
|
data/lib/ghostbuster.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
require 'ghostbuster/version'
|
2
2
|
require 'ghostbuster/shell'
|
3
|
+
require 'ghostbuster/config'
|
3
4
|
|
4
5
|
class Ghostbuster
|
5
6
|
include Shell
|
6
7
|
autoload :Rake, 'ghostbuster/rake'
|
7
8
|
autoload :Runner, 'ghostbuster/runner'
|
8
9
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
10
|
+
def initialize(path)
|
11
|
+
@path = File.exist?(path) ? path : '.'
|
12
|
+
@dir = File.directory?(@path) ? @path : File.basename(@path)
|
13
|
+
@file = File.directory?(@dir) ? File.join(@dir, 'Ghostfile') : @dir
|
13
14
|
@ghost_lib = File.expand_path(File.join(File.dirname(__FILE__), "ghostbuster.coffee"))
|
14
15
|
@phantom_bin = File.join(ENV['HOME'], '.ghostbuster', 'phantomjs')
|
16
|
+
@config = Config.new(@file)
|
15
17
|
STDOUT.sync = true
|
16
18
|
end
|
17
19
|
|
18
20
|
def run
|
19
|
-
files = Array(@paths).map{|path| Dir[path].to_a}.flatten.map{|f| File.expand_path(f)}
|
20
21
|
status = 1
|
21
22
|
Dir.chdir(@dir) do
|
22
23
|
spinner "Starting server" do
|
@@ -24,7 +25,7 @@ class Ghostbuster
|
|
24
25
|
sleep 2
|
25
26
|
end
|
26
27
|
begin
|
27
|
-
_, status = Process.waitpid2 fork { exec("#{@phantom_bin} #{@ghost_lib} #{
|
28
|
+
_, status = Process.waitpid2 fork { exec("#{@phantom_bin} #{@ghost_lib} #{@config.screenshots?} #{@config.screenshot_x} #{@config.screenshot_y} #{File.expand_path(@config.screenshot_dir)} #{Dir[@config.pattern].to_a.join(' ')}") }
|
28
29
|
ensure
|
29
30
|
spinner "Stopping server" do
|
30
31
|
sh "./stop.sh"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Ghostbuster
|
2
|
+
class Config
|
3
|
+
|
4
|
+
attr_accessor :pattern, :screenshot_dir
|
5
|
+
attr_reader :screenshot_x, :screenshot_y
|
6
|
+
def initialize(path_to_file = nil)
|
7
|
+
@config_file = path_to_file || './Ghostfile'
|
8
|
+
@screenshot_x, @screenshot_y = 800, 2000
|
9
|
+
@pattern = "./test_*.coffee"
|
10
|
+
@screenshot_dir = "."
|
11
|
+
@screenshots = true
|
12
|
+
if File.exist?(@config_file)
|
13
|
+
instance_eval File.read(@config_file), @config_file, 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def ghost
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def screenshot_dimensions(x, y)
|
22
|
+
@screenshot_x, @screenshot_y = x, y
|
23
|
+
end
|
24
|
+
|
25
|
+
def do_not_take_screenshots!
|
26
|
+
@screenshots = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def take_screenshots!
|
30
|
+
@screenshots = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def screenshots?
|
34
|
+
@screenshots
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/lib/ghostbuster/rake.rb
CHANGED
@@ -7,11 +7,11 @@ class Ghostbuster
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
def self.include_rake_tasks(opts = {})
|
10
|
+
opts[:path] ||= './ghost'
|
10
11
|
opts[:task_name] ||= :"test:ghostbuster"
|
11
|
-
opts[:file_pattern] ||= "ghost/test_*.{coffee,js}"
|
12
12
|
desc "Run ghostbuster tasks"
|
13
13
|
task opts[:task_name] do
|
14
|
-
Ghostbuster.new(opts[:
|
14
|
+
Ghostbuster.new(opts[:path]).run
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/ghostbuster/runner.rb
CHANGED
@@ -5,12 +5,12 @@ class Ghostbuster
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def run
|
8
|
-
if @args.size ==
|
9
|
-
puts "ghostbuster
|
8
|
+
if @args.size == 1 && @args.first == /^--?[\?h](|elp)$/i or @args.size > 1
|
9
|
+
puts "ghostbuster [path/to/Ghostfile]"
|
10
10
|
puts " Version #{VERSION}"
|
11
|
-
exit(
|
11
|
+
exit(0)
|
12
12
|
else
|
13
|
-
Ghostbuster.new(@args).run
|
13
|
+
Ghostbuster.new(@args.first).run
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
data/lib/ghostbuster/version.rb
CHANGED
data/test/output
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
(in /Users/joshbuddy/Development/ghostbuster)
|
2
|
+
Starting server
|
3
|
+
GhostBuster
|
4
|
+
For [1mtest_ghost.coffee[0m
|
5
|
+
[32m✓[0m Simple index
|
6
|
+
[32m✓[0m Form input
|
7
|
+
[32m✓[0m Link traversal
|
8
|
+
[31m✗[0m Bad link traversal
|
9
|
+
Assert location failed: Excepted http://127.0.0.1:4567/not-correct, got http://127.0.0.1:4567/
|
10
|
+
[31m✗[0m Form input not equal
|
11
|
+
Assert first for selector #out did not meet expectations
|
12
|
+
|
13
|
+
For [1mtest_ghostmore.coffee[0m
|
14
|
+
[32m✓[0m Simple form
|
15
|
+
[33m◐[0m Form should do more things
|
16
|
+
[32m✓[0m Simple form with wait
|
17
|
+
[32m✓[0m Slow form
|
18
|
+
[32m✓[0m Before block var
|
19
|
+
[31m✗[0m This test will explode!
|
20
|
+
I hate you!
|
21
|
+
|
22
|
+
7 success, 3 failure, 1 pending
|
23
|
+
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: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Josh Hull
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-30 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- Rakefile
|
98
98
|
- bin/ghostbuster
|
99
99
|
- bin/setup-ghostbuster
|
100
|
+
- ghost/Ghostfile
|
100
101
|
- ghost/config.ru
|
101
102
|
- ghost/start.sh
|
102
103
|
- ghost/stop.sh
|
@@ -108,12 +109,14 @@ files:
|
|
108
109
|
- ghostbuster.gemspec
|
109
110
|
- lib/ghostbuster.coffee
|
110
111
|
- lib/ghostbuster.rb
|
112
|
+
- lib/ghostbuster/config.rb
|
111
113
|
- lib/ghostbuster/install_rake.rb
|
112
114
|
- lib/ghostbuster/rake.rb
|
113
115
|
- lib/ghostbuster/runner.rb
|
114
116
|
- lib/ghostbuster/shell.rb
|
115
117
|
- lib/ghostbuster/version.rb
|
116
118
|
- log/thin.log
|
119
|
+
- test/output
|
117
120
|
has_rdoc: true
|
118
121
|
homepage: https://github.com/joshbuddy/ghostbuster
|
119
122
|
licenses: []
|
@@ -148,5 +151,5 @@ rubygems_version: 1.6.2
|
|
148
151
|
signing_key:
|
149
152
|
specification_version: 3
|
150
153
|
summary: Integration testing ftw
|
151
|
-
test_files:
|
152
|
-
|
154
|
+
test_files:
|
155
|
+
- test/output
|