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 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/tests` to run your tests. You should get some output that looks something like this.
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
@@ -0,0 +1,4 @@
1
+ ghost.pattern = "test_*.coffee"
2
+ ghost.do_not_take_screenshots! # or do_not_takescreenshots! defaults to true
3
+ ghost.screenshot_dir = '.'
4
+ ghost.screenshot_dimensions 800, 2000
@@ -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
- count = 0
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(*paths)
10
- @paths = paths
11
- @paths.flatten!
12
- @dir = File.directory?(@paths[0]) ? @paths[0] : File.dirname(@paths[0])
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} #{files.join(' ')}") }
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
+
@@ -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[:file_pattern]).run
14
+ Ghostbuster.new(opts[:path]).run
15
15
  end
16
16
  end
17
17
  end
@@ -5,12 +5,12 @@ class Ghostbuster
5
5
  end
6
6
 
7
7
  def run
8
- if @args.size == 0
9
- puts "ghostbuster <path/to/tests>"
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(1)
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
@@ -1,3 +1,3 @@
1
1
  class Ghostbuster
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/test/output ADDED
@@ -0,0 +1,23 @@
1
+ (in /Users/joshbuddy/Development/ghostbuster)
2
+ Starting server
3
+ GhostBuster
4
+ For test_ghost.coffee
5
+ ✓ Simple index
6
+ ✓ Form input
7
+ ✓ Link traversal
8
+ ✗ Bad link traversal
9
+ Assert location failed: Excepted http://127.0.0.1:4567/not-correct, got http://127.0.0.1:4567/
10
+ ✗ Form input not equal
11
+ Assert first for selector #out did not meet expectations
12
+
13
+ For test_ghostmore.coffee
14
+ ✓ Simple form
15
+ ◐ Form should do more things
16
+ ✓ Simple form with wait
17
+ ✓ Slow form
18
+ ✓ Before block var
19
+ ✗ 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: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.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-29 00:00:00 -07:00
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