diff --git a/lib/runner.js b/lib/runner.js index 374a6143bf..edfcebf141 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -394,10 +394,17 @@ Runner.prototype.hook = function(name, fn) { 'Use a return statement or other means to abort hook execution.' ); } - if (name === HOOK_TYPE_BEFORE_EACH || name === HOOK_TYPE_AFTER_EACH) { + if (name === HOOK_TYPE_AFTER_EACH) { if (self.test) { self.test.pending = true; } + } else if (name === HOOK_TYPE_BEFORE_EACH) { + if (self.test) { + self.test.pending = true; + } + self.emit(constants.EVENT_HOOK_END, hook); + hook.pending = false; // activates hook for next test + return fn(new Error('abort hookDown')); } else { suite.tests.forEach(function(test) { test.pending = true; @@ -634,6 +641,7 @@ Runner.prototype.runTests = function(suite, fn) { // execute test and hook(s) self.emit(constants.EVENT_TEST_BEGIN, (self.test = test)); self.hookDown(HOOK_TYPE_BEFORE_EACH, function(err, errSuite) { + // conditional this.skip() within beforeEach() if (test.isPending()) { if (self.forbidPending) { test.isPending = alwaysFalse; @@ -643,7 +651,13 @@ Runner.prototype.runTests = function(suite, fn) { self.emit(constants.EVENT_TEST_PENDING, test); } self.emit(constants.EVENT_TEST_END, test); - return next(); + // skip afterEach hooks below errSuite level + var origSuite = self.suite; + self.suite = errSuite; + return self.hookUp(HOOK_TYPE_AFTER_EACH, function() { + self.suite = origSuite; + next(); + }); } if (err) { return hookErr(err, errSuite, false); @@ -651,7 +665,7 @@ Runner.prototype.runTests = function(suite, fn) { self.currentRunnable = self.test; self.runTest(function(err) { test = self.test; - // conditional this.skip() + // conditional this.skip() within it() if (test.pending) { if (self.forbidPending) { test.isPending = alwaysFalse;