Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@doodle/lib-node-utilities / bin / integration-test-prompt.js
Size: Mime:
const inquirer = require('inquirer');
const chalk = require('chalk');
const execa = require('execa');

/**
 * Grab the host IPs from the pods in selenium namespace
 * @returns {Promise} - An array of HOST IPs from the Selnium Grid pods
 */
function getSeleniumIps() {
	return new Promise((resolve, reject) => {
		const command = 'kubectl get po -n selenium --output json';

		execa
			.command(command)
			.then(stdout => {
				const pods = JSON.parse(stdout.stdout);

				if (pods && pods.items) {
					const ips = pods.items.filter(pod => pod.status).map(pod => pod.status.hostIP);
					resolve(ips);
				}
			})
			.catch(err => {
				reject(err);
			});
	});
}

const TEST_ENVS = {
	JENKINS: 'Jenkins',
	BROWSERSTACK: 'Browserstack',
	BROWSERSTACK_LOCAL: 'Browserstack (running localhost)',
	LOCAL: 'Locally (without Grid)',
	GRID: 'Locally via Selenium Grid',
};

const RUN_TYPES = {
	SUITE: 'Suite',
	SPECS: 'Specs',
};

const SUITE_NAMES = {
	stableDoodle: 'stableDoodle',
	webBilling: 'webBilling',
	allStable: 'allStable',
	meetMe: 'meetMe',
	thirdPartyLogin: 'thirdPartyLogin',
	flakey: 'flakey',
	regressions: 'regressions',
	custom: 'custom',
};

const TARGET_URLS = {
	Jockey: 'https://dev.doodle-test.com',
	Staging: 'https://staging.doodle-test.com',
	Preproduction: 'https://doodle-test.com',
	'Local Monolith': 'https://doodle.local:8443',
	'devbox-growth-1': 'https://devbox-growth-1.kubernetes.doodle-test.com',
	'devbox-groups-1': 'https://devbox-groups-1.kubernetes.doodle-test.com',
	'devbox-ep-1': 'https://devbox-ep-1.kubernetes.doodle-test.com',
	CUSTOM: 'CUSTOM',
};

const INTEGRATION_TEST_LOCALES = {
	DOODLE: 'doodle',
	MEETME: 'meetme',
	EPAM: 'epam',
	TAMEDIA: 'tamedia',
	JENKINS: 'jenkins',
	GRID: 'grid',
};

async function startIntegrationTests() {
	await inquirer
		.prompt([
			{
				type: 'list',
				name: 'locale',
				message: 'What is your test user locale?',
				choices: Object.values(INTEGRATION_TEST_LOCALES),
				default: 'doodle',
			},
			{
				type: 'list',
				name: 'location',
				message: 'Where will you run the tests?',
				choices: Object.values(TEST_ENVS),
				default: 'Browserstack',
			},
			{
				type: 'input',
				name: 'recoveryPhoneNumber',
				message: 'What is the recovery phone number to use for the Selenium Grid run?',
				choices: Object.values(TEST_ENVS),
				when: answers => answers.location === TEST_ENVS.GRID,
			},
			{
				type: 'input',
				name: 'seleniumGridIP',
				message: 'What is the host IP to use for the Selenium Grid? (leave blank for default)',
				when: answers => answers.location === TEST_ENVS.GRID,
			},
			{
				type: 'list',
				name: 'suiteOrSpecs',
				message: `Will you run a suite or one or more spec files?`,
				choices: Object.values(RUN_TYPES),
			},
			{
				type: 'list',
				name: 'suiteName',
				message: 'Name of suite',
				choices: Object.keys(SUITE_NAMES),
				when: answers => answers.suiteOrSpecs === RUN_TYPES.SUITE,
			},
			{
				type: 'input',
				name: 'customSuiteName',
				message: 'Custom suite name',
				when: answers => answers.suiteName === SUITE_NAMES.custom,
			},
			{
				type: 'input',
				name: 'specNames',
				message: 'Enter one or more comma-delimited spec files',
				when: answers => answers.suiteOrSpecs === RUN_TYPES.SPECS,
			},
			{
				type: 'confirm',
				name: 'mobile',
				message: 'Are you running mobile tests?',
				default: false,
			},
			{
				type: 'list',
				name: 'server',
				message: 'What enviornment should the tests run against?',
				default: TARGET_URLS.Preproduction,
				choices: answers => {
					// If running tests in Jenkins, don't supply localhost options
					if (answers.location === TEST_ENVS.JENKINS) {
						return Object.keys(TARGET_URLS).filter(key => TARGET_URLS[key].search(/dev\.doodle|local/i) === -1);
					}
					return Object.keys(TARGET_URLS);
				},
			},
			{
				type: 'input',
				name: 'serverCustom',
				message: 'Enter the absolute url of the custom server (i.e https://..)',
				when: answers => answers.server === TARGET_URLS.CUSTOM,
				validate: input => {
					if (input.trim().search('https://') !== 0) {
						return 'Absolute urls must start with https://';
					}
					return true;
				},
			},
		])
		.then(async answers => {
			const {
				locale,
				location,
				recoveryPhoneNumber,
				suiteOrSpecs,
				suiteName,
				specNames,
				server,
				serverCustom,
				mobile,
				customSuiteName,
			} = answers;

			// Now let's build the command needed to run the tests
			const command = [`LOCALE=${locale}`];

			// Set the BrowserStack, Jenkins or Grid specific env vars
			if (location === TEST_ENVS.GRID) {
				const hosts = await getSeleniumIps();
				command.push(`GRID=true RECOVERY_PHONE=${recoveryPhoneNumber} HOST=${hosts.pop()} PORT=30053`);
			} else if (location === TEST_ENVS.BROWSERSTACK) {
				command.push('BROWSERSTACK=true BROWSERSTACK_LOCAL=false');
			} else if (location === TEST_ENVS.BROWSERSTACK_LOCAL) {
				command.push('BROWSERSTACK=true BROWSERSTACK_LOCAL=true');
			} else if (location === TEST_ENVS.JENKINS) {
				command.push('IS_JENKINS=true');
			}

			// Set the mobile specific env vars
			if (mobile) {
				command.push('MOBILE=true');
			}

			// Set the SERVER env var
			if (serverCustom) {
				command.push(`SERVER=${serverCustom}`);
			} else {
				command.push(`SERVER=${TARGET_URLS[server]}`);
			}

			// Now create the wdio command. This should happen AFTER all of the env vars have been set
			if (location === TEST_ENVS.BROWSERSTACK_LOCAL || location === TEST_ENVS.BROWSERSTACK) {
				command.push('npx wdio src/wdio/wdio.browserstack.conf.js');
			} else {
				command.push('npx wdio src/wdio/wdio.config.js');
			}

			// Set the suite or spec flag for Cucumber
			if (suiteOrSpecs === RUN_TYPES.SUITE) {
				const suite = customSuiteName || suiteName;
				command.push(`--suite=${suite}`);
			} else if (suiteOrSpecs === RUN_TYPES.SPECS) {
				command.push(`--spec=${specNames}`);
			}

			if (location === TEST_ENVS.JENKINS) {
				console.log(
					'\nSince you chose Jenkins as your run target, you can now open Jenkins and use the command to help build your run'
				);
			}

			console.log(chalk.yellow('\nUse this command to start the integration tests:\n'));
			console.log(command.join(' '));
		});
}

module.exports = startIntegrationTests;