cypress 15.0.0 → 15.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.
- package/bin/cypress +3 -1
- package/index.js +49 -24
- package/lib/VerboseRenderer.js +50 -47
- package/lib/cli.js +455 -351
- package/lib/cypress.js +93 -90
- package/lib/errors.js +181 -194
- package/lib/exec/info.js +85 -74
- package/lib/exec/open.js +77 -73
- package/lib/exec/run.js +144 -154
- package/lib/exec/shared.js +37 -44
- package/lib/exec/spawn.js +270 -232
- package/lib/exec/versions.js +57 -49
- package/lib/exec/xvfb.js +79 -81
- package/lib/fs.js +7 -3
- package/lib/logger.js +37 -32
- package/lib/tasks/cache.js +128 -113
- package/lib/tasks/download.js +247 -258
- package/lib/tasks/get-folder-size.js +33 -22
- package/lib/tasks/install.js +274 -312
- package/lib/tasks/state.js +132 -143
- package/lib/tasks/unzip.js +186 -188
- package/lib/tasks/verify.js +274 -261
- package/lib/util.js +357 -356
- package/package.json +7 -4
- package/react/package.json +1 -1
- package/react/react/package.json +1 -1
- package/types/cypress-automation.d.ts +18 -0
- package/types/cypress.d.ts +15 -2
- package/types/index.d.ts +1 -1
- package/vue/package.json +1 -1
- package/vue/vue/package.json +1 -1
package/lib/errors.js
CHANGED
@@ -1,78 +1,78 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
const
|
10
|
-
const
|
11
|
-
const
|
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
|
+
exports.errors = exports.exitWithError = exports.throwFormErrorText = exports.raise = exports.hr = void 0;
|
7
|
+
exports.getError = getError;
|
8
|
+
exports.formErrorText = formErrorText;
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
10
|
+
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"));
|
13
|
+
const util_1 = __importDefault(require("./util"));
|
14
|
+
const state_1 = __importDefault(require("./tasks/state"));
|
12
15
|
const docsUrl = 'https://on.cypress.io';
|
13
16
|
const requiredDependenciesUrl = `${docsUrl}/required-dependencies`;
|
14
17
|
const runDocumentationUrl = `${docsUrl}/cypress-run`;
|
15
|
-
|
16
18
|
// TODO it would be nice if all error objects could be enforced via types
|
17
19
|
// to only have description + solution properties
|
18
|
-
|
19
|
-
const
|
20
|
-
const genericErrorSolution = stripIndent`
|
20
|
+
exports.hr = '----------';
|
21
|
+
const genericErrorSolution = (0, common_tags_1.stripIndent) `
|
21
22
|
Search for an existing issue or open a GitHub issue at
|
22
23
|
|
23
|
-
${
|
24
|
+
${chalk_1.default.blue(util_1.default.issuesUrl)}
|
24
25
|
`;
|
25
|
-
|
26
26
|
// common errors Cypress application can encounter
|
27
27
|
const unknownError = {
|
28
|
-
|
29
|
-
|
28
|
+
description: 'Unknown Cypress CLI error',
|
29
|
+
solution: genericErrorSolution,
|
30
30
|
};
|
31
31
|
const invalidRunProjectPath = {
|
32
|
-
|
33
|
-
|
32
|
+
description: 'Invalid --project path',
|
33
|
+
solution: (0, common_tags_1.stripIndent) `
|
34
34
|
Please provide a valid project path.
|
35
35
|
|
36
|
-
Learn more about ${
|
36
|
+
Learn more about ${chalk_1.default.cyan('cypress run')} at:
|
37
37
|
|
38
|
-
${
|
39
|
-
|
38
|
+
${chalk_1.default.blue(runDocumentationUrl)}
|
39
|
+
`,
|
40
40
|
};
|
41
41
|
const invalidOS = {
|
42
|
-
|
43
|
-
|
42
|
+
description: 'The Cypress App could not be installed. Your machine does not meet the operating system requirements.',
|
43
|
+
solution: (0, common_tags_1.stripIndent) `
|
44
44
|
|
45
|
-
${
|
45
|
+
${chalk_1.default.blue('https://on.cypress.io/app/get-started/install-cypress#System-requirements')}`,
|
46
46
|
};
|
47
47
|
const failedDownload = {
|
48
|
-
|
49
|
-
|
48
|
+
description: 'The Cypress App could not be downloaded.',
|
49
|
+
solution: (0, common_tags_1.stripIndent) `
|
50
50
|
Does your workplace require a proxy to be used to access the Internet? If so, you must configure the HTTP_PROXY environment variable before downloading Cypress. Read more: https://on.cypress.io/proxy-configuration
|
51
51
|
|
52
|
-
Otherwise, please check network connectivity and try again
|
52
|
+
Otherwise, please check network connectivity and try again:`,
|
53
53
|
};
|
54
54
|
const failedUnzip = {
|
55
|
-
|
56
|
-
|
55
|
+
description: 'The Cypress App could not be unzipped.',
|
56
|
+
solution: genericErrorSolution,
|
57
57
|
};
|
58
58
|
const failedUnzipWindowsMaxPathLength = {
|
59
|
-
|
60
|
-
|
59
|
+
description: 'The Cypress App could not be unzipped.',
|
60
|
+
solution: `This is most likely because the maximum path length is being exceeded on your system.
|
61
61
|
|
62
|
-
Read here for solutions to this problem: https://on.cypress.io/win-max-path-length-error
|
62
|
+
Read here for solutions to this problem: https://on.cypress.io/win-max-path-length-error`,
|
63
63
|
};
|
64
|
-
const missingApp = binaryDir => {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
\nPlease reinstall Cypress by running: ${
|
69
|
-
|
70
|
-
|
64
|
+
const missingApp = (binaryDir) => {
|
65
|
+
return {
|
66
|
+
description: `No version of Cypress is installed in: ${chalk_1.default.cyan(binaryDir)}`,
|
67
|
+
solution: (0, common_tags_1.stripIndent) `
|
68
|
+
\nPlease reinstall Cypress by running: ${chalk_1.default.cyan('cypress install')}
|
69
|
+
`,
|
70
|
+
};
|
71
71
|
};
|
72
|
-
const binaryNotExecutable = executable => {
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
const binaryNotExecutable = (executable) => {
|
73
|
+
return {
|
74
|
+
description: `Cypress cannot run because this binary file does not have executable permissions here:\n\n${executable}`,
|
75
|
+
solution: (0, common_tags_1.stripIndent) `\n
|
76
76
|
Reasons this may happen:
|
77
77
|
|
78
78
|
- node was installed as 'root' or with 'sudo'
|
@@ -81,141 +81,140 @@ const binaryNotExecutable = executable => {
|
|
81
81
|
Please check that you have the appropriate user permissions.
|
82
82
|
|
83
83
|
You can also try clearing the cache with 'cypress cache clear' and reinstalling.
|
84
|
-
|
85
|
-
|
84
|
+
`,
|
85
|
+
};
|
86
86
|
};
|
87
|
-
const notInstalledCI = executable => {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
We expected the binary to be installed here: ${
|
87
|
+
const notInstalledCI = (executable) => {
|
88
|
+
return {
|
89
|
+
description: 'The cypress npm package is installed, but the Cypress binary is missing.',
|
90
|
+
solution: (0, common_tags_1.stripIndent) `\n
|
91
|
+
We expected the binary to be installed here: ${chalk_1.default.cyan(executable)}
|
92
92
|
|
93
93
|
Reasons it may be missing:
|
94
94
|
|
95
|
-
- You're caching 'node_modules' but are not caching this path: ${
|
96
|
-
- You ran 'npm install' at an earlier build step but did not persist: ${
|
95
|
+
- You're caching 'node_modules' but are not caching this path: ${util_1.default.getCacheDir()}
|
96
|
+
- You ran 'npm install' at an earlier build step but did not persist: ${util_1.default.getCacheDir()}
|
97
97
|
|
98
98
|
Properly caching the binary will fix this error and avoid downloading and unzipping Cypress.
|
99
99
|
|
100
100
|
Alternatively, you can run 'cypress install' to download the binary again.
|
101
101
|
|
102
|
-
${
|
103
|
-
|
104
|
-
|
102
|
+
${chalk_1.default.blue('https://on.cypress.io/not-installed-ci-error')}
|
103
|
+
`,
|
104
|
+
};
|
105
105
|
};
|
106
106
|
const nonZeroExitCodeXvfb = {
|
107
|
-
|
108
|
-
|
107
|
+
description: 'Xvfb exited with a non zero exit code.',
|
108
|
+
solution: (0, common_tags_1.stripIndent) `
|
109
109
|
There was a problem spawning Xvfb.
|
110
110
|
|
111
111
|
This is likely a problem with your system, permissions, or installation of Xvfb.
|
112
|
-
|
112
|
+
`,
|
113
113
|
};
|
114
114
|
const missingXvfb = {
|
115
|
-
|
116
|
-
|
115
|
+
description: 'Your system is missing the dependency: Xvfb',
|
116
|
+
solution: (0, common_tags_1.stripIndent) `
|
117
117
|
Install Xvfb and run Cypress again.
|
118
118
|
|
119
119
|
Read our documentation on dependencies for more information:
|
120
120
|
|
121
|
-
${
|
121
|
+
${chalk_1.default.blue(requiredDependenciesUrl)}
|
122
122
|
|
123
123
|
If you are using Docker, we provide containers with all required dependencies installed.
|
124
|
-
|
124
|
+
`,
|
125
125
|
};
|
126
126
|
const smokeTestFailure = (smokeTestCommand, timedOut) => {
|
127
|
-
|
128
|
-
|
129
|
-
|
127
|
+
return {
|
128
|
+
description: `Cypress verification ${timedOut ? 'timed out' : 'failed'}.`,
|
129
|
+
solution: (0, common_tags_1.stripIndent) `
|
130
130
|
This command failed with the following output:
|
131
131
|
|
132
132
|
${smokeTestCommand}
|
133
133
|
|
134
|
-
|
135
|
-
|
134
|
+
`,
|
135
|
+
};
|
136
136
|
};
|
137
137
|
const invalidSmokeTestDisplayError = {
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
138
|
+
code: 'INVALID_SMOKE_TEST_DISPLAY_ERROR',
|
139
|
+
description: 'Cypress verification failed.',
|
140
|
+
solution(msg) {
|
141
|
+
return (0, common_tags_1.stripIndent) `
|
142
142
|
Cypress failed to start after spawning a new Xvfb server.
|
143
143
|
|
144
144
|
The error logs we received were:
|
145
145
|
|
146
|
-
${hr}
|
146
|
+
${exports.hr}
|
147
147
|
|
148
148
|
${msg}
|
149
149
|
|
150
|
-
${hr}
|
150
|
+
${exports.hr}
|
151
151
|
|
152
|
-
This may be due to a missing library or dependency. ${
|
152
|
+
This may be due to a missing library or dependency. ${chalk_1.default.blue(requiredDependenciesUrl)}
|
153
153
|
|
154
154
|
Please refer to the error above for more detail.
|
155
155
|
`;
|
156
|
-
|
156
|
+
},
|
157
157
|
};
|
158
158
|
const missingDependency = {
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
This may be due to a missing library or dependency. ${
|
159
|
+
description: 'Cypress failed to start.',
|
160
|
+
// this message is too Linux specific
|
161
|
+
solution: (0, common_tags_1.stripIndent) `
|
162
|
+
This may be due to a missing library or dependency. ${chalk_1.default.blue(requiredDependenciesUrl)}
|
163
163
|
|
164
164
|
Please refer to the error below for more details.
|
165
|
-
|
165
|
+
`,
|
166
166
|
};
|
167
167
|
const invalidCacheDirectory = {
|
168
|
-
|
169
|
-
|
168
|
+
description: 'Cypress cannot write to the cache directory due to file permissions',
|
169
|
+
solution: (0, common_tags_1.stripIndent) `
|
170
170
|
See discussion and possible solutions at
|
171
|
-
${
|
172
|
-
|
171
|
+
${chalk_1.default.blue(util_1.default.getGitHubIssueUrl(1281))}
|
172
|
+
`,
|
173
173
|
};
|
174
174
|
const versionMismatch = {
|
175
|
-
|
176
|
-
|
175
|
+
description: 'Installed version does not match package version.',
|
176
|
+
solution: 'Install Cypress and verify app again',
|
177
177
|
};
|
178
178
|
const incompatibleHeadlessFlags = {
|
179
|
-
|
180
|
-
|
179
|
+
description: '`--headed` and `--headless` cannot both be passed.',
|
180
|
+
solution: 'Either pass `--headed` or `--headless`, but not both.',
|
181
181
|
};
|
182
|
-
const solutionUnknown = stripIndent`
|
182
|
+
const solutionUnknown = (0, common_tags_1.stripIndent) `
|
183
183
|
Please search Cypress documentation for possible solutions:
|
184
184
|
|
185
|
-
${
|
185
|
+
${chalk_1.default.blue(docsUrl)}
|
186
186
|
|
187
187
|
Check if there is a GitHub issue describing this crash:
|
188
188
|
|
189
|
-
${
|
189
|
+
${chalk_1.default.blue(util_1.default.issuesUrl)}
|
190
190
|
|
191
191
|
Consider opening a new issue.
|
192
192
|
`;
|
193
193
|
const unexpected = {
|
194
|
-
|
195
|
-
|
194
|
+
description: 'An unexpected error occurred while verifying the Cypress executable.',
|
195
|
+
solution: solutionUnknown,
|
196
196
|
};
|
197
197
|
const invalidCypressEnv = {
|
198
|
-
|
199
|
-
|
200
|
-
|
198
|
+
description: chalk_1.default.red('The environment variable with the reserved name "CYPRESS_INTERNAL_ENV" is set.'),
|
199
|
+
solution: chalk_1.default.red('Unset the "CYPRESS_INTERNAL_ENV" environment variable and run Cypress again.'),
|
200
|
+
exitCode: 11,
|
201
201
|
};
|
202
202
|
const invalidTestingType = {
|
203
|
-
|
204
|
-
|
203
|
+
description: 'Invalid testingType',
|
204
|
+
solution: `Please provide a valid testingType. Valid test types are ${chalk_1.default.cyan('\'e2e\'')} and ${chalk_1.default.cyan('\'component\'')}.`,
|
205
205
|
};
|
206
206
|
const incompatibleTestTypeFlags = {
|
207
|
-
|
208
|
-
|
207
|
+
description: '`--e2e` and `--component` cannot both be passed.',
|
208
|
+
solution: 'Either pass `--e2e` or `--component`, but not both.',
|
209
209
|
};
|
210
210
|
const incompatibleTestingTypeAndFlag = {
|
211
|
-
|
212
|
-
|
211
|
+
description: 'Set a `testingType` and also passed `--e2e` or `--component` flags.',
|
212
|
+
solution: 'Either set `testingType` or pass a testing type flag, but not both.',
|
213
213
|
};
|
214
214
|
const invalidConfigFile = {
|
215
|
-
|
216
|
-
|
215
|
+
description: '`--config-file` cannot be false.',
|
216
|
+
solution: 'Either pass a relative path to a valid Cypress config file or remove this option.',
|
217
217
|
};
|
218
|
-
|
219
218
|
/**
|
220
219
|
* This error happens when CLI detects that the child Test Runner process
|
221
220
|
* was killed with a signal, like SIGBUS
|
@@ -224,29 +223,25 @@ const invalidConfigFile = {
|
|
224
223
|
* @param {string} signal Signal that closed the child process, like "SIGBUS"
|
225
224
|
*/
|
226
225
|
const childProcessKilled = (eventName, signal) => {
|
227
|
-
return {
|
228
|
-
description: `The Test Runner unexpectedly exited via a ${chalk.cyan(eventName)} event with signal ${chalk.cyan(signal)}`,
|
229
|
-
solution: solutionUnknown
|
230
|
-
};
|
231
|
-
};
|
232
|
-
const CYPRESS_RUN_BINARY = {
|
233
|
-
notValid: value => {
|
234
|
-
const properFormat = `**/${state.getPlatformExecutable()}`;
|
235
226
|
return {
|
236
|
-
|
237
|
-
|
227
|
+
description: `The Test Runner unexpectedly exited via a ${chalk_1.default.cyan(eventName)} event with signal ${chalk_1.default.cyan(signal)}`,
|
228
|
+
solution: solutionUnknown,
|
238
229
|
};
|
239
|
-
|
230
|
+
};
|
231
|
+
const CYPRESS_RUN_BINARY = {
|
232
|
+
notValid: (value) => {
|
233
|
+
const properFormat = `**/${state_1.default.getPlatformExecutable()}`;
|
234
|
+
return {
|
235
|
+
description: `Could not run binary set by environment variable: CYPRESS_RUN_BINARY=${value}`,
|
236
|
+
solution: `Ensure the environment variable is a path to the Cypress binary, matching ${properFormat}`,
|
237
|
+
};
|
238
|
+
},
|
240
239
|
};
|
241
240
|
function addPlatformInformation(info) {
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
platform
|
246
|
-
};
|
247
|
-
});
|
241
|
+
return util_1.default.getPlatformInfo().then((platform) => {
|
242
|
+
return Object.assign(Object.assign({}, info), { platform });
|
243
|
+
});
|
248
244
|
}
|
249
|
-
|
250
245
|
/**
|
251
246
|
* Given an error object (see the errors above), forms error message text with details,
|
252
247
|
* then resolves with Error instance you can throw or reject with.
|
@@ -260,109 +255,102 @@ function addPlatformInformation(info) {
|
|
260
255
|
```
|
261
256
|
*/
|
262
257
|
function getError(errorObject) {
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
258
|
+
return formErrorText(errorObject).then((errorMessage) => {
|
259
|
+
const err = new Error(errorMessage);
|
260
|
+
err.known = true;
|
261
|
+
return err;
|
262
|
+
});
|
268
263
|
}
|
269
|
-
|
270
264
|
/**
|
271
265
|
* Forms nice error message with error and platform information,
|
272
266
|
* and if possible a way to solve it. Resolves with a string.
|
273
267
|
*/
|
274
268
|
function formErrorText(info, msg, prevMessage) {
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
add(`
|
269
|
+
return addPlatformInformation(info).then((obj) => {
|
270
|
+
const formatted = [];
|
271
|
+
function add(msg) {
|
272
|
+
formatted.push((0, common_tags_1.stripIndents)(msg));
|
273
|
+
}
|
274
|
+
(0, lazy_ass_1.default)(check_more_types_1.default.unemptyString(obj.description), 'expected error description to be text', obj.description);
|
275
|
+
// assuming that if there the solution is a function it will handle
|
276
|
+
// 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);
|
280
|
+
add(`
|
288
281
|
${obj.description}
|
289
282
|
|
290
283
|
${text}
|
291
284
|
|
292
285
|
`);
|
293
|
-
|
294
|
-
|
295
|
-
|
286
|
+
}
|
287
|
+
else {
|
288
|
+
(0, lazy_ass_1.default)(check_more_types_1.default.unemptyString(obj.solution), 'expected error solution to be text', obj.solution);
|
289
|
+
add(`
|
296
290
|
${obj.description}
|
297
291
|
|
298
292
|
${obj.solution}
|
299
293
|
|
300
294
|
`);
|
301
|
-
|
302
|
-
|
303
|
-
${hr}
|
295
|
+
if (msg) {
|
296
|
+
add(`
|
297
|
+
${exports.hr}
|
304
298
|
|
305
299
|
${msg}
|
306
300
|
|
307
301
|
`);
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
${hr}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
add(`
|
305
|
+
${exports.hr}
|
312
306
|
|
313
307
|
${obj.platform}
|
314
308
|
`);
|
315
|
-
|
316
|
-
|
309
|
+
if (obj.footer) {
|
310
|
+
add(`
|
317
311
|
|
318
|
-
${hr}
|
312
|
+
${exports.hr}
|
319
313
|
|
320
314
|
${obj.footer}
|
321
315
|
`);
|
322
|
-
|
323
|
-
|
324
|
-
|
316
|
+
}
|
317
|
+
return formatted.join('\n\n');
|
318
|
+
});
|
325
319
|
}
|
326
|
-
const raise = info => {
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
320
|
+
const raise = (info) => {
|
321
|
+
return (text) => {
|
322
|
+
const err = new Error(text);
|
323
|
+
if (info.code) {
|
324
|
+
err.code = info.code;
|
325
|
+
}
|
326
|
+
err.known = true;
|
327
|
+
throw err;
|
328
|
+
};
|
335
329
|
};
|
336
|
-
|
337
|
-
|
338
|
-
return
|
339
|
-
|
330
|
+
exports.raise = raise;
|
331
|
+
const throwFormErrorText = (info) => {
|
332
|
+
return (msg, prevMessage) => {
|
333
|
+
return formErrorText(info, msg, prevMessage).then((0, exports.raise)(info));
|
334
|
+
};
|
340
335
|
};
|
341
|
-
|
336
|
+
exports.throwFormErrorText = throwFormErrorText;
|
342
337
|
/**
|
343
338
|
* Forms full error message with error and OS details, prints to the error output
|
344
339
|
* and then exits the process.
|
345
340
|
* @param {ErrorInformation} info Error information {description, solution}
|
346
341
|
* @example return exitWithError(errors.invalidCypressEnv)('foo')
|
347
342
|
*/
|
348
|
-
const exitWithError = info => {
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
343
|
+
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
|
+
};
|
356
351
|
};
|
357
|
-
|
358
|
-
|
359
|
-
exitWithError,
|
360
|
-
// formError,
|
361
|
-
formErrorText,
|
362
|
-
throwFormErrorText,
|
363
|
-
getError,
|
364
|
-
hr,
|
365
|
-
errors: {
|
352
|
+
exports.exitWithError = exitWithError;
|
353
|
+
exports.errors = {
|
366
354
|
unknownError,
|
367
355
|
nonZeroExitCodeXvfb,
|
368
356
|
missingXvfb,
|
@@ -387,6 +375,5 @@ module.exports = {
|
|
387
375
|
invalidTestingType,
|
388
376
|
incompatibleTestTypeFlags,
|
389
377
|
incompatibleTestingTypeAndFlag,
|
390
|
-
invalidConfigFile
|
391
|
-
|
392
|
-
};
|
378
|
+
invalidConfigFile,
|
379
|
+
};
|