base.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. 'use strict'
  2. const util = require('util')
  3. const constants = require('../constants')
  4. const helper = require('../helper')
  5. const BaseReporter = function (formatError, reportSlow, useColors, browserConsoleLogOptions, adapter) {
  6. this.adapters = [adapter || process.stdout.write.bind(process.stdout)]
  7. this.USE_COLORS = false
  8. this.EXCLUSIVELY_USE_COLORS = undefined
  9. this.LOG_SINGLE_BROWSER = '%s: %s\n'
  10. this.LOG_MULTI_BROWSER = '%s %s: %s\n'
  11. this.SPEC_FAILURE = '%s %s FAILED' + '\n'
  12. this.SPEC_SLOW = '%s SLOW %s: %s\n'
  13. this.ERROR = '%s ERROR\n'
  14. this.FINISHED_ERROR = ' ERROR'
  15. this.FINISHED_SUCCESS = ' SUCCESS'
  16. this.FINISHED_DISCONNECTED = ' DISCONNECTED'
  17. this.X_FAILED = ' (%d FAILED)'
  18. this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS\n'
  19. this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS\n'
  20. this.onRunStart = () => {
  21. this._browsers = []
  22. }
  23. this.onBrowserStart = (browser) => {
  24. this._browsers.push(browser)
  25. }
  26. this.renderBrowser = (browser) => {
  27. const results = browser.lastResult
  28. const totalExecuted = results.success + results.failed
  29. let msg = util.format('%s: Executed %d of %d', browser, totalExecuted, results.total)
  30. if (results.failed) {
  31. msg += util.format(this.X_FAILED, results.failed)
  32. }
  33. if (results.skipped) {
  34. msg += util.format(' (skipped %d)', results.skipped)
  35. }
  36. if (browser.isReady) {
  37. if (results.disconnected) {
  38. msg += this.FINISHED_DISCONNECTED
  39. } else if (results.error) {
  40. msg += this.FINISHED_ERROR
  41. } else if (!results.failed) {
  42. msg += this.FINISHED_SUCCESS
  43. }
  44. msg += util.format(' (%s / %s)', helper.formatTimeInterval(results.totalTime),
  45. helper.formatTimeInterval(results.netTime))
  46. }
  47. return msg
  48. }
  49. this.write = function () {
  50. const msg = util.format.apply(null, Array.prototype.slice.call(arguments))
  51. this.adapters.forEach((adapter) => {
  52. if (!helper.isDefined(adapter.colors)) {
  53. adapter.colors = useColors
  54. }
  55. if (!helper.isDefined(this.EXCLUSIVELY_USE_COLORS) || adapter.colors === this.EXCLUSIVELY_USE_COLORS) {
  56. return adapter(msg)
  57. }
  58. })
  59. }
  60. this.writeCommonMsg = function () {
  61. this.write.apply(this, arguments)
  62. }
  63. this.onBrowserError = (browser, error) => {
  64. this.writeCommonMsg(util.format(this.ERROR, browser) + formatError(error, ' '))
  65. }
  66. this.onBrowserLog = (browser, log, type) => {
  67. if (!browserConsoleLogOptions || !browserConsoleLogOptions.terminal) return
  68. type = type.toUpperCase()
  69. if (browserConsoleLogOptions.level) {
  70. const logPriority = constants.LOG_PRIORITIES.indexOf(browserConsoleLogOptions.level.toUpperCase())
  71. if (constants.LOG_PRIORITIES.indexOf(type) > logPriority) return
  72. }
  73. if (!helper.isString(log)) {
  74. // TODO(vojta): change util to new syntax (config object)
  75. log = util.inspect(log, false, undefined, this.USE_COLORS)
  76. }
  77. if (this._browsers && this._browsers.length === 1) {
  78. this.writeCommonMsg(util.format(this.LOG_SINGLE_BROWSER, type, log))
  79. } else {
  80. this.writeCommonMsg(util.format(this.LOG_MULTI_BROWSER, browser, type, log))
  81. }
  82. }
  83. this.onSpecComplete = (browser, result) => {
  84. if (result.skipped) {
  85. this.specSkipped(browser, result)
  86. } else if (result.success) {
  87. this.specSuccess(browser, result)
  88. } else {
  89. this.specFailure(browser, result)
  90. }
  91. if (reportSlow && result.time > reportSlow) {
  92. const specName = result.suite.join(' ') + ' ' + result.description
  93. const time = helper.formatTimeInterval(result.time)
  94. this.writeCommonMsg(util.format(this.SPEC_SLOW, browser, time, specName))
  95. }
  96. }
  97. this.specSuccess = () => {
  98. }
  99. this.specSkipped = () => {
  100. }
  101. this.specFailure = (browser, result) => {
  102. const specName = result.suite.join(' ') + ' ' + result.description
  103. let msg = util.format(this.SPEC_FAILURE, browser, specName)
  104. result.log.forEach((log) => {
  105. msg += formatError(log, '\t')
  106. })
  107. this.writeCommonMsg(msg)
  108. }
  109. this.onRunComplete = (browsers, results) => {
  110. if (browsers.length > 1 && !results.error && !results.disconnected) {
  111. if (!results.failed) {
  112. this.write(this.TOTAL_SUCCESS, results.success)
  113. } else {
  114. this.write(this.TOTAL_FAILED, results.failed, results.success)
  115. }
  116. }
  117. }
  118. }
  119. BaseReporter.decoratorFactory = function (formatError, reportSlow, useColors, browserConsoleLogOptions) {
  120. return function (self) {
  121. BaseReporter.call(self, formatError, reportSlow, useColors, browserConsoleLogOptions)
  122. }
  123. }
  124. BaseReporter.decoratorFactory.$inject = [
  125. 'formatError',
  126. 'config.reportSlowerThan',
  127. 'config.colors',
  128. 'config.browserConsoleLogOptions'
  129. ]
  130. // PUBLISH
  131. module.exports = BaseReporter