cypress 9.2.0 → 9.2.1
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/lib/tasks/download.js +67 -40
- package/lib/tasks/verify.js +1 -1
- package/package.json +2 -2
package/lib/tasks/download.js
CHANGED
@@ -8,7 +8,7 @@ const is = require('check-more-types');
|
|
8
8
|
|
9
9
|
const os = require('os');
|
10
10
|
|
11
|
-
const
|
11
|
+
const Url = require('url');
|
12
12
|
|
13
13
|
const path = require('path');
|
14
14
|
|
@@ -36,6 +36,7 @@ const fs = require('../fs');
|
|
36
36
|
const util = require('../util');
|
37
37
|
|
38
38
|
const defaultBaseUrl = 'https://download.cypress.io/';
|
39
|
+
const defaultMaxRedirects = 10;
|
39
40
|
|
40
41
|
const getProxyForUrlWithNpmConfig = url => {
|
41
42
|
return getProxyForUrl(url) || process.env.npm_config_https_proxy || process.env.npm_config_proxy || null;
|
@@ -76,7 +77,7 @@ const getCA = () => {
|
|
76
77
|
};
|
77
78
|
|
78
79
|
const prepend = urlPath => {
|
79
|
-
const endpoint =
|
80
|
+
const endpoint = Url.resolve(getBaseUrl(), urlPath);
|
80
81
|
const platform = os.platform();
|
81
82
|
return `${endpoint}?platform=${platform}&arch=${arch()}`;
|
82
83
|
};
|
@@ -183,8 +184,18 @@ const downloadFromUrl = ({
|
|
183
184
|
url,
|
184
185
|
downloadDestination,
|
185
186
|
progress,
|
186
|
-
ca
|
187
|
+
ca,
|
188
|
+
version,
|
189
|
+
redirectTTL = defaultMaxRedirects
|
187
190
|
}) => {
|
191
|
+
if (redirectTTL <= 0) {
|
192
|
+
return Promise.reject(new Error(stripIndent`
|
193
|
+
Failed downloading the Cypress binary.
|
194
|
+
There were too many redirects. The default allowance is ${defaultMaxRedirects}.
|
195
|
+
Maybe you got stuck in a redirect loop?
|
196
|
+
`));
|
197
|
+
}
|
198
|
+
|
188
199
|
return new Promise((resolve, reject) => {
|
189
200
|
const proxy = getProxyForUrlWithNpmConfig(url);
|
190
201
|
debug('Downloading package', {
|
@@ -192,35 +203,24 @@ const downloadFromUrl = ({
|
|
192
203
|
proxy,
|
193
204
|
downloadDestination
|
194
205
|
});
|
195
|
-
let redirectVersion;
|
196
|
-
const reqOptions = {
|
197
|
-
url,
|
198
|
-
proxy,
|
199
|
-
|
200
|
-
followRedirect(response) {
|
201
|
-
const version = response.headers['x-version'];
|
202
|
-
debug('redirect version:', version);
|
203
|
-
|
204
|
-
if (version) {
|
205
|
-
// set the version in options if we have one.
|
206
|
-
// this insulates us from potential redirect
|
207
|
-
// problems where version would be set to undefined.
|
208
|
-
redirectVersion = version;
|
209
|
-
} // yes redirect
|
210
|
-
|
211
|
-
|
212
|
-
return true;
|
213
|
-
}
|
214
|
-
|
215
|
-
};
|
216
206
|
|
217
207
|
if (ca) {
|
218
208
|
debug('using custom CA details from npm config');
|
219
|
-
reqOptions.agentOptions = {
|
220
|
-
ca
|
221
|
-
};
|
222
209
|
}
|
223
210
|
|
211
|
+
const reqOptions = {
|
212
|
+
uri: url,
|
213
|
+
...(proxy ? {
|
214
|
+
proxy
|
215
|
+
} : {}),
|
216
|
+
...(ca ? {
|
217
|
+
agentOptions: {
|
218
|
+
ca
|
219
|
+
}
|
220
|
+
} : {}),
|
221
|
+
method: 'GET',
|
222
|
+
followRedirect: false
|
223
|
+
};
|
224
224
|
const req = request(reqOptions); // closure
|
225
225
|
|
226
226
|
let started = null;
|
@@ -248,18 +248,46 @@ const downloadFromUrl = ({
|
|
248
248
|
// response headers
|
249
249
|
|
250
250
|
|
251
|
-
started = new Date();
|
252
|
-
|
253
|
-
if (
|
251
|
+
started = new Date();
|
252
|
+
|
253
|
+
if (/^3/.test(response.statusCode)) {
|
254
|
+
const redirectVersion = response.headers['x-version'];
|
255
|
+
const redirectUrl = response.headers.location;
|
256
|
+
debug('redirect version:', redirectVersion);
|
257
|
+
debug('redirect url:', redirectUrl);
|
258
|
+
downloadFromUrl({
|
259
|
+
url: redirectUrl,
|
260
|
+
progress,
|
261
|
+
ca,
|
262
|
+
downloadDestination,
|
263
|
+
version: redirectVersion,
|
264
|
+
redirectTTL: redirectTTL - 1
|
265
|
+
}).then(resolve).catch(reject); // if our status code does not start with 200
|
266
|
+
} else if (!/^2/.test(response.statusCode)) {
|
254
267
|
debug('response code %d', response.statusCode);
|
255
268
|
const err = new Error(stripIndent`
|
256
269
|
Failed downloading the Cypress binary.
|
257
270
|
Response code: ${response.statusCode}
|
258
271
|
Response message: ${response.statusMessage}
|
259
272
|
`);
|
260
|
-
reject(err);
|
273
|
+
reject(err); // status codes here are all 2xx
|
274
|
+
} else {
|
275
|
+
// We only enable this pipe connection when we know we've got a successful return
|
276
|
+
// and handle the completion with verify and resolve
|
277
|
+
// there was a possible race condition between end of request and close of writeStream
|
278
|
+
// that is made ordered with this Promise.all
|
279
|
+
Promise.all([new Promise(r => {
|
280
|
+
return response.pipe(fs.createWriteStream(downloadDestination).on('close', r));
|
281
|
+
}), new Promise(r => response.on('end', r))]).then(() => {
|
282
|
+
debug('downloading finished');
|
283
|
+
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(() => debug('verified')).then(() => resolve(version)).catch(reject);
|
284
|
+
});
|
261
285
|
}
|
262
|
-
}).on('error',
|
286
|
+
}).on('error', e => {
|
287
|
+
if (e.code === 'ECONNRESET') return; // sometimes proxies give ECONNRESET but we don't care
|
288
|
+
|
289
|
+
reject(e);
|
290
|
+
}).on('progress', state => {
|
263
291
|
// total time we've elapsed
|
264
292
|
// starting on our first progress notification
|
265
293
|
const elapsed = new Date() - started; // request-progress sends a value between 0 and 1
|
@@ -268,12 +296,6 @@ const downloadFromUrl = ({
|
|
268
296
|
const eta = util.calculateEta(percentage, elapsed); // send up our percent and seconds remaining
|
269
297
|
|
270
298
|
progress.onProgress(percentage, util.secsRemaining(eta));
|
271
|
-
}) // save this download here
|
272
|
-
.pipe(fs.createWriteStream(downloadDestination)).on('finish', () => {
|
273
|
-
debug('downloading finished');
|
274
|
-
verifyDownloadedFile(downloadDestination, expectedSize, expectedChecksum).then(() => {
|
275
|
-
return resolve(redirectVersion);
|
276
|
-
}, reject);
|
277
299
|
});
|
278
300
|
});
|
279
301
|
};
|
@@ -288,7 +310,8 @@ const start = opts => {
|
|
288
310
|
let {
|
289
311
|
version,
|
290
312
|
downloadDestination,
|
291
|
-
progress
|
313
|
+
progress,
|
314
|
+
redirectTTL
|
292
315
|
} = opts;
|
293
316
|
|
294
317
|
if (!downloadDestination) {
|
@@ -316,7 +339,11 @@ const start = opts => {
|
|
316
339
|
url,
|
317
340
|
downloadDestination,
|
318
341
|
progress,
|
319
|
-
ca
|
342
|
+
ca,
|
343
|
+
version,
|
344
|
+
...(redirectTTL ? {
|
345
|
+
redirectTTL
|
346
|
+
} : {})
|
320
347
|
});
|
321
348
|
}).catch(err => {
|
322
349
|
return prettyDownloadErr(err, version);
|
package/lib/tasks/verify.js
CHANGED
@@ -37,7 +37,7 @@ const xvfb = require('../exec/xvfb');
|
|
37
37
|
|
38
38
|
const state = require('./state');
|
39
39
|
|
40
|
-
const VERIFY_TEST_RUNNER_TIMEOUT_MS = process.env.CYPRESS_VERIFY_TIMEOUT || 30000;
|
40
|
+
const VERIFY_TEST_RUNNER_TIMEOUT_MS = +process.env.CYPRESS_VERIFY_TIMEOUT || 30000;
|
41
41
|
|
42
42
|
const checkExecutable = binaryDir => {
|
43
43
|
const executable = state.getPathToExecutable(binaryDir);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "cypress",
|
3
|
-
"version": "9.2.
|
3
|
+
"version": "9.2.1",
|
4
4
|
"main": "index.js",
|
5
5
|
"scripts": {
|
6
6
|
"postinstall": "node index.js --exec install",
|
@@ -19,7 +19,7 @@
|
|
19
19
|
"chalk": "^4.1.0",
|
20
20
|
"check-more-types": "^2.24.0",
|
21
21
|
"cli-cursor": "^3.1.0",
|
22
|
-
"cli-table3": "~0.6.
|
22
|
+
"cli-table3": "~0.6.1",
|
23
23
|
"commander": "^5.1.0",
|
24
24
|
"common-tags": "^1.8.0",
|
25
25
|
"dayjs": "^1.10.4",
|