cypress 15.0.0 → 15.2.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.
- package/bin/cypress +3 -1
- package/index.js +49 -24
- package/lib/VerboseRenderer.js +50 -47
- package/lib/cli.js +455 -351
- package/lib/cypress.js +93 -90
- package/lib/errors.js +181 -194
- package/lib/exec/info.js +85 -74
- package/lib/exec/open.js +77 -73
- package/lib/exec/run.js +144 -154
- package/lib/exec/shared.js +37 -44
- package/lib/exec/spawn.js +270 -232
- package/lib/exec/versions.js +57 -49
- package/lib/exec/xvfb.js +79 -81
- package/lib/fs.js +7 -3
- package/lib/logger.js +37 -32
- package/lib/tasks/cache.js +128 -113
- package/lib/tasks/download.js +247 -258
- package/lib/tasks/get-folder-size.js +33 -22
- package/lib/tasks/install.js +274 -312
- package/lib/tasks/state.js +132 -143
- package/lib/tasks/unzip.js +186 -188
- package/lib/tasks/verify.js +274 -261
- package/lib/util.js +357 -356
- package/package.json +7 -4
- package/react/package.json +1 -1
- package/react/react/package.json +1 -1
- package/types/cypress-automation.d.ts +18 -0
- package/types/cypress.d.ts +15 -2
- package/types/index.d.ts +1 -1
- package/vue/package.json +1 -1
- package/vue/vue/package.json +1 -1
package/lib/exec/versions.js
CHANGED
@@ -1,53 +1,61 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
const
|
7
|
-
const
|
8
|
-
const
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
8
|
+
const path_1 = __importDefault(require("path"));
|
9
|
+
const util_1 = __importDefault(require("../util"));
|
10
|
+
const state_1 = __importDefault(require("../tasks/state"));
|
11
|
+
const errors_1 = require("../errors");
|
12
|
+
const debug = (0, debug_1.default)('cypress:cli');
|
12
13
|
const getVersions = () => {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
return bluebird_1.default.try(() => {
|
15
|
+
if (util_1.default.getEnv('CYPRESS_RUN_BINARY')) {
|
16
|
+
let envBinaryPath = path_1.default.resolve(util_1.default.getEnv('CYPRESS_RUN_BINARY'));
|
17
|
+
return state_1.default.parseRealPlatformBinaryFolderAsync(envBinaryPath)
|
18
|
+
.then((envBinaryDir) => {
|
19
|
+
if (!envBinaryDir) {
|
20
|
+
return (0, errors_1.throwFormErrorText)(errors_1.errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))();
|
21
|
+
}
|
22
|
+
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
23
|
+
return envBinaryDir;
|
24
|
+
})
|
25
|
+
.catch({ code: 'ENOENT' }, (err) => {
|
26
|
+
return (0, errors_1.throwFormErrorText)(errors_1.errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message);
|
27
|
+
});
|
19
28
|
}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
29
|
+
return state_1.default.getBinaryDir();
|
30
|
+
})
|
31
|
+
.then(state_1.default.getBinaryPkgAsync)
|
32
|
+
.then((pkg) => {
|
33
|
+
const versions = {
|
34
|
+
binary: state_1.default.getBinaryPkgVersion(pkg),
|
35
|
+
electronVersion: state_1.default.getBinaryElectronVersion(pkg),
|
36
|
+
electronNodeVersion: state_1.default.getBinaryElectronNodeVersion(pkg),
|
37
|
+
};
|
38
|
+
debug('binary versions %o', versions);
|
39
|
+
return versions;
|
40
|
+
})
|
41
|
+
.then((binaryVersions) => {
|
42
|
+
const buildInfo = util_1.default.pkgBuildInfo();
|
43
|
+
let packageVersion = util_1.default.pkgVersion();
|
44
|
+
if (!buildInfo)
|
45
|
+
packageVersion += ' (development)';
|
46
|
+
else if (!buildInfo.stable)
|
47
|
+
packageVersion += ' (pre-release)';
|
48
|
+
const versions = {
|
49
|
+
package: packageVersion,
|
50
|
+
binary: binaryVersions.binary || 'not installed',
|
51
|
+
electronVersion: binaryVersions.electronVersion || 'not found',
|
52
|
+
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found',
|
53
|
+
};
|
54
|
+
debug('combined versions %o', versions);
|
55
|
+
return versions;
|
56
|
+
});
|
57
|
+
};
|
58
|
+
const versionsModule = {
|
59
|
+
getVersions,
|
50
60
|
};
|
51
|
-
|
52
|
-
getVersions
|
53
|
-
};
|
61
|
+
exports.default = versionsModule;
|
package/lib/exec/xvfb.js
CHANGED
@@ -1,72 +1,66 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
const
|
7
|
-
|
8
|
-
|
9
|
-
const
|
10
|
-
const
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
const
|
15
|
-
|
16
|
-
const debugXvfb = Debug('cypress:xvfb');
|
17
|
-
debug.Debug = debugXvfb.Debug = Debug;
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const os_1 = __importDefault(require("os"));
|
7
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
8
|
+
const xvfb_1 = __importDefault(require("@cypress/xvfb"));
|
9
|
+
const common_tags_1 = require("common-tags");
|
10
|
+
const debug_1 = __importDefault(require("debug"));
|
11
|
+
const errors_1 = require("../errors");
|
12
|
+
const util_1 = __importDefault(require("../util"));
|
13
|
+
const debug = (0, debug_1.default)('cypress:cli');
|
14
|
+
const debugXvfb = (0, debug_1.default)('cypress:xvfb');
|
15
|
+
debug.Debug = debugXvfb.Debug = debug_1.default;
|
18
16
|
const xvfbOptions = {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
}
|
29
|
-
}
|
17
|
+
displayNum: process.env.XVFB_DISPLAY_NUM,
|
18
|
+
timeout: 30000, // milliseconds
|
19
|
+
// need to explicitly define screen otherwise electron will crash
|
20
|
+
// https://github.com/cypress-io/cypress/issues/6184
|
21
|
+
xvfb_args: ['-screen', '0', '1280x1024x24'],
|
22
|
+
onStderrData(data) {
|
23
|
+
if (debugXvfb.enabled) {
|
24
|
+
debugXvfb(data.toString());
|
25
|
+
}
|
26
|
+
},
|
30
27
|
};
|
31
|
-
const xvfb =
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
if (process.env.DISPLAY) {
|
68
|
-
const issueUrl = util.getGitHubIssueUrl(4034);
|
69
|
-
const message = stripIndent`
|
28
|
+
const xvfb = bluebird_1.default.promisifyAll(new xvfb_1.default(xvfbOptions));
|
29
|
+
const xvfbModule = {
|
30
|
+
_debugXvfb: debugXvfb, // expose for testing
|
31
|
+
_xvfb: xvfb, // expose for testing
|
32
|
+
_xvfbOptions: xvfbOptions, // expose for testing
|
33
|
+
start() {
|
34
|
+
debug('Starting Xvfb');
|
35
|
+
return xvfb.startAsync()
|
36
|
+
.return(null)
|
37
|
+
.catch({ nonZeroExitCode: true }, (0, errors_1.throwFormErrorText)(errors_1.errors.nonZeroExitCodeXvfb))
|
38
|
+
.catch((err) => {
|
39
|
+
if (err.known) {
|
40
|
+
throw err;
|
41
|
+
}
|
42
|
+
return (0, errors_1.throwFormErrorText)(errors_1.errors.missingXvfb)(err);
|
43
|
+
});
|
44
|
+
},
|
45
|
+
stop() {
|
46
|
+
debug('Stopping Xvfb');
|
47
|
+
return xvfb.stopAsync()
|
48
|
+
.return(null)
|
49
|
+
.catch(() => {
|
50
|
+
// noop
|
51
|
+
});
|
52
|
+
},
|
53
|
+
isNeeded() {
|
54
|
+
if (process.env.ELECTRON_RUN_AS_NODE) {
|
55
|
+
debug('Environment variable ELECTRON_RUN_AS_NODE detected, xvfb is not needed');
|
56
|
+
return false; // xvfb required for electron processes only.
|
57
|
+
}
|
58
|
+
if (os_1.default.platform() !== 'linux') {
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
if (process.env.DISPLAY) {
|
62
|
+
const issueUrl = util_1.default.getGitHubIssueUrl(4034);
|
63
|
+
const message = (0, common_tags_1.stripIndent) `
|
70
64
|
DISPLAY environment variable is set to ${process.env.DISPLAY} on Linux
|
71
65
|
Assuming this DISPLAY points at working X11 server,
|
72
66
|
Cypress will not spawn own Xvfb
|
@@ -76,18 +70,22 @@ module.exports = {
|
|
76
70
|
Solution: Unset the DISPLAY variable and try again:
|
77
71
|
DISPLAY= npx cypress run ...
|
78
72
|
`;
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
}
|
73
|
+
debug(message);
|
74
|
+
return false;
|
75
|
+
}
|
76
|
+
debug('undefined DISPLAY environment variable');
|
77
|
+
debug('Cypress will spawn its own Xvfb');
|
78
|
+
return true;
|
79
|
+
},
|
80
|
+
// async method, resolved with Boolean
|
81
|
+
verify() {
|
82
|
+
return xvfb.startAsync()
|
83
|
+
.return(true)
|
84
|
+
.catch((err) => {
|
85
|
+
debug('Could not verify xvfb: %s', err.message);
|
86
|
+
return false;
|
87
|
+
})
|
88
|
+
.finally(xvfb.stopAsync);
|
89
|
+
},
|
90
|
+
};
|
91
|
+
exports.default = xvfbModule;
|
package/lib/fs.js
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
8
|
+
exports.default = bluebird_1.default.promisifyAll(fs_extra_1.default);
|
package/lib/logger.js
CHANGED
@@ -1,50 +1,55 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
4
7
|
let logs = [];
|
5
8
|
const logLevel = () => {
|
6
|
-
|
9
|
+
return (process.env.npm_config_loglevel || 'notice');
|
7
10
|
};
|
8
11
|
const error = (...messages) => {
|
9
|
-
|
10
|
-
|
12
|
+
logs.push(messages.join(' '));
|
13
|
+
console.log(chalk_1.default.red(...messages)); // eslint-disable-line no-console
|
11
14
|
};
|
12
15
|
const warn = (...messages) => {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
if (logLevel() === 'silent')
|
17
|
+
return;
|
18
|
+
logs.push(messages.join(' '));
|
19
|
+
console.log(chalk_1.default.yellow(...messages)); // eslint-disable-line no-console
|
16
20
|
};
|
17
21
|
const log = (...messages) => {
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
if (logLevel() === 'silent' || logLevel() === 'warn')
|
23
|
+
return;
|
24
|
+
logs.push(messages.join(' '));
|
25
|
+
console.log(...messages); // eslint-disable-line no-console
|
21
26
|
};
|
22
27
|
const always = (...messages) => {
|
23
|
-
|
24
|
-
|
28
|
+
logs.push(messages.join(' '));
|
29
|
+
console.log(...messages); // eslint-disable-line no-console
|
25
30
|
};
|
26
|
-
|
27
31
|
// splits long text into lines and calls log()
|
28
32
|
// on each one to allow easy unit testing for specific message
|
29
|
-
const logLines = text => {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
const logLines = (text) => {
|
34
|
+
const lines = text.split('\n');
|
35
|
+
for (const line of lines) {
|
36
|
+
log(line);
|
37
|
+
}
|
34
38
|
};
|
35
39
|
const print = () => {
|
36
|
-
|
40
|
+
return logs.join('\n');
|
37
41
|
};
|
38
42
|
const reset = () => {
|
39
|
-
|
40
|
-
};
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
};
|
43
|
+
logs = [];
|
44
|
+
};
|
45
|
+
const loggerModule = {
|
46
|
+
log,
|
47
|
+
warn,
|
48
|
+
error,
|
49
|
+
always,
|
50
|
+
logLines,
|
51
|
+
print,
|
52
|
+
reset,
|
53
|
+
logLevel,
|
54
|
+
};
|
55
|
+
exports.default = loggerModule;
|
package/lib/tasks/cache.js
CHANGED
@@ -1,132 +1,147 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
const
|
16
|
-
const
|
17
|
-
|
18
|
-
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const state_1 = __importDefault(require("./state"));
|
16
|
+
const logger_1 = __importDefault(require("../logger"));
|
17
|
+
const fs_1 = __importDefault(require("../fs"));
|
18
|
+
const util_1 = __importDefault(require("../util"));
|
19
|
+
const path_1 = require("path");
|
20
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
21
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
22
|
+
const relativeTime_1 = __importDefault(require("dayjs/plugin/relativeTime"));
|
23
|
+
const chalk_1 = __importDefault(require("chalk"));
|
24
|
+
const lodash_1 = __importDefault(require("lodash"));
|
25
|
+
const get_folder_size_1 = __importDefault(require("./get-folder-size"));
|
26
|
+
dayjs_1.default.extend(relativeTime_1.default);
|
19
27
|
// output colors for the table
|
20
28
|
const colors = {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
titles: chalk_1.default.white,
|
30
|
+
dates: chalk_1.default.cyan,
|
31
|
+
values: chalk_1.default.green,
|
32
|
+
size: chalk_1.default.gray,
|
25
33
|
};
|
26
34
|
const logCachePath = () => {
|
27
|
-
|
28
|
-
|
35
|
+
logger_1.default.always(state_1.default.getCacheDir());
|
36
|
+
return undefined;
|
29
37
|
};
|
30
38
|
const clear = () => {
|
31
|
-
|
39
|
+
return fs_1.default.removeAsync(state_1.default.getCacheDir());
|
32
40
|
};
|
33
|
-
const prune = () => {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
const prune = () => __awaiter(void 0, void 0, void 0, function* () {
|
42
|
+
const cacheDir = state_1.default.getCacheDir();
|
43
|
+
const checkedInBinaryVersion = util_1.default.pkgVersion();
|
44
|
+
let deletedBinary = false;
|
45
|
+
try {
|
46
|
+
const versions = yield fs_1.default.readdirAsync(cacheDir);
|
47
|
+
for (const version of versions) {
|
48
|
+
if (version !== checkedInBinaryVersion) {
|
49
|
+
deletedBinary = true;
|
50
|
+
const versionDir = (0, path_1.join)(cacheDir, version);
|
51
|
+
yield fs_1.default.removeAsync(versionDir);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
if (deletedBinary) {
|
55
|
+
logger_1.default.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`);
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
logger_1.default.always(`No binary caches found to prune.`);
|
59
|
+
}
|
50
60
|
}
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
catch (e) {
|
62
|
+
if (e.code === 'ENOENT') {
|
63
|
+
logger_1.default.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
throw e;
|
67
|
+
}
|
68
|
+
});
|
69
|
+
const fileSizeInMB = (size) => {
|
70
|
+
return `${(size / 1024 / 1024).toFixed(1)}MB`;
|
59
71
|
};
|
60
|
-
|
61
72
|
/**
|
62
73
|
* Collects all cached versions, finds when each was used
|
63
74
|
* and prints a table with results to the terminal
|
64
75
|
*/
|
65
|
-
const list = showSize => {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
76
|
+
const list = (showSize = false) => {
|
77
|
+
return getCachedVersions(showSize)
|
78
|
+
.then((binaries) => {
|
79
|
+
const head = [colors.titles('version'), colors.titles('last used')];
|
80
|
+
if (showSize) {
|
81
|
+
head.push(colors.titles('size'));
|
82
|
+
}
|
83
|
+
const table = new cli_table3_1.default({
|
84
|
+
head,
|
85
|
+
});
|
86
|
+
binaries.forEach((binary) => {
|
87
|
+
const versionString = colors.values(binary.version);
|
88
|
+
const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
|
89
|
+
const row = [versionString, lastUsed];
|
90
|
+
if (showSize) {
|
91
|
+
const size = colors.size(fileSizeInMB(binary.size));
|
92
|
+
row.push(size);
|
93
|
+
}
|
94
|
+
return table.push(row);
|
95
|
+
});
|
96
|
+
logger_1.default.always(table.toString());
|
83
97
|
});
|
84
|
-
logger.always(table.toString());
|
85
|
-
});
|
86
98
|
};
|
87
|
-
const getCachedVersions = showSize => {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
};
|
94
|
-
}).mapSeries(binary => {
|
95
|
-
// last access time on the folder is different from last access time
|
96
|
-
// on the Cypress binary
|
97
|
-
const binaryDir = state.getBinaryDir(binary.version);
|
98
|
-
const executable = state.getPathToExecutable(binaryDir);
|
99
|
-
return fs.statAsync(executable).then(stat => {
|
100
|
-
const lastAccessedTime = _.get(stat, 'atime');
|
101
|
-
if (!lastAccessedTime) {
|
102
|
-
// the test runner has never been opened
|
103
|
-
// or could be a test simulating missing timestamp
|
104
|
-
return binary;
|
105
|
-
}
|
106
|
-
const accessed = dayjs(lastAccessedTime).fromNow();
|
107
|
-
binary.accessed = accessed;
|
108
|
-
return binary;
|
109
|
-
}, e => {
|
110
|
-
// could not find the binary or gets its stats
|
111
|
-
return binary;
|
112
|
-
});
|
113
|
-
}).mapSeries(binary => {
|
114
|
-
if (showSize) {
|
115
|
-
const binaryDir = state.getBinaryDir(binary.version);
|
116
|
-
return getFolderSize(binaryDir).then(size => {
|
99
|
+
const getCachedVersions = (showSize) => {
|
100
|
+
const cacheDir = state_1.default.getCacheDir();
|
101
|
+
return fs_1.default
|
102
|
+
.readdirAsync(cacheDir)
|
103
|
+
.filter(util_1.default.isSemver)
|
104
|
+
.map((version) => {
|
117
105
|
return {
|
118
|
-
|
119
|
-
|
106
|
+
version,
|
107
|
+
folderPath: (0, path_1.join)(cacheDir, version),
|
120
108
|
};
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
109
|
+
})
|
110
|
+
.mapSeries((binary) => {
|
111
|
+
// last access time on the folder is different from last access time
|
112
|
+
// on the Cypress binary
|
113
|
+
const binaryDir = state_1.default.getBinaryDir(binary.version);
|
114
|
+
const executable = state_1.default.getPathToExecutable(binaryDir);
|
115
|
+
return fs_1.default.statAsync(executable).then((stat) => {
|
116
|
+
const lastAccessedTime = lodash_1.default.get(stat, 'atime');
|
117
|
+
if (!lastAccessedTime) {
|
118
|
+
// the test runner has never been opened
|
119
|
+
// or could be a test simulating missing timestamp
|
120
|
+
return binary;
|
121
|
+
}
|
122
|
+
const accessed = (0, dayjs_1.default)(lastAccessedTime).fromNow();
|
123
|
+
binary.accessed = accessed;
|
124
|
+
return binary;
|
125
|
+
}, (e) => {
|
126
|
+
// could not find the binary or gets its stats
|
127
|
+
return binary;
|
128
|
+
});
|
129
|
+
})
|
130
|
+
.mapSeries((binary) => {
|
131
|
+
if (showSize) {
|
132
|
+
const binaryDir = state_1.default.getBinaryDir(binary.version);
|
133
|
+
return (0, get_folder_size_1.default)(binaryDir).then((size) => {
|
134
|
+
return Object.assign(Object.assign({}, binary), { size });
|
135
|
+
});
|
136
|
+
}
|
137
|
+
return binary;
|
138
|
+
});
|
139
|
+
};
|
140
|
+
const cacheModule = {
|
141
|
+
path: logCachePath,
|
142
|
+
clear,
|
143
|
+
prune,
|
144
|
+
list,
|
145
|
+
getCachedVersions,
|
125
146
|
};
|
126
|
-
|
127
|
-
path: logCachePath,
|
128
|
-
clear,
|
129
|
-
prune,
|
130
|
-
list,
|
131
|
-
getCachedVersions
|
132
|
-
};
|
147
|
+
exports.default = cacheModule;
|