cypress 5.2.0 → 5.6.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/index.js +6 -6
- package/lib/cli.js +119 -107
- package/lib/cypress.js +21 -21
- package/lib/errors.js +233 -276
- package/lib/exec/info.js +29 -32
- package/lib/exec/open.js +7 -8
- package/lib/exec/run.js +20 -20
- package/lib/exec/spawn.js +53 -49
- package/lib/exec/versions.js +18 -17
- package/lib/exec/xvfb.js +43 -37
- package/lib/fs.js +1 -1
- package/lib/logger.js +24 -50
- package/lib/tasks/cache.js +96 -36
- package/lib/tasks/download.js +113 -133
- package/lib/tasks/get-folder-size.js +41 -0
- package/lib/tasks/install.js +165 -249
- package/lib/tasks/state.js +54 -56
- package/lib/tasks/unzip.js +72 -69
- package/lib/tasks/verify.js +112 -147
- package/lib/util.js +172 -176
- package/package.json +4 -4
- package/types/cypress-npm-api.d.ts +13 -5
- package/types/cypress.d.ts +15 -15
- package/types/mocha/index.d.ts +123 -308
- package/types/net-stubbing.ts +132 -21
package/lib/tasks/state.js
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const _ = require('lodash');
|
4
4
|
|
5
|
-
|
5
|
+
const os = require('os');
|
6
6
|
|
7
|
-
|
7
|
+
const path = require('path');
|
8
8
|
|
9
|
-
|
9
|
+
const untildify = require('untildify');
|
10
10
|
|
11
|
-
|
11
|
+
const debug = require('debug')('cypress:cli');
|
12
12
|
|
13
|
-
|
13
|
+
const fs = require('../fs');
|
14
14
|
|
15
|
-
|
15
|
+
const util = require('../util');
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
const getPlatformExecutable = () => {
|
18
|
+
const platform = os.platform();
|
19
19
|
|
20
20
|
switch (platform) {
|
21
21
|
case 'darwin':
|
@@ -29,12 +29,12 @@ var getPlatformExecutable = function getPlatformExecutable() {
|
|
29
29
|
// TODO handle this error using our standard
|
30
30
|
|
31
31
|
default:
|
32
|
-
throw new Error(
|
32
|
+
throw new Error(`Platform: "${platform}" is not supported.`);
|
33
33
|
}
|
34
34
|
};
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
const getPlatFormBinaryFolder = () => {
|
37
|
+
const platform = os.platform();
|
38
38
|
|
39
39
|
switch (platform) {
|
40
40
|
case 'darwin':
|
@@ -48,12 +48,12 @@ var getPlatFormBinaryFolder = function getPlatFormBinaryFolder() {
|
|
48
48
|
// TODO handle this error using our standard
|
49
49
|
|
50
50
|
default:
|
51
|
-
throw new Error(
|
51
|
+
throw new Error(`Platform: "${platform}" is not supported.`);
|
52
52
|
}
|
53
53
|
};
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
const getBinaryPkgPath = binaryDir => {
|
56
|
+
const platform = os.platform();
|
57
57
|
|
58
58
|
switch (platform) {
|
59
59
|
case 'darwin':
|
@@ -67,7 +67,7 @@ var getBinaryPkgPath = function getBinaryPkgPath(binaryDir) {
|
|
67
67
|
// TODO handle this error using our standard
|
68
68
|
|
69
69
|
default:
|
70
|
-
throw new Error(
|
70
|
+
throw new Error(`Platform: "${platform}" is not supported.`);
|
71
71
|
}
|
72
72
|
};
|
73
73
|
/**
|
@@ -75,13 +75,11 @@ var getBinaryPkgPath = function getBinaryPkgPath(binaryDir) {
|
|
75
75
|
*/
|
76
76
|
|
77
77
|
|
78
|
-
|
79
|
-
var version = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : util.pkgVersion();
|
78
|
+
const getBinaryDir = (version = util.pkgVersion()) => {
|
80
79
|
return path.join(getVersionDir(version), getPlatFormBinaryFolder());
|
81
80
|
};
|
82
81
|
|
83
|
-
|
84
|
-
var version = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : util.pkgVersion();
|
82
|
+
const getVersionDir = (version = util.pkgVersion()) => {
|
85
83
|
return path.join(getCacheDir(), version);
|
86
84
|
};
|
87
85
|
/**
|
@@ -90,22 +88,22 @@ var getVersionDir = function getVersionDir() {
|
|
90
88
|
*/
|
91
89
|
|
92
90
|
|
93
|
-
|
91
|
+
const isInstallingFromPostinstallHook = () => {
|
94
92
|
// individual folders
|
95
|
-
|
96
|
-
|
93
|
+
const cwdFolders = process.cwd().split(path.sep);
|
94
|
+
const length = cwdFolders.length;
|
97
95
|
return cwdFolders[length - 2] === 'node_modules' && cwdFolders[length - 1] === 'cypress';
|
98
96
|
};
|
99
97
|
|
100
|
-
|
101
|
-
|
98
|
+
const getCacheDir = () => {
|
99
|
+
let cache_directory = util.getCacheDir();
|
102
100
|
|
103
101
|
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
|
104
|
-
|
102
|
+
const envVarCacheDir = untildify(util.getEnv('CYPRESS_CACHE_FOLDER'));
|
105
103
|
debug('using environment variable CYPRESS_CACHE_FOLDER %s', envVarCacheDir);
|
106
104
|
|
107
105
|
if (!path.isAbsolute(envVarCacheDir) && isInstallingFromPostinstallHook()) {
|
108
|
-
|
106
|
+
const packageRootFolder = path.join('..', '..', envVarCacheDir);
|
109
107
|
cache_directory = path.resolve(packageRootFolder);
|
110
108
|
debug('installing from postinstall hook, original root folder is %s', packageRootFolder);
|
111
109
|
debug('and resolved cache directory is %s', cache_directory);
|
@@ -117,8 +115,8 @@ var getCacheDir = function getCacheDir() {
|
|
117
115
|
return cache_directory;
|
118
116
|
};
|
119
117
|
|
120
|
-
|
121
|
-
return fs.realpathAsync(binaryPath).then(
|
118
|
+
const parseRealPlatformBinaryFolderAsync = binaryPath => {
|
119
|
+
return fs.realpathAsync(binaryPath).then(realPath => {
|
122
120
|
debug('CYPRESS_RUN_BINARY has realpath:', realPath);
|
123
121
|
|
124
122
|
if (!realPath.toString().endsWith(getPlatformExecutable())) {
|
@@ -133,7 +131,7 @@ var parseRealPlatformBinaryFolderAsync = function parseRealPlatformBinaryFolderA
|
|
133
131
|
});
|
134
132
|
};
|
135
133
|
|
136
|
-
|
134
|
+
const getDistDir = () => {
|
137
135
|
return path.join(__dirname, '..', '..', 'dist');
|
138
136
|
};
|
139
137
|
/**
|
@@ -143,25 +141,25 @@ var getDistDir = function getDistDir() {
|
|
143
141
|
*/
|
144
142
|
|
145
143
|
|
146
|
-
|
144
|
+
const getBinaryStatePath = binaryDir => {
|
147
145
|
return path.join(binaryDir, '..', 'binary_state.json');
|
148
146
|
};
|
149
147
|
|
150
|
-
|
151
|
-
|
152
|
-
return fs.readJsonAsync(fullPath)
|
148
|
+
const getBinaryStateContentsAsync = binaryDir => {
|
149
|
+
const fullPath = getBinaryStatePath(binaryDir);
|
150
|
+
return fs.readJsonAsync(fullPath).catch({
|
153
151
|
code: 'ENOENT'
|
154
|
-
}, SyntaxError,
|
152
|
+
}, SyntaxError, () => {
|
155
153
|
debug('could not read binary_state.json file at "%s"', fullPath);
|
156
154
|
return {};
|
157
155
|
});
|
158
156
|
};
|
159
157
|
|
160
|
-
|
158
|
+
const getBinaryVerifiedAsync = binaryDir => {
|
161
159
|
return getBinaryStateContentsAsync(binaryDir).tap(debug).get('verified');
|
162
160
|
};
|
163
161
|
|
164
|
-
|
162
|
+
const clearBinaryStateAsync = binaryDir => {
|
165
163
|
return fs.removeAsync(getBinaryStatePath(binaryDir));
|
166
164
|
};
|
167
165
|
/**
|
@@ -172,24 +170,24 @@ var clearBinaryStateAsync = function clearBinaryStateAsync(binaryDir) {
|
|
172
170
|
*/
|
173
171
|
|
174
172
|
|
175
|
-
|
176
|
-
return getBinaryStateContentsAsync(binaryDir).then(
|
173
|
+
const writeBinaryVerifiedAsync = (verified, binaryDir) => {
|
174
|
+
return getBinaryStateContentsAsync(binaryDir).then(contents => {
|
177
175
|
return fs.outputJsonAsync(getBinaryStatePath(binaryDir), _.extend(contents, {
|
178
|
-
verified
|
176
|
+
verified
|
179
177
|
}), {
|
180
178
|
spaces: 2
|
181
179
|
});
|
182
180
|
});
|
183
181
|
};
|
184
182
|
|
185
|
-
|
183
|
+
const getPathToExecutable = binaryDir => {
|
186
184
|
return path.join(binaryDir, getPlatformExecutable());
|
187
185
|
};
|
188
186
|
|
189
|
-
|
190
|
-
|
187
|
+
const getBinaryPkgVersionAsync = binaryDir => {
|
188
|
+
const pathToPackageJson = getBinaryPkgPath(binaryDir);
|
191
189
|
debug('Reading binary package.json from:', pathToPackageJson);
|
192
|
-
return fs.pathExistsAsync(pathToPackageJson).then(
|
190
|
+
return fs.pathExistsAsync(pathToPackageJson).then(exists => {
|
193
191
|
if (!exists) {
|
194
192
|
return null;
|
195
193
|
}
|
@@ -199,16 +197,16 @@ var getBinaryPkgVersionAsync = function getBinaryPkgVersionAsync(binaryDir) {
|
|
199
197
|
};
|
200
198
|
|
201
199
|
module.exports = {
|
202
|
-
getPathToExecutable
|
203
|
-
getPlatformExecutable
|
204
|
-
getBinaryPkgVersionAsync
|
205
|
-
getBinaryVerifiedAsync
|
206
|
-
getBinaryPkgPath
|
207
|
-
getBinaryDir
|
208
|
-
getCacheDir
|
209
|
-
clearBinaryStateAsync
|
210
|
-
writeBinaryVerifiedAsync
|
211
|
-
parseRealPlatformBinaryFolderAsync
|
212
|
-
getDistDir
|
213
|
-
getVersionDir
|
200
|
+
getPathToExecutable,
|
201
|
+
getPlatformExecutable,
|
202
|
+
getBinaryPkgVersionAsync,
|
203
|
+
getBinaryVerifiedAsync,
|
204
|
+
getBinaryPkgPath,
|
205
|
+
getBinaryDir,
|
206
|
+
getCacheDir,
|
207
|
+
clearBinaryStateAsync,
|
208
|
+
writeBinaryVerifiedAsync,
|
209
|
+
parseRealPlatformBinaryFolderAsync,
|
210
|
+
getDistDir,
|
211
|
+
getVersionDir
|
214
212
|
};
|
package/lib/tasks/unzip.js
CHANGED
@@ -1,41 +1,43 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
3
|
+
const _ = require('lodash');
|
4
4
|
|
5
|
-
|
5
|
+
const la = require('lazy-ass');
|
6
6
|
|
7
|
-
|
7
|
+
const is = require('check-more-types');
|
8
8
|
|
9
|
-
|
9
|
+
const cp = require('child_process');
|
10
10
|
|
11
|
-
|
11
|
+
const os = require('os');
|
12
12
|
|
13
|
-
|
13
|
+
const yauzl = require('yauzl');
|
14
14
|
|
15
|
-
|
15
|
+
const debug = require('debug')('cypress:cli:unzip');
|
16
16
|
|
17
|
-
|
17
|
+
const extract = require('extract-zip');
|
18
18
|
|
19
|
-
|
19
|
+
const Promise = require('bluebird');
|
20
20
|
|
21
|
-
|
21
|
+
const readline = require('readline');
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
const {
|
24
|
+
throwFormErrorText,
|
25
|
+
errors
|
26
|
+
} = require('../errors');
|
26
27
|
|
27
|
-
|
28
|
+
const fs = require('../fs');
|
28
29
|
|
29
|
-
|
30
|
+
const util = require('../util');
|
30
31
|
|
31
|
-
|
32
|
-
extract
|
32
|
+
const unzipTools = {
|
33
|
+
extract
|
33
34
|
}; // expose this function for simple testing
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
const unzip = ({
|
37
|
+
zipFilePath,
|
38
|
+
installDir,
|
39
|
+
progress
|
40
|
+
}) => {
|
39
41
|
debug('unzipping from %s', zipFilePath);
|
40
42
|
debug('into', installDir);
|
41
43
|
|
@@ -43,11 +45,11 @@ var unzip = function unzip(_ref) {
|
|
43
45
|
throw new Error('Missing zip filename');
|
44
46
|
}
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
return fs.ensureDirAsync(installDir).then(
|
49
|
-
return new Promise(
|
50
|
-
return yauzl.open(zipFilePath,
|
48
|
+
const startTime = Date.now();
|
49
|
+
let yauzlDoneTime = 0;
|
50
|
+
return fs.ensureDirAsync(installDir).then(() => {
|
51
|
+
return new Promise((resolve, reject) => {
|
52
|
+
return yauzl.open(zipFilePath, (err, zipFile) => {
|
51
53
|
yauzlDoneTime = Date.now();
|
52
54
|
|
53
55
|
if (err) {
|
@@ -55,29 +57,29 @@ var unzip = function unzip(_ref) {
|
|
55
57
|
return reject(err);
|
56
58
|
}
|
57
59
|
|
58
|
-
|
60
|
+
const total = zipFile.entryCount;
|
59
61
|
debug('zipFile entries count', total);
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
const started = new Date();
|
63
|
+
let percent = 0;
|
64
|
+
let count = 0;
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
66
|
+
const notify = percent => {
|
67
|
+
const elapsed = +new Date() - +started;
|
68
|
+
const eta = util.calculateEta(percent, elapsed);
|
67
69
|
progress.onProgress(percent, util.secsRemaining(eta));
|
68
70
|
};
|
69
71
|
|
70
|
-
|
72
|
+
const tick = () => {
|
71
73
|
count += 1;
|
72
74
|
percent = count / total * 100;
|
73
|
-
|
75
|
+
const displayPercent = percent.toFixed(0);
|
74
76
|
return notify(displayPercent);
|
75
77
|
};
|
76
78
|
|
77
|
-
|
79
|
+
const unzipWithNode = () => {
|
78
80
|
debug('unzipping with node.js (slow)');
|
79
81
|
|
80
|
-
|
82
|
+
const endFn = err => {
|
81
83
|
if (err) {
|
82
84
|
debug('error %s', err.message);
|
83
85
|
return reject(err);
|
@@ -87,7 +89,7 @@ var unzip = function unzip(_ref) {
|
|
87
89
|
return resolve();
|
88
90
|
};
|
89
91
|
|
90
|
-
|
92
|
+
const opts = {
|
91
93
|
dir: installDir,
|
92
94
|
onEntry: tick
|
93
95
|
};
|
@@ -95,17 +97,17 @@ var unzip = function unzip(_ref) {
|
|
95
97
|
return unzipTools.extract(zipFilePath, opts, endFn);
|
96
98
|
};
|
97
99
|
|
98
|
-
|
100
|
+
const unzipFallback = _.once(unzipWithNode);
|
99
101
|
|
100
|
-
|
102
|
+
const unzipWithUnzipTool = () => {
|
101
103
|
debug('unzipping via `unzip`');
|
102
|
-
|
103
|
-
|
104
|
-
sp.on('error',
|
104
|
+
const inflatingRe = /inflating:/;
|
105
|
+
const sp = cp.spawn('unzip', ['-o', zipFilePath, '-d', installDir]);
|
106
|
+
sp.on('error', err => {
|
105
107
|
debug('unzip tool error: %s', err.message);
|
106
108
|
unzipFallback();
|
107
109
|
});
|
108
|
-
sp.on('close',
|
110
|
+
sp.on('close', code => {
|
109
111
|
debug('unzip tool close with code %d', code);
|
110
112
|
|
111
113
|
if (code === 0) {
|
@@ -115,16 +117,16 @@ var unzip = function unzip(_ref) {
|
|
115
117
|
}
|
116
118
|
|
117
119
|
debug('`unzip` failed %o', {
|
118
|
-
code
|
120
|
+
code
|
119
121
|
});
|
120
122
|
return unzipFallback();
|
121
123
|
});
|
122
|
-
sp.stdout.on('data',
|
124
|
+
sp.stdout.on('data', data => {
|
123
125
|
if (inflatingRe.test(data)) {
|
124
126
|
return tick();
|
125
127
|
}
|
126
128
|
});
|
127
|
-
sp.stderr.on('data',
|
129
|
+
sp.stderr.on('data', data => {
|
128
130
|
debug('`unzip` stderr %s', data);
|
129
131
|
});
|
130
132
|
}; // we attempt to first unzip with the native osx
|
@@ -134,16 +136,16 @@ var unzip = function unzip(_ref) {
|
|
134
136
|
// http://automatica.com.au/2011/02/unzip-mac-os-x-zip-in-terminal/
|
135
137
|
|
136
138
|
|
137
|
-
|
139
|
+
const unzipWithOsx = () => {
|
138
140
|
debug('unzipping via `ditto`');
|
139
|
-
|
140
|
-
|
141
|
+
const copyingFileRe = /^copying file/;
|
142
|
+
const sp = cp.spawn('ditto', ['-xkV', zipFilePath, installDir]); // f-it just unzip with node
|
141
143
|
|
142
|
-
sp.on('error',
|
144
|
+
sp.on('error', err => {
|
143
145
|
debug(err.message);
|
144
146
|
unzipFallback();
|
145
147
|
});
|
146
|
-
sp.on('close',
|
148
|
+
sp.on('close', code => {
|
147
149
|
if (code === 0) {
|
148
150
|
// make sure we get to 100% on the progress bar
|
149
151
|
// because reading in lines is not really accurate
|
@@ -153,13 +155,13 @@ var unzip = function unzip(_ref) {
|
|
153
155
|
}
|
154
156
|
|
155
157
|
debug('`ditto` failed %o', {
|
156
|
-
code
|
158
|
+
code
|
157
159
|
});
|
158
160
|
return unzipFallback();
|
159
161
|
});
|
160
162
|
return readline.createInterface({
|
161
163
|
input: sp.stderr
|
162
|
-
}).on('line',
|
164
|
+
}).on('line', line => {
|
163
165
|
if (copyingFileRe.test(line)) {
|
164
166
|
return tick();
|
165
167
|
}
|
@@ -180,7 +182,7 @@ var unzip = function unzip(_ref) {
|
|
180
182
|
return;
|
181
183
|
}
|
182
184
|
});
|
183
|
-
}).tap(
|
185
|
+
}).tap(() => {
|
184
186
|
debug('unzip completed %o', {
|
185
187
|
yauzlMs: yauzlDoneTime - startTime,
|
186
188
|
unzipMs: Date.now() - yauzlDoneTime
|
@@ -189,38 +191,39 @@ var unzip = function unzip(_ref) {
|
|
189
191
|
});
|
190
192
|
};
|
191
193
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
194
|
+
const start = ({
|
195
|
+
zipFilePath,
|
196
|
+
installDir,
|
197
|
+
progress
|
198
|
+
}) => {
|
196
199
|
la(is.unemptyString(installDir), 'missing installDir');
|
197
200
|
|
198
201
|
if (!progress) {
|
199
202
|
progress = {
|
200
|
-
onProgress:
|
203
|
+
onProgress: () => {
|
201
204
|
return {};
|
202
205
|
}
|
203
206
|
};
|
204
207
|
}
|
205
208
|
|
206
|
-
return fs.pathExists(installDir).then(
|
209
|
+
return fs.pathExists(installDir).then(exists => {
|
207
210
|
if (exists) {
|
208
211
|
debug('removing existing unzipped binary', installDir);
|
209
212
|
return fs.removeAsync(installDir);
|
210
213
|
}
|
211
|
-
}).then(
|
214
|
+
}).then(() => {
|
212
215
|
return unzip({
|
213
|
-
zipFilePath
|
214
|
-
installDir
|
215
|
-
progress
|
216
|
+
zipFilePath,
|
217
|
+
installDir,
|
218
|
+
progress
|
216
219
|
});
|
217
|
-
})
|
220
|
+
}).catch(throwFormErrorText(errors.failedUnzip));
|
218
221
|
};
|
219
222
|
|
220
223
|
module.exports = {
|
221
|
-
start
|
224
|
+
start,
|
222
225
|
utils: {
|
223
|
-
unzip
|
224
|
-
unzipTools
|
226
|
+
unzip,
|
227
|
+
unzipTools
|
225
228
|
}
|
226
229
|
};
|