testcase.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. var path = require('path');
  2. var Q = require('q');
  3. var Logger = require('../util/logger.js');
  4. var Utils = require('../util/utils.js');
  5. var Reporter = require('../runner/reporter.js');
  6. var DEFAULT_UNITTEST_HOOK_TIMEOUT = 2000;
  7. function TestCase(suite, testFn, numRetries, maxRetries) {
  8. this.suite = suite;
  9. this.testFn = testFn;
  10. this.numRetries = numRetries;
  11. this.maxRetries = maxRetries;
  12. this.currentDeferred = null;
  13. this._deferredNext = null;
  14. this.running = false;
  15. this.lastTimerId = null;
  16. this.asyncHookTimeout = this.suite.client.globals('asyncHookTimeout') || DEFAULT_UNITTEST_HOOK_TIMEOUT;
  17. }
  18. TestCase.prototype.print = function () {
  19. var opts = this.suite.options;
  20. if (opts.output && opts.start_session && opts.detailed_output) {
  21. process.stdout.write('\n');
  22. if (this.numRetries > 0) {
  23. console.log('Retrying (' + this.numRetries + '/' + this.maxRetries + '): ',
  24. Logger.colors.red(this.testFn));
  25. } else {
  26. console.log((opts.parallelMode && !opts.live_output ? 'Results for: ' : 'Running: '),
  27. Logger.colors.green(this.testFn));
  28. }
  29. }
  30. return this;
  31. };
  32. TestCase.prototype.getResults = function () {
  33. return this.suite.client.results();
  34. };
  35. TestCase.prototype.getErrors = function () {
  36. return this.suite.client.errors();
  37. };
  38. TestCase.prototype.run = function () {
  39. var self = this;
  40. this.currentDeferred = Q.defer();
  41. this.startTime = new Date().getTime();
  42. this.results = null;
  43. this.errors = null;
  44. this.running = true;
  45. this.suite
  46. .beforeEach()
  47. .then(function() {
  48. self._deferredNext = Q.defer();
  49. self.suite.client.once('complete', function(results, errors) {
  50. if (self.suite.client.options.start_session) {
  51. self._deferredNext.resolve({
  52. results: self.getResults(),
  53. errors: self.getErrors()
  54. });
  55. }
  56. }).on('error', function(result) {
  57. self._deferredNext.reject(result);
  58. });
  59. try {
  60. if (self.suite.client.options.start_session) {
  61. self.suite.module.call(self.testFn, self.suite.client.api());
  62. } else {
  63. var doneFn = self.setDoneCallbackTimer(self.doneCallback.bind(self), self.testFn, function(timeoutId) {
  64. timeoutId.currentTest = self.testFn;
  65. self.lastTimerId = timeoutId;
  66. });
  67. self.doneFn = self.suite.module.callAsync(self.testFn, self.suite.client.api(), doneFn, self.suite.expectedAsyncArgs);
  68. }
  69. } catch (err) {
  70. self.catchHandler(err);
  71. return self._deferredNext.promise;
  72. }
  73. self.suite.client.start();
  74. return self._deferredNext.promise;
  75. })
  76. .then(function onSuccess(response) {
  77. return self.suite.afterEach(response.results, response.errors);
  78. }, function onError(error) {
  79. self.currentDeferred.reject(error);
  80. })
  81. .then(function() {
  82. var time = new Date().getTime() - self.startTime;
  83. self.currentDeferred.resolve({
  84. results: self.getResults(),
  85. errors: self.getErrors(),
  86. time : time
  87. });
  88. self.running = false;
  89. })
  90. .catch(function(error) {
  91. self.currentDeferred.reject(error);
  92. self.running = false;
  93. });
  94. return self.currentDeferred.promise;
  95. };
  96. TestCase.prototype.setDoneCallbackTimer = function(done, fnName, onTimerStarted) {
  97. return Utils.setCallbackTimeout(done, fnName, this.asyncHookTimeout, function(err) {
  98. throw err;
  99. }, onTimerStarted);
  100. };
  101. TestCase.prototype.doneCallback = function(err) {
  102. var self = this;
  103. if (this.lastTimerId) {
  104. clearTimeout(this.lastTimerId);
  105. this.lastTimerId = null;
  106. }
  107. if (this.suite.currentHookTimeoutId) {
  108. clearTimeout(this.suite.currentHookTimeoutId);
  109. this.suite.currentHookTimeoutId = null;
  110. }
  111. setImmediate(function() {
  112. if (self._deferredNext) {
  113. self._deferredNext.resolve({
  114. results : self.getResults(),
  115. errors : self.getErrors()
  116. });
  117. }
  118. });
  119. if (Utils.isErrorObject(err)) {
  120. this.setFailed(err);
  121. }
  122. if (!this.suite.options.output || !this.currentDeferred) {
  123. return;
  124. }
  125. if (!this.suite.options.start_session) {
  126. this.currentDeferred.promise.then(function(results) {
  127. console.log(Reporter.getTestOutput(err, this.testFn, results.time));
  128. }.bind(this));
  129. }
  130. if (err && this.suite.options.start_session) {
  131. this.suite.client.terminate();
  132. }
  133. };
  134. TestCase.prototype.setFailed = function(err) {
  135. this.suite.client.handleException(err);
  136. };
  137. TestCase.prototype.catchHandler = function(err) {
  138. this.doneCallback(err);
  139. };
  140. module.exports = TestCase;