system = require('system');

console.log system.args # Set default values options =

url: system.args[1] || 'http://localhost:3000/jasmine'
timeout: parseInt(system.args[2] || 10000)

# Create the web page. page = require('webpage').create()

# Define fs to write files for custom reporters fs = require('fs')

# Catch JavaScript errors # abort the request and return the error page.onError = (message, trace) ->

reportError "Javascript error encountered on Jasmine test page: #{ message }", trace

page.onResourceError = (error)->

page.reason = error.errorString
page.reason_url = error.url

# Once the page is initialized, setup the script for # the GuardReporter class page.onInitialized = ->

page.injectJs 'guard-reporter.js'
injectReporter = (pathSeparator) ->
    window.onload = ->
        window.reporter = new GuardReporter()
        window.fs_path_separator = "#{pathSeparator}"
        window.__phantom_writeFile = (filename, text) ->
            window.callPhantom({event: 'writeFile', filename: filename, text: text})
        window.jasmine.getEnv().addReporter(window.reporter) if window.jasmine
page.evaluate injectReporter, fs.separator

# Once the page is finished loading page.onLoadFinished = (status) ->

if status isnt 'success'
    reportError "Unable to access Jasmine specs at #{page.reason_url}. #{page.reason}"
else
    waitFor reporterReady, jasmineAvailable, options.timeout, reporterMissing

page.onCallback = (data) ->

if data.event is 'writeFile'
    fs.write(data.filename, data.text, 'w')
else
    console.log('unknown event callback: ' + data.event)

# Open web page, which will kick off the Jasmine test runner page.open options.url

# Test if Jasmine and guard has been loaded reporterReady = ->

page.evaluate ->
    window.jasmine && window.reporter

# Start specs after they are have been loaded jasmineAvailable = ->

waitFor specsDone, exitSuccessfully, options.timeout, specsTimedout

# Error message for when jasmine never loaded asynchronously reporterMissing = ->

text = page.evaluate -> document.getElementsByTagName('body')[0]?.innerText
reportError """
          The reporter is not available!
          Perhaps the url ( #{ options.url } ) is incorrect?

          #{ text }
          """

# tests if the resultComplete flag is set on the reporter specsDone = ->

result = page.evaluate ->
    window.reporter.resultComplete

# Workaround for github.com/ariya/phantomjs/issues/12697 since # it doesn't seem like there will be another 1.9.x release fixing this phantomExit = (exitCode)->

page.close()
setTimeout( ->
    phantom.exit(exitCode)
,0)

# We should end up here. Logs the results as JSON and exits exitSuccessfully = ->

results  = page.evaluate -> window.reporter.results()
console.log JSON.stringify( results )
phantomExit()

exitError = (message)->

console.log JSON.stringify({error: message})
phantomExit(1)

# Error message for when specs time out specsTimedout = ->

text = page.evaluate -> document.getElementsByTagName('body')[0]?.innerText
reportError """
        Timeout waiting for the Jasmine test results!

        #{ text }
        """
return phantomExit(1)

# Wait until the test condition is true or a timeout occurs. # # @param [Function] test the test that returns true if condition is met # @param [Function] ready the action when the condition is fulfilled # @param [Number] timeout the max amount of time to wait in milliseconds # waitFor = (test, ready, timeout = 10000, timeoutFunction)->

condition = false
interval = undefined
start = Date.now(0)
wait = ->
    if !condition && (Date.now() - start < timeout)
        try
            condition = test()
        catch e
            exitError(e)
    else
      clearInterval interval
      if condition
          ready()
      else
          timeoutFunction()
interval = setInterval( wait, 250 )

# Logs the error to the console as JSON and exits with status '1' hasLoggedError = false reportError = (msg, trace=[])->

return if hasLoggedError
if 0 == trace.length
    err = new Error();
    trace = err.stack
console.log JSON.stringify({ error: msg, trace: trace })
hasLoggedError = true
return phantomExit(1)