UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

303 lines (238 loc) 10.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runServiceHook = runServiceHook; exports.runLauncherHook = runLauncherHook; exports.runOnCompleteHook = runOnCompleteHook; exports.getRunnerName = getRunnerName; exports.findInConfig = findInConfig; exports.replaceConfig = replaceConfig; exports.addServiceDeps = addServiceDeps; exports.convertPackageHashToObject = convertPackageHashToObject; exports.renderConfigurationFile = renderConfigurationFile; exports.missingConfigurationPrompt = missingConfigurationPrompt; exports.getCapabilities = getCapabilities; exports.hasFile = hasFile; exports.generateTestFiles = generateTestFiles; exports.getAnswers = getAnswers; exports.validateServiceAnswers = void 0; var _fsExtra = _interopRequireDefault(require("fs-extra")); var _ejs = _interopRequireDefault(require("ejs")); var _path = _interopRequireDefault(require("path")); var _inquirer = _interopRequireDefault(require("inquirer")); var _logger = _interopRequireDefault(require("@wdio/logger")); var _recursiveReaddir = _interopRequireDefault(require("recursive-readdir")); var _webdriverio = require("webdriverio"); var _child_process = require("child_process"); var _util = require("util"); var _config = require("./commands/config"); var _constants = require("./constants"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const log = (0, _logger.default)('@wdio/cli:utils'); const TEMPLATE_ROOT_DIR = _path.default.join(__dirname, 'templates', 'exampleFiles'); const renderFile = (0, _util.promisify)(_ejs.default.renderFile); async function runServiceHook(launcher, hookName, ...args) { return Promise.all(launcher.map(async service => { try { if (typeof service[hookName] === 'function') { await service[hookName](...args); } } catch (e) { const message = `A service failed in the '${hookName}' hook\n${e.stack}\n\n`; if (e instanceof _webdriverio.SevereServiceError) { return { status: 'rejected', reason: message }; } log.error(`${message}Continue...`); } })).then(results => { const rejectedHooks = results.filter(p => p && p.status === 'rejected'); if (rejectedHooks.length) { return Promise.reject(`\n${rejectedHooks.map(p => p.reason).join()}\n\nStopping runner...`); } }); } async function runLauncherHook(hook, ...args) { const catchFn = e => log.error(`Error in hook: ${e.stack}`); if (typeof hook === 'function') { hook = [hook]; } return Promise.all(hook.map(hook => { try { return hook(...args); } catch (e) { return catchFn(e); } })).catch(catchFn); } async function runOnCompleteHook(onCompleteHook, config, capabilities, exitCode, results) { if (typeof onCompleteHook === 'function') { onCompleteHook = [onCompleteHook]; } return Promise.all(onCompleteHook.map(async hook => { try { await hook(exitCode, config, capabilities, results); return 0; } catch (e) { log.error(`Error in onCompleteHook: ${e.stack}`); return 1; } })); } function getRunnerName(caps = {}) { let runner = caps.browserName || caps.appPackage || caps.appWaitActivity || caps.app || caps.platformName; if (!runner) { runner = Object.values(caps).length === 0 || Object.values(caps).some(cap => !cap.capabilities) ? 'undefined' : 'MultiRemote'; } return runner; } function buildNewConfigArray(str, type, change) { const newStr = str.split(`${type}s: `)[1].replace('\'', ''); let newArray = newStr.match(/(\w*)/gmi).filter(e => !!e).concat([change]); return str.replace('// ', '').replace(new RegExp(`(${type}s: )((.*\\s*)*)`), `$1[${newArray.map(e => `'${e}'`)}]`); } function buildNewConfigString(str, type, change) { return str.replace(new RegExp(`(${type}: )('\\w*')`), `$1'${change}'`); } function findInConfig(config, type) { let regexStr = `[\\/\\/]*[\\s]*${type}s: [\\s]*\\[([\\s]*['|"]\\w*['|"],*)*[\\s]*\\]`; if (type === 'framework') { regexStr = `[\\/\\/]*[\\s]*${type}: ([\\s]*['|"]\\w*['|"])`; } const regex = new RegExp(regexStr, 'gmi'); return config.match(regex); } function replaceConfig(config, type, name) { const match = findInConfig(config, type); if (!match || match.length === 0) { return; } if (type === 'framework') { return buildNewConfigString(config, type, name); } const text = match.pop(); return config.replace(text, buildNewConfigArray(text, type, name)); } function addServiceDeps(names, packages, update) { if (names.some(({ short }) => short === 'chromedriver')) { packages.push('chromedriver'); if (update) { console.log('\n=======', '\nPlease change path to / in your wdio.conf.js:', "\npath: '/'", '\n=======\n'); } } if (names.some(({ short }) => short === 'appium')) { const result = (0, _child_process.execSync)('appium --version || echo APPIUM_MISSING').toString().trim(); if (result === 'APPIUM_MISSING') { packages.push('appium'); } else if (update) { console.log('\n=======', '\nUsing globally installed appium', result, '\nPlease add the following to your wdio.conf.js:', "\nappium: { command: 'appium' }", '\n=======\n'); } } } function convertPackageHashToObject(string, hash = '$--$') { const splitHash = string.split(hash); return { package: splitHash[0], short: splitHash[1] }; } async function renderConfigurationFile(answers) { const tplPath = _path.default.join(__dirname, 'templates/wdio.conf.tpl.ejs'); const renderedTpl = await renderFile(tplPath, { answers }); _fsExtra.default.writeFileSync(_path.default.join(process.cwd(), 'wdio.conf.js'), renderedTpl); } async function missingConfigurationPrompt(command, message, useYarn = false) { const { config } = await _inquirer.default.prompt([{ type: 'confirm', name: 'config', message: `Error: Could not execute "${command}" due to missing configuration. Would you like to create one?`, default: false }]); if (!config && !process.env.JEST_WORKER_ID) { console.log(message); return process.exit(0); } return await (0, _config.runConfig)(useYarn, false, true); } const validateServiceAnswers = answers => { let result = true; Object.entries(_constants.EXCLUSIVE_SERVICES).forEach(([name, { services, message }]) => { const exists = answers.some(answer => answer.includes(name)); const hasExclusive = services.some(service => answers.some(answer => answer.includes(service))); if (exists && hasExclusive) { result = `${name} cannot work together with ${services.join(', ')}\n${message}\nPlease uncheck one of them.`; } }); return result; }; exports.validateServiceAnswers = validateServiceAnswers; function getCapabilities(arg) { const optionalCapabilites = _objectSpread({ platformVersion: arg.platformVersion || null, udid: arg.udid || null }, arg.deviceName && { deviceName: arg.deviceName }); if (/.*\.(apk|app|ipa)$/.test(arg.option)) { return { capabilities: _objectSpread(_objectSpread({ app: arg.option }, arg.option.endsWith('apk') ? _constants.ANDROID_CONFIG : _constants.IOS_CONFIG), optionalCapabilites) }; } else if (/android/.test(arg.option)) { return { capabilities: _objectSpread(_objectSpread({ browserName: 'Chrome' }, _constants.ANDROID_CONFIG), optionalCapabilites) }; } else if (/ios/.test(arg.option)) { return { capabilities: _objectSpread(_objectSpread({ browserName: 'Safari' }, _constants.IOS_CONFIG), optionalCapabilites) }; } return { capabilities: { browserName: arg.option } }; } function hasFile(filename) { return _fsExtra.default.existsSync(_path.default.join(process.cwd(), filename)); } async function generateTestFiles(answers) { const testFiles = answers.framework === 'cucumber' ? [_path.default.join(TEMPLATE_ROOT_DIR, 'cucumber')] : [_path.default.join(TEMPLATE_ROOT_DIR, 'mochaJasmine')]; if (answers.usePageObjects) { testFiles.push(_path.default.join(TEMPLATE_ROOT_DIR, 'pageobjects')); } const files = (await Promise.all(testFiles.map(dirPath => (0, _recursiveReaddir.default)(dirPath, [(file, stats) => !stats.isDirectory() && !(file.endsWith('.ejs') || file.endsWith('.feature'))])))).reduce((cur, acc) => [...acc, ...cur], []); for (const file of files) { const renderedTpl = await renderFile(file, answers); let destPath = (file.endsWith('page.js.ejs') ? `${answers.destPageObjectRootPath}/${_path.default.basename(file)}` : file.includes('step_definition') ? `${answers.stepDefinitions}` : `${answers.destSpecRootPath}/${_path.default.basename(file)}`).replace(/\.ejs$/, '').replace(/\.js$/, answers.isUsingTypeScript ? '.ts' : '.js'); _fsExtra.default.ensureDirSync(_path.default.dirname(destPath)); _fsExtra.default.writeFileSync(destPath, renderedTpl); } } async function getAnswers(yes) { return yes ? _constants.QUESTIONNAIRE.reduce((answers, question) => Object.assign(answers, question.when && !question.when(answers) ? {} : { [question.name]: typeof question.default !== 'undefined' ? typeof question.default === 'function' ? question.default(answers) : question.default : question.choices && question.choices.length ? question.choices[0].value ? question.choices[0].value : question.choices[0] : {} }), {}) : await _inquirer.default.prompt(_constants.QUESTIONNAIRE); }