Skip to content

Commit

Permalink
Fixes errors when Jasmine is loaded asynchronously
Browse files Browse the repository at this point in the history
In order to use RequireJS and guard-jasmine, the check for 'window.jasmine' needs also to have a wait-loop.
Also small fixes in the Readme file.
  • Loading branch information
Manuel Deschamps committed Jun 26, 2013
1 parent 7ddc3c7 commit 7369b8e
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 96 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,9 @@ Options:
# Default: spec/javascripts
-u, [--url=URL] # The url of the Jasmine test runner_options
# Default: nil
-t, [--timeout=N] # The maximum time in milliseconds to wait for the spec
-t, [--timeout=N] # The maximum time in seconds to wait for the spec
# runner to finish
# Default: 10000
# Default: 10
[--console=CONSOLE] # Whether to show console.log statements in the spec runner,
# either `always`, `never` or `failure`
# Default: failure
Expand Down
99 changes: 57 additions & 42 deletions lib/guard/jasmine/phantomjs/guard-jasmine.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ phantom.injectJs 'lib/result.js'
# Set default values
options =
url: phantom.args[0] || 'http://127.0.0.1:3000/jasmine'
timeout: parseInt(phantom.args[1] || 5000)
timeout: parseInt(phantom.args[1] || 10000)
specdoc: phantom.args[2] || 'failure'
focus: /true/i.test phantom.args[3]
console: phantom.args[4] || 'failure'
Expand Down Expand Up @@ -53,75 +53,90 @@ page.onInitialized = ->
page.evaluate ->
# Attach the console reporter when the document is ready.
window.onload = ->
window.onload = null
window.resultReceived = false
window.reporter = new ConsoleReporter()
jasmine.getEnv().addReporter(window.reporter)
if window.jasmine
jasmine.getEnv().addReporter(window.reporter)

# Open web page and run the Jasmine test runner
#
page.open options.url, (status) ->
# Avoid that a failed iframe load breaks the runner, see https://github.com/netzpirat/guard-jasmine/pull/19
page.onLoadFinished = ->

if status isnt 'success'
console.log JSON.stringify({ error: "Unable to access Jasmine specs at #{ options.url }" })
phantom.exit()
else
runnerAvailable = page.evaluate -> window.jasmine
waitFor jasmineReady, jasmineAvailable, options.timeout, jasmineMissing

if runnerAvailable
done = -> phantom.exit()
waitFor specsReady, done, options.timeout
else
text = page.evaluate -> document.getElementsByTagName('body')[0]?.innerText

if text
error = """
The Jasmine reporter is not available!
# Test if the jasmine has been loaded
#
jasmineReady = ->
page.evaluate -> window.jasmine

#{ text }
"""
console.log JSON.stringify({ error: error })
else
console.log JSON.stringify({ error: 'The Jasmine reporter is not available!' })
# Start specs after they are have been loaded
#
jasmineAvailable = ->
waitFor specsReady, specsDone, options.timeout, specsTimedout

phantom.exit(1)
# Error message for when jasmine never loaded asynchronously
#
jasmineMissing = ->
text = page.evaluate -> document.getElementsByTagName('body')[0].innerText

if text
error = """
The Jasmine reporter is not available!
#{ text }
"""
console.log JSON.stringify({ error: error })
else
console.log JSON.stringify({ error: 'The Jasmine reporter is not available!' })

# Test if the specs have finished.
#
specsReady = ->
page.evaluate -> window.resultReceived

# Error message for when specs time out
#
specsTimedout = ->
text = page.evaluate -> document.getElementsByTagName('body')[0].innerText
if text
error = """
Timeout waiting for the Jasmine test results!
#{ text }
"""
console.log JSON.stringify({ error: error })
else
console.log JSON.stringify({ error: 'Timeout for the Jasmine test results!' })

specsDone = ->
phantom.exit()

# 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 = 5000) ->
start = new Date().getTime()
condition = false
waitFor = (test, ready, timeout = 10000, timeoutFunction) ->
start = Date.now()
condition = false

wait = ->
if (new Date().getTime() - start < timeout) and not condition
condition = test()
wait = ->
if (Date.now() - start < timeout) and not condition
condition = test()
else
clearInterval interval
if condition
ready()
else
if not condition
text = page.evaluate -> document.getElementsByTagName('body')[0]?.innerText

if text
error = """
Timeout waiting for the Jasmine test results!
#{ text }
"""
console.log JSON.stringify({ error: error })
else
console.log JSON.stringify({ error: 'Timeout waiting for the Jasmine test results!' })

phantom.exit(1)
else
ready()
clearInterval interval
timeoutFunction()
phantom.exit(1)

interval = setInterval wait, 250
interval = setInterval wait, 250
120 changes: 68 additions & 52 deletions lib/guard/jasmine/phantomjs/guard-jasmine.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(function() {
var currentSpecId, errors, logs, options, page, specsReady, waitFor;
var currentSpecId, errors, jasmineAvailable, jasmineMissing, jasmineReady, logs, options, page, specsDone, specsReady, specsTimedout, waitFor;

phantom.injectJs('lib/result.js');

options = {
url: phantom.args[0] || 'http://127.0.0.1:3000/jasmine',
timeout: parseInt(phantom.args[1] || 5000),
timeout: parseInt(phantom.args[1] || 10000),
specdoc: phantom.args[2] || 'failure',
focus: /true/i.test(phantom.args[3]),
console: phantom.args[4] || 'failure',
Expand All @@ -32,6 +32,7 @@

page.onConsoleMessage = function(msg, line, source) {
var result;

if (/^RUNNER_END$/.test(msg)) {
result = page.evaluate(function() {
return window.reporter.runnerResult;
Expand All @@ -53,87 +54,102 @@
page.injectJs('lib/reporter.js');
return page.evaluate(function() {
return window.onload = function() {
window.onload = null;
window.resultReceived = false;
window.reporter = new ConsoleReporter();
return jasmine.getEnv().addReporter(window.reporter);
if (window.jasmine) {
return jasmine.getEnv().addReporter(window.reporter);
}
};
});
};

page.open(options.url, function(status) {
var done, error, runnerAvailable, text;
page.onLoadFinished = function() {};
if (status !== 'success') {
console.log(JSON.stringify({
error: "Unable to access Jasmine specs at " + options.url
}));
return phantom.exit();
} else {
runnerAvailable = page.evaluate(function() {
return window.jasmine;
});
if (runnerAvailable) {
done = function() {
return phantom.exit();
};
return waitFor(specsReady, done, options.timeout);
} else {
text = page.evaluate(function() {
var _ref;
return (_ref = document.getElementsByTagName('body')[0]) != null ? _ref.innerText : void 0;
});
if (text) {
error = "The Jasmine reporter is not available!\n\n" + text;
console.log(JSON.stringify({
error: error
}));
} else {
console.log(JSON.stringify({
error: 'The Jasmine reporter is not available!'
}));
}
return phantom.exit(1);
}
return waitFor(jasmineReady, jasmineAvailable, options.timeout, jasmineMissing);
}
});

jasmineReady = function() {
return page.evaluate(function() {
return window.jasmine;
});
};

jasmineAvailable = function() {
return waitFor(specsReady, specsDone, options.timeout, specsTimedout);
};

jasmineMissing = function() {
var error, text;

text = page.evaluate(function() {
return document.getElementsByTagName('body')[0].innerText;
});
if (text) {
error = "The Jasmine reporter is not available!\n\n" + text;
return console.log(JSON.stringify({
error: error
}));
} else {
return console.log(JSON.stringify({
error: 'The Jasmine reporter is not available!'
}));
}
};

specsReady = function() {
return page.evaluate(function() {
return window.resultReceived;
});
};

waitFor = function(test, ready, timeout) {
specsTimedout = function() {
var error, text;

text = page.evaluate(function() {
return document.getElementsByTagName('body')[0].innerText;
});
if (text) {
error = "Timeout waiting for the Jasmine test results!\n\n" + text;
return console.log(JSON.stringify({
error: error
}));
} else {
return console.log(JSON.stringify({
error: 'Timeout for the Jasmine test results!'
}));
}
};

specsDone = function() {
return phantom.exit();
};

waitFor = function(test, ready, timeout, timeoutFunction) {
var condition, interval, start, wait;

if (timeout == null) {
timeout = 5000;
timeout = 10000;
}
start = new Date().getTime();
start = Date.now();
condition = false;
wait = function() {
var error, text;
if ((new Date().getTime() - start < timeout) && !condition) {
if ((Date.now() - start < timeout) && !condition) {
return condition = test();
} else {
if (!condition) {
text = page.evaluate(function() {
var _ref;
return (_ref = document.getElementsByTagName('body')[0]) != null ? _ref.innerText : void 0;
});
if (text) {
error = "Timeout waiting for the Jasmine test results!\n\n" + text;
console.log(JSON.stringify({
error: error
}));
} else {
console.log(JSON.stringify({
error: 'Timeout waiting for the Jasmine test results!'
}));
}
return phantom.exit(1);
clearInterval(interval);
if (condition) {
return ready();
} else {
ready();
return clearInterval(interval);
timeoutFunction();
return phantom.exit(1);
}
}
};
Expand Down

0 comments on commit 7369b8e

Please sign in to comment.