browsertime 22.5.2 → 22.5.4
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.
- package/CHANGELOG.md +11 -0
- package/bin/browsertime.js +6 -3
- package/lib/android/index.js +3 -3
- package/lib/chrome/networkManager.js +1 -1
- package/lib/chrome/webdriver/chromium.js +5 -5
- package/lib/core/engine/collector.js +2 -2
- package/lib/core/engine/command/measure.js +4 -3
- package/lib/core/engine/index.js +2 -2
- package/lib/firefox/geckoProfiler.js +12 -5
- package/lib/firefox/networkManager.js +1 -1
- package/lib/firefox/webdriver/firefox.js +3 -3
- package/lib/screenshot/index.js +4 -4
- package/lib/support/engineUtils.js +8 -5
- package/lib/support/fileUtil.js +3 -3
- package/lib/support/filters.js +2 -2
- package/lib/support/images/index.js +4 -4
- package/lib/support/storageManager.js +8 -8
- package/lib/support/tcpdump.js +4 -4
- package/lib/video/postprocessing/finetune/index.js +6 -6
- package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +2 -2
- package/lib/video/postprocessing/visualmetrics/visualMetrics.js +6 -4
- package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +10 -8
- package/lib/video/screenRecording/ios/iosRecorder.js +4 -5
- package/lib/video/screenRecording/iosSimulator/recorder.js +2 -2
- package/lib/video/video.js +11 -8
- package/package.json +21 -16
- package/types/android/index.d.ts +1 -4
- package/types/android/index.d.ts.map +1 -1
- package/types/core/engine/command/addText.d.ts.map +1 -1
- package/types/core/engine/command/android.d.ts.map +1 -1
- package/types/core/engine/command/bidi.d.ts.map +1 -1
- package/types/core/engine/command/cache.d.ts.map +1 -1
- package/types/core/engine/command/chromeDevToolsProtocol.d.ts.map +1 -1
- package/types/core/engine/command/chromeTrace.d.ts.map +1 -1
- package/types/core/engine/command/click.d.ts.map +1 -1
- package/types/core/engine/command/debug.d.ts.map +1 -1
- package/types/core/engine/command/element.d.ts.map +1 -1
- package/types/core/engine/command/geckoProfiler.d.ts.map +1 -1
- package/types/core/engine/command/javaScript.d.ts.map +1 -1
- package/types/core/engine/command/measure.d.ts.map +1 -1
- package/types/core/engine/command/mouse/clickAndHold.d.ts.map +1 -1
- package/types/core/engine/command/mouse/contextClick.d.ts.map +1 -1
- package/types/core/engine/command/mouse/doubleClick.d.ts.map +1 -1
- package/types/core/engine/command/mouse/mouseMove.d.ts.map +1 -1
- package/types/core/engine/command/mouse/singleClick.d.ts.map +1 -1
- package/types/core/engine/command/navigation.d.ts.map +1 -1
- package/types/core/engine/command/screenshot.d.ts.map +1 -1
- package/types/core/engine/command/scroll.d.ts.map +1 -1
- package/types/core/engine/command/select.d.ts.map +1 -1
- package/types/core/engine/command/set.d.ts.map +1 -1
- package/types/core/engine/command/wait.d.ts.map +1 -1
- package/types/core/engine/context.d.ts +3 -3
- package/types/core/engine/context.d.ts.map +1 -1
- package/types/firefox/geckoProfiler.d.ts.map +1 -1
- package/types/support/engineUtils.d.ts.map +1 -1
- package/types/support/storageManager.d.ts.map +1 -1
- package/types/support/tcpdump.d.ts +4 -2
- package/types/support/tcpdump.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/addTextToVideo.d.ts +1 -1
- package/types/video/postprocessing/finetune/addTextToVideo.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/convertFps.d.ts +1 -1
- package/types/video/postprocessing/finetune/convertFps.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/removeOrange.d.ts +1 -1
- package/types/video/postprocessing/finetune/removeOrange.d.ts.map +1 -1
- package/types/video/postprocessing/visualmetrics/visualMetrics.d.ts +1 -1
- package/types/video/postprocessing/visualmetrics/visualMetrics.d.ts.map +1 -1
- package/types/video/screenRecording/desktop/convert.d.ts +1 -1
- package/types/video/screenRecording/desktop/convert.d.ts.map +1 -1
- package/types/video/screenRecording/desktop/desktopRecorder.d.ts +2 -2
- package/types/video/screenRecording/desktop/ffmpegRecorder.d.ts +1 -1
- package/types/video/screenRecording/firefox/firefoxWindowRecorder.d.ts.map +1 -1
- package/types/video/screenRecording/ios/convertToMp4.d.ts +1 -1
- package/types/video/screenRecording/ios/convertToMp4.d.ts.map +1 -1
- package/types/video/screenRecording/ios/iosRecorder.d.ts +6 -2
- package/types/video/screenRecording/ios/iosRecorder.d.ts.map +1 -1
- package/types/video/screenRecording/iosSimulator/convertToMp4.d.ts +1 -1
- package/types/video/screenRecording/iosSimulator/convertToMp4.d.ts.map +1 -1
- package/types/video/screenRecording/iosSimulator/recorder.d.ts +6 -2
- package/types/video/screenRecording/iosSimulator/recorder.d.ts.map +1 -1
- package/types/video/video.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Browsertime changelog (we do [semantic versioning](https://semver.org))
|
|
2
2
|
|
|
3
|
+
## 22.5.4 - 2024-07-06
|
|
4
|
+
### Fixed
|
|
5
|
+
* Update to Chrome-HAR 0.13.3 [#2148](https://github.com/sitespeedio/browsertime/pull/2148).
|
|
6
|
+
* Update Chrome remore interface [#2149](https://github.com/sitespeedio/browsertime/pull/2149).
|
|
7
|
+
* Update execa, dayjs and get-port [#2153](https://github.com/sitespeedio/browsertime/pull/2153).
|
|
8
|
+
* Update developer dependencies [#2154](https://github.com/sitespeedio/browsertime/pull/2154), [#2152](https://github.com/sitespeedio/browsertime/pull/2152), [#2151](https://github.com/sitespeedio/browsertime/pull/2151) and [#2150](https://github.com/sitespeedio/browsertime/pull/2150).
|
|
9
|
+
|
|
10
|
+
## 22.5.3 - 2024-06-25
|
|
11
|
+
### Fixed
|
|
12
|
+
* Another fix to make IntelliSense/Code completion work again [#2147](https://github.com/sitespeedio/browsertime/pull/2147).
|
|
13
|
+
|
|
3
14
|
## 22.5.2 - 2024-06-24
|
|
4
15
|
### Fixed
|
|
5
16
|
* Updated Selenium dependencies [#2146](https://github.com/sitespeedio/browsertime/pull/2146).
|
package/bin/browsertime.js
CHANGED
|
@@ -4,7 +4,7 @@ import get from 'lodash.get';
|
|
|
4
4
|
import set from 'lodash.set';
|
|
5
5
|
import intel from 'intel';
|
|
6
6
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
7
|
-
import
|
|
7
|
+
import path from 'node:path';
|
|
8
8
|
import { Engine } from '../lib/core/engine/index.js';
|
|
9
9
|
import {
|
|
10
10
|
findAndParseScripts,
|
|
@@ -25,7 +25,7 @@ async function parseUserScripts(scripts) {
|
|
|
25
25
|
if (!Array.isArray(scripts)) scripts = [scripts];
|
|
26
26
|
const results = {};
|
|
27
27
|
for (const script of scripts) {
|
|
28
|
-
const code = await findAndParseScripts(resolve(script), 'custom');
|
|
28
|
+
const code = await findAndParseScripts(path.resolve(script), 'custom');
|
|
29
29
|
merge(results, code);
|
|
30
30
|
}
|
|
31
31
|
return results;
|
|
@@ -125,7 +125,10 @@ async function run(urls, options) {
|
|
|
125
125
|
|
|
126
126
|
await Promise.all(saveOperations);
|
|
127
127
|
|
|
128
|
-
const resultDirectory = relative(
|
|
128
|
+
const resultDirectory = path.relative(
|
|
129
|
+
process.cwd(),
|
|
130
|
+
storageManager.directory
|
|
131
|
+
);
|
|
129
132
|
|
|
130
133
|
// check for errors
|
|
131
134
|
// If we have set the exit code in scripts, respect that
|
package/lib/android/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promisify } from 'node:util';
|
|
2
2
|
import { mkdir as _mkdir, createWriteStream } from 'node:fs';
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import { EOL as endOfLine } from 'node:os';
|
|
5
5
|
import { execa } from 'execa';
|
|
6
6
|
import intel from 'intel';
|
|
@@ -105,7 +105,7 @@ export class Android {
|
|
|
105
105
|
|
|
106
106
|
for (const file of files) {
|
|
107
107
|
const fullSourcePath = `${sourcePath}/${file.name}`;
|
|
108
|
-
const fullDestinationPath = join(destinationPath, file.name);
|
|
108
|
+
const fullDestinationPath = path.join(destinationPath, file.name);
|
|
109
109
|
|
|
110
110
|
if (file.isFile()) {
|
|
111
111
|
await this._downloadFile(fullSourcePath, fullDestinationPath);
|
|
@@ -475,7 +475,7 @@ export class Android {
|
|
|
475
475
|
|
|
476
476
|
async getUsbPowerUsageProfile(index, url, result, options, storageManager) {
|
|
477
477
|
let profileData = await usbPowerProfiler.profileFromData();
|
|
478
|
-
let destinationFilename = join(
|
|
478
|
+
let destinationFilename = path.join(
|
|
479
479
|
await pathToFolder(url, options),
|
|
480
480
|
`powerProfile-${index}.json`
|
|
481
481
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promisify } from 'node:util';
|
|
2
2
|
import { unlink as _unlink, rm as _rm } from 'node:fs';
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import { logging } from 'selenium-webdriver';
|
|
5
5
|
import intel from 'intel';
|
|
6
6
|
import usbPowerProfiler from 'usb-power-profiling/usb-power-profiling.js';
|
|
@@ -261,12 +261,12 @@ export class Chromium {
|
|
|
261
261
|
|
|
262
262
|
if (this.chrome.collectNetLog && !this.chrome.android) {
|
|
263
263
|
await this.storageManager.createSubDataDir(
|
|
264
|
-
join(pathToFolder(result.url, this.options))
|
|
264
|
+
path.join(pathToFolder(result.url, this.options))
|
|
265
265
|
);
|
|
266
266
|
|
|
267
267
|
await this.storageManager.gzip(
|
|
268
268
|
`${this.baseDir}/chromeNetlog.json`,
|
|
269
|
-
join(
|
|
269
|
+
path.join(
|
|
270
270
|
this.baseDir,
|
|
271
271
|
pathToFolder(result.url, this.options),
|
|
272
272
|
`chromeNetlog-${index}.json.gz`
|
|
@@ -350,13 +350,13 @@ export class Chromium {
|
|
|
350
350
|
|
|
351
351
|
if (this.chrome.collectNetLog && this.chrome.android) {
|
|
352
352
|
// THIS needs to be unique per page
|
|
353
|
-
const filename = join(
|
|
353
|
+
const filename = path.join(
|
|
354
354
|
this.baseDir,
|
|
355
355
|
pathToFolder(result.url, this.options),
|
|
356
356
|
`chromeNetlog-${index}.json`
|
|
357
357
|
);
|
|
358
358
|
|
|
359
|
-
const gzFilename = join(
|
|
359
|
+
const gzFilename = path.join(
|
|
360
360
|
this.baseDir,
|
|
361
361
|
pathToFolder(result.url, this.options),
|
|
362
362
|
`chromeNetlog-${index}.json.gz`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import get from 'lodash.get';
|
|
4
4
|
import intel from 'intel';
|
|
@@ -482,7 +482,7 @@ export class Collector {
|
|
|
482
482
|
for (let filename of Object.keys(data.extraJson)) {
|
|
483
483
|
extraWork.push(
|
|
484
484
|
this.storageManager.writeJson(
|
|
485
|
-
join(pathToFolder(url, this.options), filename),
|
|
485
|
+
path.join(pathToFolder(url, this.options), filename),
|
|
486
486
|
data.extraJson[filename],
|
|
487
487
|
true
|
|
488
488
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import intel from 'intel';
|
|
3
3
|
import get from 'lodash.get';
|
|
4
4
|
import merge from 'lodash.merge';
|
|
@@ -429,13 +429,14 @@ export class Measure {
|
|
|
429
429
|
|
|
430
430
|
// We have the URL, create the data dir
|
|
431
431
|
await this.storageManager.createSubDataDir(
|
|
432
|
-
join(pathToFolder(url, this.options))
|
|
432
|
+
path.join(pathToFolder(url, this.options))
|
|
433
433
|
);
|
|
434
434
|
await this._stopVideo(url);
|
|
435
435
|
|
|
436
436
|
const alias = this.options.urlMetaData
|
|
437
437
|
? this.options.urlMetaData[url]
|
|
438
|
-
:
|
|
438
|
+
: // eslint-disable-next-line no-constant-binary-expression
|
|
439
|
+
undefined || this.result[this.numberOfMeasuredPages].alias;
|
|
439
440
|
const res = await this.engineDelegate.afterPageCompleteCheck(
|
|
440
441
|
this.browser,
|
|
441
442
|
this.index,
|
package/lib/core/engine/index.js
CHANGED
|
@@ -224,7 +224,7 @@ export class Engine {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
return
|
|
227
|
+
return this.myXVFB.start();
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
async runByScript(
|
|
@@ -518,6 +518,6 @@ export class Engine {
|
|
|
518
518
|
await this.gnirehtet.stop();
|
|
519
519
|
}
|
|
520
520
|
|
|
521
|
-
return
|
|
521
|
+
return this.myXVFB.stop();
|
|
522
522
|
}
|
|
523
523
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import get from 'lodash.get';
|
|
3
3
|
import intel from 'intel';
|
|
4
4
|
import { geckoProfilerDefaults } from './settings/geckoProfilerDefaults.js';
|
|
@@ -156,9 +156,12 @@ export class GeckoProfiler {
|
|
|
156
156
|
const options = this.options;
|
|
157
157
|
|
|
158
158
|
let profileDir = await storageManager.createSubDataDir(
|
|
159
|
-
join(pathToFolder(url, options))
|
|
159
|
+
path.join(pathToFolder(url, options))
|
|
160
|
+
);
|
|
161
|
+
let destinationFilename = path.join(
|
|
162
|
+
profileDir,
|
|
163
|
+
`geckoProfile-${index}.json`
|
|
160
164
|
);
|
|
161
|
-
let destinationFilename = join(profileDir, `geckoProfile-${index}.json`);
|
|
162
165
|
|
|
163
166
|
let deviceProfileFilename = destinationFilename;
|
|
164
167
|
if (isAndroidConfigured(options)) {
|
|
@@ -214,7 +217,7 @@ export class GeckoProfiler {
|
|
|
214
217
|
const profile = JSON.parse(
|
|
215
218
|
await storageManager.readData(
|
|
216
219
|
`geckoProfile-${index}.json`,
|
|
217
|
-
join(pathToFolder(url, options))
|
|
220
|
+
path.join(pathToFolder(url, options))
|
|
218
221
|
)
|
|
219
222
|
);
|
|
220
223
|
let power = 0;
|
|
@@ -237,7 +240,11 @@ export class GeckoProfiler {
|
|
|
237
240
|
? `geckoProfile-${index}-extra.json.gz`
|
|
238
241
|
: `geckoProfile-${index}.json.gz`;
|
|
239
242
|
await timeout(
|
|
240
|
-
storageManager.gzip(
|
|
243
|
+
storageManager.gzip(
|
|
244
|
+
destinationFilename,
|
|
245
|
+
path.join(profileDir, name),
|
|
246
|
+
true
|
|
247
|
+
),
|
|
241
248
|
300_000, // 5 minutes
|
|
242
249
|
'Could not gzip the profile.'
|
|
243
250
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { rename as _rename } from 'node:fs';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import intel from 'intel';
|
|
5
5
|
import get from 'lodash.get';
|
|
6
6
|
import usbPowerProfiler from 'usb-power-profiling/usb-power-profiling.js';
|
|
@@ -312,7 +312,7 @@ export class Firefox {
|
|
|
312
312
|
for (const file of files) {
|
|
313
313
|
await rename(
|
|
314
314
|
`${this.baseDir}/${file}`,
|
|
315
|
-
join(
|
|
315
|
+
path.join(
|
|
316
316
|
this.baseDir,
|
|
317
317
|
pathToFolder(result.url, this.options),
|
|
318
318
|
`${file}-${index}.txt`
|
|
@@ -358,7 +358,7 @@ export class Firefox {
|
|
|
358
358
|
geckoProfile.meta.visualMetrics = result.visualMetrics;
|
|
359
359
|
|
|
360
360
|
await this.storageManager.writeJson(
|
|
361
|
-
join(profileSubdir, `geckoProfile-${index}.json`),
|
|
361
|
+
path.join(profileSubdir, `geckoProfile-${index}.json`),
|
|
362
362
|
geckoProfile,
|
|
363
363
|
true
|
|
364
364
|
);
|
package/lib/screenshot/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import merge from 'lodash.merge';
|
|
3
3
|
import intel from 'intel';
|
|
4
4
|
import { screenshotDefaults } from './defaults.js';
|
|
@@ -36,7 +36,7 @@ export class ScreenshotManager {
|
|
|
36
36
|
data,
|
|
37
37
|
url,
|
|
38
38
|
this.storageManager,
|
|
39
|
-
join(SCREENSHOT_DIR, `${index}`),
|
|
39
|
+
path.join(SCREENSHOT_DIR, `${index}`),
|
|
40
40
|
this.options
|
|
41
41
|
);
|
|
42
42
|
this.savedScreenshots.push(
|
|
@@ -50,7 +50,7 @@ export class ScreenshotManager {
|
|
|
50
50
|
url,
|
|
51
51
|
this.storageManager,
|
|
52
52
|
this.config,
|
|
53
|
-
join(SCREENSHOT_DIR, `${index}`),
|
|
53
|
+
path.join(SCREENSHOT_DIR, `${index}`),
|
|
54
54
|
this.options
|
|
55
55
|
);
|
|
56
56
|
this.savedScreenshots.push(
|
|
@@ -63,7 +63,7 @@ export class ScreenshotManager {
|
|
|
63
63
|
url,
|
|
64
64
|
this.storageManager,
|
|
65
65
|
this.config,
|
|
66
|
-
join(SCREENSHOT_DIR, `${index}`),
|
|
66
|
+
path.join(SCREENSHOT_DIR, `${index}`),
|
|
67
67
|
this.options
|
|
68
68
|
);
|
|
69
69
|
this.savedScreenshots.push(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import {
|
|
4
4
|
writeFile as _writeFile,
|
|
@@ -32,7 +32,7 @@ async function loadFile(script, options, throwError) {
|
|
|
32
32
|
script.endsWith('.mjs') ||
|
|
33
33
|
script.endsWith('.cjs')
|
|
34
34
|
) {
|
|
35
|
-
let myFunction = await import(pathToFileURL(resolve(script)));
|
|
35
|
+
let myFunction = await import(pathToFileURL(path.resolve(script)));
|
|
36
36
|
return myFunction.default ?? myFunction;
|
|
37
37
|
} else {
|
|
38
38
|
// Hack a way! Try to add a package.json file in the same folder as the
|
|
@@ -43,7 +43,10 @@ async function loadFile(script, options, throwError) {
|
|
|
43
43
|
);
|
|
44
44
|
let createdPackageJson = false;
|
|
45
45
|
try {
|
|
46
|
-
const packageJson = join(
|
|
46
|
+
const packageJson = path.join(
|
|
47
|
+
path.dirname(path.resolve(script)),
|
|
48
|
+
'package.json'
|
|
49
|
+
);
|
|
47
50
|
try {
|
|
48
51
|
await writeFile(packageJson, '{}');
|
|
49
52
|
createdPackageJson = true;
|
|
@@ -53,7 +56,7 @@ async function loadFile(script, options, throwError) {
|
|
|
53
56
|
script
|
|
54
57
|
);
|
|
55
58
|
}
|
|
56
|
-
const myFunction = await import(resolve(script));
|
|
59
|
+
const myFunction = await import(path.resolve(script));
|
|
57
60
|
|
|
58
61
|
try {
|
|
59
62
|
if (createdPackageJson) {
|
|
@@ -89,7 +92,7 @@ export async function loadPrePostScripts(scripts, options) {
|
|
|
89
92
|
|
|
90
93
|
export async function loadPageCompleteScript(script) {
|
|
91
94
|
if (script && script.endsWith('js')) {
|
|
92
|
-
return readFile(resolve(script), 'utf8');
|
|
95
|
+
return readFile(path.resolve(script), 'utf8');
|
|
93
96
|
}
|
|
94
97
|
return script;
|
|
95
98
|
}
|
package/lib/support/fileUtil.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import {
|
|
4
4
|
readdir as _readdir,
|
|
@@ -50,7 +50,7 @@ export async function removeDirAndFiles(dirName) {
|
|
|
50
50
|
await Promise.all(
|
|
51
51
|
files.map(async file => {
|
|
52
52
|
try {
|
|
53
|
-
const p = join(dir, file);
|
|
53
|
+
const p = path.join(dir, file);
|
|
54
54
|
const stat = await lstat(p);
|
|
55
55
|
await (stat.isDirectory() ? removeDir(p) : unlink(p));
|
|
56
56
|
} catch (error) {
|
|
@@ -68,7 +68,7 @@ export async function removeDirAndFiles(dirName) {
|
|
|
68
68
|
export async function removeByType(dir, type) {
|
|
69
69
|
const fileNames = await readdir(dir);
|
|
70
70
|
const filePaths = fileNames
|
|
71
|
-
.map(fileName => join(dir, fileName))
|
|
71
|
+
.map(fileName => path.join(dir, fileName))
|
|
72
72
|
.filter(element => onlyFiles(element))
|
|
73
73
|
.filter(onlyWithExtension('.' + type));
|
|
74
74
|
|
package/lib/support/filters.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { promisify } from 'node:util';
|
|
2
2
|
import { stat as _stat } from 'node:fs';
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
const stat = promisify(_stat);
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Filters to use with Array.prototype.filter, e.g. ['/a/path', '/another/path'].filter(onlyFiles)
|
|
8
8
|
*/
|
|
9
9
|
export function onlyWithExtension(extension) {
|
|
10
|
-
return filepath => extname(filepath) === extension;
|
|
10
|
+
return filepath => path.extname(filepath) === extension;
|
|
11
11
|
}
|
|
12
12
|
export async function onlyFiles(filepath) {
|
|
13
13
|
const stats = await stat(filepath);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { pathToFolder } from '../pathToFolder.js';
|
|
3
3
|
|
|
4
4
|
export async function savePngWithoutResize(
|
|
@@ -12,7 +12,7 @@ export async function savePngWithoutResize(
|
|
|
12
12
|
return storageManager.writeData(
|
|
13
13
|
`${name}.png`,
|
|
14
14
|
data,
|
|
15
|
-
join(pathToFolder(url, options), dir)
|
|
15
|
+
path.join(pathToFolder(url, options), dir)
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
export async function savePng(
|
|
@@ -41,7 +41,7 @@ export async function savePng(
|
|
|
41
41
|
return storageManager.writeData(
|
|
42
42
|
`${name}.png`,
|
|
43
43
|
buffer,
|
|
44
|
-
join(pathToFolder(url, options), dir)
|
|
44
|
+
path.join(pathToFolder(url, options), dir)
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -70,7 +70,7 @@ export async function saveJpg(
|
|
|
70
70
|
return storageManager.writeData(
|
|
71
71
|
`${name}.jpg`,
|
|
72
72
|
buffer,
|
|
73
|
-
join(pathToFolder(url, options), dir)
|
|
73
|
+
path.join(pathToFolder(url, options), dir)
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { gunzip as _gunzip, gzip as _gzip, createGzip } from 'node:zlib';
|
|
4
4
|
import { parse } from 'node:url';
|
|
@@ -52,8 +52,8 @@ async function streamToString(stream) {
|
|
|
52
52
|
export class StorageManager {
|
|
53
53
|
constructor(url, { resultDir, prettyPrint = false } = {}) {
|
|
54
54
|
this.baseDir = resultDir
|
|
55
|
-
?
|
|
56
|
-
:
|
|
55
|
+
? path.resolve(resultDir)
|
|
56
|
+
: path.resolve(defaultDir, pathNameFromUrl(url), timestamp);
|
|
57
57
|
this.jsonIndentation = prettyPrint ? 2 : 0;
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -63,13 +63,13 @@ export class StorageManager {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
async createSubDataDir(...name) {
|
|
66
|
-
const dir = join(this.baseDir, ...name);
|
|
66
|
+
const dir = path.join(this.baseDir, ...name);
|
|
67
67
|
await mkdir(dir, { recursive: true });
|
|
68
68
|
return dir;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
async rm(filename) {
|
|
72
|
-
return unlink(join(this.baseDir, filename));
|
|
72
|
+
return unlink(path.join(this.baseDir, filename));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
async writeData(filename, data, subdir) {
|
|
@@ -77,7 +77,7 @@ export class StorageManager {
|
|
|
77
77
|
dirPath = await (subdir
|
|
78
78
|
? this.createSubDataDir(subdir)
|
|
79
79
|
: this.createDataDir());
|
|
80
|
-
const fullPath = join(dirPath, filename);
|
|
80
|
+
const fullPath = path.join(dirPath, filename);
|
|
81
81
|
return writeFile(fullPath, data).then(() => {
|
|
82
82
|
return fullPath;
|
|
83
83
|
});
|
|
@@ -96,8 +96,8 @@ export class StorageManager {
|
|
|
96
96
|
async readData(filename, subdir) {
|
|
97
97
|
let filepath;
|
|
98
98
|
filepath = subdir
|
|
99
|
-
? join(this.baseDir, subdir, filename)
|
|
100
|
-
: join(this.baseDir, filename);
|
|
99
|
+
? path.join(this.baseDir, subdir, filename)
|
|
100
|
+
: path.join(this.baseDir, filename);
|
|
101
101
|
|
|
102
102
|
if (filename.endsWith('.gz')) {
|
|
103
103
|
const readStream = createReadStream(filepath);
|
package/lib/support/tcpdump.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import { execa } from 'execa';
|
|
3
3
|
import { pathToFolder } from './pathToFolder.js';
|
|
4
4
|
import { rename } from './fileUtil.js';
|
|
@@ -9,7 +9,7 @@ export class TCPDump {
|
|
|
9
9
|
this.options = options;
|
|
10
10
|
}
|
|
11
11
|
async start(iteration) {
|
|
12
|
-
const captureFile = join(this.baseDir, iteration + '.pcap');
|
|
12
|
+
const captureFile = path.join(this.baseDir, iteration + '.pcap');
|
|
13
13
|
const parameters = [
|
|
14
14
|
'tcpdump',
|
|
15
15
|
'-i',
|
|
@@ -36,8 +36,8 @@ export class TCPDump {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async mv(url, iteration) {
|
|
39
|
-
const oldLocation = join(this.baseDir, iteration + '.pcap');
|
|
40
|
-
const newLocation = join(
|
|
39
|
+
const oldLocation = path.join(this.baseDir, iteration + '.pcap');
|
|
40
|
+
const newLocation = path.join(
|
|
41
41
|
this.baseDir,
|
|
42
42
|
pathToFolder(url, this.options),
|
|
43
43
|
iteration + '.pcap'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import {
|
|
3
3
|
rename as _rename,
|
|
4
4
|
copyFile as _copyFile,
|
|
@@ -26,10 +26,10 @@ export async function finetuneVideo(
|
|
|
26
26
|
options
|
|
27
27
|
) {
|
|
28
28
|
const newStart = videoMetrics.videoRecordingStart / 1000;
|
|
29
|
-
let temporaryFile = join(videoDir, 'tmp.mp4');
|
|
29
|
+
let temporaryFile = path.join(videoDir, 'tmp.mp4');
|
|
30
30
|
|
|
31
31
|
if (get(options, 'videoParams.keepOriginalVideo', false)) {
|
|
32
|
-
const originalFile = join(videoDir, index + '-original.mp4');
|
|
32
|
+
const originalFile = path.join(videoDir, index + '-original.mp4');
|
|
33
33
|
await copyFile(videoPath, originalFile);
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -59,19 +59,19 @@ export async function finetuneVideo(
|
|
|
59
59
|
isAndroidConfigured(options) &&
|
|
60
60
|
get(options, 'videoParams.convert', _convert)
|
|
61
61
|
) {
|
|
62
|
-
const temporaryFile2 = join(videoDir, 'tmp-60fps.mp4');
|
|
62
|
+
const temporaryFile2 = path.join(videoDir, 'tmp-60fps.mp4');
|
|
63
63
|
await convert(temporaryFile, temporaryFile2, 60);
|
|
64
64
|
await unlink(temporaryFile);
|
|
65
65
|
await rename(temporaryFile2, temporaryFile);
|
|
66
66
|
} else if (options.safari && options.safari.useSimulator) {
|
|
67
|
-
const temporaryFile2 = join(videoDir, 'tmp-60fps.mp4');
|
|
67
|
+
const temporaryFile2 = path.join(videoDir, 'tmp-60fps.mp4');
|
|
68
68
|
await convert(temporaryFile, temporaryFile2, 60);
|
|
69
69
|
await unlink(temporaryFile);
|
|
70
70
|
await rename(temporaryFile2, temporaryFile);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (options.videoParams.addTimer) {
|
|
74
|
-
const temporaryFile2 = join(videoDir, 'tmp2.mp4');
|
|
74
|
+
const temporaryFile2 = path.join(videoDir, 'tmp2.mp4');
|
|
75
75
|
await addTextToVideo(
|
|
76
76
|
temporaryFile,
|
|
77
77
|
temporaryFile2,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
import intel from 'intel';
|
|
3
3
|
import { run } from './visualMetrics.js';
|
|
4
4
|
import { extraMetrics } from './extraMetrics.js';
|
|
@@ -25,7 +25,7 @@ export async function getVideoMetrics(
|
|
|
25
25
|
true
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
|
-
const elementsFile = join(
|
|
28
|
+
const elementsFile = path.join(
|
|
29
29
|
storageManager.directory,
|
|
30
30
|
index + '-visualElements.json.gz'
|
|
31
31
|
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
2
|
import path from 'node:path';
|
|
4
3
|
import { execa } from 'execa';
|
|
5
4
|
import intel from 'intel';
|
|
@@ -8,7 +7,7 @@ import { readFile, removeFile, copyFile } from '../../../support/fileUtil.js';
|
|
|
8
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
8
|
const log = intel.getLogger('browsertime.video');
|
|
10
9
|
|
|
11
|
-
const SCRIPT_PATH = join(
|
|
10
|
+
const SCRIPT_PATH = path.join(
|
|
12
11
|
__dirname,
|
|
13
12
|
'..',
|
|
14
13
|
'..',
|
|
@@ -18,7 +17,7 @@ const SCRIPT_PATH = join(
|
|
|
18
17
|
'visualmetrics.py'
|
|
19
18
|
);
|
|
20
19
|
|
|
21
|
-
const PORTABLE_SCRIPT_PATH = join(
|
|
20
|
+
const PORTABLE_SCRIPT_PATH = path.join(
|
|
22
21
|
__dirname,
|
|
23
22
|
'..',
|
|
24
23
|
'..',
|
|
@@ -120,7 +119,10 @@ export async function run(
|
|
|
120
119
|
}
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
const visualMetricsLogFile = join(
|
|
122
|
+
const visualMetricsLogFile = path.join(
|
|
123
|
+
videoDir,
|
|
124
|
+
index + '.visualmetrics.log'
|
|
125
|
+
);
|
|
124
126
|
|
|
125
127
|
scriptArguments.push('--logfile', visualMetricsLogFile);
|
|
126
128
|
if (options.verbose >= 1) {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createWriteStream,
|
|
7
7
|
copyFileSync
|
|
8
8
|
} from 'node:fs';
|
|
9
|
-
import
|
|
9
|
+
import path from 'node:path';
|
|
10
10
|
import intel from 'intel';
|
|
11
11
|
import { execa } from 'execa';
|
|
12
12
|
import { removeDirAndFiles } from '../../../support/fileUtil.js';
|
|
@@ -41,7 +41,7 @@ function findRecordingDirectory(baseDir) {
|
|
|
41
41
|
|
|
42
42
|
for (const file of readdirSync(baseDir)) {
|
|
43
43
|
if (file.startsWith('windowrecording-')) {
|
|
44
|
-
let fullPath = join(baseDir, file);
|
|
44
|
+
let fullPath = path.join(baseDir, file);
|
|
45
45
|
let mtime = statSync(fullPath).mtime;
|
|
46
46
|
if (mtime > closest_mtime) {
|
|
47
47
|
closest_mtime = mtime;
|
|
@@ -79,17 +79,19 @@ function findTimeToFirstFrame(recordingDir) {
|
|
|
79
79
|
|
|
80
80
|
function writeFrameDurationsToFile(directoryName, imageFiles) {
|
|
81
81
|
return new Promise((resolve, reject) => {
|
|
82
|
-
const stream = createWriteStream(join(directoryName, 'durations.txt'));
|
|
82
|
+
const stream = createWriteStream(path.join(directoryName, 'durations.txt'));
|
|
83
83
|
stream.once('open', function () {
|
|
84
84
|
stream.write(
|
|
85
|
-
"file '" + join(directoryName, imageFiles[0].filename) + "'\n"
|
|
85
|
+
"file '" + path.join(directoryName, imageFiles[0].filename) + "'\n"
|
|
86
86
|
);
|
|
87
87
|
for (let index = 1; index < imageFiles.length; index++) {
|
|
88
88
|
let duration =
|
|
89
89
|
(imageFiles[index].offset - imageFiles[index - 1].offset) / 1000;
|
|
90
90
|
stream.write('duration ' + duration.toString() + '\n');
|
|
91
91
|
stream.write(
|
|
92
|
-
"file '" +
|
|
92
|
+
"file '" +
|
|
93
|
+
path.join(directoryName, imageFiles[index].filename) +
|
|
94
|
+
"'\n"
|
|
93
95
|
);
|
|
94
96
|
}
|
|
95
97
|
stream.end();
|
|
@@ -114,8 +116,8 @@ async function generateVideo(destination, recordingDirectoryName) {
|
|
|
114
116
|
let newFilename = 'frame' + frameno + '.png';
|
|
115
117
|
let offset = fields[2].split('.')[0];
|
|
116
118
|
copyFileSync(
|
|
117
|
-
join(recordingDirectoryName, file),
|
|
118
|
-
join(recordingDirectoryName, newFilename)
|
|
119
|
+
path.join(recordingDirectoryName, file),
|
|
120
|
+
path.join(recordingDirectoryName, newFilename)
|
|
119
121
|
);
|
|
120
122
|
imageFiles.push({ filename: newFilename, offset: offset });
|
|
121
123
|
}
|
|
@@ -133,7 +135,7 @@ async function generateVideo(destination, recordingDirectoryName) {
|
|
|
133
135
|
'-safe',
|
|
134
136
|
'0',
|
|
135
137
|
'-i',
|
|
136
|
-
join(recordingDirectoryName, 'durations.txt'),
|
|
138
|
+
path.join(recordingDirectoryName, 'durations.txt'),
|
|
137
139
|
'-vf',
|
|
138
140
|
'pad=ceil(iw/2)*2:ceil(ih/2)*2',
|
|
139
141
|
'-vsync',
|