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/doodle-node-cli / src / prompts / 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',
  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;