@wdio/cli 8.17.0 → 8.18.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/build/commands/config.d.ts.map +1 -1
- package/build/commands/config.js +13 -5
- package/build/constants.d.ts +9 -3
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +40 -23
- package/build/templates/EjsHelpers.d.ts +18 -0
- package/build/templates/EjsHelpers.d.ts.map +1 -0
- package/build/templates/EjsHelpers.js +59 -0
- package/build/templates/EjsHelpers.ts +84 -0
- package/build/templates/exampleFiles/serenity-js/common/config/serenity.properties.ejs +1 -0
- package/build/templates/exampleFiles/serenity-js/common/serenity/github-api/GitHubStatus.ts.ejs +41 -0
- package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoList.ts.ejs +100 -0
- package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoListItem.ts.ejs +36 -0
- package/build/templates/exampleFiles/serenity-js/cucumber/step-definitions/steps.ts.ejs +37 -0
- package/build/templates/exampleFiles/serenity-js/cucumber/support/parameter.config.ts.ejs +18 -0
- package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/completing_items.feature.ejs +23 -0
- package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/narrative.md.ejs +17 -0
- package/build/templates/exampleFiles/serenity-js/jasmine/example.spec.ts.ejs +86 -0
- package/build/templates/exampleFiles/serenity-js/mocha/example.spec.ts.ejs +88 -0
- package/build/templates/snippets/capabilities.ejs +9 -3
- package/build/templates/snippets/cucumber.ejs +48 -0
- package/build/templates/snippets/jasmine.ejs +20 -0
- package/build/templates/snippets/mocha.ejs +14 -0
- package/build/templates/snippets/serenity.ejs +18 -0
- package/build/templates/wdio.conf.tpl.ejs +11 -86
- package/build/types.d.ts +5 -1
- package/build/types.d.ts.map +1 -1
- package/build/utils.d.ts +4 -2
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +102 -21
- package/package.json +7 -7
package/build/utils.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
-
import util from 'node:util';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
2
|
+
import util, { promisify } from 'node:util';
|
|
3
|
+
import path, { dirname } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { execSync, spawn } from 'node:child_process';
|
|
6
|
-
import { promisify } from 'node:util';
|
|
7
6
|
import ejs from 'ejs';
|
|
8
7
|
import chalk from 'chalk';
|
|
9
|
-
import path from 'node:path';
|
|
10
8
|
import inquirer from 'inquirer';
|
|
11
9
|
import pickBy from 'lodash.pickby';
|
|
12
10
|
import logger from '@wdio/logger';
|
|
@@ -18,7 +16,8 @@ import { resolve } from 'import-meta-resolve';
|
|
|
18
16
|
import { SevereServiceError } from 'webdriverio';
|
|
19
17
|
import { ConfigParser } from '@wdio/config';
|
|
20
18
|
import { CAPABILITY_KEYS } from '@wdio/protocols';
|
|
21
|
-
import { ANDROID_CONFIG,
|
|
19
|
+
import { ANDROID_CONFIG, CompilerOptions, DEPENDENCIES_INSTALLATION_MESSAGE, IOS_CONFIG, pkg, QUESTIONNAIRE, TESTING_LIBRARY_PACKAGES, usesSerenity, } from './constants.js';
|
|
20
|
+
import { EjsHelpers } from './templates/EjsHelpers.js';
|
|
22
21
|
const log = logger('@wdio/cli:utils');
|
|
23
22
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
23
|
const NPM_COMMAND = /^win/.test(process.platform) ? 'npm.cmd' : 'npm';
|
|
@@ -181,6 +180,44 @@ export function convertPackageHashToObject(pkg, hash = '$--$') {
|
|
|
181
180
|
const [p, short, purpose] = pkg.split(hash);
|
|
182
181
|
return { package: p, short, purpose };
|
|
183
182
|
}
|
|
183
|
+
export function getSerenityPackages(answers) {
|
|
184
|
+
const framework = convertPackageHashToObject(answers.framework);
|
|
185
|
+
if (framework.package !== '@serenity-js/webdriverio') {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
const isUsingTypeScript = answers.isUsingCompiler === CompilerOptions.TS;
|
|
189
|
+
const packages = {
|
|
190
|
+
cucumber: [
|
|
191
|
+
'@cucumber/cucumber',
|
|
192
|
+
'@serenity-js/cucumber',
|
|
193
|
+
],
|
|
194
|
+
mocha: [
|
|
195
|
+
'@serenity-js/mocha',
|
|
196
|
+
'mocha',
|
|
197
|
+
isUsingTypeScript && '@types/mocha',
|
|
198
|
+
],
|
|
199
|
+
jasmine: [
|
|
200
|
+
'@serenity-js/jasmine',
|
|
201
|
+
'jasmine',
|
|
202
|
+
isUsingTypeScript && '@types/jasmine',
|
|
203
|
+
],
|
|
204
|
+
common: [
|
|
205
|
+
'@serenity-js/assertions',
|
|
206
|
+
'@serenity-js/console-reporter',
|
|
207
|
+
'@serenity-js/core',
|
|
208
|
+
'@serenity-js/rest',
|
|
209
|
+
'@serenity-js/serenity-bdd',
|
|
210
|
+
'@serenity-js/web',
|
|
211
|
+
isUsingTypeScript && '@types/node',
|
|
212
|
+
'npm-failsafe',
|
|
213
|
+
'rimraf',
|
|
214
|
+
]
|
|
215
|
+
};
|
|
216
|
+
return [
|
|
217
|
+
...packages[framework.purpose],
|
|
218
|
+
...packages.common,
|
|
219
|
+
].filter(Boolean).sort();
|
|
220
|
+
}
|
|
184
221
|
export async function getCapabilities(arg) {
|
|
185
222
|
const optionalCapabilites = {
|
|
186
223
|
platformVersion: arg.platformVersion,
|
|
@@ -287,6 +324,9 @@ export async function hasPackage(pkg) {
|
|
|
287
324
|
* generate test files based on CLI answers
|
|
288
325
|
*/
|
|
289
326
|
export async function generateTestFiles(answers) {
|
|
327
|
+
if (answers.serenityAdapter) {
|
|
328
|
+
return generateSerenityExamples(answers);
|
|
329
|
+
}
|
|
290
330
|
if (answers.runner === 'local') {
|
|
291
331
|
return generateLocalRunnerTestFiles(answers);
|
|
292
332
|
}
|
|
@@ -345,6 +385,25 @@ async function generateLocalRunnerTestFiles(answers) {
|
|
|
345
385
|
await fs.writeFile(destPath, renderedTpl);
|
|
346
386
|
}
|
|
347
387
|
}
|
|
388
|
+
async function generateSerenityExamples(answers) {
|
|
389
|
+
const templateDirectories = {
|
|
390
|
+
[answers.projectRootDir]: path.join(TEMPLATE_ROOT_DIR, 'serenity-js', 'common', 'config'),
|
|
391
|
+
[answers.destSpecRootPath]: path.join(TEMPLATE_ROOT_DIR, 'serenity-js', answers.serenityAdapter),
|
|
392
|
+
[answers.destSerenityLibRootPath]: path.join(TEMPLATE_ROOT_DIR, 'serenity-js', 'common', 'serenity'),
|
|
393
|
+
};
|
|
394
|
+
for (const [destinationRootDir, templateRootDir] of Object.entries(templateDirectories)) {
|
|
395
|
+
const pathsToTemplates = await readDir(templateRootDir);
|
|
396
|
+
for (const pathToTemplate of pathsToTemplates) {
|
|
397
|
+
const extension = answers.isUsingTypeScript ? '.ts' : '.js';
|
|
398
|
+
const destination = path.join(destinationRootDir, path.relative(templateRootDir, pathToTemplate))
|
|
399
|
+
.replace(/\.ejs$/, '')
|
|
400
|
+
.replace(/\.ts$/, extension);
|
|
401
|
+
const contents = await renderFile(pathToTemplate, { answers, _: new EjsHelpers({ useEsm: answers.esmSupport, useTypeScript: answers.isUsingTypeScript }) });
|
|
402
|
+
await fs.mkdir(path.dirname(destination), { recursive: true });
|
|
403
|
+
await fs.writeFile(destination, contents);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
348
407
|
export async function getAnswers(yes) {
|
|
349
408
|
if (yes) {
|
|
350
409
|
const ignoredQuestions = ['e2eEnvironment'];
|
|
@@ -430,6 +489,9 @@ export function getPathForFileGeneration(answers, projectRootDir) {
|
|
|
430
489
|
const destPageObjectRootPath = answers.usePageObjects
|
|
431
490
|
? path.resolve(projectRootDir, path.dirname(answers.pages || '').replace(/\*\*$/, ''))
|
|
432
491
|
: '';
|
|
492
|
+
const destSerenityLibRootPath = usesSerenity(answers)
|
|
493
|
+
? path.resolve(projectRootDir, answers.serenityLibPath || 'serenity')
|
|
494
|
+
: '';
|
|
433
495
|
const relativePath = (answers.generateTestFiles && answers.usePageObjects)
|
|
434
496
|
? !(convertPackageHashToObject(answers.framework).short === 'cucumber')
|
|
435
497
|
? path.relative(destSpecRootPath, destPageObjectRootPath)
|
|
@@ -439,6 +501,7 @@ export function getPathForFileGeneration(answers, projectRootDir) {
|
|
|
439
501
|
destSpecRootPath: destSpecRootPath,
|
|
440
502
|
destStepRootPath: destStepRootPath,
|
|
441
503
|
destPageObjectRootPath: destPageObjectRootPath,
|
|
504
|
+
destSerenityLibRootPath: destSerenityLibRootPath,
|
|
442
505
|
relativePath: relativePath.replaceAll(path.sep, '/')
|
|
443
506
|
};
|
|
444
507
|
}
|
|
@@ -635,16 +698,17 @@ export async function setupTypeScript(parsedAnswers) {
|
|
|
635
698
|
const frameworkPackage = convertPackageHashToObject(parsedAnswers.rawAnswers.framework);
|
|
636
699
|
const servicePackages = parsedAnswers.rawAnswers.services.map((service) => convertPackageHashToObject(service));
|
|
637
700
|
parsedAnswers.packagesToInstall.push('ts-node', 'typescript');
|
|
701
|
+
const serenityTypes = parsedAnswers.serenityAdapter === 'jasmine' ? ['jasmine'] : [];
|
|
638
702
|
const types = [
|
|
639
703
|
'node',
|
|
640
704
|
'@wdio/globals/types',
|
|
641
705
|
'expect-webdriverio',
|
|
642
|
-
frameworkPackage.package,
|
|
706
|
+
...(parsedAnswers.serenityAdapter ? serenityTypes : [frameworkPackage.package]),
|
|
643
707
|
...(parsedAnswers.runner === 'browser' ? ['@wdio/browser-runner'] : []),
|
|
644
708
|
...servicePackages
|
|
645
709
|
.map(service => service.package)
|
|
646
710
|
/**
|
|
647
|
-
* given that we know that all "
|
|
711
|
+
* given that we know that all "official" services have
|
|
648
712
|
* typescript support we only include them
|
|
649
713
|
*/
|
|
650
714
|
.filter(service => service.startsWith('@wdio'))
|
|
@@ -657,6 +721,7 @@ export async function setupTypeScript(parsedAnswers) {
|
|
|
657
721
|
moduleResolution: 'node',
|
|
658
722
|
module: !parsedAnswers.esmSupport ? 'commonjs' : 'ESNext',
|
|
659
723
|
target: 'es2022',
|
|
724
|
+
lib: ['es2022', 'dom'],
|
|
660
725
|
types,
|
|
661
726
|
skipLibCheck: true,
|
|
662
727
|
// bundler
|
|
@@ -755,7 +820,10 @@ export async function createWDIOConfig(parsedAnswers) {
|
|
|
755
820
|
try {
|
|
756
821
|
console.log('Creating a WebdriverIO config file...');
|
|
757
822
|
const tplPath = path.resolve(__dirname, 'templates', 'wdio.conf.tpl.ejs');
|
|
758
|
-
const renderedTpl = await renderFile(tplPath, {
|
|
823
|
+
const renderedTpl = await renderFile(tplPath, {
|
|
824
|
+
answers: parsedAnswers,
|
|
825
|
+
_: new EjsHelpers({ useEsm: parsedAnswers.esmSupport, useTypeScript: parsedAnswers.isUsingTypeScript })
|
|
826
|
+
});
|
|
759
827
|
await fs.writeFile(parsedAnswers.wdioConfigPath, renderedTpl);
|
|
760
828
|
console.log(chalk.green.bold('✔ Success!\n'));
|
|
761
829
|
if (parsedAnswers.generateTestFiles) {
|
|
@@ -770,20 +838,33 @@ export async function createWDIOConfig(parsedAnswers) {
|
|
|
770
838
|
}
|
|
771
839
|
export async function createWDIOScript(parsedAnswers) {
|
|
772
840
|
const projectProps = await getProjectProps(process.cwd());
|
|
773
|
-
const
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
841
|
+
const pathToWdioConfig = `./${path.join('.', parsedAnswers.wdioConfigPath.replace(projectProps?.path || process.cwd(), ''))}`;
|
|
842
|
+
const wdioScripts = {
|
|
843
|
+
'wdio': `wdio run ${pathToWdioConfig}`,
|
|
844
|
+
};
|
|
845
|
+
const serenityScripts = {
|
|
846
|
+
'serenity': 'failsafe serenity:update serenity:clean wdio serenity:report',
|
|
847
|
+
'serenity:update': 'serenity-bdd update',
|
|
848
|
+
'serenity:clean': 'rimraf target',
|
|
849
|
+
'wdio': `wdio run ${pathToWdioConfig}`,
|
|
850
|
+
'serenity:report': 'serenity-bdd run',
|
|
851
|
+
};
|
|
852
|
+
const scripts = parsedAnswers.serenityAdapter ? serenityScripts : wdioScripts;
|
|
853
|
+
for (const [script, command] of Object.entries(scripts)) {
|
|
854
|
+
const args = ['pkg', 'set', `scripts.${script}=${command}`];
|
|
855
|
+
try {
|
|
856
|
+
console.log(`Adding ${chalk.bold(`"${script}"`)} script to package.json`);
|
|
857
|
+
await runProgram(NPM_COMMAND, args, { cwd: parsedAnswers.projectRootDir });
|
|
858
|
+
}
|
|
859
|
+
catch (err) {
|
|
860
|
+
const [preArgs, scriptPath] = args.join(' ').split('=');
|
|
861
|
+
console.error(`⚠️ Couldn't add script to package.json: "${err.message}", you can add it manually ` +
|
|
862
|
+
`by running:\n\n\t${NPM_COMMAND} ${preArgs}="${scriptPath}"`);
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
786
865
|
}
|
|
866
|
+
console.log(chalk.green.bold('✔ Success!'));
|
|
867
|
+
return true;
|
|
787
868
|
}
|
|
788
869
|
export async function runAppiumInstaller(parsedAnswers) {
|
|
789
870
|
if (parsedAnswers.e2eEnvironment !== 'mobile') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.18.0",
|
|
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",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"typeScriptVersion": "3.8.3",
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@types/node": "^20.1.1",
|
|
49
|
-
"@wdio/config": "8.
|
|
50
|
-
"@wdio/globals": "8.
|
|
49
|
+
"@wdio/config": "8.18.0",
|
|
50
|
+
"@wdio/globals": "8.18.0",
|
|
51
51
|
"@wdio/logger": "8.16.17",
|
|
52
|
-
"@wdio/protocols": "8.
|
|
52
|
+
"@wdio/protocols": "8.18.0",
|
|
53
53
|
"@wdio/types": "8.17.0",
|
|
54
|
-
"@wdio/utils": "8.
|
|
54
|
+
"@wdio/utils": "8.18.0",
|
|
55
55
|
"async-exit-hook": "^2.0.1",
|
|
56
56
|
"chalk": "^5.2.0",
|
|
57
57
|
"chokidar": "^3.5.3",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"lodash.union": "^4.6.0",
|
|
67
67
|
"read-pkg-up": "10.1.0",
|
|
68
68
|
"recursive-readdir": "^2.2.3",
|
|
69
|
-
"webdriverio": "8.
|
|
69
|
+
"webdriverio": "8.18.0",
|
|
70
70
|
"yargs": "^17.7.2",
|
|
71
71
|
"yarn-install": "^1.0.0"
|
|
72
72
|
},
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"publishConfig": {
|
|
84
84
|
"access": "public"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "66cd3ccfe1c8a94f89afa11fb51f58742ae379c5"
|
|
87
87
|
}
|