cypress 5.2.0 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/download.js
CHANGED
@@ -1,98 +1,48 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
|
4
|
-
var data = _taggedTemplateLiteral(["\n Failed downloading the Cypress binary.\n Response code: ", "\n Response message: ", "\n "]);
|
3
|
+
const arch = require('arch');
|
5
4
|
|
6
|
-
|
7
|
-
return data;
|
8
|
-
};
|
5
|
+
const la = require('lazy-ass');
|
9
6
|
|
10
|
-
|
11
|
-
}
|
7
|
+
const is = require('check-more-types');
|
12
8
|
|
13
|
-
|
14
|
-
var data = _taggedTemplateLiteral(["\n Corrupted download\n\n Expected downloaded file to have size: ", "\n Computed size: ", "\n "]);
|
9
|
+
const os = require('os');
|
15
10
|
|
16
|
-
|
17
|
-
return data;
|
18
|
-
};
|
11
|
+
const url = require('url');
|
19
12
|
|
20
|
-
|
21
|
-
}
|
13
|
+
const path = require('path');
|
22
14
|
|
23
|
-
|
24
|
-
var data = _taggedTemplateLiteral(["\n Corrupted download\n\n Expected downloaded file to have checksum: ", "\n Computed checksum: ", "\n "]);
|
15
|
+
const debug = require('debug')('cypress:cli');
|
25
16
|
|
26
|
-
|
27
|
-
return data;
|
28
|
-
};
|
17
|
+
const request = require('@cypress/request');
|
29
18
|
|
30
|
-
|
31
|
-
}
|
19
|
+
const Promise = require('bluebird');
|
32
20
|
|
33
|
-
|
34
|
-
var data = _taggedTemplateLiteral(["\n Corrupted download\n\n Expected downloaded file to have checksum: ", "\n Computed checksum: ", "\n\n Expected downloaded file to have size: ", "\n Computed size: ", "\n "]);
|
21
|
+
const requestProgress = require('request-progress');
|
35
22
|
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
const {
|
24
|
+
stripIndent
|
25
|
+
} = require('common-tags');
|
39
26
|
|
40
|
-
|
41
|
-
|
27
|
+
const {
|
28
|
+
throwFormErrorText,
|
29
|
+
errors
|
30
|
+
} = require('../errors');
|
42
31
|
|
43
|
-
|
44
|
-
var data = _taggedTemplateLiteral(["\n URL: ", "\n ", "\n "]);
|
32
|
+
const fs = require('../fs');
|
45
33
|
|
46
|
-
|
47
|
-
return data;
|
48
|
-
};
|
34
|
+
const util = require('../util');
|
49
35
|
|
50
|
-
|
51
|
-
}
|
36
|
+
const defaultBaseUrl = 'https://download.cypress.io/';
|
52
37
|
|
53
|
-
|
54
|
-
|
55
|
-
var arch = require('arch');
|
56
|
-
|
57
|
-
var la = require('lazy-ass');
|
58
|
-
|
59
|
-
var is = require('check-more-types');
|
60
|
-
|
61
|
-
var os = require('os');
|
62
|
-
|
63
|
-
var url = require('url');
|
64
|
-
|
65
|
-
var path = require('path');
|
66
|
-
|
67
|
-
var debug = require('debug')('cypress:cli');
|
68
|
-
|
69
|
-
var request = require('@cypress/request');
|
70
|
-
|
71
|
-
var Promise = require('bluebird');
|
72
|
-
|
73
|
-
var requestProgress = require('request-progress');
|
74
|
-
|
75
|
-
var _require = require('common-tags'),
|
76
|
-
stripIndent = _require.stripIndent;
|
77
|
-
|
78
|
-
var _require2 = require('../errors'),
|
79
|
-
throwFormErrorText = _require2.throwFormErrorText,
|
80
|
-
errors = _require2.errors;
|
81
|
-
|
82
|
-
var fs = require('../fs');
|
83
|
-
|
84
|
-
var util = require('../util');
|
85
|
-
|
86
|
-
var defaultBaseUrl = 'https://download.cypress.io/';
|
87
|
-
|
88
|
-
var getProxyUrl = function getProxyUrl() {
|
38
|
+
const getProxyUrl = () => {
|
89
39
|
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.npm_config_https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || process.env.npm_config_proxy || null;
|
90
40
|
};
|
91
41
|
|
92
|
-
|
42
|
+
const getRealOsArch = () => {
|
93
43
|
// os.arch() returns the arch for which this node was compiled
|
94
44
|
// we want the operating system's arch instead: x64 or x86
|
95
|
-
|
45
|
+
const osArch = arch();
|
96
46
|
|
97
47
|
if (osArch === 'x86') {
|
98
48
|
// match process.platform output
|
@@ -102,9 +52,9 @@ var getRealOsArch = function getRealOsArch() {
|
|
102
52
|
return osArch;
|
103
53
|
};
|
104
54
|
|
105
|
-
|
55
|
+
const getBaseUrl = () => {
|
106
56
|
if (util.getEnv('CYPRESS_DOWNLOAD_MIRROR')) {
|
107
|
-
|
57
|
+
let baseUrl = util.getEnv('CYPRESS_DOWNLOAD_MIRROR');
|
108
58
|
|
109
59
|
if (!baseUrl.endsWith('/')) {
|
110
60
|
baseUrl += '/';
|
@@ -116,28 +66,31 @@ var getBaseUrl = function getBaseUrl() {
|
|
116
66
|
return defaultBaseUrl;
|
117
67
|
};
|
118
68
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
return
|
69
|
+
const prepend = urlPath => {
|
70
|
+
const endpoint = url.resolve(getBaseUrl(), urlPath);
|
71
|
+
const platform = os.platform();
|
72
|
+
const arch = getRealOsArch();
|
73
|
+
return `${endpoint}?platform=${platform}&arch=${arch}`;
|
124
74
|
};
|
125
75
|
|
126
|
-
|
76
|
+
const getUrl = version => {
|
127
77
|
if (is.url(version)) {
|
128
78
|
debug('version is already an url', version);
|
129
79
|
return version;
|
130
80
|
}
|
131
81
|
|
132
|
-
return version ? prepend(
|
82
|
+
return version ? prepend(`desktop/${version}`) : prepend('desktop');
|
133
83
|
};
|
134
84
|
|
135
|
-
|
85
|
+
const statusMessage = err => {
|
136
86
|
return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString();
|
137
87
|
};
|
138
88
|
|
139
|
-
|
140
|
-
|
89
|
+
const prettyDownloadErr = (err, version) => {
|
90
|
+
const msg = stripIndent`
|
91
|
+
URL: ${getUrl(version)}
|
92
|
+
${statusMessage(err)}
|
93
|
+
`;
|
141
94
|
debug(msg);
|
142
95
|
return throwFormErrorText(errors.failedDownload)(msg);
|
143
96
|
};
|
@@ -147,17 +100,25 @@ var prettyDownloadErr = function prettyDownloadErr(err, version) {
|
|
147
100
|
*/
|
148
101
|
|
149
102
|
|
150
|
-
|
103
|
+
const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
|
151
104
|
if (expectedSize && expectedChecksum) {
|
152
105
|
debug('verifying checksum and file size');
|
153
|
-
return Promise.join(util.getFileChecksum(filename), util.getFileSize(filename),
|
106
|
+
return Promise.join(util.getFileChecksum(filename), util.getFileSize(filename), (checksum, filesize) => {
|
154
107
|
if (checksum === expectedChecksum && filesize === expectedSize) {
|
155
108
|
debug('downloaded file has the expected checksum and size ✅');
|
156
109
|
return;
|
157
110
|
}
|
158
111
|
|
159
112
|
debug('raising error: checksum or file size mismatch');
|
160
|
-
|
113
|
+
const text = stripIndent`
|
114
|
+
Corrupted download
|
115
|
+
|
116
|
+
Expected downloaded file to have checksum: ${expectedChecksum}
|
117
|
+
Computed checksum: ${checksum}
|
118
|
+
|
119
|
+
Expected downloaded file to have size: ${expectedSize}
|
120
|
+
Computed size: ${filesize}
|
121
|
+
`;
|
161
122
|
debug(text);
|
162
123
|
throw new Error(text);
|
163
124
|
});
|
@@ -165,14 +126,19 @@ var verifyDownloadedFile = function verifyDownloadedFile(filename, expectedSize,
|
|
165
126
|
|
166
127
|
if (expectedChecksum) {
|
167
128
|
debug('only checking expected file checksum %d', expectedChecksum);
|
168
|
-
return util.getFileChecksum(filename).then(
|
129
|
+
return util.getFileChecksum(filename).then(checksum => {
|
169
130
|
if (checksum === expectedChecksum) {
|
170
131
|
debug('downloaded file has the expected checksum ✅');
|
171
132
|
return;
|
172
133
|
}
|
173
134
|
|
174
135
|
debug('raising error: file checksum mismatch');
|
175
|
-
|
136
|
+
const text = stripIndent`
|
137
|
+
Corrupted download
|
138
|
+
|
139
|
+
Expected downloaded file to have checksum: ${expectedChecksum}
|
140
|
+
Computed checksum: ${checksum}
|
141
|
+
`;
|
176
142
|
throw new Error(text);
|
177
143
|
});
|
178
144
|
}
|
@@ -181,14 +147,19 @@ var verifyDownloadedFile = function verifyDownloadedFile(filename, expectedSize,
|
|
181
147
|
// maybe we don't have a checksum, but at least CDN returns content length
|
182
148
|
// which we can check against the file size
|
183
149
|
debug('only checking expected file size %d', expectedSize);
|
184
|
-
return util.getFileSize(filename).then(
|
150
|
+
return util.getFileSize(filename).then(filesize => {
|
185
151
|
if (filesize === expectedSize) {
|
186
152
|
debug('downloaded file has the expected size ✅');
|
187
153
|
return;
|
188
154
|
}
|
189
155
|
|
190
156
|
debug('raising error: file size mismatch');
|
191
|
-
|
157
|
+
const text = stripIndent`
|
158
|
+
Corrupted download
|
159
|
+
|
160
|
+
Expected downloaded file to have size: ${expectedSize}
|
161
|
+
Computed size: ${filesize}
|
162
|
+
`;
|
192
163
|
throw new Error(text);
|
193
164
|
});
|
194
165
|
}
|
@@ -200,23 +171,25 @@ var verifyDownloadedFile = function verifyDownloadedFile(filename, expectedSize,
|
|
200
171
|
// {filename: ..., downloaded: true}
|
201
172
|
|
202
173
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
174
|
+
const downloadFromUrl = ({
|
175
|
+
url,
|
176
|
+
downloadDestination,
|
177
|
+
progress
|
178
|
+
}) => {
|
179
|
+
return new Promise((resolve, reject) => {
|
180
|
+
const proxy = getProxyUrl();
|
209
181
|
debug('Downloading package', {
|
210
|
-
url
|
211
|
-
proxy
|
212
|
-
downloadDestination
|
182
|
+
url,
|
183
|
+
proxy,
|
184
|
+
downloadDestination
|
213
185
|
});
|
214
|
-
|
215
|
-
|
216
|
-
url
|
217
|
-
proxy
|
218
|
-
|
219
|
-
|
186
|
+
let redirectVersion;
|
187
|
+
const req = request({
|
188
|
+
url,
|
189
|
+
proxy,
|
190
|
+
|
191
|
+
followRedirect(response) {
|
192
|
+
const version = response.headers['x-version'];
|
220
193
|
debug('redirect version:', version);
|
221
194
|
|
222
195
|
if (version) {
|
@@ -229,14 +202,15 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
229
202
|
|
230
203
|
return true;
|
231
204
|
}
|
205
|
+
|
232
206
|
}); // closure
|
233
207
|
|
234
|
-
|
235
|
-
|
236
|
-
|
208
|
+
let started = null;
|
209
|
+
let expectedSize;
|
210
|
+
let expectedChecksum;
|
237
211
|
requestProgress(req, {
|
238
212
|
throttle: progress.throttle
|
239
|
-
}).on('response',
|
213
|
+
}).on('response', response => {
|
240
214
|
// we have computed checksum and filesize during test runner binary build
|
241
215
|
// and have set it on the S3 object as user meta data, available via
|
242
216
|
// these custom headers "x-amz-meta-..."
|
@@ -260,22 +234,26 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
260
234
|
|
261
235
|
if (!/^2/.test(response.statusCode)) {
|
262
236
|
debug('response code %d', response.statusCode);
|
263
|
-
|
237
|
+
const err = new Error(stripIndent`
|
238
|
+
Failed downloading the Cypress binary.
|
239
|
+
Response code: ${response.statusCode}
|
240
|
+
Response message: ${response.statusMessage}
|
241
|
+
`);
|
264
242
|
reject(err);
|
265
243
|
}
|
266
|
-
}).on('error', reject).on('progress',
|
244
|
+
}).on('error', reject).on('progress', state => {
|
267
245
|
// total time we've elapsed
|
268
246
|
// starting on our first progress notification
|
269
|
-
|
247
|
+
const elapsed = new Date() - started; // request-progress sends a value between 0 and 1
|
270
248
|
|
271
|
-
|
272
|
-
|
249
|
+
const percentage = util.convertPercentToPercentage(state.percent);
|
250
|
+
const eta = util.calculateEta(percentage, elapsed); // send up our percent and seconds remaining
|
273
251
|
|
274
252
|
progress.onProgress(percentage, util.secsRemaining(eta));
|
275
253
|
}) // save this download here
|
276
|
-
.pipe(fs.createWriteStream(downloadDestination)).on('finish',
|
254
|
+
.pipe(fs.createWriteStream(downloadDestination)).on('finish', () => {
|
277
255
|
debug('downloading finished');
|
278
|
-
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(
|
256
|
+
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(() => {
|
279
257
|
return resolve(redirectVersion);
|
280
258
|
}, reject);
|
281
259
|
});
|
@@ -288,10 +266,12 @@ var downloadFromUrl = function downloadFromUrl(_ref) {
|
|
288
266
|
*/
|
289
267
|
|
290
268
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
269
|
+
const start = opts => {
|
270
|
+
let {
|
271
|
+
version,
|
272
|
+
downloadDestination,
|
273
|
+
progress
|
274
|
+
} = opts;
|
295
275
|
|
296
276
|
if (!downloadDestination) {
|
297
277
|
la(is.unemptyString(downloadDestination), 'missing download dir', opts);
|
@@ -299,31 +279,31 @@ var start = function start(opts) {
|
|
299
279
|
|
300
280
|
if (!progress) {
|
301
281
|
progress = {
|
302
|
-
onProgress:
|
282
|
+
onProgress: () => {
|
303
283
|
return {};
|
304
284
|
}
|
305
285
|
};
|
306
286
|
}
|
307
287
|
|
308
|
-
|
288
|
+
const url = getUrl(version);
|
309
289
|
progress.throttle = 100;
|
310
290
|
debug('needed Cypress version: %s', version);
|
311
291
|
debug('source url %s', url);
|
312
|
-
debug(
|
292
|
+
debug(`downloading cypress.zip to "${downloadDestination}"`); // ensure download dir exists
|
313
293
|
|
314
|
-
return fs.ensureDirAsync(path.dirname(downloadDestination)).then(
|
294
|
+
return fs.ensureDirAsync(path.dirname(downloadDestination)).then(() => {
|
315
295
|
return downloadFromUrl({
|
316
|
-
url
|
317
|
-
downloadDestination
|
318
|
-
progress
|
296
|
+
url,
|
297
|
+
downloadDestination,
|
298
|
+
progress
|
319
299
|
});
|
320
|
-
})
|
300
|
+
}).catch(err => {
|
321
301
|
return prettyDownloadErr(err, version);
|
322
302
|
});
|
323
303
|
};
|
324
304
|
|
325
305
|
module.exports = {
|
326
|
-
start
|
327
|
-
getUrl
|
328
|
-
getProxyUrl
|
306
|
+
start,
|
307
|
+
getUrl,
|
308
|
+
getProxyUrl
|
329
309
|
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
const fs = require('../fs');
|
4
|
+
|
5
|
+
const {
|
6
|
+
join
|
7
|
+
} = require('path');
|
8
|
+
|
9
|
+
const Bluebird = require('bluebird');
|
10
|
+
/**
|
11
|
+
* Get the size of a folder or a file.
|
12
|
+
*
|
13
|
+
* This function returns the actual file size of the folder (size), not the allocated space on disk (size on disk).
|
14
|
+
* For more details between the difference, check this link:
|
15
|
+
* https://www.howtogeek.com/180369/why-is-there-a-big-difference-between-size-and-size-on-disk/
|
16
|
+
*
|
17
|
+
* @param {string} path path to the file or the folder.
|
18
|
+
*/
|
19
|
+
|
20
|
+
|
21
|
+
async function getSize(path) {
|
22
|
+
const stat = await fs.lstat(path);
|
23
|
+
|
24
|
+
if (stat.isDirectory()) {
|
25
|
+
const list = await fs.readdir(path);
|
26
|
+
return Bluebird.resolve(list).reduce(async (prev, curr) => {
|
27
|
+
const currPath = join(path, curr);
|
28
|
+
const s = await fs.lstat(currPath);
|
29
|
+
|
30
|
+
if (s.isDirectory()) {
|
31
|
+
return prev + (await getSize(currPath));
|
32
|
+
}
|
33
|
+
|
34
|
+
return prev + s.size;
|
35
|
+
}, 0);
|
36
|
+
}
|
37
|
+
|
38
|
+
return stat.size;
|
39
|
+
}
|
40
|
+
|
41
|
+
module.exports = getSize;
|