aboutsummaryrefslogtreecommitdiffstats
path: root/src/scenario/SpecRunner.js
diff options
context:
space:
mode:
authorElliott Sprehn2010-10-19 13:17:49 -0700
committerElliott Sprehn2010-10-20 14:38:00 -0700
commit2115db69035c5993533fe7a3825e64cf6e9068ad (patch)
tree796a502b28cd2bda8108a672eac0bf28c8bc21d4 /src/scenario/SpecRunner.js
parent9c8b1800b90e14b643bab6ada8e96f8f850e84a6 (diff)
downloadangular.js-2115db69035c5993533fe7a3825e64cf6e9068ad.tar.bz2
Lots of stability and performance updates and UI polish too.
Polish the Scenario Runner UI to include: - a scroll pane that steps appear in since the list can be very long - Collapse successful tests - Show the line where the DSL statements were when there's an error (Chrome, Firefox) Also: - Remove lots angular.bind calls to reduce the amount of stack space used. - Use setTimeout(...,0) to schedule the next future to let the browser breathe and have it repaint the steps. Also prevents overflowing the stack when an it() creates many futures. - Run afterEach() handlers even if the it() block fails. - Make navigateTo() take a function as the second argument so you can compute a URL in the future. - Add wait() DSL statement to allow interactive debugging of tests. - Allow custom jQuery selectors with element(...).query(fn) DSL statement. Known Issues: - All afterEach() handlers run even if a beforeEach() handler fails. Only after handlers for the same level as the failure and above should run.
Diffstat (limited to 'src/scenario/SpecRunner.js')
-rw-r--r--src/scenario/SpecRunner.js61
1 files changed, 44 insertions, 17 deletions
diff --git a/src/scenario/SpecRunner.js b/src/scenario/SpecRunner.js
index 26fa9b91..98ce4b53 100644
--- a/src/scenario/SpecRunner.js
+++ b/src/scenario/SpecRunner.js
@@ -8,6 +8,7 @@
*/
angular.scenario.SpecRunner = function() {
this.futures = [];
+ this.afterIndex = 0;
};
/**
@@ -20,32 +21,52 @@ angular.scenario.SpecRunner = function() {
* @param {Function} Callback function that is called when the spec finshes.
*/
angular.scenario.SpecRunner.prototype.run = function(ui, spec, specDone) {
+ var self = this;
var specUI = ui.addSpec(spec);
try {
- spec.fn.call(this);
+ spec.before.call(this);
+ spec.body.call(this);
+ this.afterIndex = this.futures.length;
+ spec.after.call(this);
} catch (e) {
specUI.error(e);
specDone();
return;
}
+ var handleError = function(error, done) {
+ if (self.error) {
+ return done();
+ }
+ self.error = true;
+ done(null, self.afterIndex);
+ };
+
+ var spec = this;
asyncForEach(
this.futures,
function(future, futureDone) {
- var stepUI = specUI.addStep(future.name);
+ var stepUI = specUI.addStep(future.name, future.line);
try {
future.execute(function(error) {
stepUI.finish(error);
- futureDone(error);
+ if (error) {
+ return handleError(error, futureDone);
+ }
+ spec.$window.setTimeout( function() { futureDone(); }, 0);
});
} catch (e) {
stepUI.error(e);
- throw e;
+ handleError(e, futureDone);
}
},
function(e) {
- specUI.finish(e);
+ if (e) {
+ specUI.error(e);
+ } else {
+ specUI.finish();
+ }
specDone();
}
);
@@ -54,11 +75,14 @@ angular.scenario.SpecRunner.prototype.run = function(ui, spec, specDone) {
/**
* Adds a new future action.
*
+ * Note: Do not pass line manually. It happens automatically.
+ *
* @param {String} Name of the future
* @param {Function} Behavior of the future
+ * @param {Function} fn() that returns file/line number
*/
-angular.scenario.SpecRunner.prototype.addFuture = function(name, behavior) {
- var future = new angular.scenario.Future(name, angular.bind(this, behavior));
+angular.scenario.SpecRunner.prototype.addFuture = function(name, behavior, line) {
+ var future = new angular.scenario.Future(name, angular.bind(this, behavior), line);
this.futures.push(future);
return future;
};
@@ -66,17 +90,20 @@ angular.scenario.SpecRunner.prototype.addFuture = function(name, behavior) {
/**
* Adds a new future action to be executed on the application window.
*
+ * Note: Do not pass line manually. It happens automatically.
+ *
* @param {String} Name of the future
* @param {Function} Behavior of the future
+ * @param {Function} fn() that returns file/line number
*/
-angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior) {
+angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior, line) {
+ var self = this;
return this.addFuture(name, function(done) {
- this.application.executeAction(angular.bind(this, function($window, $document) {
-
- $document.elements = angular.bind(this, function(selector) {
+ this.application.executeAction(function($window, $document) {
+ $document.elements = function(selector) {
var args = Array.prototype.slice.call(arguments, 1);
- if (this.selector) {
- selector = this.selector + ' ' + (selector || '');
+ if (self.selector) {
+ selector = self.selector + ' ' + (selector || '');
}
angular.foreach(args, function(value, index) {
selector = selector.replace('$' + (index + 1), value);
@@ -90,10 +117,10 @@ angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior)
}
return result;
- });
+ };
try {
- behavior.call(this, $window, $document, done);
+ behavior.call(self, $window, $document, done);
} catch(e) {
if (e.type && e.type === 'selector') {
done(e.message);
@@ -101,6 +128,6 @@ angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior)
throw e;
}
}
- }));
- });
+ });
+ }, line);
};