Files
openlayers/test/mocha-phantomjs.coffee
2013-03-13 04:32:43 +01:00

262 lines
7.3 KiB
CoffeeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
system = require 'system'
webpage = require 'webpage'
USAGE = """
Usage: phantomjs mocha-phantomjs.coffee URL REPORTER [CONFIG]
"""
class Reporter
constructor: (@reporter, @config) ->
@url = system.args[1]
@columns = parseInt(system.env.COLUMNS or 75) * .75 | 0
@mochaStarted = false
@mochaStartWait = @config.timeout || 6000
@startTime = Date.now()
@fail(USAGE) unless @url
run: ->
@initPage()
@loadPage()
# Subclass Hooks
customizeRunner: (options) ->
undefined
customizeProcessStdout: (options) ->
undefined
customizeConsole: (options) ->
undefined
customizeOptions: ->
columns: @columns
# Private
fail: (msg, errno) ->
console.log msg if msg
phantom.exit errno || 1
finish: ->
phantom.exit @page.evaluate -> mochaPhantomJS.failures
initPage: ->
@page = webpage.create
settings: @config.settings
@page.customHeaders = @config.headers if @config.headers
for name, value of @config.cookies
@page.addCookie
name: name
value: value
@page.viewportSize = @config.viewportSize if @config.viewportSize
@page.onConsoleMessage = (msg) -> console.log msg
@page.onInitialized = =>
@page.evaluate ->
window.mochaPhantomJS =
failures: 0
ended: false
started: false
run: ->
mochaPhantomJS.started = true
window.callPhantom 'mochaPhantomJS.run'
loadPage: ->
@page.open @url
@page.onLoadFinished = (status) =>
@page.onLoadFinished = ->
@onLoadFailed() if status isnt 'success'
@waitForInitMocha()
@page.onCallback = (data) =>
if data is 'mochaPhantomJS.run'
@waitForRunMocha() if @injectJS()
onLoadFailed: ->
@fail "Failed to load the page. Check the url: #{@url}"
injectJS: ->
if @page.evaluate(-> window.mocha?)
@page.injectJs 'mocha-phantomjs/core_extensions.js'
@page.evaluate @customizeProcessStdout, @customizeOptions()
@page.evaluate @customizeConsole, @customizeOptions()
true
else
@fail "Failed to find mocha on the page."
false
runMocha: ->
if @config.useColors is false then @page.evaluate -> Mocha.reporters.Base.useColors = false
@page.evaluate @runner, @reporter
@mochaStarted = @page.evaluate -> mochaPhantomJS.runner or false
if @mochaStarted
@mochaRunAt = new Date().getTime()
@page.evaluate @customizeRunner, @customizeOptions()
@waitForMocha()
else
@fail "Failed to start mocha."
waitForMocha: =>
ended = @page.evaluate -> mochaPhantomJS.ended
if ended then @finish() else setTimeout @waitForMocha, 100
waitForInitMocha: =>
setTimeout @waitForInitMocha, 100 unless @checkStarted()
waitForRunMocha: =>
if @checkStarted() then @runMocha() else setTimeout @waitForRunMocha, 100
checkStarted: =>
started = @page.evaluate -> mochaPhantomJS.started
if !started && @mochaStartWait && @startTime + @mochaStartWait < Date.now()
@fail "Failed to start mocha: Init timeout", 255
started
runner: (reporter) ->
try
mocha.setup reporter: reporter
mochaPhantomJS.runner = mocha.run()
if mochaPhantomJS.runner
cleanup = ->
mochaPhantomJS.failures = mochaPhantomJS.runner.failures
mochaPhantomJS.ended = true
if mochaPhantomJS.runner?.stats?.end
cleanup()
else
mochaPhantomJS.runner.on 'end', cleanup
catch error
false
class Spec extends Reporter
constructor: (config) ->
super 'spec', config
customizeProcessStdout: (options) ->
process.stdout.write = (string) ->
return if string is process.cursor.deleteLine or string is process.cursor.beginningOfLine
console.log string
customizeConsole: (options) ->
process.cursor.CRMatcher = /\s+◦\s\S/
process.cursor.CRCleaner = process.cursor.up + process.cursor.deleteLine
origLog = console.log
console.log = ->
string = console.format.apply(console, arguments)
if string.match(process.cursor.CRMatcher)
process.cursor.CRCleanup = true
else if process.cursor.CRCleanup
string = process.cursor.CRCleaner + string
process.cursor.CRCleanup = false
origLog.call console, string
class Dot extends Reporter
constructor: (config) ->
super 'dot', config
customizeProcessStdout: (options) ->
process.cursor.margin = 2
process.cursor.CRMatcher = /\u001b\[\d\dm\\u001b\[0m/
process.stdout.columns = options.columns
process.stdout.allowedFirstNewLine = false
process.stdout.write = (string) ->
if string is '\n '
unless process.stdout.allowedFirstNewLine
process.stdout.allowedFirstNewLine = true
else
return
else if string.match(process.cursor.CRMatcher)
if process.cursor.count is process.stdout.columns
process.cursor.count = 0
forward = process.cursor.margin
string = process.cursor.forwardN(forward) + string
else
forward = process.cursor.margin + process.cursor.count
string = process.cursor.up + process.cursor.forwardN(forward) + string
++process.cursor.count
console.log string
class Tap extends Reporter
constructor: (config) ->
super 'tap', config
class List extends Reporter
constructor: (config) ->
super 'list', config
customizeProcessStdout: (options) ->
process.stdout.write = (string) ->
return if string is process.cursor.deleteLine or string is process.cursor.beginningOfLine
console.log string
customizeProcessStdout: (options) ->
process.cursor.CRMatcher = /\u001b\[90m.*:\s\u001b\[0m/
process.cursor.CRCleaner = (string) -> process.cursor.up + process.cursor.deleteLine + string + process.cursor.up + process.cursor.up
origLog = console.log
console.log = ->
string = console.format.apply(console, arguments)
if string.match /\u001b\[32m\s\s-\u001b\[0m/
string = string
process.cursor.CRCleanup = false
if string.match(process.cursor.CRMatcher)
process.cursor.CRCleanup = true
else if process.cursor.CRCleanup
string = process.cursor.CRCleaner(string)
process.cursor.CRCleanup = false
origLog.call console, string
class Min extends Reporter
constructor: (config) ->
super 'min', config
class Doc extends Reporter
constructor: (config) ->
super 'doc', config
class Teamcity extends Reporter
constructor: (config) ->
super 'teamcity', config
class Xunit extends Reporter
constructor: (config) ->
super 'xunit', config
class Json extends Reporter
constructor: (config) ->
super 'json', config
class JsonCov extends Reporter
constructor: (config) ->
super 'json-cov', config
class HtmlCov extends Reporter
constructor: (config) ->
super 'html-cov', config
reporterString = system.args[2] || 'spec'
reporterString = ("#{s.charAt(0).toUpperCase()}#{s.slice(1)}" for s in reporterString.split('-')).join('')
reporterKlass = try
eval(reporterString)
catch error
undefined
config = JSON.parse(system.args[3] || '{}')
if reporterKlass
reporter = new reporterKlass config
reporter.run()
else
console.log "Reporter class not implemented: #{reporterString}"
phantom.exit 1