api-content-tracing-spec.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. const { remote } = require('electron')
  2. const chai = require('chai')
  3. const dirtyChai = require('dirty-chai')
  4. const fs = require('fs')
  5. const path = require('path')
  6. const { expect } = chai
  7. const { app, contentTracing } = remote
  8. chai.use(dirtyChai)
  9. const timeout = async (milliseconds) => {
  10. return new Promise((resolve) => {
  11. setTimeout(resolve, milliseconds)
  12. })
  13. }
  14. const getPathInATempFolder = (filename) => {
  15. return path.join(app.getPath('temp'), filename)
  16. }
  17. describe('contentTracing', () => {
  18. beforeEach(function () {
  19. // FIXME: The tests are skipped on arm/arm64.
  20. if (process.platform === 'linux' &&
  21. ['arm', 'arm64'].includes(process.arch)) {
  22. this.skip()
  23. }
  24. })
  25. const record = async (options, outputFilePath, recordTimeInMilliseconds = 1e3) => {
  26. await app.whenReady()
  27. await contentTracing.startRecording(options)
  28. await timeout(recordTimeInMilliseconds)
  29. const resultFilePath = await contentTracing.stopRecording(outputFilePath)
  30. return resultFilePath
  31. }
  32. // TODO(codebytere): remove when promisification is complete
  33. const recordCallback = async (options, outputFilePath, recordTimeInMilliseconds = 1e3) => {
  34. await app.whenReady()
  35. await startRecording(options)
  36. await timeout(recordTimeInMilliseconds)
  37. const resultFilePath = await stopRecording(outputFilePath)
  38. return resultFilePath
  39. }
  40. // TODO(codebytere): remove when promisification is complete
  41. const startRecording = async (options) => {
  42. return new Promise((resolve) => {
  43. contentTracing.startRecording(options, () => {
  44. resolve()
  45. })
  46. })
  47. }
  48. // TODO(codebytere): remove when promisification is complete
  49. const stopRecording = async (filePath) => {
  50. return new Promise((resolve) => {
  51. contentTracing.stopRecording(filePath, (resultFilePath) => {
  52. resolve(resultFilePath)
  53. })
  54. })
  55. }
  56. const outputFilePath = getPathInATempFolder('trace.json')
  57. beforeEach(() => {
  58. if (fs.existsSync(outputFilePath)) {
  59. fs.unlinkSync(outputFilePath)
  60. }
  61. })
  62. describe('startRecording', function () {
  63. this.timeout(5e3)
  64. const getFileSizeInKiloBytes = (filePath) => {
  65. const stats = fs.statSync(filePath)
  66. const fileSizeInBytes = stats.size
  67. const fileSizeInKiloBytes = fileSizeInBytes / 1024
  68. return fileSizeInKiloBytes
  69. }
  70. it('accepts an empty config', async () => {
  71. const config = {}
  72. await record(config, outputFilePath)
  73. expect(fs.existsSync(outputFilePath)).to.be.true()
  74. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  75. expect(fileSizeInKiloBytes).to.be.above(0,
  76. `the trace output file is empty, check "${outputFilePath}"`)
  77. })
  78. // TODO(codebytere): remove when promisification is complete
  79. it('accepts an empty config (callback)', async () => {
  80. const config = {}
  81. await recordCallback(config, outputFilePath)
  82. expect(fs.existsSync(outputFilePath)).to.be.true()
  83. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  84. expect(fileSizeInKiloBytes).to.be.above(0,
  85. `the trace output file is empty, check "${outputFilePath}"`)
  86. })
  87. it('accepts a trace config', async () => {
  88. // (alexeykuzmin): All categories are excluded on purpose,
  89. // so only metadata gets into the output file.
  90. const config = {
  91. excluded_categories: ['*']
  92. }
  93. await record(config, outputFilePath)
  94. expect(fs.existsSync(outputFilePath)).to.be.true()
  95. // If the `excluded_categories` param above is not respected
  96. // the file size will be above 50KB.
  97. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  98. const expectedMaximumFileSize = 10 // Depends on a platform.
  99. expect(fileSizeInKiloBytes).to.be.above(0,
  100. `the trace output file is empty, check "${outputFilePath}"`)
  101. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  102. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  103. check "${outputFilePath}"`)
  104. })
  105. // TODO(codebytere): remove when promisification is complete
  106. it('accepts a trace config (callback)', async () => {
  107. // (alexeykuzmin): All categories are excluded on purpose,
  108. // so only metadata gets into the output file.
  109. const config = {
  110. excluded_categories: ['*']
  111. }
  112. await recordCallback(config, outputFilePath)
  113. expect(fs.existsSync(outputFilePath)).to.be.true()
  114. // If the `excluded_categories` param above is not respected
  115. // the file size will be above 50KB.
  116. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  117. const expectedMaximumFileSize = 10 // Depends on a platform.
  118. expect(fileSizeInKiloBytes).to.be.above(0,
  119. `the trace output file is empty, check "${outputFilePath}"`)
  120. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  121. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  122. check "${outputFilePath}"`)
  123. })
  124. it('accepts "categoryFilter" and "traceOptions" as a config', async () => {
  125. // (alexeykuzmin): All categories are excluded on purpose,
  126. // so only metadata gets into the output file.
  127. const config = {
  128. categoryFilter: '__ThisIsANonexistentCategory__',
  129. traceOptions: ''
  130. }
  131. await record(config, outputFilePath)
  132. expect(fs.existsSync(outputFilePath)).to.be.true()
  133. // If the `categoryFilter` param above is not respected
  134. // the file size will be above 50KB.
  135. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  136. const expectedMaximumFileSize = 10 // Depends on a platform.
  137. expect(fileSizeInKiloBytes).to.be.above(0,
  138. `the trace output file is empty, check "${outputFilePath}"`)
  139. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  140. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  141. check "${outputFilePath}"`)
  142. })
  143. // TODO(codebytere): remove when promisification is complete
  144. it('accepts "categoryFilter" and "traceOptions" as a config (callback)', async () => {
  145. // (alexeykuzmin): All categories are excluded on purpose,
  146. // so only metadata gets into the output file.
  147. const config = {
  148. categoryFilter: '__ThisIsANonexistentCategory__',
  149. traceOptions: ''
  150. }
  151. await recordCallback(config, outputFilePath)
  152. expect(fs.existsSync(outputFilePath)).to.be.true()
  153. // If the `categoryFilter` param above is not respected
  154. // the file size will be above 50KB.
  155. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
  156. const expectedMaximumFileSize = 10 // Depends on a platform.
  157. expect(fileSizeInKiloBytes).to.be.above(0,
  158. `the trace output file is empty, check "${outputFilePath}"`)
  159. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  160. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  161. check "${outputFilePath}"`)
  162. })
  163. })
  164. describe('stopRecording', function () {
  165. this.timeout(5e3)
  166. it('calls its callback with a result file path', async () => {
  167. const resultFilePath = await record(/* options */ {}, outputFilePath)
  168. expect(resultFilePath).to.be.a('string').and.be.equal(outputFilePath)
  169. })
  170. // TODO(codebytere): remove when promisification is complete
  171. it('calls its callback with a result file path (callback)', async () => {
  172. const resultFilePath = await recordCallback(/* options */ {}, outputFilePath)
  173. expect(resultFilePath).to.be.a('string').and.be.equal(outputFilePath)
  174. })
  175. it('creates a temporary file when an empty string is passed', async function () {
  176. const resultFilePath = await record(/* options */ {}, /* outputFilePath */ '')
  177. expect(resultFilePath).to.be.a('string').that.is.not.empty()
  178. })
  179. })
  180. })