browsertime 16.17.0 → 17.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/bin/browsertime.js +43 -43
  3. package/bin/browsertimeWebPageReplay.js +10 -9
  4. package/browserscripts/pageinfo/generator.js +1 -1
  5. package/index.js +14 -13
  6. package/lib/android/gnirehtet.js +14 -15
  7. package/lib/android/index.js +92 -89
  8. package/lib/android/root.js +6 -9
  9. package/lib/chrome/chromeDevtoolsProtocol.js +46 -45
  10. package/lib/chrome/har.js +12 -13
  11. package/lib/chrome/longTaskMetrics.js +3 -5
  12. package/lib/chrome/parseCpuTrace.js +13 -10
  13. package/lib/chrome/settings/chromeAndroidOptions.js +1 -3
  14. package/lib/chrome/settings/chromeDesktopOptions.js +1 -3
  15. package/lib/chrome/settings/traceCategories.js +1 -3
  16. package/lib/chrome/traceCategoriesParser.js +35 -36
  17. package/lib/chrome/webdriver/builder.js +18 -26
  18. package/lib/chrome/webdriver/chromium.js +56 -46
  19. package/lib/chrome/webdriver/setupChromiumOptions.js +32 -27
  20. package/lib/connectivity/humble.js +13 -14
  21. package/lib/connectivity/index.js +74 -77
  22. package/lib/connectivity/trafficShapeParser.js +31 -35
  23. package/lib/core/engine/collector.js +22 -22
  24. package/lib/core/engine/command/addText.js +24 -27
  25. package/lib/core/engine/command/android.js +7 -11
  26. package/lib/core/engine/command/cache.js +3 -4
  27. package/lib/core/engine/command/chromeDevToolsProtocol.js +20 -20
  28. package/lib/core/engine/command/click.js +48 -49
  29. package/lib/core/engine/command/debug.js +3 -4
  30. package/lib/core/engine/command/javaScript.js +18 -19
  31. package/lib/core/engine/command/measure.js +31 -37
  32. package/lib/core/engine/command/meta.js +1 -4
  33. package/lib/core/engine/command/mouse/clickAndHold.js +36 -39
  34. package/lib/core/engine/command/mouse/contextClick.js +17 -18
  35. package/lib/core/engine/command/mouse/doubleClick.js +17 -19
  36. package/lib/core/engine/command/mouse/index.js +5 -9
  37. package/lib/core/engine/command/mouse/mouseMove.js +19 -23
  38. package/lib/core/engine/command/mouse/singleClick.js +15 -19
  39. package/lib/core/engine/command/navigation.js +12 -14
  40. package/lib/core/engine/command/screenshot.js +1 -4
  41. package/lib/core/engine/command/scroll.js +4 -7
  42. package/lib/core/engine/command/select.js +26 -26
  43. package/lib/core/engine/command/set.js +25 -23
  44. package/lib/core/engine/command/stopWatch.js +5 -8
  45. package/lib/core/engine/command/switch.js +18 -20
  46. package/lib/core/engine/command/util/lcpHighlightScript.js +1 -2
  47. package/lib/core/engine/command/util/lsHighlightScript.js +1 -2
  48. package/lib/core/engine/command/wait.js +18 -18
  49. package/lib/core/engine/index.js +81 -71
  50. package/lib/core/engine/iteration.js +83 -79
  51. package/lib/core/engine/run.js +5 -9
  52. package/lib/core/pageCompleteChecks/defaultPageCompleteCheck.js +1 -2
  53. package/lib/core/pageCompleteChecks/pageCompleteCheckByInactivity.js +1 -3
  54. package/lib/core/pageCompleteChecks/spaInactivity.js +1 -3
  55. package/lib/core/seleniumRunner.js +92 -100
  56. package/lib/core/webdriver/index.js +24 -21
  57. package/lib/edge/webdriver/builder.js +21 -26
  58. package/lib/extensionserver/httpServer.js +17 -21
  59. package/lib/extensionserver/index.js +8 -12
  60. package/lib/extensionserver/setup.js +12 -12
  61. package/lib/firefox/geckoProfiler.js +27 -21
  62. package/lib/firefox/getHAR.js +7 -8
  63. package/lib/firefox/memoryReport.js +9 -11
  64. package/lib/firefox/perfStats.js +5 -7
  65. package/lib/firefox/settings/disableSafeBrowsingPreferences.js +1 -3
  66. package/lib/firefox/settings/disableTrackingProtectionPreferences.js +1 -3
  67. package/lib/firefox/settings/firefoxPreferences.js +2 -4
  68. package/lib/firefox/settings/geckoProfilerDefaults.js +5 -9
  69. package/lib/firefox/webdriver/builder.js +66 -63
  70. package/lib/firefox/webdriver/firefox.js +43 -48
  71. package/lib/safari/webdriver/builder.js +4 -5
  72. package/lib/safari/webdriver/safari.js +4 -8
  73. package/lib/screenshot/defaults.js +1 -3
  74. package/lib/screenshot/index.js +24 -21
  75. package/lib/support/browserScript.js +65 -56
  76. package/lib/support/cli.js +120 -87
  77. package/lib/support/dns.js +6 -7
  78. package/lib/support/engineUtils.js +85 -38
  79. package/lib/support/errors.js +4 -13
  80. package/lib/support/fileUtil.js +81 -68
  81. package/lib/support/filters.js +15 -20
  82. package/lib/support/getViewPort.js +6 -7
  83. package/lib/support/har/index.js +208 -216
  84. package/lib/support/images/index.js +54 -26
  85. package/lib/support/logging.js +20 -17
  86. package/lib/support/pathToFolder.js +18 -23
  87. package/lib/support/preURL.js +5 -6
  88. package/lib/support/processes.js +4 -6
  89. package/lib/support/setResourceTimingBufferSize.js +2 -4
  90. package/lib/support/statistics.js +58 -56
  91. package/lib/support/stop.js +7 -8
  92. package/lib/support/storageManager.js +44 -44
  93. package/lib/support/tcpdump.js +22 -16
  94. package/lib/support/userTiming.js +7 -13
  95. package/lib/support/util.js +204 -224
  96. package/lib/support/xvfb.js +11 -13
  97. package/lib/video/defaults.js +6 -10
  98. package/lib/video/postprocessing/finetune/addTextToVideo.js +15 -15
  99. package/lib/video/postprocessing/finetune/convertFps.js +14 -8
  100. package/lib/video/postprocessing/finetune/getFont.js +7 -9
  101. package/lib/video/postprocessing/finetune/getTimingMetrics.js +19 -18
  102. package/lib/video/postprocessing/finetune/index.js +40 -36
  103. package/lib/video/postprocessing/finetune/removeOrange.js +10 -11
  104. package/lib/video/postprocessing/visualmetrics/extraMetrics.js +17 -13
  105. package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +12 -13
  106. package/lib/video/postprocessing/visualmetrics/visualMetrics.js +117 -128
  107. package/lib/video/screenRecording/android/recorder.js +12 -17
  108. package/lib/video/screenRecording/desktop/convert.js +13 -11
  109. package/lib/video/screenRecording/desktop/desktopRecorder.js +29 -24
  110. package/lib/video/screenRecording/desktop/ffmpegRecorder.js +60 -63
  111. package/lib/video/screenRecording/desktop/osx/getSPDisplaysDataType.js +4 -6
  112. package/lib/video/screenRecording/desktop/osx/getScreen.js +9 -10
  113. package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +54 -54
  114. package/lib/video/screenRecording/ios/convertToMp4.js +10 -11
  115. package/lib/video/screenRecording/ios/iosRecorder.js +23 -21
  116. package/lib/video/screenRecording/iosSimulator/convertToMp4.js +10 -11
  117. package/lib/video/screenRecording/iosSimulator/recorder.js +10 -9
  118. package/lib/video/screenRecording/recorder.js +8 -9
  119. package/lib/video/screenRecording/setOrangeBackground.js +5 -6
  120. package/lib/video/video.js +28 -34
  121. package/package.json +19 -17
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Browsertime changelog (we do [semantic versioning](https://semver.org))
2
2
 
3
+ ## 17.0.0 - UNRELEASED
4
+
5
+ ### Breaking changes
6
+ * We moved the project to be a [pure ESM package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) [#1859](https://github.com/sitespeedio/browsertime/pull/1859). That helps us keep up to date with dependencies that already did the move.
7
+
8
+ If you are a command line user, everything will work as before. If you import Browsertime in NodeJS
9
+ we changed how you do your import.
10
+
11
+ If you use ES modules you can import Browsertime like this:
12
+ ```JavaScript
13
+ import { BrowsertimeEngine } from 'browsertime';
14
+ const engine = new BrowsertimEngine(options);
15
+ ```
16
+
17
+ If you are still on CommonJS:
18
+ ```JavaScript
19
+ const { BrowsertimeEngine } = await import ('browsertime');
20
+ const engine = new BrowsertimEngine(options);
21
+ ```
22
+
23
+ Read [Sindre Sorhus Pure ESM package guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) on how you can move your project.
24
+
25
+ * We moved to use a new [Visual Metrics script](https://github.com/sitespeedio/browsertime/blob/main/browsertime/visualmetrics-portable.py) as default contributed by [Gregory Mierzwinski](https://github.com/gmierz) that do _not_ use ImageMagick. Mozilla has used this script for many months and we have internally used it in our test infrastructure since it was first released.
26
+
27
+ If you run Browsertime direct using NodeJs (and not using Docker) you need to install two new Python dependencies OpenCV-Python Numpy.
28
+
29
+ ```
30
+ python -m pip install --user OpenCV-Python Numpy
31
+ ```
32
+
33
+ This is pretty cool because it makes dependencies easier to install on all platforms + the script has also been cleaned up so its easier for us to maintain.
34
+
35
+ ### Added
36
+ * Chrome and Chromedriver 106 [#1853](https://github.com/sitespeedio/browsertime/pull/1853).
37
+ * Selenium 4.5 [#1852](https://github.com/sitespeedio/browsertime/pull/1852).
38
+ * Updated dependencies: edgedriver, execa, days, find-up, get-ports, jimp, yargs [#1860](https://github.com/sitespeedio/browsertime/pull/1860)
39
+ * Updated to Chrome 107 in the Docker container.
40
+ * Updated to NodeJS 18 in the Docker container.
41
+
42
+ ### Fixed
43
+ * Pause the gecko profiler before starting to collect the profile data, thank you [Nazım Can Altınova](https://github.com/canova) for PR [#1856](https://github.com/sitespeedio/browsertime/pull/1856).
44
+
45
+ * All Android configurations has been moved to an Android group. That makes it easier when you run --help and can see all Android configuration grouped together. For example `--androidBatteryTemperature` is now `--android.batteryTemperatureLimit`. Old names will still work. [#1865](https://github.com/sitespeedio/browsertime/pull/1865)
46
+
3
47
  ## 16.17.0 - 2022-09-27
4
48
  ### Added
5
49
  * Add ability to ignore shutdown failures on android, thank you [Gregory Mierzwinski](https://github.com/gmierz) for PR [#1850](https://github.com/sitespeedio/browsertime/pull/1850).
@@ -1,29 +1,31 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const Engine = require('../').Engine;
5
- const browserScripts = require('../lib/support/browserScript');
6
- const logging = require('../').logging;
7
- const cli = require('../lib/support/cli');
8
- const StorageManager = require('../lib/support/storageManager');
9
- const merge = require('lodash.merge');
10
- const get = require('lodash.get');
11
- const set = require('lodash.set');
12
- const fs = require('fs');
13
- const path = require('path');
14
- const log = require('intel').getLogger('browsertime');
15
- const engineUtils = require('../lib/support/engineUtils');
2
+ import merge from 'lodash.merge';
3
+ import get from 'lodash.get';
4
+ import set from 'lodash.set';
5
+ import intel from 'intel';
6
+ import { existsSync, mkdirSync } from 'node:fs';
7
+ import { resolve, relative } from 'node:path';
8
+ import Engine from '../lib/core/engine/index.js';
9
+ import {
10
+ findAndParseScripts,
11
+ allScriptCategories,
12
+ getScriptsForCategories
13
+ } from '../lib/support/browserScript.js';
14
+ import logging from '../lib/support/logging.js';
15
+ import { parseCommandLine } from '../lib/support/cli.js';
16
+ import StorageManager from '../lib/support/storageManager.js';
17
+ import { loadScript } from '../lib/support/engineUtils.js';
18
+ import { isAndroidConfigured } from '../lib/android/index.js';
19
+
20
+ const log = intel.getLogger('browsertime');
16
21
  const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
17
- const delay = ms => new Promise(res => setTimeout(res, ms));
22
+ const delay = ms => new Promise(response => setTimeout(response, ms));
18
23
 
19
24
  async function parseUserScripts(scripts) {
20
25
  if (!Array.isArray(scripts)) scripts = [scripts];
21
26
  const results = {};
22
27
  for (const script of scripts) {
23
- const code = await browserScripts.findAndParseScripts(
24
- path.resolve(script),
25
- 'custom'
26
- );
28
+ const code = await findAndParseScripts(resolve(script), 'custom');
27
29
  merge(results, code);
28
30
  }
29
31
  return results;
@@ -34,7 +36,7 @@ async function preWarmServer(urls, options) {
34
36
  browser: options.browser,
35
37
  iterations: 1,
36
38
  xvfb: options.xvfb,
37
- android: options.android,
39
+ android: isAndroidConfigured(options),
38
40
  docker: options.docker,
39
41
  headless: options.headless
40
42
  };
@@ -44,7 +46,7 @@ async function preWarmServer(urls, options) {
44
46
  const safariDeviceName = get(options, 'safari.deviceName');
45
47
  const safariDeviceUDID = get(options, 'safari.deviceUDID ');
46
48
 
47
- if (options.android && options.browser === 'chrome') {
49
+ if (isAndroidConfigured(options) && options.browser === 'chrome') {
48
50
  set(preWarmOptions, 'chrome.android.package', 'com.android.chrome');
49
51
  }
50
52
  if (chromeDevice) {
@@ -79,17 +81,15 @@ async function run(urls, options) {
79
81
  try {
80
82
  if (!options.resultDir) {
81
83
  let dir = 'browsertime-results';
82
- if (!fs.existsSync(dir)) {
83
- fs.mkdirSync(dir);
84
+ if (!existsSync(dir)) {
85
+ mkdirSync(dir);
84
86
  }
85
87
  }
86
88
 
87
89
  let engine = new Engine(options);
88
90
 
89
- const scriptCategories = await browserScripts.allScriptCategories;
90
- let scriptsByCategory = await browserScripts.getScriptsForCategories(
91
- scriptCategories
92
- );
91
+ const scriptCategories = await allScriptCategories();
92
+ let scriptsByCategory = await getScriptsForCategories(scriptCategories);
93
93
 
94
94
  if (options.script) {
95
95
  const userScripts = await parseUserScripts(options.script);
@@ -107,12 +107,12 @@ async function run(urls, options) {
107
107
  // TODO setup by name
108
108
  let firstUrl = urls[0];
109
109
  // if the url is an array, it's of the form [filename, function]
110
- if (firstUrl instanceof Array) {
110
+ if (Array.isArray(firstUrl)) {
111
111
  firstUrl = firstUrl[0];
112
112
  }
113
113
  const storageManager = new StorageManager(firstUrl, options);
114
- const harName = options.har ? options.har : 'browsertime';
115
- const jsonName = options.output ? options.output : 'browsertime';
114
+ const harName = options.har ?? 'browsertime';
115
+ const jsonName = options.output ?? 'browsertime';
116
116
 
117
117
  saveOperations.push(storageManager.writeJson(jsonName + '.json', result));
118
118
 
@@ -124,7 +124,7 @@ async function run(urls, options) {
124
124
  }
125
125
  await Promise.all(saveOperations);
126
126
 
127
- const resultDir = path.relative(process.cwd(), storageManager.directory);
127
+ const resultDirectory = relative(process.cwd(), storageManager.directory);
128
128
 
129
129
  // check for errors
130
130
  for (let eachResult of result) {
@@ -134,26 +134,26 @@ async function run(urls, options) {
134
134
  }
135
135
  }
136
136
  }
137
- log.info(`Wrote data to ${resultDir}`);
137
+ log.info(`Wrote data to ${resultDirectory}`);
138
138
  } finally {
139
139
  log.debug('Stopping Browsertime');
140
140
  try {
141
141
  await engine.stop();
142
142
  log.debug('Stopped Browsertime');
143
- } catch (e) {
144
- log.error('Error stopping Browsertime!', e);
143
+ } catch (error) {
144
+ log.error('Error stopping Browsertime!', error);
145
145
  process.exitCode = 1;
146
146
  }
147
147
  }
148
- } catch (e) {
149
- log.error('Error running browsertime', e);
148
+ } catch (error) {
149
+ log.error('Error running browsertime', error);
150
150
  process.exitCode = 1;
151
151
  } finally {
152
152
  process.exit();
153
153
  }
154
154
  }
155
155
 
156
- let cliResult = cli.parseCommandLine();
156
+ let cliResult = parseCommandLine();
157
157
 
158
158
  /*
159
159
  Each url can be:
@@ -166,15 +166,15 @@ let cliResult = cli.parseCommandLine();
166
166
  */
167
167
  const tests = [];
168
168
 
169
- cliResult.urls.forEach(function convert(url) {
169
+ for (const url of cliResult.urls) {
170
170
  // for each url, we try to load it as a script, that may contain
171
171
  // export a single function or an object containing setUp/test/tearDown functions.
172
- let testScript = engineUtils.loadScript(url);
172
+ let testScript = await loadScript(url);
173
173
 
174
174
  // if the value is an url or a not a single function, we can return the original value
175
175
  if (typeof testScript == 'string' || testScript instanceof AsyncFunction) {
176
176
  tests.push(url);
177
- return;
177
+ continue;
178
178
  }
179
179
 
180
180
  if (testScript.setUp) {
@@ -191,8 +191,8 @@ cliResult.urls.forEach(function convert(url) {
191
191
  }
192
192
  // here, url is the filename containing the script, and test the callable.
193
193
  tests.push([url, testScript.test]);
194
- });
194
+ }
195
195
 
196
- logging.configure(cliResult.options);
196
+ logging(cliResult.options);
197
197
 
198
- run(tests, cliResult.options);
198
+ await run(tests, cliResult.options);
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
+ import merge from 'lodash.merge';
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
2
5
 
3
- 'use strict';
4
-
5
- const yargs = require('yargs');
6
- const browsertime = require('../');
7
- const merge = require('lodash.merge');
6
+ import Engine from '../lib/core/engine/index.js';
7
+ import logging from '../lib/support/logging.js';
8
8
 
9
9
  async function runBrowsertime() {
10
- let parsed = yargs
10
+ let yargsInstance = yargs(hideBin(process.argv));
11
+ let parsed = yargsInstance
11
12
  .env('BROWSERTIME')
12
13
  .require(1, 'url')
13
14
  .option('browser', {
@@ -45,9 +46,9 @@ async function runBrowsertime() {
45
46
  };
46
47
 
47
48
  const btOptions = merge({}, parsed.argv, defaultConfig);
48
- browsertime.logging.configure(parsed.argv);
49
+ logging(parsed.argv);
49
50
 
50
- const engine = new browsertime.Engine(btOptions);
51
+ const engine = new Engine(btOptions);
51
52
  try {
52
53
  await engine.start();
53
54
  const result = await engine.runMultiple(parsed.argv._);
@@ -62,4 +63,4 @@ async function runBrowsertime() {
62
63
  }
63
64
  }
64
65
 
65
- runBrowsertime();
66
+ await runBrowsertime();
@@ -1,5 +1,5 @@
1
1
  (function() {
2
- 'use strict';
2
+
3
3
  const description = document.querySelector('meta[name="generator"]');
4
4
  if (description) {
5
5
  return description.getAttribute('content');
package/index.js CHANGED
@@ -1,15 +1,16 @@
1
- 'use strict';
1
+ import {
2
+ defaultScriptCategories,
3
+ allScriptCategories,
4
+ getScriptsForCategories,
5
+ findAndParseScripts
6
+ } from './lib/support/browserScript.js';
2
7
 
3
- const Engine = require('./lib/core/engine/'),
4
- SeleniumRunner = require('./lib/core/seleniumRunner'),
5
- errors = require('./lib/support/errors'),
6
- browserScripts = require('./lib/support/browserScript'),
7
- logging = require('./lib/support/logging');
8
-
9
- module.exports = {
10
- Engine,
11
- SeleniumRunner,
12
- errors,
13
- logging,
14
- browserScripts
8
+ export const browserScripts = {
9
+ defaultScriptCategories,
10
+ allScriptCategories,
11
+ getScriptsForCategories,
12
+ findAndParseScripts
15
13
  };
14
+
15
+ export { default as BrowsertimeEngine } from './lib/core/engine/index.js';
16
+ export { default as configureLogging } from './lib/support/logging.js';
@@ -1,15 +1,14 @@
1
- 'use strict';
2
-
3
- const execa = require('execa');
4
- const log = require('intel').getLogger('browsertime.gnirehtet');
5
- const delay = ms => new Promise(res => setTimeout(res, ms));
1
+ import { execa } from 'execa';
2
+ import intel from 'intel';
3
+ const log = intel.getLogger('browsertime.gnirehtet');
4
+ const delay = ms => new Promise(response => setTimeout(response, ms));
6
5
 
7
6
  class Gnirehtet {
8
7
  constructor(options) {
9
8
  this.options = options;
10
9
  }
11
10
  async start() {
12
- const scriptArgs = ['run'];
11
+ const scriptArguments = ['run'];
13
12
  const options = this.options;
14
13
 
15
14
  if (
@@ -17,17 +16,17 @@ class Gnirehtet {
17
16
  options.chrome.android &&
18
17
  options.chrome.android.deviceSerial
19
18
  ) {
20
- scriptArgs.push(options.chrome.android.deviceSerial);
19
+ scriptArguments.push(options.chrome.android.deviceSerial);
21
20
  } else if (
22
21
  options.firefox &&
23
22
  options.firefox.android &&
24
23
  options.firefox.android.deviceSerial
25
24
  ) {
26
- scriptArgs.push(options.firefox.android.deviceSerial);
25
+ scriptArguments.push(options.firefox.android.deviceSerial);
27
26
  }
28
27
 
29
28
  log.info('Starting gnirehtet');
30
- const extraArgs =
29
+ const extraArguments =
31
30
  options.verbose >= 1
32
31
  ? {
33
32
  stdio: 'inherit',
@@ -35,29 +34,29 @@ class Gnirehtet {
35
34
  }
36
35
  : { stdio: 'ignore' };
37
36
 
38
- this.gnirehtet = execa('gnirehtet', scriptArgs, extraArgs);
37
+ this.gnirehtet = execa('gnirehtet', scriptArguments, extraArguments);
39
38
  // Wait so Gnirehtet can start
40
39
  return delay(4000);
41
40
  }
42
41
  async stop() {
43
42
  const options = this.options;
44
- const scriptArgs = ['stop'];
43
+ const scriptArguments = ['stop'];
45
44
  if (
46
45
  options.chrome &&
47
46
  options.chrome.android &&
48
47
  options.chrome.android.deviceSerial
49
48
  ) {
50
- scriptArgs.push(this.options.chrome.android.deviceSerial);
49
+ scriptArguments.push(this.options.chrome.android.deviceSerial);
51
50
  } else if (
52
51
  options.firefox &&
53
52
  options.firefox.android &&
54
53
  options.firefox.android.deviceSerial
55
54
  ) {
56
- scriptArgs.push(this.options.firefox.android.deviceSerial);
55
+ scriptArguments.push(this.options.firefox.android.deviceSerial);
57
56
  }
58
57
 
59
58
  // Try to stop the client nicely
60
- await execa('gnirehtet', scriptArgs);
59
+ await execa('gnirehtet', scriptArguments);
61
60
  await delay(2000);
62
61
  // This should stop both desktop and client.
63
62
  await this.gnirehtet.kill('SIGINT', {
@@ -66,4 +65,4 @@ class Gnirehtet {
66
65
  return delay(2000);
67
66
  }
68
67
  }
69
- module.exports = Gnirehtet;
68
+ export default Gnirehtet;