cypress 15.2.0 → 15.4.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,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 lazy_ass_1 = __importDefault(require("lazy-ass"));
12
- const check_more_types_1 = __importDefault(require("check-more-types"));
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 util_1.default.getPlatformInfo().then((platform) => {
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 formErrorText(errorObject).then((errorMessage) => {
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 addPlatformInformation(info).then((obj) => {
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
- (0, lazy_ass_1.default)(check_more_types_1.default.unemptyString(obj.description), 'expected error description to be text', obj.description);
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 (check_more_types_1.default.fn(obj.solution)) {
278
- const text = obj.solution(msg, prevMessage);
279
- (0, lazy_ass_1.default)(check_more_types_1.default.unemptyString(text), 'expected solution to be text', text);
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
- ${obj.description}
293
+ ${infoWithPlatform.description}
282
294
 
283
295
  ${text}
284
296
 
285
297
  `);
286
298
  }
287
299
  else {
288
- (0, lazy_ass_1.default)(check_more_types_1.default.unemptyString(obj.solution), 'expected error solution to be text', obj.solution);
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
- ${obj.description}
302
+ ${infoWithPlatform.description}
291
303
 
292
- ${obj.solution}
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
- ${obj.platform}
319
+ ${infoWithPlatform.platform}
308
320
  `);
309
- if (obj.footer) {
321
+ if (infoWithPlatform.footer) {
310
322
  add(`
311
323
 
312
324
  ${exports.hr}
313
325
 
314
- ${obj.footer}
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
- return formErrorText(info, msg, prevMessage).then((0, exports.raise)(info));
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
- return formErrorText(info, msg).then((text) => {
346
- // eslint-disable-next-line no-console
347
- console.error(text);
348
- process.exit(info.exitCode || 1);
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 = {
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  /* eslint-disable no-console */
16
- const spawn_1 = __importDefault(require("./spawn"));
16
+ const spawn_1 = require("./spawn");
17
17
  const util_1 = __importDefault(require("../util"));
18
18
  const state_1 = __importDefault(require("../tasks/state"));
19
19
  const os_1 = __importDefault(require("os"));
@@ -49,7 +49,7 @@ const formatCypressVariables = () => {
49
49
  };
50
50
  methods.start = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (options = {}) {
51
51
  const args = ['--mode=info'];
52
- yield spawn_1.default.start(args, {
52
+ yield (0, spawn_1.start)(args, {
53
53
  dev: options.dev,
54
54
  });
55
55
  console.log();
@@ -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
  };
@@ -6,8 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
15
  exports.start = exports.processOpenOptions = void 0;
7
16
  const debug_1 = __importDefault(require("debug"));
8
17
  const util_1 = __importDefault(require("../util"));
9
- const spawn_1 = __importDefault(require("./spawn"));
10
- const verify_1 = __importDefault(require("../tasks/verify"));
18
+ const spawn_1 = require("./spawn");
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,11 +74,11 @@ 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);
72
- return spawn_1.default.start(args, {
81
+ return (0, spawn_1.start)(args, {
73
82
  dev: options.dev,
74
83
  detached: Boolean(options.detached),
75
84
  });
@@ -84,9 +93,9 @@ const start = (options = {}) => {
84
93
  if (options.dev) {
85
94
  return open();
86
95
  }
87
- return verify_1.default.start()
88
- .then(open);
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,
@@ -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
  };
@@ -6,8 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
15
  const lodash_1 = __importDefault(require("lodash"));
7
16
  const debug_1 = __importDefault(require("debug"));
8
17
  const util_1 = __importDefault(require("../util"));
9
- const spawn_1 = __importDefault(require("./spawn"));
10
- const verify_1 = __importDefault(require("../tasks/verify"));
18
+ const spawn_1 = require("./spawn");
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');
@@ -91,6 +100,9 @@ const processRunOptions = (options = {}) => {
91
100
  if (options.parallel) {
92
101
  args.push('--parallel');
93
102
  }
103
+ if (options.posixExitCodes) {
104
+ args.push('--posix-exit-codes');
105
+ }
94
106
  if (options.port) {
95
107
  args.push('--port', options.port);
96
108
  }
@@ -133,34 +145,36 @@ const runModule = {
133
145
  processRunOptions,
134
146
  isValidProject,
135
147
  // resolves with the number of failed tests
136
- start(options = {}) {
137
- lodash_1.default.defaults(options, {
138
- key: null,
139
- spec: null,
140
- reporter: null,
141
- reporterOptions: null,
142
- project: process.cwd(),
143
- });
144
- function run() {
145
- try {
146
- const args = processRunOptions(options);
147
- debug('run to spawn.start args %j', args);
148
- return spawn_1.default.start(args, {
149
- dev: options.dev,
150
- });
151
- }
152
- catch (err) {
153
- if (err.details) {
154
- return (0, errors_1.exitWithError)(err.details)();
148
+ start() {
149
+ return __awaiter(this, arguments, void 0, function* (options = {}) {
150
+ lodash_1.default.defaults(options, {
151
+ key: null,
152
+ spec: null,
153
+ reporter: null,
154
+ reporterOptions: null,
155
+ project: process.cwd(),
156
+ });
157
+ function run() {
158
+ try {
159
+ const args = processRunOptions(options);
160
+ debug('run to spawn.start args %j', args);
161
+ return (0, spawn_1.start)(args, {
162
+ dev: options.dev,
163
+ });
164
+ }
165
+ catch (err) {
166
+ if (err.details) {
167
+ return (0, errors_1.exitWithError)(err.details)();
168
+ }
169
+ throw err;
155
170
  }
156
- throw err;
157
171
  }
158
- }
159
- if (options.dev) {
172
+ if (options.dev) {
173
+ return run();
174
+ }
175
+ yield (0, verify_1.start)();
160
176
  return run();
161
- }
162
- return verify_1.default.start()
163
- .then(run);
177
+ });
164
178
  },
165
179
  };
166
180
  exports.default = runModule;
@@ -0,0 +1,311 @@
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
+ exports.start = start;
49
+ const lodash_1 = __importDefault(require("lodash"));
50
+ const os_1 = __importDefault(require("os"));
51
+ const child_process_1 = __importDefault(require("child_process"));
52
+ const path_1 = __importDefault(require("path"));
53
+ const bluebird_1 = __importDefault(require("bluebird"));
54
+ const debug_1 = __importDefault(require("debug"));
55
+ const util_1 = __importDefault(require("../util"));
56
+ const state_1 = __importDefault(require("../tasks/state"));
57
+ const xvfb_1 = __importDefault(require("./xvfb"));
58
+ const verify_1 = require("../tasks/verify");
59
+ const errors_1 = require("../errors");
60
+ const readline_1 = __importDefault(require("readline"));
61
+ const process_1 = require("process");
62
+ const debug = (0, debug_1.default)('cypress:cli');
63
+ const DBUS_ERROR_PATTERN = /ERROR:dbus\/(bus|object_proxy)\.cc/;
64
+ function isPlatform(platform) {
65
+ return os_1.default.platform() === platform;
66
+ }
67
+ function needsStderrPiped(needsXvfb) {
68
+ return lodash_1.default.some([
69
+ isPlatform('darwin'),
70
+ (needsXvfb && isPlatform('linux')),
71
+ util_1.default.isPossibleLinuxWithIncorrectDisplay(),
72
+ ]);
73
+ }
74
+ function needsEverythingPipedDirectly() {
75
+ return isPlatform('win32');
76
+ }
77
+ function getStdioStrategy(needsXvfb) {
78
+ if (needsEverythingPipedDirectly()) {
79
+ return 'pipe';
80
+ }
81
+ // https://github.com/cypress-io/cypress/issues/921
82
+ // https://github.com/cypress-io/cypress/issues/1143
83
+ // https://github.com/cypress-io/cypress/issues/1745
84
+ if (needsStderrPiped(needsXvfb)) {
85
+ // returning pipe here so we can massage stderr
86
+ // and remove garbage from Xlib and libuv
87
+ // due to starting the Xvfb process on linux
88
+ return ['inherit', 'inherit', 'pipe'];
89
+ }
90
+ return 'inherit';
91
+ }
92
+ function createSpawnFunction(executable, args, options) {
93
+ return (overrides = {}) => {
94
+ return new bluebird_1.default((resolve, reject) => {
95
+ lodash_1.default.defaults(overrides, {
96
+ onStderrData: false,
97
+ });
98
+ const { onStderrData } = overrides;
99
+ const envOverrides = util_1.default.getEnvOverrides(options);
100
+ const electronArgs = [];
101
+ const node11WindowsFix = isPlatform('win32');
102
+ let startScriptPath;
103
+ if (options.dev) {
104
+ executable = 'node';
105
+ // if we're in dev then reset
106
+ // the launch cmd to be 'npm run dev'
107
+ startScriptPath = path_1.default.resolve(__dirname, '..', '..', '..', 'scripts', 'start.js');
108
+ debug('in dev mode the args became %o', args);
109
+ }
110
+ if (!options.dev && (0, verify_1.needsSandbox)()) {
111
+ electronArgs.push('--no-sandbox');
112
+ }
113
+ // strip dev out of child process options
114
+ /**
115
+ * @type {import('child_process').ForkOptions}
116
+ */
117
+ let stdioOptions = lodash_1.default.pick(options, 'env', 'detached', 'stdio');
118
+ // figure out if we're going to be force enabling or disabling colors.
119
+ // also figure out whether we should force stdout and stderr into thinking
120
+ // it is a tty as opposed to a pipe.
121
+ stdioOptions.env = lodash_1.default.extend({}, stdioOptions.env, envOverrides);
122
+ if (node11WindowsFix) {
123
+ stdioOptions = lodash_1.default.extend({}, stdioOptions, { windowsHide: false });
124
+ }
125
+ if (util_1.default.isPossibleLinuxWithIncorrectDisplay()) {
126
+ // make sure we use the latest DISPLAY variable if any
127
+ debug('passing DISPLAY', process.env.DISPLAY);
128
+ stdioOptions.env.DISPLAY = process.env.DISPLAY;
129
+ }
130
+ if (stdioOptions.env.ELECTRON_RUN_AS_NODE) {
131
+ // Since we are running electron as node, we need to add an entry point file.
132
+ startScriptPath = path_1.default.join(state_1.default.getBinaryPkgPath(path_1.default.dirname(executable)), '..', 'index.js');
133
+ }
134
+ else {
135
+ // Start arguments with "--" so Electron knows these are OUR
136
+ // arguments and does not try to sanitize them. Otherwise on Windows
137
+ // an url in one of the arguments crashes it :(
138
+ // https://github.com/cypress-io/cypress/issues/5466
139
+ args = [...electronArgs, '--', ...args];
140
+ }
141
+ if (startScriptPath) {
142
+ args.unshift(startScriptPath);
143
+ }
144
+ if (process.env.CYPRESS_INTERNAL_DEV_DEBUG) {
145
+ args.unshift(process.env.CYPRESS_INTERNAL_DEV_DEBUG);
146
+ }
147
+ debug('spawn args %o %o', args, lodash_1.default.omit(stdioOptions, 'env'));
148
+ debug('spawning Cypress with executable: %s', executable);
149
+ const child = child_process_1.default.spawn(executable, args, stdioOptions);
150
+ function resolveOn(event) {
151
+ return function (code, signal) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ debug('child event fired %o', { event, code, signal });
154
+ if (code === null) {
155
+ const errorObject = errors_1.errors.childProcessKilled(event, signal);
156
+ const err = yield (0, errors_1.getError)(errorObject);
157
+ return reject(err);
158
+ }
159
+ resolve(code);
160
+ });
161
+ };
162
+ }
163
+ child.on('close', resolveOn('close'));
164
+ child.on('exit', resolveOn('exit'));
165
+ child.on('error', reject);
166
+ if (isPlatform('win32')) {
167
+ const rl = readline_1.default.createInterface({
168
+ input: process_1.stdin,
169
+ output: process_1.stdout,
170
+ });
171
+ // on windows, SIGINT does not propagate to the child process when ctrl+c is pressed
172
+ // this makes sure all nested processes are closed(ex: firefox inside the server)
173
+ rl.on('SIGINT', function () {
174
+ return __awaiter(this, void 0, void 0, function* () {
175
+ const kill = (yield Promise.resolve().then(() => __importStar(require('tree-kill')))).default;
176
+ kill(child.pid, 'SIGINT');
177
+ });
178
+ });
179
+ }
180
+ // if stdio options is set to 'pipe', then
181
+ // we should set up pipes:
182
+ // process STDIN (read stream) => child STDIN (writeable)
183
+ // child STDOUT => process STDOUT
184
+ // child STDERR => process STDERR with additional filtering
185
+ if (child.stdin) {
186
+ debug('piping process STDIN into child STDIN');
187
+ process_1.stdin.pipe(child.stdin);
188
+ }
189
+ if (child.stdout) {
190
+ debug('piping child STDOUT to process STDOUT');
191
+ child.stdout.pipe(process_1.stdout);
192
+ }
193
+ // if this is defined then we are manually piping for linux
194
+ // to filter out the garbage
195
+ if (child.stderr) {
196
+ debug('piping child STDERR to process STDERR');
197
+ child.stderr.on('data', (data) => {
198
+ const str = data.toString();
199
+ // if we have a callback and this explicitly returns
200
+ // false then bail
201
+ if (onStderrData && onStderrData(str)) {
202
+ return;
203
+ }
204
+ if (str.match(DBUS_ERROR_PATTERN)) {
205
+ debug(str);
206
+ }
207
+ else {
208
+ // else pass it along!
209
+ process_1.stderr.write(data);
210
+ }
211
+ });
212
+ }
213
+ // https://github.com/cypress-io/cypress/issues/1841
214
+ // https://github.com/cypress-io/cypress/issues/5241
215
+ // In some versions of node, it will throw on windows
216
+ // when you close the parent process after piping
217
+ // into the child process. unpiping does not seem
218
+ // to have any effect. so we're just catching the
219
+ // error here and not doing anything.
220
+ process_1.stdin.on('error', (err) => {
221
+ if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
222
+ return;
223
+ }
224
+ throw err;
225
+ });
226
+ if (stdioOptions.detached) {
227
+ child.unref();
228
+ }
229
+ });
230
+ };
231
+ }
232
+ function spawnInXvfb(spawn) {
233
+ return __awaiter(this, void 0, void 0, function* () {
234
+ try {
235
+ yield xvfb_1.default.start();
236
+ const code = yield userFriendlySpawn(spawn);
237
+ return code;
238
+ }
239
+ finally {
240
+ yield xvfb_1.default.stop();
241
+ }
242
+ });
243
+ }
244
+ function userFriendlySpawn(spawn, linuxWithDisplayEnv) {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv));
247
+ let brokenGtkDisplay = false;
248
+ const overrides = {};
249
+ if (linuxWithDisplayEnv) {
250
+ lodash_1.default.extend(overrides, {
251
+ electronLogging: true,
252
+ onStderrData(str) {
253
+ // if we receive a broken pipe anywhere
254
+ // then we know that's why cypress exited early
255
+ if (util_1.default.isBrokenGtkDisplay(str)) {
256
+ brokenGtkDisplay = true;
257
+ }
258
+ },
259
+ });
260
+ }
261
+ try {
262
+ const code = yield spawn(overrides);
263
+ if (code !== 0 && brokenGtkDisplay) {
264
+ util_1.default.logBrokenGtkDisplayWarning();
265
+ return spawnInXvfb(spawn);
266
+ }
267
+ return code;
268
+ }
269
+ catch (error) {
270
+ // we can format and handle an error message from the code above
271
+ // prevent wrapping error again by using "known: undefined" filter
272
+ if (error.known === undefined) {
273
+ const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.unexpected);
274
+ yield raiseErrorFn(error.message);
275
+ }
276
+ throw error;
277
+ }
278
+ });
279
+ }
280
+ function start(args_1) {
281
+ return __awaiter(this, arguments, void 0, function* (args, options = {}) {
282
+ var _a, _b, _c, _d;
283
+ let executable = util_1.default.getEnv('CYPRESS_RUN_BINARY') ?
284
+ path_1.default.resolve(util_1.default.getEnv('CYPRESS_RUN_BINARY')) :
285
+ state_1.default.getPathToExecutable(state_1.default.getBinaryDir());
286
+ // Always push cwd into the args
287
+ // which additionally acts as a signal to the
288
+ // binary that it was invoked through the NPM module
289
+ const baseArgs = args ? (typeof args === 'string' ? [args] : args) : [];
290
+ const decoratedArgs = baseArgs.concat([
291
+ '--cwd', process.cwd(),
292
+ '--userNodePath', process.execPath,
293
+ '--userNodeVersion', process.versions.node,
294
+ ]);
295
+ const needsXvfb = xvfb_1.default.isNeeded();
296
+ debug('needs to start own Xvfb?', needsXvfb);
297
+ const stdio = (_a = options.stdio) !== null && _a !== void 0 ? _a : getStdioStrategy(needsXvfb);
298
+ const dev = (_b = options.dev) !== null && _b !== void 0 ? _b : false;
299
+ const detached = (_c = options.detached) !== null && _c !== void 0 ? _c : false;
300
+ const env = (_d = options.env) !== null && _d !== void 0 ? _d : process.env;
301
+ const spawn = createSpawnFunction(executable, decoratedArgs, { stdio, dev, detached, env });
302
+ if (needsXvfb) {
303
+ return spawnInXvfb(spawn);
304
+ }
305
+ // if we are on linux and there's already a DISPLAY
306
+ // set, then we may need to rerun cypress after
307
+ // spawning our own Xvfb server
308
+ const linuxWithDisplayEnv = util_1.default.isPossibleLinuxWithIncorrectDisplay();
309
+ return userFriendlySpawn(spawn, linuxWithDisplayEnv);
310
+ });
311
+ }