@wdio/cli 7.20.9 → 8.0.0-alpha.219
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/wdio.js +7 -1
- package/build/commands/config.d.ts +3 -3
- package/build/commands/config.d.ts.map +1 -1
- package/build/commands/config.js +56 -61
- package/build/commands/index.d.ts +2 -0
- package/build/commands/index.d.ts.map +1 -0
- package/build/commands/index.js +5 -0
- package/build/commands/install.d.ts +3 -3
- package/build/commands/install.d.ts.map +1 -1
- package/build/commands/install.js +27 -35
- package/build/commands/repl.d.ts +5 -5
- package/build/commands/repl.d.ts.map +1 -1
- package/build/commands/repl.js +15 -29
- package/build/commands/run.d.ts +3 -3
- package/build/commands/run.d.ts.map +1 -1
- package/build/commands/run.js +24 -33
- package/build/constants.d.ts +2 -1
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +45 -46
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +24 -41
- package/build/interface.d.ts +2 -2
- package/build/interface.d.ts.map +1 -1
- package/build/interface.js +27 -34
- package/build/launcher.d.ts +4 -4
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +59 -52
- package/build/types.d.ts +2 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.js +1 -2
- package/build/utils.d.ts +1 -1
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +71 -92
- package/build/watcher.d.ts +1 -1
- package/build/watcher.d.ts.map +1 -1
- package/build/watcher.js +21 -24
- package/package.json +32 -26
package/build/utils.js
CHANGED
|
@@ -1,36 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
class HookError extends webdriverio_1.SevereServiceError {
|
|
1
|
+
import { dirname } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { execSync } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import ejs from 'ejs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import inquirer from 'inquirer';
|
|
10
|
+
import pickBy from 'lodash.pickby';
|
|
11
|
+
import logger from '@wdio/logger';
|
|
12
|
+
import readDir from 'recursive-readdir';
|
|
13
|
+
import { SevereServiceError } from 'webdriverio';
|
|
14
|
+
import { ConfigParser } from '@wdio/config';
|
|
15
|
+
import { CAPABILITY_KEYS } from '@wdio/protocols';
|
|
16
|
+
import { EXCLUSIVE_SERVICES, ANDROID_CONFIG, IOS_CONFIG, QUESTIONNAIRE } from './constants.js';
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const log = logger('@wdio/cli:utils');
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const TEMPLATE_ROOT_DIR = path.join(__dirname, 'templates', 'exampleFiles');
|
|
21
|
+
const renderFile = promisify(ejs.renderFile);
|
|
22
|
+
export class HookError extends SevereServiceError {
|
|
24
23
|
constructor(message, origin) {
|
|
25
24
|
super(message);
|
|
26
25
|
this.origin = origin;
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
|
-
exports.HookError = HookError;
|
|
30
28
|
/**
|
|
31
29
|
* run service launch sequences
|
|
32
30
|
*/
|
|
33
|
-
async function runServiceHook(launcher, hookName, ...args) {
|
|
31
|
+
export async function runServiceHook(launcher, hookName, ...args) {
|
|
34
32
|
const start = Date.now();
|
|
35
33
|
return Promise.all(launcher.map(async (service) => {
|
|
36
34
|
try {
|
|
@@ -40,7 +38,7 @@ async function runServiceHook(launcher, hookName, ...args) {
|
|
|
40
38
|
}
|
|
41
39
|
catch (err) {
|
|
42
40
|
const message = `A service failed in the '${hookName}' hook\n${err.stack}\n\n`;
|
|
43
|
-
if (err instanceof
|
|
41
|
+
if (err instanceof SevereServiceError) {
|
|
44
42
|
return { status: 'rejected', reason: message, origin: hookName };
|
|
45
43
|
}
|
|
46
44
|
log.error(`${message}Continue...`);
|
|
@@ -55,20 +53,19 @@ async function runServiceHook(launcher, hookName, ...args) {
|
|
|
55
53
|
}
|
|
56
54
|
});
|
|
57
55
|
}
|
|
58
|
-
exports.runServiceHook = runServiceHook;
|
|
59
56
|
/**
|
|
60
57
|
* Run hook in service launcher
|
|
61
58
|
* @param {Array|Function} hook - can be array of functions or single function
|
|
62
59
|
* @param {Object} config
|
|
63
60
|
* @param {Object} capabilities
|
|
64
61
|
*/
|
|
65
|
-
async function runLauncherHook(hook, ...args) {
|
|
62
|
+
export async function runLauncherHook(hook, ...args) {
|
|
66
63
|
if (typeof hook === 'function') {
|
|
67
64
|
hook = [hook];
|
|
68
65
|
}
|
|
69
66
|
const catchFn = (e) => {
|
|
70
67
|
log.error(`Error in hook: ${e.stack}`);
|
|
71
|
-
if (e instanceof
|
|
68
|
+
if (e instanceof SevereServiceError) {
|
|
72
69
|
throw new HookError(e.message, hook[0].name);
|
|
73
70
|
}
|
|
74
71
|
};
|
|
@@ -81,7 +78,6 @@ async function runLauncherHook(hook, ...args) {
|
|
|
81
78
|
}
|
|
82
79
|
})).catch(catchFn);
|
|
83
80
|
}
|
|
84
|
-
exports.runLauncherHook = runLauncherHook;
|
|
85
81
|
/**
|
|
86
82
|
* Run onCompleteHook in Launcher
|
|
87
83
|
* @param {Array|Function} onCompleteHook - can be array of functions or single function
|
|
@@ -90,7 +86,7 @@ exports.runLauncherHook = runLauncherHook;
|
|
|
90
86
|
* @param {*} exitCode
|
|
91
87
|
* @param {*} results
|
|
92
88
|
*/
|
|
93
|
-
async function runOnCompleteHook(onCompleteHook, config, capabilities, exitCode, results) {
|
|
89
|
+
export async function runOnCompleteHook(onCompleteHook, config, capabilities, exitCode, results) {
|
|
94
90
|
if (typeof onCompleteHook === 'function') {
|
|
95
91
|
onCompleteHook = [onCompleteHook];
|
|
96
92
|
}
|
|
@@ -101,18 +97,17 @@ async function runOnCompleteHook(onCompleteHook, config, capabilities, exitCode,
|
|
|
101
97
|
}
|
|
102
98
|
catch (err) {
|
|
103
99
|
log.error(`Error in onCompleteHook: ${err.stack}`);
|
|
104
|
-
if (err instanceof
|
|
100
|
+
if (err instanceof SevereServiceError) {
|
|
105
101
|
throw new HookError(err.message, 'onComplete');
|
|
106
102
|
}
|
|
107
103
|
return 1;
|
|
108
104
|
}
|
|
109
105
|
}));
|
|
110
106
|
}
|
|
111
|
-
exports.runOnCompleteHook = runOnCompleteHook;
|
|
112
107
|
/**
|
|
113
108
|
* get runner identification by caps
|
|
114
109
|
*/
|
|
115
|
-
function getRunnerName(caps = {}) {
|
|
110
|
+
export function getRunnerName(caps = {}) {
|
|
116
111
|
let runner = caps.browserName ||
|
|
117
112
|
caps.appPackage ||
|
|
118
113
|
caps.appWaitActivity ||
|
|
@@ -128,13 +123,11 @@ function getRunnerName(caps = {}) {
|
|
|
128
123
|
}
|
|
129
124
|
return runner;
|
|
130
125
|
}
|
|
131
|
-
exports.getRunnerName = getRunnerName;
|
|
132
126
|
function buildNewConfigArray(str, type, change) {
|
|
133
|
-
var _a;
|
|
134
127
|
const newStr = str
|
|
135
128
|
.split(`${type}s: `)[1]
|
|
136
129
|
.replace(/'/g, '');
|
|
137
|
-
let newArray =
|
|
130
|
+
let newArray = newStr.match(/(\w*)/gmi)?.filter(e => !!e).concat([change]) || [];
|
|
138
131
|
return str
|
|
139
132
|
.replace('// ', '')
|
|
140
133
|
.replace(new RegExp(`(${type}s: )((.*\\s*)*)`), `$1[${newArray.map(e => `'${e}'`)}]`);
|
|
@@ -142,7 +135,7 @@ function buildNewConfigArray(str, type, change) {
|
|
|
142
135
|
function buildNewConfigString(str, type, change) {
|
|
143
136
|
return str.replace(new RegExp(`(${type}: )('\\w*')`), `$1'${change}'`);
|
|
144
137
|
}
|
|
145
|
-
function findInConfig(config, type) {
|
|
138
|
+
export function findInConfig(config, type) {
|
|
146
139
|
let regexStr = `[\\/\\/]*[\\s]*${type}s: [\\s]*\\[([\\s]*['|"]\\w*['|"],*)*[\\s]*\\]`;
|
|
147
140
|
if (type === 'framework') {
|
|
148
141
|
regexStr = `[\\/\\/]*[\\s]*${type}: ([\\s]*['|"]\\w*['|"])`;
|
|
@@ -150,8 +143,7 @@ function findInConfig(config, type) {
|
|
|
150
143
|
const regex = new RegExp(regexStr, 'gmi');
|
|
151
144
|
return config.match(regex);
|
|
152
145
|
}
|
|
153
|
-
|
|
154
|
-
function replaceConfig(config, type, name) {
|
|
146
|
+
export function replaceConfig(config, type, name) {
|
|
155
147
|
if (type === 'framework') {
|
|
156
148
|
return buildNewConfigString(config, type, name);
|
|
157
149
|
}
|
|
@@ -162,8 +154,7 @@ function replaceConfig(config, type, name) {
|
|
|
162
154
|
const text = match.pop() || '';
|
|
163
155
|
return config.replace(text, buildNewConfigArray(text, type, name));
|
|
164
156
|
}
|
|
165
|
-
|
|
166
|
-
function addServiceDeps(names, packages, update = false) {
|
|
157
|
+
export function addServiceDeps(names, packages, update = false) {
|
|
167
158
|
/**
|
|
168
159
|
* automatically install latest Chromedriver if `wdio-chromedriver-service`
|
|
169
160
|
* was selected for install
|
|
@@ -180,7 +171,7 @@ function addServiceDeps(names, packages, update = false) {
|
|
|
180
171
|
* was selected for install
|
|
181
172
|
*/
|
|
182
173
|
if (names.some(({ short }) => short === 'appium')) {
|
|
183
|
-
const result =
|
|
174
|
+
const result = execSync('appium --version || echo APPIUM_MISSING').toString().trim();
|
|
184
175
|
if (result === 'APPIUM_MISSING') {
|
|
185
176
|
packages.push('appium');
|
|
186
177
|
}
|
|
@@ -190,28 +181,25 @@ function addServiceDeps(names, packages, update = false) {
|
|
|
190
181
|
}
|
|
191
182
|
}
|
|
192
183
|
}
|
|
193
|
-
exports.addServiceDeps = addServiceDeps;
|
|
194
184
|
/**
|
|
195
185
|
* @todo add JSComments
|
|
196
186
|
*/
|
|
197
|
-
function convertPackageHashToObject(pkg, hash = '$--$') {
|
|
187
|
+
export function convertPackageHashToObject(pkg, hash = '$--$') {
|
|
198
188
|
const splitHash = pkg.split(hash);
|
|
199
189
|
return {
|
|
200
190
|
package: splitHash[0],
|
|
201
191
|
short: splitHash[1]
|
|
202
192
|
};
|
|
203
193
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const tplPath = path_1.default.join(__dirname, 'templates/wdio.conf.tpl.ejs');
|
|
194
|
+
export async function renderConfigurationFile(answers) {
|
|
195
|
+
const tplPath = path.join(__dirname, 'templates/wdio.conf.tpl.ejs');
|
|
207
196
|
const filename = `wdio.conf.${answers.isUsingTypeScript ? 'ts' : 'js'}`;
|
|
208
197
|
const renderedTpl = await renderFile(tplPath, { answers });
|
|
209
|
-
return
|
|
198
|
+
return fs.promises.writeFile(path.join(process.cwd(), answers.isUsingTypeScript ? 'test' : '', filename), renderedTpl);
|
|
210
199
|
}
|
|
211
|
-
|
|
212
|
-
const validateServiceAnswers = (answers) => {
|
|
200
|
+
export const validateServiceAnswers = (answers) => {
|
|
213
201
|
let result = true;
|
|
214
|
-
Object.entries(
|
|
202
|
+
Object.entries(EXCLUSIVE_SERVICES).forEach(([name, { services, message }]) => {
|
|
215
203
|
const exists = answers.some(answer => answer.includes(name));
|
|
216
204
|
const hasExclusive = services.some(service => answers.some(answer => answer.includes(service)));
|
|
217
205
|
if (exists && hasExclusive) {
|
|
@@ -220,8 +208,7 @@ const validateServiceAnswers = (answers) => {
|
|
|
220
208
|
});
|
|
221
209
|
return result;
|
|
222
210
|
};
|
|
223
|
-
|
|
224
|
-
function getCapabilities(arg) {
|
|
211
|
+
export function getCapabilities(arg) {
|
|
225
212
|
const optionalCapabilites = {
|
|
226
213
|
platformVersion: arg.platformVersion,
|
|
227
214
|
udid: arg.udid,
|
|
@@ -235,19 +222,19 @@ function getCapabilities(arg) {
|
|
|
235
222
|
return {
|
|
236
223
|
capabilities: {
|
|
237
224
|
app: arg.option,
|
|
238
|
-
...(arg.option.endsWith('apk') ?
|
|
225
|
+
...(arg.option.endsWith('apk') ? ANDROID_CONFIG : IOS_CONFIG),
|
|
239
226
|
...optionalCapabilites,
|
|
240
227
|
}
|
|
241
228
|
};
|
|
242
229
|
}
|
|
243
230
|
else if (/android/.test(arg.option)) {
|
|
244
|
-
return { capabilities: { browserName: 'Chrome', ...
|
|
231
|
+
return { capabilities: { browserName: 'Chrome', ...ANDROID_CONFIG, ...optionalCapabilites } };
|
|
245
232
|
}
|
|
246
233
|
else if (/ios/.test(arg.option)) {
|
|
247
|
-
return { capabilities: { browserName: 'Safari', ...
|
|
234
|
+
return { capabilities: { browserName: 'Safari', ...IOS_CONFIG, ...optionalCapabilites } };
|
|
248
235
|
}
|
|
249
236
|
else if (/(js|ts)$/.test(arg.option)) {
|
|
250
|
-
const config = new
|
|
237
|
+
const config = new ConfigParser();
|
|
251
238
|
config.autoCompile();
|
|
252
239
|
try {
|
|
253
240
|
config.addConfigFile(arg.option);
|
|
@@ -265,7 +252,7 @@ function getCapabilities(arg) {
|
|
|
265
252
|
requiredCaps[parseInt(arg.capabilities, 10)] ||
|
|
266
253
|
// multiremote
|
|
267
254
|
requiredCaps[arg.capabilities]);
|
|
268
|
-
const requiredW3CCaps = (
|
|
255
|
+
const requiredW3CCaps = pickBy(requiredCaps, (_, key) => CAPABILITY_KEYS.includes(key) || key.includes(':'));
|
|
269
256
|
if (!Object.keys(requiredW3CCaps).length) {
|
|
270
257
|
throw Error(`No capability found in given config file with the provided capability indexed/named property: ${arg.capabilities}. Please check the capability in your wdio config file.`);
|
|
271
258
|
}
|
|
@@ -273,26 +260,24 @@ function getCapabilities(arg) {
|
|
|
273
260
|
}
|
|
274
261
|
return { capabilities: { browserName: arg.option } };
|
|
275
262
|
}
|
|
276
|
-
exports.getCapabilities = getCapabilities;
|
|
277
263
|
/**
|
|
278
264
|
* Check if file exists in current work directory
|
|
279
265
|
* @param {string} filename to check existance for
|
|
280
266
|
*/
|
|
281
|
-
function hasFile(filename) {
|
|
282
|
-
return
|
|
267
|
+
export function hasFile(filename) {
|
|
268
|
+
return fs.existsSync(path.join(process.cwd(), filename));
|
|
283
269
|
}
|
|
284
|
-
exports.hasFile = hasFile;
|
|
285
270
|
/**
|
|
286
271
|
* Check if package is installed
|
|
287
272
|
* @param {string} package to check existance for
|
|
288
273
|
*/
|
|
289
|
-
function hasPackage(pkg) {
|
|
274
|
+
export function hasPackage(pkg) {
|
|
290
275
|
try {
|
|
291
276
|
/**
|
|
292
277
|
* this is only for testing purposes as we want to check whether
|
|
293
278
|
* we add `@babel/register` to the packages to install when resolving fails
|
|
294
279
|
*/
|
|
295
|
-
if (process.env.
|
|
280
|
+
if (process.env.VITEST_WORKER_ID && process.env.WDIO_TEST_THROW_RESOLVE) {
|
|
296
281
|
throw new Error('resolve error');
|
|
297
282
|
}
|
|
298
283
|
require.resolve(pkg);
|
|
@@ -302,35 +287,33 @@ function hasPackage(pkg) {
|
|
|
302
287
|
return false;
|
|
303
288
|
}
|
|
304
289
|
}
|
|
305
|
-
exports.hasPackage = hasPackage;
|
|
306
290
|
/**
|
|
307
291
|
* generate test files based on CLI answers
|
|
308
292
|
*/
|
|
309
|
-
async function generateTestFiles(answers) {
|
|
293
|
+
export async function generateTestFiles(answers) {
|
|
310
294
|
const testFiles = answers.framework === 'cucumber'
|
|
311
|
-
? [
|
|
295
|
+
? [path.join(TEMPLATE_ROOT_DIR, 'cucumber')]
|
|
312
296
|
: (answers.framework === 'mocha'
|
|
313
|
-
? [
|
|
314
|
-
: [
|
|
297
|
+
? [path.join(TEMPLATE_ROOT_DIR, 'mocha')]
|
|
298
|
+
: [path.join(TEMPLATE_ROOT_DIR, 'jasmine')]);
|
|
315
299
|
if (answers.usePageObjects) {
|
|
316
|
-
testFiles.push(
|
|
300
|
+
testFiles.push(path.join(TEMPLATE_ROOT_DIR, 'pageobjects'));
|
|
317
301
|
}
|
|
318
|
-
const files = (await Promise.all(testFiles.map((dirPath) => (
|
|
302
|
+
const files = (await Promise.all(testFiles.map((dirPath) => readDir(dirPath, [(file, stats) => !stats.isDirectory() && !(file.endsWith('.ejs') || file.endsWith('.feature'))])))).reduce((cur, acc) => [...acc, ...(cur)], []);
|
|
319
303
|
for (const file of files) {
|
|
320
304
|
const renderedTpl = await renderFile(file, answers);
|
|
321
305
|
let destPath = (file.endsWith('page.js.ejs')
|
|
322
|
-
? `${answers.destPageObjectRootPath}/${
|
|
306
|
+
? `${answers.destPageObjectRootPath}/${path.basename(file)}`
|
|
323
307
|
: file.includes('step_definition')
|
|
324
308
|
? `${answers.stepDefinitions}`
|
|
325
|
-
: `${answers.destSpecRootPath}/${
|
|
326
|
-
|
|
327
|
-
await
|
|
309
|
+
: `${answers.destSpecRootPath}/${path.basename(file)}`).replace(/\.ejs$/, '').replace(/\.js$/, answers.isUsingTypeScript ? '.ts' : '.js');
|
|
310
|
+
fs.ensureDirSync(path.dirname(destPath));
|
|
311
|
+
await fs.promises.writeFile(destPath, renderedTpl);
|
|
328
312
|
}
|
|
329
313
|
}
|
|
330
|
-
|
|
331
|
-
async function getAnswers(yes) {
|
|
314
|
+
export async function getAnswers(yes) {
|
|
332
315
|
return yes
|
|
333
|
-
?
|
|
316
|
+
? QUESTIONNAIRE.reduce((answers, question) => Object.assign(answers, question.when && !question.when(answers)
|
|
334
317
|
/**
|
|
335
318
|
* set nothing if question doesn't apply
|
|
336
319
|
*/
|
|
@@ -351,19 +334,18 @@ async function getAnswers(yes) {
|
|
|
351
334
|
: question.choices[0]
|
|
352
335
|
: {}
|
|
353
336
|
}), {})
|
|
354
|
-
: await
|
|
337
|
+
: await inquirer.prompt(QUESTIONNAIRE);
|
|
355
338
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
const destStepRootPath = path_1.default.join(process.cwd(), path_1.default.dirname(answers.stepDefinitions || ''));
|
|
339
|
+
export function getPathForFileGeneration(answers) {
|
|
340
|
+
const destSpecRootPath = path.join(process.cwd(), path.dirname(answers.specs || '').replace(/\*\*$/, ''));
|
|
341
|
+
const destStepRootPath = path.join(process.cwd(), path.dirname(answers.stepDefinitions || ''));
|
|
360
342
|
const destPageObjectRootPath = answers.usePageObjects
|
|
361
|
-
?
|
|
343
|
+
? path.join(process.cwd(), path.dirname(answers.pages || '').replace(/\*\*$/, ''))
|
|
362
344
|
: '';
|
|
363
345
|
let relativePath = (answers.generateTestFiles && answers.usePageObjects)
|
|
364
346
|
? !(convertPackageHashToObject(answers.framework).short === 'cucumber')
|
|
365
|
-
?
|
|
366
|
-
:
|
|
347
|
+
? path.relative(destSpecRootPath, destPageObjectRootPath)
|
|
348
|
+
: path.relative(destStepRootPath, destPageObjectRootPath)
|
|
367
349
|
: '';
|
|
368
350
|
/**
|
|
369
351
|
* On Windows, path.relative can return backslashes that could be interpreted as espace sequences in strings
|
|
@@ -378,11 +360,8 @@ function getPathForFileGeneration(answers) {
|
|
|
378
360
|
relativePath: relativePath
|
|
379
361
|
};
|
|
380
362
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
var _a;
|
|
384
|
-
return ((_a = answers === null || answers === void 0 ? void 0 : answers.isUsingCompiler) === null || _a === void 0 ? void 0 : _a.toString().includes('TypeScript'))
|
|
363
|
+
export function getDefaultFiles(answers, filePath) {
|
|
364
|
+
return answers?.isUsingCompiler?.toString().includes('TypeScript')
|
|
385
365
|
? `${filePath}.ts`
|
|
386
366
|
: `${filePath}.js`;
|
|
387
367
|
}
|
|
388
|
-
exports.getDefaultFiles = getDefaultFiles;
|
package/build/watcher.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Workers } from '@wdio/types';
|
|
2
|
-
import { RunCommandArguments, ValueKeyIteratee } from './types
|
|
2
|
+
import type { RunCommandArguments, ValueKeyIteratee } from './types';
|
|
3
3
|
declare type Spec = string | string[];
|
|
4
4
|
export default class Watcher {
|
|
5
5
|
private _configFile;
|
package/build/watcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAgB,OAAO,EAAE,MAAM,aAAa,CAAA;AAGxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAIpE,aAAK,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;AAC7B,MAAM,CAAC,OAAO,OAAO,OAAO;IAKpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IALjB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,MAAM,CAAQ;gBAGV,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC;IAYpD,KAAK;IAwCX;;;;OAIG;IACH,eAAe,CAAE,UAAU,UAAO,UAChB,MAAM;IA6BxB;;;;;OAKG;IACH,UAAU,CAAE,SAAS,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU;IAqB7H;;;OAGG;IACH,GAAG,CAAE,MAAM,GAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,IAAI,CAAA;KAAO;IAuC9E,OAAO;CAGV"}
|
package/build/watcher.js
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const lodash_flattendeep_1 = __importDefault(require("lodash.flattendeep"));
|
|
10
|
-
const lodash_union_1 = __importDefault(require("lodash.union"));
|
|
11
|
-
const launcher_1 = __importDefault(require("./launcher"));
|
|
12
|
-
const log = (0, logger_1.default)('@wdio/cli:watch');
|
|
13
|
-
class Watcher {
|
|
1
|
+
import chokidar from 'chokidar';
|
|
2
|
+
import logger from '@wdio/logger';
|
|
3
|
+
import pickBy from 'lodash.pickby';
|
|
4
|
+
import flattenDeep from 'lodash.flattendeep';
|
|
5
|
+
import union from 'lodash.union';
|
|
6
|
+
import Launcher from './launcher.js';
|
|
7
|
+
const log = logger('@wdio/cli:watch');
|
|
8
|
+
export default class Watcher {
|
|
14
9
|
constructor(_configFile, _args) {
|
|
15
10
|
this._configFile = _configFile;
|
|
16
11
|
this._args = _args;
|
|
17
12
|
log.info('Starting launcher in watch mode');
|
|
18
|
-
this._launcher = new
|
|
13
|
+
this._launcher = new Launcher(this._configFile, this._args, true);
|
|
19
14
|
const specs = this._launcher.configParser.getSpecs();
|
|
20
|
-
const capSpecs = this._launcher.isMultiremote ? [] : (
|
|
15
|
+
const capSpecs = this._launcher.isMultiremote ? [] : union(flattenDeep(this._launcher.configParser.getCapabilities().map(cap => cap.specs || [])));
|
|
21
16
|
this._specs = [...specs, ...capSpecs];
|
|
22
17
|
}
|
|
23
18
|
async watch() {
|
|
24
19
|
/**
|
|
25
20
|
* listen on spec changes and rerun specific spec file
|
|
26
21
|
*/
|
|
27
|
-
let flattenedSpecs = (
|
|
28
|
-
|
|
22
|
+
let flattenedSpecs = flattenDeep(this._specs);
|
|
23
|
+
chokidar.watch(flattenedSpecs, { ignoreInitial: true })
|
|
29
24
|
.on('add', this.getFileListener())
|
|
30
25
|
.on('change', this.getFileListener());
|
|
31
26
|
/**
|
|
@@ -33,7 +28,7 @@ class Watcher {
|
|
|
33
28
|
*/
|
|
34
29
|
const { filesToWatch } = this._launcher.configParser.getConfig();
|
|
35
30
|
if (filesToWatch.length) {
|
|
36
|
-
|
|
31
|
+
chokidar.watch(filesToWatch, { ignoreInitial: true })
|
|
37
32
|
.on('add', this.getFileListener(false))
|
|
38
33
|
.on('change', this.getFileListener(false));
|
|
39
34
|
}
|
|
@@ -52,7 +47,7 @@ class Watcher {
|
|
|
52
47
|
if (Object.values(workers).find((w) => w.isBusy)) {
|
|
53
48
|
return;
|
|
54
49
|
}
|
|
55
|
-
this._launcher.interface
|
|
50
|
+
this._launcher.interface?.finalise();
|
|
56
51
|
}));
|
|
57
52
|
}
|
|
58
53
|
/**
|
|
@@ -95,15 +90,18 @@ class Watcher {
|
|
|
95
90
|
* @return Object with workers, e.g. {'0-0': { ... }}
|
|
96
91
|
*/
|
|
97
92
|
getWorkers(predicate, includeBusyWorker) {
|
|
93
|
+
if (!this._launcher.runner) {
|
|
94
|
+
throw new Error('Internal Error: no runner initialised, call run() first');
|
|
95
|
+
}
|
|
98
96
|
let workers = this._launcher.runner.workerPool;
|
|
99
97
|
if (typeof predicate === 'function') {
|
|
100
|
-
workers = (
|
|
98
|
+
workers = pickBy(workers, predicate);
|
|
101
99
|
}
|
|
102
100
|
/**
|
|
103
101
|
* filter out busy workers, only skip if explicitly desired
|
|
104
102
|
*/
|
|
105
103
|
if (!includeBusyWorker) {
|
|
106
|
-
workers = (
|
|
104
|
+
workers = pickBy(workers, (worker) => !worker.isBusy);
|
|
107
105
|
}
|
|
108
106
|
return workers;
|
|
109
107
|
}
|
|
@@ -121,7 +119,7 @@ class Watcher {
|
|
|
121
119
|
/**
|
|
122
120
|
* don't do anything if no worker was found
|
|
123
121
|
*/
|
|
124
|
-
if (Object.keys(workers).length === 0) {
|
|
122
|
+
if (Object.keys(workers).length === 0 || !this._launcher.interface) {
|
|
125
123
|
return;
|
|
126
124
|
}
|
|
127
125
|
/**
|
|
@@ -144,7 +142,6 @@ class Watcher {
|
|
|
144
142
|
}
|
|
145
143
|
}
|
|
146
144
|
cleanUp() {
|
|
147
|
-
this._launcher.interface
|
|
145
|
+
this._launcher.interface?.setup();
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
|
-
exports.default = Watcher;
|
package/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-alpha.219+4aab2cef1",
|
|
4
4
|
"description": "WebdriverIO testrunner command line interface",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-cli",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"main": "./build/index",
|
|
9
8
|
"bin": {
|
|
10
9
|
"wdio": "./bin/wdio.js"
|
|
11
10
|
},
|
|
12
11
|
"engines": {
|
|
13
|
-
"node": ">=
|
|
12
|
+
"node": "^16.13 || >=18"
|
|
14
13
|
},
|
|
15
14
|
"scripts": {
|
|
16
15
|
"copy": "copyfiles -u 1 -V \"src/templates/**/*\" ./build/"
|
|
@@ -28,39 +27,46 @@
|
|
|
28
27
|
"bugs": {
|
|
29
28
|
"url": "https://github.com/webdriverio/webdriverio/issues"
|
|
30
29
|
},
|
|
30
|
+
"type": "module",
|
|
31
|
+
"exports": "./build/index.js",
|
|
32
|
+
"types": "./build/index.d.ts",
|
|
33
|
+
"typeScriptVersion": "3.8.3",
|
|
31
34
|
"dependencies": {
|
|
32
|
-
"@types/ejs": "^3.
|
|
33
|
-
"@types/fs-extra": "^9.0.
|
|
34
|
-
"@types/inquirer": "^8.1
|
|
35
|
-
"@types/lodash.flattendeep": "^4.4.
|
|
36
|
-
"@types/lodash.pickby": "^4.6.
|
|
37
|
-
"@types/lodash.union": "^4.6.
|
|
38
|
-
"@types/
|
|
39
|
-
"@types/
|
|
40
|
-
"@wdio/config": "
|
|
41
|
-
"@wdio/
|
|
42
|
-
"@wdio/
|
|
43
|
-
"@wdio/
|
|
44
|
-
"@wdio/
|
|
35
|
+
"@types/ejs": "^3.1.1",
|
|
36
|
+
"@types/fs-extra": "^9.0.13",
|
|
37
|
+
"@types/inquirer": "^8.2.1",
|
|
38
|
+
"@types/lodash.flattendeep": "^4.4.7",
|
|
39
|
+
"@types/lodash.pickby": "^4.6.7",
|
|
40
|
+
"@types/lodash.union": "^4.6.7",
|
|
41
|
+
"@types/recursive-readdir": "^2.2.1",
|
|
42
|
+
"@types/yargs": "^17.0.10",
|
|
43
|
+
"@wdio/config": "8.0.0-alpha.219+4aab2cef1",
|
|
44
|
+
"@wdio/globals": "8.0.0-alpha.219+4aab2cef1",
|
|
45
|
+
"@wdio/logger": "8.0.0-alpha.219+4aab2cef1",
|
|
46
|
+
"@wdio/protocols": "8.0.0-alpha.219+4aab2cef1",
|
|
47
|
+
"@wdio/types": "8.0.0-alpha.219+4aab2cef1",
|
|
48
|
+
"@wdio/utils": "8.0.0-alpha.219+4aab2cef1",
|
|
45
49
|
"async-exit-hook": "^2.0.1",
|
|
46
|
-
"chalk": "^
|
|
47
|
-
"chokidar": "^3.
|
|
48
|
-
"cli-spinners": "^2.1
|
|
49
|
-
"ejs": "^3.
|
|
50
|
-
"fs-extra": "^10.
|
|
51
|
-
"inquirer": "
|
|
50
|
+
"chalk": "^5.0.1",
|
|
51
|
+
"chokidar": "^3.5.3",
|
|
52
|
+
"cli-spinners": "^2.6.1",
|
|
53
|
+
"ejs": "^3.1.8",
|
|
54
|
+
"fs-extra": "^10.1.0",
|
|
55
|
+
"inquirer": "9.1.0",
|
|
52
56
|
"lodash.flattendeep": "^4.4.0",
|
|
53
57
|
"lodash.pickby": "^4.6.0",
|
|
54
58
|
"lodash.union": "^4.6.0",
|
|
55
59
|
"mkdirp": "^1.0.4",
|
|
56
60
|
"recursive-readdir": "^2.2.2",
|
|
57
|
-
"webdriverio": "
|
|
58
|
-
"yargs": "^17.
|
|
61
|
+
"webdriverio": "8.0.0-alpha.219+4aab2cef1",
|
|
62
|
+
"yargs": "^17.5.1",
|
|
59
63
|
"yarn-install": "^1.0.0"
|
|
60
64
|
},
|
|
61
65
|
"publishConfig": {
|
|
62
66
|
"access": "public"
|
|
63
67
|
},
|
|
64
|
-
"
|
|
65
|
-
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@types/node": "^18.0.0"
|
|
70
|
+
},
|
|
71
|
+
"gitHead": "4aab2cef1b8b195ac8cc611f28b1fd54e4ba3443"
|
|
66
72
|
}
|