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
@@ -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,7 +17,8 @@ const os_1 = __importDefault(require("os"));
|
|
8
17
|
const path_1 = __importDefault(require("path"));
|
9
18
|
const untildify_1 = __importDefault(require("untildify"));
|
10
19
|
const debug_1 = __importDefault(require("debug"));
|
11
|
-
const
|
20
|
+
const process_1 = require("process");
|
21
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
12
22
|
const util_1 = __importDefault(require("../util"));
|
13
23
|
const debug = (0, debug_1.default)('cypress:cli');
|
14
24
|
const getPlatformExecutable = () => {
|
@@ -59,7 +69,7 @@ const getVersionDir = (version = util_1.default.pkgVersion(), buildInfo = util_1
|
|
59
69
|
*/
|
60
70
|
const isInstallingFromPostinstallHook = () => {
|
61
71
|
// individual folders
|
62
|
-
const cwdFolders =
|
72
|
+
const cwdFolders = (0, process_1.cwd)().split(path_1.default.sep);
|
63
73
|
const length = cwdFolders.length;
|
64
74
|
return cwdFolders[length - 2] === 'node_modules' && cwdFolders[length - 1] === 'cypress';
|
65
75
|
};
|
@@ -80,19 +90,17 @@ const getCacheDir = () => {
|
|
80
90
|
}
|
81
91
|
return cache_directory;
|
82
92
|
};
|
83
|
-
const parseRealPlatformBinaryFolderAsync = (binaryPath) => {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
});
|
95
|
-
};
|
93
|
+
const parseRealPlatformBinaryFolderAsync = (binaryPath) => __awaiter(void 0, void 0, void 0, function* () {
|
94
|
+
const realPath = yield fs_extra_1.default.realpath(binaryPath);
|
95
|
+
debug('CYPRESS_RUN_BINARY has realpath:', realPath);
|
96
|
+
if (!realPath.toString().endsWith(getPlatformExecutable())) {
|
97
|
+
return false;
|
98
|
+
}
|
99
|
+
if (os_1.default.platform() === 'darwin') {
|
100
|
+
return path_1.default.resolve(realPath, '..', '..', '..');
|
101
|
+
}
|
102
|
+
return path_1.default.resolve(realPath, '..');
|
103
|
+
});
|
96
104
|
const getDistDir = () => {
|
97
105
|
return path_1.default.join(__dirname, '..', '..', 'dist');
|
98
106
|
};
|
@@ -104,34 +112,38 @@ const getDistDir = () => {
|
|
104
112
|
const getBinaryStatePath = (binaryDir) => {
|
105
113
|
return path_1.default.join(binaryDir, '..', 'binary_state.json');
|
106
114
|
};
|
107
|
-
const getBinaryStateContentsAsync = (binaryDir) => {
|
115
|
+
const getBinaryStateContentsAsync = (binaryDir) => __awaiter(void 0, void 0, void 0, function* () {
|
108
116
|
const fullPath = getBinaryStatePath(binaryDir);
|
109
|
-
|
110
|
-
|
111
|
-
debug('
|
112
|
-
return
|
113
|
-
}
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
117
|
+
try {
|
118
|
+
const contents = yield fs_extra_1.default.readJson(fullPath);
|
119
|
+
debug('binary_state.json contents:', contents);
|
120
|
+
return contents;
|
121
|
+
}
|
122
|
+
catch (error) {
|
123
|
+
if (error.code === 'ENOENT' || error instanceof SyntaxError) {
|
124
|
+
debug('could not read binary_state.json file at "%s"', fullPath);
|
125
|
+
return {};
|
126
|
+
}
|
127
|
+
throw error;
|
128
|
+
}
|
129
|
+
});
|
130
|
+
const getBinaryVerifiedAsync = (binaryDir) => __awaiter(void 0, void 0, void 0, function* () {
|
131
|
+
const contents = yield getBinaryStateContentsAsync(binaryDir);
|
132
|
+
return contents.verified;
|
133
|
+
});
|
134
|
+
const clearBinaryStateAsync = (binaryDir) => __awaiter(void 0, void 0, void 0, function* () {
|
135
|
+
yield fs_extra_1.default.remove(getBinaryStatePath(binaryDir));
|
136
|
+
});
|
123
137
|
/**
|
124
138
|
* Writes the new binary status.
|
125
139
|
* @param {boolean} verified The new test runner state after smoke test
|
126
140
|
* @param {string} binaryDir Folder holding the binary
|
127
141
|
* @returns {Promise<void>} returns a promise
|
128
142
|
*/
|
129
|
-
const writeBinaryVerifiedAsync = (verified, binaryDir) => {
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
});
|
134
|
-
};
|
143
|
+
const writeBinaryVerifiedAsync = (verified, binaryDir) => __awaiter(void 0, void 0, void 0, function* () {
|
144
|
+
const contents = yield getBinaryStateContentsAsync(binaryDir);
|
145
|
+
yield fs_extra_1.default.outputJson(getBinaryStatePath(binaryDir), lodash_1.default.extend(contents, { verified }), { spaces: 2 });
|
146
|
+
});
|
135
147
|
const getPathToExecutable = (binaryDir) => {
|
136
148
|
return path_1.default.join(binaryDir, getPlatformExecutable());
|
137
149
|
};
|
@@ -139,17 +151,15 @@ const getPathToExecutable = (binaryDir) => {
|
|
139
151
|
* Resolves with an object read from the binary app package.json file.
|
140
152
|
* If the file does not exist resolves with null
|
141
153
|
*/
|
142
|
-
const getBinaryPkgAsync = (binaryDir) => {
|
154
|
+
const getBinaryPkgAsync = (binaryDir) => __awaiter(void 0, void 0, void 0, function* () {
|
143
155
|
const pathToPackageJson = getBinaryPkgPath(binaryDir);
|
144
156
|
debug('Reading binary package.json from:', pathToPackageJson);
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
});
|
152
|
-
};
|
157
|
+
const exists = yield fs_extra_1.default.pathExists(pathToPackageJson);
|
158
|
+
if (!exists) {
|
159
|
+
return null;
|
160
|
+
}
|
161
|
+
return fs_extra_1.default.readJson(pathToPackageJson);
|
162
|
+
});
|
153
163
|
const getBinaryPkgVersion = (o) => lodash_1.default.get(o, 'version', null);
|
154
164
|
const getBinaryElectronVersion = (o) => lodash_1.default.get(o, 'electronVersion', null);
|
155
165
|
const getBinaryElectronNodeVersion = (o) => lodash_1.default.get(o, 'electronNodeVersion', null);
|
@@ -0,0 +1,192 @@
|
|
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 lodash_1 = __importDefault(require("lodash"));
|
16
|
+
const child_process_1 = __importDefault(require("child_process"));
|
17
|
+
const os_1 = __importDefault(require("os"));
|
18
|
+
const yauzl_1 = __importDefault(require("yauzl"));
|
19
|
+
const debug_1 = __importDefault(require("debug"));
|
20
|
+
const extract_zip_1 = __importDefault(require("extract-zip"));
|
21
|
+
const readline_1 = __importDefault(require("readline"));
|
22
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
23
|
+
const errors_1 = require("../errors");
|
24
|
+
const util_1 = __importDefault(require("../util"));
|
25
|
+
const assert_1 = __importDefault(require("assert"));
|
26
|
+
const debug = (0, debug_1.default)('cypress:cli:unzip');
|
27
|
+
const unzipTools = {
|
28
|
+
extract: extract_zip_1.default,
|
29
|
+
};
|
30
|
+
// expose this function for simple testing
|
31
|
+
const unzip = (_a) => __awaiter(void 0, [_a], void 0, function* ({ zipFilePath, installDir, progress }) {
|
32
|
+
debug('unzipping from %s', zipFilePath);
|
33
|
+
debug('into', installDir);
|
34
|
+
if (!zipFilePath) {
|
35
|
+
throw new Error('Missing zip filename');
|
36
|
+
}
|
37
|
+
const startTime = Date.now();
|
38
|
+
let yauzlDoneTime = 0;
|
39
|
+
yield fs_extra_1.default.ensureDir(installDir);
|
40
|
+
yield new Promise((resolve, reject) => {
|
41
|
+
return yauzl_1.default.open(zipFilePath, (err, zipFile) => {
|
42
|
+
yauzlDoneTime = Date.now();
|
43
|
+
if (err) {
|
44
|
+
debug('error using yauzl %s', err.message);
|
45
|
+
return reject(err);
|
46
|
+
}
|
47
|
+
const total = zipFile.entryCount;
|
48
|
+
debug('zipFile entries count', total);
|
49
|
+
const started = new Date();
|
50
|
+
let percent = 0;
|
51
|
+
let count = 0;
|
52
|
+
const notify = (percent) => {
|
53
|
+
const elapsed = +new Date() - +started;
|
54
|
+
const eta = util_1.default.calculateEta(percent, elapsed);
|
55
|
+
progress.onProgress(percent, util_1.default.secsRemaining(eta));
|
56
|
+
};
|
57
|
+
const tick = () => {
|
58
|
+
count += 1;
|
59
|
+
percent = ((count / total) * 100);
|
60
|
+
const displayPercent = percent.toFixed(0);
|
61
|
+
return notify(Number(displayPercent));
|
62
|
+
};
|
63
|
+
const unzipWithNode = () => __awaiter(void 0, void 0, void 0, function* () {
|
64
|
+
debug('unzipping with node.js (slow)');
|
65
|
+
const opts = {
|
66
|
+
dir: installDir,
|
67
|
+
onEntry: tick,
|
68
|
+
};
|
69
|
+
debug('calling Node extract tool %s %o', zipFilePath, opts);
|
70
|
+
try {
|
71
|
+
yield unzipTools.extract(zipFilePath, opts);
|
72
|
+
debug('node unzip finished');
|
73
|
+
return resolve();
|
74
|
+
}
|
75
|
+
catch (err) {
|
76
|
+
const error = err || new Error('Unknown error with Node extract tool');
|
77
|
+
debug('error %s', error.message);
|
78
|
+
return reject(error);
|
79
|
+
}
|
80
|
+
});
|
81
|
+
const unzipFallback = lodash_1.default.once(unzipWithNode);
|
82
|
+
const unzipWithUnzipTool = () => {
|
83
|
+
debug('unzipping via `unzip`');
|
84
|
+
const inflatingRe = /inflating:/;
|
85
|
+
const sp = child_process_1.default.spawn('unzip', ['-o', zipFilePath, '-d', installDir]);
|
86
|
+
sp.on('error', (err) => {
|
87
|
+
debug('unzip tool error: %s', err.message);
|
88
|
+
unzipFallback();
|
89
|
+
});
|
90
|
+
sp.on('close', (code) => {
|
91
|
+
debug('unzip tool close with code %d', code);
|
92
|
+
if (code === 0) {
|
93
|
+
percent = 100;
|
94
|
+
notify(percent);
|
95
|
+
return resolve();
|
96
|
+
}
|
97
|
+
debug('`unzip` failed %o', { code });
|
98
|
+
return unzipFallback();
|
99
|
+
});
|
100
|
+
sp.stdout.on('data', (data) => {
|
101
|
+
if (inflatingRe.test(data)) {
|
102
|
+
return tick();
|
103
|
+
}
|
104
|
+
});
|
105
|
+
sp.stderr.on('data', (data) => {
|
106
|
+
debug('`unzip` stderr %s', data);
|
107
|
+
});
|
108
|
+
};
|
109
|
+
// we attempt to first unzip with the native osx
|
110
|
+
// ditto because its less likely to have problems
|
111
|
+
// with corruption, symlinks, or icons causing failures
|
112
|
+
// and can handle resource forks
|
113
|
+
// http://automatica.com.au/2011/02/unzip-mac-os-x-zip-in-terminal/
|
114
|
+
const unzipWithOsx = () => {
|
115
|
+
debug('unzipping via `ditto`');
|
116
|
+
const copyingFileRe = /^copying file/;
|
117
|
+
const sp = child_process_1.default.spawn('ditto', ['-xkV', zipFilePath, installDir]);
|
118
|
+
// f-it just unzip with node
|
119
|
+
sp.on('error', (err) => {
|
120
|
+
debug(err.message);
|
121
|
+
unzipFallback();
|
122
|
+
});
|
123
|
+
sp.on('close', (code) => {
|
124
|
+
if (code === 0) {
|
125
|
+
// make sure we get to 100% on the progress bar
|
126
|
+
// because reading in lines is not really accurate
|
127
|
+
percent = 100;
|
128
|
+
notify(percent);
|
129
|
+
return resolve();
|
130
|
+
}
|
131
|
+
debug('`ditto` failed %o', { code });
|
132
|
+
return unzipFallback();
|
133
|
+
});
|
134
|
+
return readline_1.default.createInterface({
|
135
|
+
input: sp.stderr,
|
136
|
+
})
|
137
|
+
.on('line', (line) => {
|
138
|
+
if (copyingFileRe.test(line)) {
|
139
|
+
return tick();
|
140
|
+
}
|
141
|
+
});
|
142
|
+
};
|
143
|
+
switch (os_1.default.platform()) {
|
144
|
+
case 'darwin':
|
145
|
+
return unzipWithOsx();
|
146
|
+
case 'linux':
|
147
|
+
return unzipWithUnzipTool();
|
148
|
+
case 'win32':
|
149
|
+
return unzipWithNode();
|
150
|
+
default:
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
});
|
154
|
+
});
|
155
|
+
debug('unzip completed %o', {
|
156
|
+
yauzlMs: yauzlDoneTime - startTime,
|
157
|
+
unzipMs: Date.now() - yauzlDoneTime,
|
158
|
+
});
|
159
|
+
});
|
160
|
+
function isMaybeWindowsMaxPathLengthError(err) {
|
161
|
+
return os_1.default.platform() === 'win32' && err.code === 'ENOENT' && err.syscall === 'realpath';
|
162
|
+
}
|
163
|
+
const start = (_a) => __awaiter(void 0, [_a], void 0, function* ({ zipFilePath, installDir, progress }) {
|
164
|
+
assert_1.default.ok(lodash_1.default.isString(installDir) && !lodash_1.default.isEmpty(installDir), 'missing installDir');
|
165
|
+
if (!progress) {
|
166
|
+
progress = { onProgress: () => {
|
167
|
+
return {};
|
168
|
+
} };
|
169
|
+
}
|
170
|
+
try {
|
171
|
+
const installDirExists = yield fs_extra_1.default.pathExists(installDir);
|
172
|
+
if (installDirExists) {
|
173
|
+
debug('removing existing unzipped binary', installDir);
|
174
|
+
yield fs_extra_1.default.remove(installDir);
|
175
|
+
}
|
176
|
+
yield unzip({ zipFilePath, installDir, progress });
|
177
|
+
}
|
178
|
+
catch (err) {
|
179
|
+
const errorTemplate = isMaybeWindowsMaxPathLengthError(err) ?
|
180
|
+
errors_1.errors.failedUnzipWindowsMaxPathLength
|
181
|
+
: errors_1.errors.failedUnzip;
|
182
|
+
yield (0, errors_1.throwFormErrorText)(errorTemplate)(err);
|
183
|
+
}
|
184
|
+
});
|
185
|
+
const unzipModule = {
|
186
|
+
start,
|
187
|
+
utils: {
|
188
|
+
unzip,
|
189
|
+
unzipTools,
|
190
|
+
},
|
191
|
+
};
|
192
|
+
exports.default = unzipModule;
|