cypress 15.1.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.
Files changed (49) hide show
  1. package/bin/cypress +3 -1
  2. package/dist/VerboseRenderer.js +61 -0
  3. package/dist/cli.js +544 -0
  4. package/dist/cypress.js +104 -0
  5. package/dist/errors.js +391 -0
  6. package/dist/exec/info.js +103 -0
  7. package/dist/exec/open.js +103 -0
  8. package/dist/exec/run.js +177 -0
  9. package/dist/exec/shared.js +55 -0
  10. package/dist/exec/spawn.js +301 -0
  11. package/dist/exec/versions.js +67 -0
  12. package/dist/exec/xvfb.js +118 -0
  13. package/dist/index.js +52 -0
  14. package/dist/index.mjs +9 -0
  15. package/dist/logger.js +55 -0
  16. package/dist/tasks/cache.js +144 -0
  17. package/dist/tasks/download.js +304 -0
  18. package/dist/tasks/get-folder-size.js +44 -0
  19. package/dist/tasks/install.js +326 -0
  20. package/dist/tasks/state.js +184 -0
  21. package/dist/tasks/unzip.js +192 -0
  22. package/dist/tasks/verify.js +303 -0
  23. package/dist/util.js +452 -0
  24. package/package.json +10 -13
  25. package/types/cypress-automation.d.ts +2 -1
  26. package/types/cypress.d.ts +1 -0
  27. package/index.js +0 -27
  28. package/index.mjs +0 -17
  29. package/lib/VerboseRenderer.js +0 -58
  30. package/lib/cli.js +0 -411
  31. package/lib/cypress.js +0 -98
  32. package/lib/errors.js +0 -392
  33. package/lib/exec/info.js +0 -92
  34. package/lib/exec/open.js +0 -90
  35. package/lib/exec/run.js +0 -176
  36. package/lib/exec/shared.js +0 -62
  37. package/lib/exec/spawn.js +0 -247
  38. package/lib/exec/versions.js +0 -53
  39. package/lib/exec/xvfb.js +0 -93
  40. package/lib/fs.js +0 -4
  41. package/lib/logger.js +0 -50
  42. package/lib/tasks/cache.js +0 -132
  43. package/lib/tasks/download.js +0 -324
  44. package/lib/tasks/get-folder-size.js +0 -33
  45. package/lib/tasks/install.js +0 -368
  46. package/lib/tasks/state.js +0 -185
  47. package/lib/tasks/unzip.js +0 -200
  48. package/lib/tasks/verify.js +0 -300
  49. package/lib/util.js +0 -448
@@ -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;
@@ -0,0 +1,118 @@
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 os_1 = __importDefault(require("os"));
16
+ const bluebird_1 = __importDefault(require("bluebird"));
17
+ const xvfb_1 = __importDefault(require("@cypress/xvfb"));
18
+ const common_tags_1 = require("common-tags");
19
+ const debug_1 = __importDefault(require("debug"));
20
+ const errors_1 = require("../errors");
21
+ const util_1 = __importDefault(require("../util"));
22
+ const debug = (0, debug_1.default)('cypress:cli');
23
+ const debugXvfb = (0, debug_1.default)('cypress:xvfb');
24
+ debug.Debug = debugXvfb.Debug = debug_1.default;
25
+ const xvfbOptions = {
26
+ displayNum: process.env.XVFB_DISPLAY_NUM,
27
+ timeout: 30000, // milliseconds
28
+ // need to explicitly define screen otherwise electron will crash
29
+ // https://github.com/cypress-io/cypress/issues/6184
30
+ xvfb_args: ['-screen', '0', '1280x1024x24'],
31
+ onStderrData(data) {
32
+ if (debugXvfb.enabled) {
33
+ debugXvfb(data.toString());
34
+ }
35
+ },
36
+ };
37
+ const xvfb = bluebird_1.default.promisifyAll(new xvfb_1.default(xvfbOptions));
38
+ const xvfbModule = {
39
+ _debugXvfb: debugXvfb, // expose for testing
40
+ _xvfb: xvfb, // expose for testing
41
+ _xvfbOptions: xvfbOptions, // expose for testing
42
+ start() {
43
+ return __awaiter(this, void 0, void 0, function* () {
44
+ debug('Starting Xvfb');
45
+ try {
46
+ yield xvfb.startAsync();
47
+ return null;
48
+ }
49
+ catch (e) {
50
+ if (e.nonZeroExitCode === true) {
51
+ const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.nonZeroExitCodeXvfb);
52
+ yield raiseErrorFn(e);
53
+ }
54
+ if (e.known) {
55
+ throw e;
56
+ }
57
+ const raiseErrorFn = (0, errors_1.throwFormErrorText)(errors_1.errors.missingXvfb);
58
+ yield raiseErrorFn(e);
59
+ }
60
+ });
61
+ },
62
+ stop() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ debug('Stopping Xvfb');
65
+ try {
66
+ yield xvfb.stopAsync();
67
+ return null;
68
+ }
69
+ catch (e) {
70
+ return null;
71
+ }
72
+ });
73
+ },
74
+ isNeeded() {
75
+ if (process.env.ELECTRON_RUN_AS_NODE) {
76
+ debug('Environment variable ELECTRON_RUN_AS_NODE detected, xvfb is not needed');
77
+ return false; // xvfb required for electron processes only.
78
+ }
79
+ if (os_1.default.platform() !== 'linux') {
80
+ return false;
81
+ }
82
+ if (process.env.DISPLAY) {
83
+ const issueUrl = util_1.default.getGitHubIssueUrl(4034);
84
+ const message = (0, common_tags_1.stripIndent) `
85
+ DISPLAY environment variable is set to ${process.env.DISPLAY} on Linux
86
+ Assuming this DISPLAY points at working X11 server,
87
+ Cypress will not spawn own Xvfb
88
+
89
+ NOTE: if the X11 server is NOT working, Cypress will exit without explanation,
90
+ see ${issueUrl}
91
+ Solution: Unset the DISPLAY variable and try again:
92
+ DISPLAY= npx cypress run ...
93
+ `;
94
+ debug(message);
95
+ return false;
96
+ }
97
+ debug('undefined DISPLAY environment variable');
98
+ debug('Cypress will spawn its own Xvfb');
99
+ return true;
100
+ },
101
+ // async method, resolved with Boolean
102
+ verify() {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ try {
105
+ yield xvfb.startAsync();
106
+ return true;
107
+ }
108
+ catch (err) {
109
+ debug('Could not verify xvfb: %s', err.message);
110
+ return false;
111
+ }
112
+ finally {
113
+ yield xvfb.stopAsync();
114
+ }
115
+ });
116
+ },
117
+ };
118
+ exports.default = xvfbModule;
package/dist/index.js ADDED
@@ -0,0 +1,52 @@
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
+ const minimist_1 = __importDefault(require("minimist"));
15
+ const debug_1 = __importDefault(require("debug"));
16
+ const util_1 = __importDefault(require("./util"));
17
+ const cypress_1 = __importDefault(require("./cypress"));
18
+ const install_1 = __importDefault(require("./tasks/install"));
19
+ const verify_1 = require("./tasks/verify");
20
+ const debugCli = (0, debug_1.default)('cypress:cli');
21
+ const args = (0, minimist_1.default)(process.argv.slice(2));
22
+ // we're being used from the command line
23
+ function handleExec() {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ switch (args.exec) {
26
+ case 'install': {
27
+ debugCli('installing Cypress from NPM');
28
+ install_1.default.start({ force: args.force })
29
+ .catch(util_1.default.logErrorExit1);
30
+ break;
31
+ }
32
+ case 'verify': {
33
+ // for simple testing in the monorepo
34
+ debugCli('verifying Cypress');
35
+ (0, verify_1.start)({ force: true }) // always force verification
36
+ .catch(util_1.default.logErrorExit1);
37
+ break;
38
+ }
39
+ default: {
40
+ break;
41
+ }
42
+ }
43
+ });
44
+ }
45
+ // Execute the async function
46
+ if (args.exec) {
47
+ handleExec().catch(util_1.default.logErrorExit1);
48
+ }
49
+ else {
50
+ debugCli('exporting Cypress module interface');
51
+ }
52
+ module.exports = cypress_1.default;
package/dist/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import module from 'module';
2
+ const require = module.createRequire(import.meta.url);
3
+ const cypress = require('./cypress');
4
+ export default cypress;
5
+ export const defineConfig = cypress.defineConfig;
6
+ export const defineComponentFramework = cypress.defineComponentFramework;
7
+ export const run = cypress.run;
8
+ export const open = cypress.open;
9
+ export const cli = cypress.cli;
package/dist/logger.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const chalk_1 = __importDefault(require("chalk"));
7
+ let logs = [];
8
+ const logLevel = () => {
9
+ return (process.env.npm_config_loglevel || 'notice');
10
+ };
11
+ const error = (...messages) => {
12
+ logs.push(messages.join(' '));
13
+ console.log(chalk_1.default.red(...messages)); // eslint-disable-line no-console
14
+ };
15
+ const warn = (...messages) => {
16
+ if (logLevel() === 'silent')
17
+ return;
18
+ logs.push(messages.join(' '));
19
+ console.log(chalk_1.default.yellow(...messages)); // eslint-disable-line no-console
20
+ };
21
+ const log = (...messages) => {
22
+ if (logLevel() === 'silent' || logLevel() === 'warn')
23
+ return;
24
+ logs.push(messages.join(' '));
25
+ console.log(...messages); // eslint-disable-line no-console
26
+ };
27
+ const always = (...messages) => {
28
+ logs.push(messages.join(' '));
29
+ console.log(...messages); // eslint-disable-line no-console
30
+ };
31
+ // splits long text into lines and calls log()
32
+ // on each one to allow easy unit testing for specific message
33
+ const logLines = (text) => {
34
+ const lines = text.split('\n');
35
+ for (const line of lines) {
36
+ log(line);
37
+ }
38
+ };
39
+ const print = () => {
40
+ return logs.join('\n');
41
+ };
42
+ const reset = () => {
43
+ logs = [];
44
+ };
45
+ const loggerModule = {
46
+ log,
47
+ warn,
48
+ error,
49
+ always,
50
+ logLines,
51
+ print,
52
+ reset,
53
+ logLevel,
54
+ };
55
+ exports.default = loggerModule;
@@ -0,0 +1,144 @@
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 state_1 = __importDefault(require("./state"));
16
+ const logger_1 = __importDefault(require("../logger"));
17
+ const fs_extra_1 = __importDefault(require("fs-extra"));
18
+ const util_1 = __importDefault(require("../util"));
19
+ const path_1 = require("path");
20
+ const cli_table3_1 = __importDefault(require("cli-table3"));
21
+ const dayjs_1 = __importDefault(require("dayjs"));
22
+ const relativeTime_1 = __importDefault(require("dayjs/plugin/relativeTime"));
23
+ const chalk_1 = __importDefault(require("chalk"));
24
+ const lodash_1 = __importDefault(require("lodash"));
25
+ const get_folder_size_1 = __importDefault(require("./get-folder-size"));
26
+ dayjs_1.default.extend(relativeTime_1.default);
27
+ // output colors for the table
28
+ const colors = {
29
+ titles: chalk_1.default.white,
30
+ dates: chalk_1.default.cyan,
31
+ values: chalk_1.default.green,
32
+ size: chalk_1.default.gray,
33
+ };
34
+ const logCachePath = () => {
35
+ logger_1.default.always(state_1.default.getCacheDir());
36
+ return undefined;
37
+ };
38
+ const clear = () => {
39
+ return fs_extra_1.default.remove(state_1.default.getCacheDir());
40
+ };
41
+ const prune = () => __awaiter(void 0, void 0, void 0, function* () {
42
+ const cacheDir = state_1.default.getCacheDir();
43
+ const checkedInBinaryVersion = util_1.default.pkgVersion();
44
+ let deletedBinary = false;
45
+ try {
46
+ const versions = yield fs_extra_1.default.readdir(cacheDir);
47
+ for (const version of versions) {
48
+ if (version !== checkedInBinaryVersion) {
49
+ deletedBinary = true;
50
+ const versionDir = (0, path_1.join)(cacheDir, version);
51
+ yield fs_extra_1.default.remove(versionDir);
52
+ }
53
+ }
54
+ if (deletedBinary) {
55
+ logger_1.default.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`);
56
+ }
57
+ else {
58
+ logger_1.default.always(`No binary caches found to prune.`);
59
+ }
60
+ }
61
+ catch (e) {
62
+ if (e.code === 'ENOENT') {
63
+ logger_1.default.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
64
+ return;
65
+ }
66
+ throw e;
67
+ }
68
+ });
69
+ const fileSizeInMB = (size) => {
70
+ return `${(size / 1024 / 1024).toFixed(1)}MB`;
71
+ };
72
+ /**
73
+ * Collects all cached versions, finds when each was used
74
+ * and prints a table with results to the terminal
75
+ */
76
+ const list = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (showSize = false) {
77
+ const binaries = yield getCachedVersions(showSize);
78
+ const head = [colors.titles('version'), colors.titles('last used')];
79
+ if (showSize) {
80
+ head.push(colors.titles('size'));
81
+ }
82
+ const table = new cli_table3_1.default({
83
+ head,
84
+ });
85
+ binaries.forEach((binary) => {
86
+ const versionString = colors.values(binary.version);
87
+ const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
88
+ const row = [versionString, lastUsed];
89
+ if (showSize) {
90
+ const size = colors.size(fileSizeInMB(binary.size));
91
+ row.push(size);
92
+ }
93
+ return table.push(row);
94
+ });
95
+ logger_1.default.always(table.toString());
96
+ });
97
+ const getCachedVersions = (showSize) => __awaiter(void 0, void 0, void 0, function* () {
98
+ const cacheDir = state_1.default.getCacheDir();
99
+ const versions = yield fs_extra_1.default.readdir(cacheDir);
100
+ const filteredVersions = versions.filter(util_1.default.isSemver).map((version) => {
101
+ return {
102
+ version,
103
+ folderPath: (0, path_1.join)(cacheDir, version),
104
+ };
105
+ });
106
+ const binaries = [];
107
+ for (const binary of filteredVersions) {
108
+ const binaryDir = state_1.default.getBinaryDir(binary.version);
109
+ const executable = state_1.default.getPathToExecutable(binaryDir);
110
+ try {
111
+ const stat = yield fs_extra_1.default.stat(executable);
112
+ const lastAccessedTime = lodash_1.default.get(stat, 'atime');
113
+ if (lastAccessedTime) {
114
+ const accessed = (0, dayjs_1.default)(lastAccessedTime).fromNow();
115
+ // @ts-expect-error - accessed is not defined in the type
116
+ binary.accessed = accessed;
117
+ }
118
+ // if no lastAccessedTime
119
+ // the test runner has never been opened
120
+ // or could be a test simulating missing timestamp
121
+ }
122
+ catch (e) {
123
+ // could not find the binary or gets its stats
124
+ // no-op
125
+ }
126
+ if (showSize) {
127
+ const binaryDir = state_1.default.getBinaryDir(binary.version);
128
+ const size = yield (0, get_folder_size_1.default)(binaryDir);
129
+ binaries.push(Object.assign(Object.assign({}, binary), { size }));
130
+ }
131
+ else {
132
+ binaries.push(binary);
133
+ }
134
+ }
135
+ return binaries;
136
+ });
137
+ const cacheModule = {
138
+ path: logCachePath,
139
+ clear,
140
+ prune,
141
+ list,
142
+ getCachedVersions,
143
+ };
144
+ exports.default = cacheModule;