cypress 12.1.0 → 12.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.
@@ -1,49 +1,35 @@
1
1
  "use strict";
2
2
 
3
3
  const state = require('./state');
4
-
5
4
  const logger = require('../logger');
6
-
7
5
  const fs = require('../fs');
8
-
9
6
  const util = require('../util');
10
-
11
7
  const {
12
8
  join
13
9
  } = require('path');
14
-
15
10
  const Table = require('cli-table3');
16
-
17
11
  const dayjs = require('dayjs');
18
-
19
12
  const relativeTime = require('dayjs/plugin/relativeTime');
20
-
21
13
  const chalk = require('chalk');
22
-
23
14
  const _ = require('lodash');
24
-
25
15
  const getFolderSize = require('./get-folder-size');
26
-
27
16
  const Bluebird = require('bluebird');
17
+ dayjs.extend(relativeTime);
28
18
 
29
- dayjs.extend(relativeTime); // output colors for the table
30
-
19
+ // output colors for the table
31
20
  const colors = {
32
21
  titles: chalk.white,
33
22
  dates: chalk.cyan,
34
23
  values: chalk.green,
35
24
  size: chalk.gray
36
25
  };
37
-
38
26
  const logCachePath = () => {
39
27
  logger.always(state.getCacheDir());
40
28
  return undefined;
41
29
  };
42
-
43
30
  const clear = () => {
44
31
  return fs.removeAsync(state.getCacheDir());
45
32
  };
46
-
47
33
  const prune = () => {
48
34
  const cacheDir = state.getCacheDir();
49
35
  const currentVersion = util.pkgVersion();
@@ -68,24 +54,20 @@ const prune = () => {
68
54
  logger.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
69
55
  });
70
56
  };
71
-
72
57
  const fileSizeInMB = size => {
73
58
  return `${(size / 1024 / 1024).toFixed(1)}MB`;
74
59
  };
60
+
75
61
  /**
76
62
  * Collects all cached versions, finds when each was used
77
63
  * and prints a table with results to the terminal
78
64
  */
79
-
80
-
81
65
  const list = showSize => {
82
66
  return getCachedVersions(showSize).then(binaries => {
83
67
  const head = [colors.titles('version'), colors.titles('last used')];
84
-
85
68
  if (showSize) {
86
69
  head.push(colors.titles('size'));
87
70
  }
88
-
89
71
  const table = new Table({
90
72
  head
91
73
  });
@@ -93,18 +75,15 @@ const list = showSize => {
93
75
  const versionString = colors.values(binary.version);
94
76
  const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
95
77
  const row = [versionString, lastUsed];
96
-
97
78
  if (showSize) {
98
79
  const size = colors.size(fileSizeInMB(binary.size));
99
80
  row.push(size);
100
81
  }
101
-
102
82
  return table.push(row);
103
83
  });
104
84
  logger.always(table.toString());
105
85
  });
106
86
  };
107
-
108
87
  const getCachedVersions = showSize => {
109
88
  const cacheDir = state.getCacheDir();
110
89
  return fs.readdirAsync(cacheDir).filter(util.isSemver).map(version => {
@@ -119,13 +98,11 @@ const getCachedVersions = showSize => {
119
98
  const executable = state.getPathToExecutable(binaryDir);
120
99
  return fs.statAsync(executable).then(stat => {
121
100
  const lastAccessedTime = _.get(stat, 'atime');
122
-
123
101
  if (!lastAccessedTime) {
124
102
  // the test runner has never been opened
125
103
  // or could be a test simulating missing timestamp
126
104
  return binary;
127
105
  }
128
-
129
106
  const accessed = dayjs(lastAccessedTime).fromNow();
130
107
  binary.accessed = accessed;
131
108
  return binary;
@@ -137,16 +114,15 @@ const getCachedVersions = showSize => {
137
114
  if (showSize) {
138
115
  const binaryDir = state.getBinaryDir(binary.version);
139
116
  return getFolderSize(binaryDir).then(size => {
140
- return { ...binary,
117
+ return {
118
+ ...binary,
141
119
  size
142
120
  };
143
121
  });
144
122
  }
145
-
146
123
  return binary;
147
124
  });
148
125
  };
149
-
150
126
  module.exports = {
151
127
  path: logCachePath,
152
128
  clear,
@@ -1,59 +1,39 @@
1
1
  "use strict";
2
2
 
3
3
  const la = require('lazy-ass');
4
-
5
4
  const is = require('check-more-types');
6
-
7
5
  const os = require('os');
8
-
9
6
  const url = require('url');
10
-
11
7
  const path = require('path');
12
-
13
8
  const debug = require('debug')('cypress:cli');
14
-
15
9
  const request = require('@cypress/request');
16
-
17
10
  const Promise = require('bluebird');
18
-
19
11
  const requestProgress = require('request-progress');
20
-
21
12
  const {
22
13
  stripIndent
23
14
  } = require('common-tags');
24
-
25
15
  const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
26
-
27
16
  const {
28
17
  throwFormErrorText,
29
18
  errors
30
19
  } = require('../errors');
31
-
32
20
  const fs = require('../fs');
33
-
34
21
  const util = require('../util');
35
-
36
22
  const defaultBaseUrl = 'https://download.cypress.io/';
37
23
  const defaultMaxRedirects = 10;
38
-
39
24
  const getProxyForUrlWithNpmConfig = url => {
40
25
  return getProxyForUrl(url) || process.env.npm_config_https_proxy || process.env.npm_config_proxy || null;
41
26
  };
42
-
43
27
  const getBaseUrl = () => {
44
28
  if (util.getEnv('CYPRESS_DOWNLOAD_MIRROR')) {
45
29
  let baseUrl = util.getEnv('CYPRESS_DOWNLOAD_MIRROR');
46
-
47
30
  if (!baseUrl.endsWith('/')) {
48
31
  baseUrl += '/';
49
32
  }
50
-
51
33
  return baseUrl;
52
34
  }
53
-
54
35
  return defaultBaseUrl;
55
36
  };
56
-
57
37
  const getCA = () => {
58
38
  return new Promise(resolve => {
59
39
  if (process.env.npm_config_cafile) {
@@ -69,28 +49,23 @@ const getCA = () => {
69
49
  }
70
50
  });
71
51
  };
72
-
73
52
  const prepend = (arch, urlPath, version) => {
74
53
  const endpoint = url.resolve(getBaseUrl(), urlPath);
75
54
  const platform = os.platform();
76
55
  const pathTemplate = util.getEnv('CYPRESS_DOWNLOAD_PATH_TEMPLATE', true);
77
56
  return pathTemplate ? pathTemplate.replace(/\\?\$\{endpoint\}/, endpoint).replace(/\\?\$\{platform\}/, platform).replace(/\\?\$\{arch\}/, arch).replace(/\\?\$\{version\}/, version) : `${endpoint}?platform=${platform}&arch=${arch}`;
78
57
  };
79
-
80
58
  const getUrl = (arch, version) => {
81
59
  if (is.url(version)) {
82
60
  debug('version is already an url', version);
83
61
  return version;
84
62
  }
85
-
86
63
  const urlPath = version ? `desktop/${version}` : 'desktop';
87
64
  return prepend(arch, urlPath, version);
88
65
  };
89
-
90
66
  const statusMessage = err => {
91
67
  return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString();
92
68
  };
93
-
94
69
  const prettyDownloadErr = (err, url) => {
95
70
  const msg = stripIndent`
96
71
  URL: ${url}
@@ -99,12 +74,11 @@ const prettyDownloadErr = (err, url) => {
99
74
  debug(msg);
100
75
  return throwFormErrorText(errors.failedDownload)(msg);
101
76
  };
77
+
102
78
  /**
103
79
  * Checks checksum and file size for the given file. Allows both
104
80
  * values or just one of them to be checked.
105
81
  */
106
-
107
-
108
82
  const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
109
83
  if (expectedSize && expectedChecksum) {
110
84
  debug('verifying checksum and file size');
@@ -113,7 +87,6 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
113
87
  debug('downloaded file has the expected checksum and size ✅');
114
88
  return;
115
89
  }
116
-
117
90
  debug('raising error: checksum or file size mismatch');
118
91
  const text = stripIndent`
119
92
  Corrupted download
@@ -128,7 +101,6 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
128
101
  throw new Error(text);
129
102
  });
130
103
  }
131
-
132
104
  if (expectedChecksum) {
133
105
  debug('only checking expected file checksum %d', expectedChecksum);
134
106
  return util.getFileChecksum(filename).then(checksum => {
@@ -136,7 +108,6 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
136
108
  debug('downloaded file has the expected checksum ✅');
137
109
  return;
138
110
  }
139
-
140
111
  debug('raising error: file checksum mismatch');
141
112
  const text = stripIndent`
142
113
  Corrupted download
@@ -147,7 +118,6 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
147
118
  throw new Error(text);
148
119
  });
149
120
  }
150
-
151
121
  if (expectedSize) {
152
122
  // maybe we don't have a checksum, but at least CDN returns content length
153
123
  // which we can check against the file size
@@ -157,7 +127,6 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
157
127
  debug('downloaded file has the expected size ✅');
158
128
  return;
159
129
  }
160
-
161
130
  debug('raising error: file size mismatch');
162
131
  const text = stripIndent`
163
132
  Corrupted download
@@ -168,14 +137,13 @@ const verifyDownloadedFile = (filename, expectedSize, expectedChecksum) => {
168
137
  throw new Error(text);
169
138
  });
170
139
  }
171
-
172
140
  debug('downloaded file lacks checksum or size to verify');
173
141
  return Promise.resolve();
174
- }; // downloads from given url
142
+ };
143
+
144
+ // downloads from given url
175
145
  // return an object with
176
146
  // {filename: ..., downloaded: true}
177
-
178
-
179
147
  const downloadFromUrl = ({
180
148
  url,
181
149
  downloadDestination,
@@ -191,7 +159,6 @@ const downloadFromUrl = ({
191
159
  Maybe you got stuck in a redirect loop?
192
160
  `));
193
161
  }
194
-
195
162
  return new Promise((resolve, reject) => {
196
163
  const proxy = getProxyForUrlWithNpmConfig(url);
197
164
  debug('Downloading package', {
@@ -199,11 +166,9 @@ const downloadFromUrl = ({
199
166
  proxy,
200
167
  downloadDestination
201
168
  });
202
-
203
169
  if (ca) {
204
170
  debug('using custom CA details from npm config');
205
171
  }
206
-
207
172
  const reqOptions = {
208
173
  uri: url,
209
174
  ...(proxy ? {
@@ -217,8 +182,9 @@ const downloadFromUrl = ({
217
182
  method: 'GET',
218
183
  followRedirect: false
219
184
  };
220
- const req = request(reqOptions); // closure
185
+ const req = request(reqOptions);
221
186
 
187
+ // closure
222
188
  let started = null;
223
189
  let expectedSize;
224
190
  let expectedChecksum;
@@ -231,21 +197,18 @@ const downloadFromUrl = ({
231
197
  // see https://github.com/cypress-io/cypress/pull/4092
232
198
  expectedSize = response.headers['x-amz-meta-size'] || response.headers['content-length'];
233
199
  expectedChecksum = response.headers['x-amz-meta-checksum'];
234
-
235
200
  if (expectedChecksum) {
236
201
  debug('expected checksum %s', expectedChecksum);
237
202
  }
238
-
239
203
  if (expectedSize) {
240
204
  // convert from string (all Amazon custom headers are strings)
241
205
  expectedSize = Number(expectedSize);
242
206
  debug('expected file size %d', expectedSize);
243
- } // start counting now once we've gotten
244
- // response headers
245
-
207
+ }
246
208
 
209
+ // start counting now once we've gotten
210
+ // response headers
247
211
  started = new Date();
248
-
249
212
  if (/^3/.test(response.statusCode)) {
250
213
  const redirectVersion = response.headers['x-version'];
251
214
  const redirectUrl = response.headers.location;
@@ -258,7 +221,9 @@ const downloadFromUrl = ({
258
221
  downloadDestination,
259
222
  version: redirectVersion,
260
223
  redirectTTL: redirectTTL - 1
261
- }).then(resolve).catch(reject); // if our status code does not start with 200
224
+ }).then(resolve).catch(reject);
225
+
226
+ // if our status code does not start with 200
262
227
  } else if (!/^2/.test(response.statusCode)) {
263
228
  debug('response code %d', response.statusCode);
264
229
  const err = new Error(stripIndent`
@@ -266,7 +231,8 @@ const downloadFromUrl = ({
266
231
  Response code: ${response.statusCode}
267
232
  Response message: ${response.statusMessage}
268
233
  `);
269
- reject(err); // status codes here are all 2xx
234
+ reject(err);
235
+ // status codes here are all 2xx
270
236
  } else {
271
237
  // We only enable this pipe connection when we know we've got a successful return
272
238
  // and handle the completion with verify and resolve
@@ -286,22 +252,23 @@ const downloadFromUrl = ({
286
252
  }).on('progress', state => {
287
253
  // total time we've elapsed
288
254
  // starting on our first progress notification
289
- const elapsed = new Date() - started; // request-progress sends a value between 0 and 1
255
+ const elapsed = new Date() - started;
290
256
 
257
+ // request-progress sends a value between 0 and 1
291
258
  const percentage = util.convertPercentToPercentage(state.percent);
292
- const eta = util.calculateEta(percentage, elapsed); // send up our percent and seconds remaining
259
+ const eta = util.calculateEta(percentage, elapsed);
293
260
 
261
+ // send up our percent and seconds remaining
294
262
  progress.onProgress(percentage, util.secsRemaining(eta));
295
263
  });
296
264
  });
297
265
  };
266
+
298
267
  /**
299
268
  * Download Cypress.zip from external versionUrl to local file.
300
269
  * @param [string] version Could be "3.3.0" or full URL
301
270
  * @param [string] downloadDestination Local filename to save as
302
271
  */
303
-
304
-
305
272
  const start = async opts => {
306
273
  let {
307
274
  version,
@@ -309,11 +276,9 @@ const start = async opts => {
309
276
  progress,
310
277
  redirectTTL
311
278
  } = opts;
312
-
313
279
  if (!downloadDestination) {
314
280
  la(is.unemptyString(downloadDestination), 'missing download dir', opts);
315
281
  }
316
-
317
282
  if (!progress) {
318
283
  progress = {
319
284
  onProgress: () => {
@@ -321,14 +286,14 @@ const start = async opts => {
321
286
  }
322
287
  };
323
288
  }
324
-
325
289
  const arch = await util.getRealArch();
326
290
  const versionUrl = getUrl(arch, version);
327
291
  progress.throttle = 100;
328
292
  debug('needed Cypress version: %s', version);
329
293
  debug('source url %s', versionUrl);
330
- debug(`downloading cypress.zip to "${downloadDestination}"`); // ensure download dir exists
294
+ debug(`downloading cypress.zip to "${downloadDestination}"`);
331
295
 
296
+ // ensure download dir exists
332
297
  return fs.ensureDirAsync(path.dirname(downloadDestination)).then(() => {
333
298
  return getCA();
334
299
  }).then(ca => {
@@ -346,7 +311,6 @@ const start = async opts => {
346
311
  return prettyDownloadErr(err, versionUrl);
347
312
  });
348
313
  };
349
-
350
314
  module.exports = {
351
315
  start,
352
316
  getUrl,
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  const fs = require('../fs');
4
-
5
4
  const {
6
5
  join
7
6
  } = require('path');
8
-
9
7
  const Bluebird = require('bluebird');
8
+
10
9
  /**
11
10
  * Get the size of a folder or a file.
12
11
  *
@@ -16,26 +15,19 @@ const Bluebird = require('bluebird');
16
15
  *
17
16
  * @param {string} path path to the file or the folder.
18
17
  */
19
-
20
-
21
18
  async function getSize(path) {
22
19
  const stat = await fs.lstat(path);
23
-
24
20
  if (stat.isDirectory()) {
25
21
  const list = await fs.readdir(path);
26
22
  return Bluebird.resolve(list).reduce(async (prev, curr) => {
27
23
  const currPath = join(path, curr);
28
24
  const s = await fs.lstat(currPath);
29
-
30
25
  if (s.isDirectory()) {
31
26
  return prev + (await getSize(currPath));
32
27
  }
33
-
34
28
  return prev + s.size;
35
29
  }, 0);
36
30
  }
37
-
38
31
  return stat.size;
39
32
  }
40
-
41
33
  module.exports = getSize;