UNPKG

@wdio/cli

Version:
201 lines (200 loc) 8.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.missingConfigurationPrompt = exports.handler = exports.builder = exports.cmdArgs = exports.desc = exports.command = void 0; const util_1 = __importDefault(require("util")); const inquirer_1 = __importDefault(require("inquirer")); const yarn_install_1 = __importDefault(require("yarn-install")); const constants_1 = require("../constants"); const utils_1 = require("../utils"); const pkg = require('../../package.json'); exports.command = 'config'; exports.desc = 'Initialize WebdriverIO and setup configuration in your current project.'; exports.cmdArgs = { yarn: { type: 'boolean', desc: 'Install packages via yarn package manager.', default: utils_1.hasFile('yarn.lock') }, yes: { alias: 'y', desc: 'will fill in all config defaults without prompting', type: 'boolean', default: false } }; exports.builder = (yargs) => { return yargs .options(exports.cmdArgs) .epilogue(constants_1.CLI_EPILOGUE) .help(); }; const runConfig = async function (useYarn, yes, exit = false) { console.log(constants_1.CONFIG_HELPER_INTRO); const answers = await utils_1.getAnswers(yes); const frameworkPackage = utils_1.convertPackageHashToObject(answers.framework); const runnerPackage = utils_1.convertPackageHashToObject(answers.runner || constants_1.SUPPORTED_PACKAGES.runner[0].value); const servicePackages = answers.services.map((service) => utils_1.convertPackageHashToObject(service)); const reporterPackages = answers.reporters.map((reporter) => utils_1.convertPackageHashToObject(reporter)); let packagesToInstall = [ runnerPackage.package, frameworkPackage.package, ...reporterPackages.map(reporter => reporter.package), ...servicePackages.map(service => service.package) ]; const syncExecution = answers.executionMode === 'sync'; if (syncExecution) { packagesToInstall.push('@wdio/sync'); } /** * add ts-node if TypeScript is desired but not installed */ if (answers.isUsingCompiler === constants_1.COMPILER_OPTIONS.ts) { try { /** * this is only for testing purposes as we want to check whether * we add `ts-node` to the packages to install when resolving fails */ if (process.env.JEST_WORKER_ID && process.env.WDIO_TEST_THROW_RESOLVE) { throw new Error('resolve error'); } require.resolve('ts-node'); } catch (e) { packagesToInstall.push('ts-node', 'typescript'); } } /** * add @babel/register package if not installed */ if (answers.isUsingCompiler === constants_1.COMPILER_OPTIONS.babel) { try { /** * this is only for testing purposes as we want to check whether * we add `@babel/register` to the packages to install when resolving fails */ if (process.env.JEST_WORKER_ID && process.env.WDIO_TEST_THROW_RESOLVE) { throw new Error('resolve error'); } require.resolve('@babel/register'); } catch (e) { packagesToInstall.push('@babel/register'); } } /** * add packages that are required by services */ utils_1.addServiceDeps(servicePackages, packagesToInstall); /** * ensure wdio packages have the same dist tag as cli */ if (pkg._requested && pkg._requested.fetchSpec) { const { fetchSpec } = pkg._requested; packagesToInstall = packagesToInstall.map((p) => (p.startsWith('@wdio') || ['devtools', 'webdriver', 'webdriverio'].includes(p)) && (fetchSpec.match(/(v)?\d+\.\d+\.\d+/) === null) ? `${p}@${fetchSpec}` : p); } console.log('\nInstalling wdio packages:\n-', packagesToInstall.join('\n- ')); const result = yarn_install_1.default({ deps: packagesToInstall, dev: true, respectNpm5: !useYarn }); if (result.status !== 0) { throw new Error(result.stderr); } console.log('\nPackages installed successfully, creating configuration file...'); /** * find relative paths between tests and pages */ const parsedPaths = utils_1.getPathForFileGeneration(answers); const parsedAnswers = { ...answers, runner: runnerPackage.short, framework: frameworkPackage.short, reporters: reporterPackages.map(({ short }) => short), services: servicePackages.map(({ short }) => short), packagesToInstall, isUsingTypeScript: answers.isUsingCompiler === constants_1.COMPILER_OPTIONS.ts, isUsingBabel: answers.isUsingCompiler === constants_1.COMPILER_OPTIONS.babel, isSync: syncExecution, _async: syncExecution ? '' : 'async ', _await: syncExecution ? '' : 'await ', destSpecRootPath: parsedPaths.destSpecRootPath, destPageObjectRootPath: parsedPaths.destPageObjectRootPath, relativePath: parsedPaths.relativePath }; try { await utils_1.renderConfigurationFile(parsedAnswers); if (answers.generateTestFiles) { console.log('\nConfig file installed successfully, creating test files...'); await utils_1.generateTestFiles(parsedAnswers); } } catch (e) { throw new Error(`Couldn't write config file: ${e.stack}`); } /** * print TypeScript configuration message */ if (answers.isUsingCompiler === constants_1.COMPILER_OPTIONS.ts) { const wdioTypes = syncExecution ? 'webdriverio/sync' : 'webdriverio/async'; const tsPkgs = `"${[ wdioTypes, frameworkPackage.package, ...servicePackages .map(service => service.package) /** * given that we know that all "offical" services have * typescript support we only include them */ .filter(service => service.startsWith('@wdio')) ].join('", "')}"`; console.log(util_1.default.format(constants_1.TS_COMPILER_INSTRUCTIONS, tsPkgs)); } console.log(constants_1.CONFIG_HELPER_SUCCESS_MESSAGE); /** * don't exit if running unit tests */ if (exit /* istanbul ignore next */ && !process.env.JEST_WORKER_ID) { /* istanbul ignore next */ process.exit(0); } return { success: true, parsedAnswers, installedPackages: packagesToInstall.map((pkg) => pkg.split('--')[0]) }; }; function handler(argv) { return runConfig(argv.yarn, argv.yes); } exports.handler = handler; /** * Helper utility used in `run` and `install` command to create config if none exist * @param {string} command to be executed by user * @param {string} message to show when no config is suppose to be created * @param {boolean} useYarn parameter set to true if yarn is used * @param {Function} runConfigCmd runConfig method to be replaceable for unit testing */ async function missingConfigurationPrompt(command, message, useYarn = false, runConfigCmd = runConfig) { const { config } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'config', message: `Error: Could not execute "${command}" due to missing configuration. Would you like to create one?`, default: false } ]); /** * don't exit if running unit tests */ if (!config && !process.env.JEST_WORKER_ID) { /* istanbul ignore next */ console.log(message); /* istanbul ignore next */ return process.exit(0); } return await runConfigCmd(useYarn, false, true); } exports.missingConfigurationPrompt = missingConfigurationPrompt;