api-content-tracing-spec.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { expect } from 'chai';
  2. import { app, contentTracing, TraceConfig, TraceCategoriesAndOptions } from 'electron';
  3. import * as fs from 'fs';
  4. import * as path from 'path';
  5. import { ifdescribe } from './spec-helpers';
  6. const timeout = async (milliseconds: number) => {
  7. return new Promise((resolve) => {
  8. setTimeout(resolve, milliseconds);
  9. });
  10. };
  11. // FIXME: The tests are skipped on arm/arm64.
  12. ifdescribe(!(process.platform === 'linux' && ['arm', 'arm64'].includes(process.arch)))('contentTracing', () => {
  13. const record = async (options: TraceConfig | TraceCategoriesAndOptions, outputFilePath: string | undefined, recordTimeInMilliseconds = 1e1) => {
  14. await app.whenReady();
  15. await contentTracing.startRecording(options);
  16. await timeout(recordTimeInMilliseconds);
  17. const resultFilePath = await contentTracing.stopRecording(outputFilePath);
  18. return resultFilePath;
  19. };
  20. const outputFilePath = path.join(app.getPath('temp'), 'trace.json');
  21. beforeEach(() => {
  22. if (fs.existsSync(outputFilePath)) {
  23. fs.unlinkSync(outputFilePath);
  24. }
  25. });
  26. describe('startRecording', function () {
  27. this.timeout(5e3);
  28. const getFileSizeInKiloBytes = (filePath: string) => {
  29. const stats = fs.statSync(filePath);
  30. const fileSizeInBytes = stats.size;
  31. const fileSizeInKiloBytes = fileSizeInBytes / 1024;
  32. return fileSizeInKiloBytes;
  33. };
  34. it('accepts an empty config', async () => {
  35. const config = {};
  36. await record(config, outputFilePath);
  37. expect(fs.existsSync(outputFilePath)).to.be.true('output exists');
  38. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath);
  39. expect(fileSizeInKiloBytes).to.be.above(0,
  40. `the trace output file is empty, check "${outputFilePath}"`);
  41. });
  42. it('accepts a trace config', async () => {
  43. // (alexeykuzmin): All categories are excluded on purpose,
  44. // so only metadata gets into the output file.
  45. const config = {
  46. excluded_categories: ['*']
  47. };
  48. await record(config, outputFilePath);
  49. expect(fs.existsSync(outputFilePath)).to.be.true('output exists');
  50. // If the `excluded_categories` param above is not respected
  51. // the file size will be above 50KB.
  52. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath);
  53. const expectedMaximumFileSize = 10; // Depends on a platform.
  54. expect(fileSizeInKiloBytes).to.be.above(0,
  55. `the trace output file is empty, check "${outputFilePath}"`);
  56. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  57. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  58. check "${outputFilePath}"`);
  59. });
  60. it('accepts "categoryFilter" and "traceOptions" as a config', async () => {
  61. // (alexeykuzmin): All categories are excluded on purpose,
  62. // so only metadata gets into the output file.
  63. const config = {
  64. categoryFilter: '__ThisIsANonexistentCategory__',
  65. traceOptions: ''
  66. };
  67. await record(config, outputFilePath);
  68. expect(fs.existsSync(outputFilePath)).to.be.true('output exists');
  69. // If the `categoryFilter` param above is not respected
  70. // the file size will be above 50KB.
  71. const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath);
  72. const expectedMaximumFileSize = 10; // Depends on a platform.
  73. expect(fileSizeInKiloBytes).to.be.above(0,
  74. `the trace output file is empty, check "${outputFilePath}"`);
  75. expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
  76. `the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
  77. check "${outputFilePath}"`);
  78. });
  79. });
  80. describe('stopRecording', function () {
  81. this.timeout(5e3);
  82. it('does not crash on empty string', async () => {
  83. const options = {
  84. categoryFilter: '*',
  85. traceOptions: 'record-until-full,enable-sampling'
  86. };
  87. await contentTracing.startRecording(options);
  88. const path = await contentTracing.stopRecording('');
  89. expect(path).to.be.a('string').that.is.not.empty('result path');
  90. expect(fs.statSync(path).isFile()).to.be.true('output exists');
  91. });
  92. it('calls its callback with a result file path', async () => {
  93. const resultFilePath = await record(/* options */ {}, outputFilePath);
  94. expect(resultFilePath).to.be.a('string').and.be.equal(outputFilePath);
  95. });
  96. it('creates a temporary file when an empty string is passed', async function () {
  97. const resultFilePath = await record(/* options */ {}, /* outputFilePath */ '');
  98. expect(resultFilePath).to.be.a('string').that.is.not.empty('result path');
  99. });
  100. it('creates a temporary file when no path is passed', async function () {
  101. const resultFilePath = await record(/* options */ {}, /* outputFilePath */ undefined);
  102. expect(resultFilePath).to.be.a('string').that.is.not.empty('result path');
  103. });
  104. });
  105. });