cypress 15.2.0 → 15.3.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 +1 -1
- package/{lib → dist}/cli.js +219 -190
- package/{lib → dist}/cypress.js +29 -26
- package/{lib → dist}/errors.js +38 -26
- package/{lib → dist}/exec/open.js +14 -5
- package/{lib → dist}/exec/run.js +37 -26
- package/dist/exec/spawn.js +301 -0
- package/dist/exec/versions.js +67 -0
- package/{lib → dist}/exec/xvfb.js +47 -20
- package/{index.js → dist/index.js} +5 -5
- package/dist/index.mjs +9 -0
- package/{lib → dist}/tasks/cache.js +49 -52
- package/{lib → dist}/tasks/download.js +55 -64
- package/{lib → dist}/tasks/get-folder-size.js +4 -4
- package/{lib → dist}/tasks/install.js +41 -45
- package/{lib → dist}/tasks/state.js +55 -45
- package/dist/tasks/unzip.js +192 -0
- package/{lib → dist}/tasks/verify.js +121 -131
- package/{lib → dist}/util.js +38 -36
- package/package.json +10 -13
- package/types/cypress-automation.d.ts +2 -1
- package/types/cypress.d.ts +1 -0
- package/index.mjs +0 -17
- package/lib/exec/spawn.js +0 -285
- package/lib/exec/versions.js +0 -61
- package/lib/fs.js +0 -8
- package/lib/tasks/unzip.js +0 -198
- /package/{lib → dist}/VerboseRenderer.js +0 -0
- /package/{lib → dist}/exec/info.js +0 -0
- /package/{lib → dist}/exec/shared.js +0 -0
- /package/{lib → dist}/logger.js +0 -0
package/{lib → dist}/errors.js
RENAMED
@@ -1,4 +1,13 @@
|
|
1
1
|
"use strict";
|
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
|
+
};
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
13
|
};
|
@@ -8,8 +17,8 @@ exports.getError = getError;
|
|
8
17
|
exports.formErrorText = formErrorText;
|
9
18
|
const chalk_1 = __importDefault(require("chalk"));
|
10
19
|
const common_tags_1 = require("common-tags");
|
11
|
-
const
|
12
|
-
const
|
20
|
+
const lodash_1 = __importDefault(require("lodash"));
|
21
|
+
const assert_1 = __importDefault(require("assert"));
|
13
22
|
const util_1 = __importDefault(require("./util"));
|
14
23
|
const state_1 = __importDefault(require("./tasks/state"));
|
15
24
|
const docsUrl = 'https://on.cypress.io';
|
@@ -238,7 +247,8 @@ const CYPRESS_RUN_BINARY = {
|
|
238
247
|
},
|
239
248
|
};
|
240
249
|
function addPlatformInformation(info) {
|
241
|
-
return
|
250
|
+
return __awaiter(this, void 0, void 0, function* () {
|
251
|
+
const platform = yield util_1.default.getPlatformInfo();
|
242
252
|
return Object.assign(Object.assign({}, info), { platform });
|
243
253
|
});
|
244
254
|
}
|
@@ -255,7 +265,8 @@ function addPlatformInformation(info) {
|
|
255
265
|
```
|
256
266
|
*/
|
257
267
|
function getError(errorObject) {
|
258
|
-
return
|
268
|
+
return __awaiter(this, void 0, void 0, function* () {
|
269
|
+
const errorMessage = yield formErrorText(errorObject);
|
259
270
|
const err = new Error(errorMessage);
|
260
271
|
err.known = true;
|
261
272
|
return err;
|
@@ -266,30 +277,31 @@ function getError(errorObject) {
|
|
266
277
|
* and if possible a way to solve it. Resolves with a string.
|
267
278
|
*/
|
268
279
|
function formErrorText(info, msg, prevMessage) {
|
269
|
-
return
|
280
|
+
return __awaiter(this, void 0, void 0, function* () {
|
281
|
+
const infoWithPlatform = yield addPlatformInformation(info);
|
270
282
|
const formatted = [];
|
271
283
|
function add(msg) {
|
272
284
|
formatted.push((0, common_tags_1.stripIndents)(msg));
|
273
285
|
}
|
274
|
-
(
|
286
|
+
assert_1.default.ok(lodash_1.default.isString(infoWithPlatform.description) && !lodash_1.default.isEmpty(infoWithPlatform.description), 'expected error description to be text.');
|
275
287
|
// assuming that if there the solution is a function it will handle
|
276
288
|
// error message and (optional previous error message)
|
277
|
-
if (
|
278
|
-
const text =
|
279
|
-
(
|
289
|
+
if (lodash_1.default.isFunction(infoWithPlatform.solution)) {
|
290
|
+
const text = infoWithPlatform.solution(msg, prevMessage);
|
291
|
+
assert_1.default.ok(lodash_1.default.isString(text) && !lodash_1.default.isEmpty(text), 'expected solution to be text.');
|
280
292
|
add(`
|
281
|
-
${
|
293
|
+
${infoWithPlatform.description}
|
282
294
|
|
283
295
|
${text}
|
284
296
|
|
285
297
|
`);
|
286
298
|
}
|
287
299
|
else {
|
288
|
-
(
|
300
|
+
assert_1.default.ok(lodash_1.default.isString(infoWithPlatform.solution) && !lodash_1.default.isEmpty(infoWithPlatform.solution), 'expected error solution to be text.');
|
289
301
|
add(`
|
290
|
-
${
|
302
|
+
${infoWithPlatform.description}
|
291
303
|
|
292
|
-
${
|
304
|
+
${infoWithPlatform.solution}
|
293
305
|
|
294
306
|
`);
|
295
307
|
if (msg) {
|
@@ -304,14 +316,14 @@ function formErrorText(info, msg, prevMessage) {
|
|
304
316
|
add(`
|
305
317
|
${exports.hr}
|
306
318
|
|
307
|
-
${
|
319
|
+
${infoWithPlatform.platform}
|
308
320
|
`);
|
309
|
-
if (
|
321
|
+
if (infoWithPlatform.footer) {
|
310
322
|
add(`
|
311
323
|
|
312
324
|
${exports.hr}
|
313
325
|
|
314
|
-
${
|
326
|
+
${infoWithPlatform.footer}
|
315
327
|
`);
|
316
328
|
}
|
317
329
|
return formatted.join('\n\n');
|
@@ -329,9 +341,10 @@ const raise = (info) => {
|
|
329
341
|
};
|
330
342
|
exports.raise = raise;
|
331
343
|
const throwFormErrorText = (info) => {
|
332
|
-
return (msg, prevMessage) => {
|
333
|
-
|
334
|
-
|
344
|
+
return (msg, prevMessage) => __awaiter(void 0, void 0, void 0, function* () {
|
345
|
+
const errorText = yield formErrorText(info, msg, prevMessage);
|
346
|
+
(0, exports.raise)(info)(errorText);
|
347
|
+
});
|
335
348
|
};
|
336
349
|
exports.throwFormErrorText = throwFormErrorText;
|
337
350
|
/**
|
@@ -341,13 +354,12 @@ exports.throwFormErrorText = throwFormErrorText;
|
|
341
354
|
* @example return exitWithError(errors.invalidCypressEnv)('foo')
|
342
355
|
*/
|
343
356
|
const exitWithError = (info) => {
|
344
|
-
return (msg) => {
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
};
|
357
|
+
return (msg) => __awaiter(void 0, void 0, void 0, function* () {
|
358
|
+
const text = yield formErrorText(info, msg);
|
359
|
+
// eslint-disable-next-line no-console
|
360
|
+
console.error(text);
|
361
|
+
process.exit(info.exitCode || 1);
|
362
|
+
});
|
351
363
|
};
|
352
364
|
exports.exitWithError = exitWithError;
|
353
365
|
exports.errors = {
|
@@ -1,4 +1,13 @@
|
|
1
1
|
"use strict";
|
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
|
+
};
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
13
|
};
|
@@ -7,7 +16,7 @@ exports.start = exports.processOpenOptions = void 0;
|
|
7
16
|
const debug_1 = __importDefault(require("debug"));
|
8
17
|
const util_1 = __importDefault(require("../util"));
|
9
18
|
const spawn_1 = __importDefault(require("./spawn"));
|
10
|
-
const verify_1 =
|
19
|
+
const verify_1 = require("../tasks/verify");
|
11
20
|
const shared_1 = require("./shared");
|
12
21
|
const errors_1 = require("../errors");
|
13
22
|
const debug = (0, debug_1.default)('cypress:cli');
|
@@ -65,7 +74,7 @@ const processOpenOptions = (options = {}) => {
|
|
65
74
|
return args;
|
66
75
|
};
|
67
76
|
exports.processOpenOptions = processOpenOptions;
|
68
|
-
const start = (options = {})
|
77
|
+
const start = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (options = {}) {
|
69
78
|
function open() {
|
70
79
|
try {
|
71
80
|
const args = (0, exports.processOpenOptions)(options);
|
@@ -84,9 +93,9 @@ const start = (options = {}) => {
|
|
84
93
|
if (options.dev) {
|
85
94
|
return open();
|
86
95
|
}
|
87
|
-
|
88
|
-
|
89
|
-
};
|
96
|
+
yield (0, verify_1.start)();
|
97
|
+
return open();
|
98
|
+
});
|
90
99
|
exports.start = start;
|
91
100
|
exports.default = {
|
92
101
|
start: exports.start,
|
package/{lib → dist}/exec/run.js
RENAMED
@@ -1,4 +1,13 @@
|
|
1
1
|
"use strict";
|
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
|
+
};
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
13
|
};
|
@@ -7,7 +16,7 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
7
16
|
const debug_1 = __importDefault(require("debug"));
|
8
17
|
const util_1 = __importDefault(require("../util"));
|
9
18
|
const spawn_1 = __importDefault(require("./spawn"));
|
10
|
-
const verify_1 =
|
19
|
+
const verify_1 = require("../tasks/verify");
|
11
20
|
const errors_1 = require("../errors");
|
12
21
|
const shared_1 = require("./shared");
|
13
22
|
const debug = (0, debug_1.default)('cypress:cli:run');
|
@@ -133,34 +142,36 @@ const runModule = {
|
|
133
142
|
processRunOptions,
|
134
143
|
isValidProject,
|
135
144
|
// resolves with the number of failed tests
|
136
|
-
start(
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
145
|
+
start() {
|
146
|
+
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
147
|
+
lodash_1.default.defaults(options, {
|
148
|
+
key: null,
|
149
|
+
spec: null,
|
150
|
+
reporter: null,
|
151
|
+
reporterOptions: null,
|
152
|
+
project: process.cwd(),
|
153
|
+
});
|
154
|
+
function run() {
|
155
|
+
try {
|
156
|
+
const args = processRunOptions(options);
|
157
|
+
debug('run to spawn.start args %j', args);
|
158
|
+
return spawn_1.default.start(args, {
|
159
|
+
dev: options.dev,
|
160
|
+
});
|
161
|
+
}
|
162
|
+
catch (err) {
|
163
|
+
if (err.details) {
|
164
|
+
return (0, errors_1.exitWithError)(err.details)();
|
165
|
+
}
|
166
|
+
throw err;
|
155
167
|
}
|
156
|
-
throw err;
|
157
168
|
}
|
158
|
-
|
159
|
-
|
169
|
+
if (options.dev) {
|
170
|
+
return run();
|
171
|
+
}
|
172
|
+
yield (0, verify_1.start)();
|
160
173
|
return run();
|
161
|
-
}
|
162
|
-
return verify_1.default.start()
|
163
|
-
.then(run);
|
174
|
+
});
|
164
175
|
},
|
165
176
|
};
|
166
177
|
exports.default = runModule;
|
@@ -0,0 +1,301 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
42
|
+
});
|
43
|
+
};
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
46
|
+
};
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
48
|
+
const lodash_1 = __importDefault(require("lodash"));
|
49
|
+
const os_1 = __importDefault(require("os"));
|
50
|
+
const child_process_1 = __importDefault(require("child_process"));
|
51
|
+
const path_1 = __importDefault(require("path"));
|
52
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
53
|
+
const debug_1 = __importDefault(require("debug"));
|
54
|
+
const util_1 = __importDefault(require("../util"));
|
55
|
+
const state_1 = __importDefault(require("../tasks/state"));
|
56
|
+
const xvfb_1 = __importDefault(require("./xvfb"));
|
57
|
+
const verify_1 = require("../tasks/verify");
|
58
|
+
const errors_1 = require("../errors");
|
59
|
+
const readline_1 = __importDefault(require("readline"));
|
60
|
+
const process_1 = require("process");
|
61
|
+
const debug = (0, debug_1.default)('cypress:cli');
|
62
|
+
function isPlatform(platform) {
|
63
|
+
return os_1.default.platform() === platform;
|
64
|
+
}
|
65
|
+
function needsStderrPiped(needsXvfb) {
|
66
|
+
return lodash_1.default.some([
|
67
|
+
isPlatform('darwin'),
|
68
|
+
(needsXvfb && isPlatform('linux')),
|
69
|
+
util_1.default.isPossibleLinuxWithIncorrectDisplay(),
|
70
|
+
]);
|
71
|
+
}
|
72
|
+
function needsEverythingPipedDirectly() {
|
73
|
+
return isPlatform('win32');
|
74
|
+
}
|
75
|
+
function getStdio(needsXvfb) {
|
76
|
+
if (needsEverythingPipedDirectly()) {
|
77
|
+
return 'pipe';
|
78
|
+
}
|
79
|
+
// https://github.com/cypress-io/cypress/issues/921
|
80
|
+
// https://github.com/cypress-io/cypress/issues/1143
|
81
|
+
// https://github.com/cypress-io/cypress/issues/1745
|
82
|
+
if (needsStderrPiped(needsXvfb)) {
|
83
|
+
// returning pipe here so we can massage stderr
|
84
|
+
// and remove garbage from Xlib and libuv
|
85
|
+
// due to starting the Xvfb process on linux
|
86
|
+
return ['inherit', 'inherit', 'pipe'];
|
87
|
+
}
|
88
|
+
return 'inherit';
|
89
|
+
}
|
90
|
+
const spawnModule = {
|
91
|
+
start(args_1) {
|
92
|
+
return __awaiter(this, arguments, void 0, function* (args, options = {}) {
|
93
|
+
const needsXvfb = xvfb_1.default.isNeeded();
|
94
|
+
let executable = state_1.default.getPathToExecutable(state_1.default.getBinaryDir());
|
95
|
+
if (util_1.default.getEnv('CYPRESS_RUN_BINARY')) {
|
96
|
+
executable = path_1.default.resolve(util_1.default.getEnv('CYPRESS_RUN_BINARY'));
|
97
|
+
}
|
98
|
+
debug('needs to start own Xvfb?', needsXvfb);
|
99
|
+
// Always push cwd into the args
|
100
|
+
// which additionally acts as a signal to the
|
101
|
+
// binary that it was invoked through the NPM module
|
102
|
+
args = args || [];
|
103
|
+
if (typeof args === 'string') {
|
104
|
+
args = [args];
|
105
|
+
}
|
106
|
+
args = [...args, '--cwd', process.cwd(), '--userNodePath', process.execPath, '--userNodeVersion', process.versions.node];
|
107
|
+
lodash_1.default.defaults(options, {
|
108
|
+
dev: false,
|
109
|
+
env: process.env,
|
110
|
+
detached: false,
|
111
|
+
stdio: getStdio(needsXvfb),
|
112
|
+
});
|
113
|
+
const spawn = (overrides = {}) => {
|
114
|
+
return new bluebird_1.default((resolve, reject) => {
|
115
|
+
lodash_1.default.defaults(overrides, {
|
116
|
+
onStderrData: false,
|
117
|
+
});
|
118
|
+
const { onStderrData } = overrides;
|
119
|
+
const envOverrides = util_1.default.getEnvOverrides(options);
|
120
|
+
const electronArgs = [];
|
121
|
+
const node11WindowsFix = isPlatform('win32');
|
122
|
+
let startScriptPath;
|
123
|
+
if (options.dev) {
|
124
|
+
executable = 'node';
|
125
|
+
// if we're in dev then reset
|
126
|
+
// the launch cmd to be 'npm run dev'
|
127
|
+
startScriptPath = path_1.default.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js');
|
128
|
+
debug('in dev mode the args became %o', args);
|
129
|
+
}
|
130
|
+
if (!options.dev && (0, verify_1.needsSandbox)()) {
|
131
|
+
electronArgs.push('--no-sandbox');
|
132
|
+
}
|
133
|
+
// strip dev out of child process options
|
134
|
+
/**
|
135
|
+
* @type {import('child_process').ForkOptions}
|
136
|
+
*/
|
137
|
+
let stdioOptions = lodash_1.default.pick(options, 'env', 'detached', 'stdio');
|
138
|
+
// figure out if we're going to be force enabling or disabling colors.
|
139
|
+
// also figure out whether we should force stdout and stderr into thinking
|
140
|
+
// it is a tty as opposed to a pipe.
|
141
|
+
stdioOptions.env = lodash_1.default.extend({}, stdioOptions.env, envOverrides);
|
142
|
+
if (node11WindowsFix) {
|
143
|
+
stdioOptions = lodash_1.default.extend({}, stdioOptions, { windowsHide: false });
|
144
|
+
}
|
145
|
+
if (util_1.default.isPossibleLinuxWithIncorrectDisplay()) {
|
146
|
+
// make sure we use the latest DISPLAY variable if any
|
147
|
+
debug('passing DISPLAY', process.env.DISPLAY);
|
148
|
+
stdioOptions.env.DISPLAY = process.env.DISPLAY;
|
149
|
+
}
|
150
|
+
if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
|
151
|
+
// Since we are running electron as node, we need to add an entry point file.
|
152
|
+
startScriptPath = path_1.default.join(state_1.default.getBinaryPkgPath(path_1.default.dirname(executable)), '..', 'index.js');
|
153
|
+
}
|
154
|
+
else {
|
155
|
+
// Start arguments with "--" so Electron knows these are OUR
|
156
|
+
// arguments and does not try to sanitize them. Otherwise on Windows
|
157
|
+
// an url in one of the arguments crashes it :(
|
158
|
+
// https://github.com/cypress-io/cypress/issues/5466
|
159
|
+
args = [...electronArgs, '--', ...args];
|
160
|
+
}
|
161
|
+
if (startScriptPath) {
|
162
|
+
args.unshift(startScriptPath);
|
163
|
+
}
|
164
|
+
if (process.env.CYPRESS_INTERNAL_DEV_DEBUG) {
|
165
|
+
args.unshift(process.env.CYPRESS_INTERNAL_DEV_DEBUG);
|
166
|
+
}
|
167
|
+
debug('spawn args %o %o', args, lodash_1.default.omit(stdioOptions, 'env'));
|
168
|
+
debug('spawning Cypress with executable: %s', executable);
|
169
|
+
const child = child_process_1.default.spawn(executable, args, stdioOptions);
|
170
|
+
function resolveOn(event) {
|
171
|
+
return function (code, signal) {
|
172
|
+
return __awaiter(this, void 0, void 0, function* () {
|
173
|
+
debug('child event fired %o', { event, code, signal });
|
174
|
+
if (code === null) {
|
175
|
+
const errorObject = errors_1.errors.childProcessKilled(event, signal);
|
176
|
+
const err = yield (0, errors_1.getError)(errorObject);
|
177
|
+
return reject(err);
|
178
|
+
}
|
179
|
+
resolve(code);
|
180
|
+
});
|
181
|
+
};
|
182
|
+
}
|
183
|
+
child.on('close', resolveOn('close'));
|
184
|
+
child.on('exit', resolveOn('exit'));
|
185
|
+
child.on('error', reject);
|
186
|
+
if (isPlatform('win32')) {
|
187
|
+
const rl = readline_1.default.createInterface({
|
188
|
+
input: process_1.stdin,
|
189
|
+
output: process_1.stdout,
|
190
|
+
});
|
191
|
+
// on windows, SIGINT does not propagate to the child process when ctrl+c is pressed
|
192
|
+
// this makes sure all nested processes are closed(ex: firefox inside the server)
|
193
|
+
rl.on('SIGINT', function () {
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
195
|
+
const kill = (yield Promise.resolve().then(() => __importStar(require('tree-kill')))).default;
|
196
|
+
kill(child.pid, 'SIGINT');
|
197
|
+
});
|
198
|
+
});
|
199
|
+
}
|
200
|
+
// if stdio options is set to 'pipe', then
|
201
|
+
// we should set up pipes:
|
202
|
+
// process STDIN (read stream) => child STDIN (writeable)
|
203
|
+
// child STDOUT => process STDOUT
|
204
|
+
// child STDERR => process STDERR with additional filtering
|
205
|
+
if (child.stdin) {
|
206
|
+
debug('piping process STDIN into child STDIN');
|
207
|
+
process_1.stdin.pipe(child.stdin);
|
208
|
+
}
|
209
|
+
if (child.stdout) {
|
210
|
+
debug('piping child STDOUT to process STDOUT');
|
211
|
+
child.stdout.pipe(process_1.stdout);
|
212
|
+
}
|
213
|
+
// if this is defined then we are manually piping for linux
|
214
|
+
// to filter out the garbage
|
215
|
+
if (child.stderr) {
|
216
|
+
debug('piping child STDERR to process STDERR');
|
217
|
+
child.stderr.on('data', (data) => {
|
218
|
+
const str = data.toString();
|
219
|
+
// if we have a callback and this explicitly returns
|
220
|
+
// false then bail
|
221
|
+
if (onStderrData && onStderrData(str)) {
|
222
|
+
return;
|
223
|
+
}
|
224
|
+
// else pass it along!
|
225
|
+
process_1.stderr.write(data);
|
226
|
+
});
|
227
|
+
}
|
228
|
+
// https://github.com/cypress-io/cypress/issues/1841
|
229
|
+
// https://github.com/cypress-io/cypress/issues/5241
|
230
|
+
// In some versions of node, it will throw on windows
|
231
|
+
// when you close the parent process after piping
|
232
|
+
// into the child process. unpiping does not seem
|
233
|
+
// to have any effect. so we're just catching the
|
234
|
+
// error here and not doing anything.
|
235
|
+
process_1.stdin.on('error', (err) => {
|
236
|
+
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
|
237
|
+
return;
|
238
|
+
}
|
239
|
+
throw err;
|
240
|
+
});
|
241
|
+
if (stdioOptions.detached) {
|
242
|
+
child.unref();
|
243
|
+
}
|
244
|
+
});
|
245
|
+
};
|
246
|
+
const spawnInXvfb = () => __awaiter(this, void 0, void 0, function* () {
|
247
|
+
try {
|
248
|
+
yield xvfb_1.default.start();
|
249
|
+
const code = yield userFriendlySpawn();
|
250
|
+
return code;
|
251
|
+
}
|
252
|
+
finally {
|
253
|
+
yield xvfb_1.default.stop();
|
254
|
+
}
|
255
|
+
});
|
256
|
+
const userFriendlySpawn = (linuxWithDisplayEnv) => __awaiter(this, void 0, void 0, function* () {
|
257
|
+
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
|
258
|
+
let brokenGtkDisplay = false;
|
259
|
+
const overrides = {};
|
260
|
+
if (linuxWithDisplayEnv) {
|
261
|
+
lodash_1.default.extend(overrides, {
|
262
|
+
electronLogging: true,
|
263
|
+
onStderrData(str) {
|
264
|
+
// if we receive a broken pipe anywhere
|
265
|
+
// then we know that's why cypress exited early
|
266
|
+
if (util_1.default.isBrokenGtkDisplay(str)) {
|
267
|
+
brokenGtkDisplay = true;
|
268
|
+
}
|
269
|
+
},
|
270
|
+
});
|
271
|
+
}
|
272
|
+
try {
|
273
|
+
const code = yield spawn(overrides);
|
274
|
+
if (code !== 0 && brokenGtkDisplay) {
|
275
|
+
util_1.default.logBrokenGtkDisplayWarning();
|
276
|
+
return spawnInXvfb();
|
277
|
+
}
|
278
|
+
return code;
|
279
|
+
}
|
280
|
+
catch (error) {
|
281
|
+
// we can format and handle an error message from the code above
|
282
|
+
// prevent wrapping error again by using "known: undefined" filter
|
283
|
+
if (error.known === undefined) {
|
284
|
+
const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.unexpected);
|
285
|
+
yield raiseErrorFn(error.message);
|
286
|
+
}
|
287
|
+
throw error;
|
288
|
+
}
|
289
|
+
});
|
290
|
+
if (needsXvfb) {
|
291
|
+
return spawnInXvfb();
|
292
|
+
}
|
293
|
+
// if we are on linux and there's already a DISPLAY
|
294
|
+
// set, then we may need to rerun cypress after
|
295
|
+
// spawning our own Xvfb server
|
296
|
+
const linuxWithDisplayEnv = util_1.default.isPossibleLinuxWithIncorrectDisplay();
|
297
|
+
return userFriendlySpawn(linuxWithDisplayEnv);
|
298
|
+
});
|
299
|
+
},
|
300
|
+
};
|
301
|
+
exports.default = spawnModule;
|
@@ -0,0 +1,67 @@
|
|
1
|
+
"use strict";
|
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 debug_1 = __importDefault(require("debug"));
|
16
|
+
const path_1 = __importDefault(require("path"));
|
17
|
+
const util_1 = __importDefault(require("../util"));
|
18
|
+
const state_1 = __importDefault(require("../tasks/state"));
|
19
|
+
const errors_1 = require("../errors");
|
20
|
+
const debug = (0, debug_1.default)('cypress:cli');
|
21
|
+
const getBinaryDirectory = () => __awaiter(void 0, void 0, void 0, function* () {
|
22
|
+
if (util_1.default.getEnv('CYPRESS_RUN_BINARY')) {
|
23
|
+
let envBinaryPath = path_1.default.resolve(util_1.default.getEnv('CYPRESS_RUN_BINARY'));
|
24
|
+
try {
|
25
|
+
const envBinaryDir = yield state_1.default.parseRealPlatformBinaryFolderAsync(envBinaryPath);
|
26
|
+
if (!envBinaryDir) {
|
27
|
+
const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath));
|
28
|
+
yield raiseErrorFn();
|
29
|
+
}
|
30
|
+
debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir);
|
31
|
+
return envBinaryDir;
|
32
|
+
}
|
33
|
+
catch (err) {
|
34
|
+
const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath));
|
35
|
+
yield raiseErrorFn(err.message);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
return state_1.default.getBinaryDir();
|
39
|
+
});
|
40
|
+
const getVersions = () => __awaiter(void 0, void 0, void 0, function* () {
|
41
|
+
const binDir = yield getBinaryDirectory();
|
42
|
+
const pkg = yield state_1.default.getBinaryPkgAsync(binDir);
|
43
|
+
const versions = {
|
44
|
+
binary: state_1.default.getBinaryPkgVersion(pkg),
|
45
|
+
electronVersion: state_1.default.getBinaryElectronVersion(pkg),
|
46
|
+
electronNodeVersion: state_1.default.getBinaryElectronNodeVersion(pkg),
|
47
|
+
};
|
48
|
+
debug('binary versions %o', versions);
|
49
|
+
const buildInfo = util_1.default.pkgBuildInfo();
|
50
|
+
let packageVersion = util_1.default.pkgVersion();
|
51
|
+
if (!buildInfo)
|
52
|
+
packageVersion += ' (development)';
|
53
|
+
else if (!buildInfo.stable)
|
54
|
+
packageVersion += ' (pre-release)';
|
55
|
+
const versionsFinal = {
|
56
|
+
package: packageVersion,
|
57
|
+
binary: versions.binary || 'not installed',
|
58
|
+
electronVersion: versions.electronVersion || 'not found',
|
59
|
+
electronNodeVersion: versions.electronNodeVersion || 'not found',
|
60
|
+
};
|
61
|
+
debug('combined versions %o', versions);
|
62
|
+
return versionsFinal;
|
63
|
+
});
|
64
|
+
const versionsModule = {
|
65
|
+
getVersions,
|
66
|
+
};
|
67
|
+
exports.default = versionsModule;
|