Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Cli util for e2e tests automation
  3.  *
  4.  * args:
  5.  * --stable     show latest CI stable failures instead of devel
  6.  * --rows=xx    number of cli rows
  7.  * --rlwrap     use rlwrap cli when invoking chimp (recommended, google rlwrap)
  8.  */
  9. const fs = require('fs');
  10. const path = require('path');
  11. const childProcess = require('child_process');
  12. const glob = require('glob');
  13. const _ = require('lodash');
  14. const http = require('axios');
  15. const featuresPath = './specifications/flows';
  16. const jsonPath = '.reports/e2e-results.json';
  17. const Gherkin = require('gherkin')
  18. const parser = new Gherkin.Parser()
  19.  
  20. const inquirer = require('inquirer');
  21. const minimist = require('minimist');
  22. const args = minimist(process.argv.slice(2));
  23.  
  24. const colors = require('colors/safe');
  25. const Log = {
  26.   silly(text) { console.log(colors.rainbow(text)) },
  27.   input(text) { console.log(colors.grey(text)) },
  28.   verbose(text) { console.log(colors.cyan(text)) },
  29.   prompt(text) { console.log(colors.grey(text)) },
  30.   info(text) { console.log(colors.green(text)) },
  31.   data(text) { console.log(colors.grey(text)) },
  32.   help(text) { console.log(colors.cyan(text)) },
  33.   warn(text) { console.log(colors.yellow(text)) },
  34.   debug(text) { console.log(colors.blue(text)) },
  35.   error(text) { console.log(colors.red(text)) },
  36. }
  37.  
  38. Log.silly('Test Runner')
  39.  
  40. let develResults = []
  41. const updateCIResults = async () => {
  42.   const auth = {
  43.     username: process.env.BEN_BAMBOO_USERNAME,
  44.     password: process.env.BEN_BAMBOO_PASSWORD,
  45.   }
  46.   if (!auth.username || !auth.password) {
  47.     Log.warn('\nCI credentials not found')
  48.     Log.warn('set BEN_BAMBOO_USERNAME and BEN_BAMBOO_PASSWORD env vars to show latest CI failures\n')
  49.     await new Promise(resolve => setTimeout(resolve, 3000));
  50.   } else {
  51.     const env = args.stable ? 'BNR-E2E30-TES' : 'BNR-E2E-TES'
  52.     const url = `https://bamboo.bengroup.com/rest/api/latest/result/${env}/latest.json`
  53.     Log.data(`Fetching latest ${args.stable ? 'stable' : 'devel'} results..`)
  54.     try {
  55.       const res = await http.get(url, { auth, params: { expand: 'testResults.failedTests' }})
  56.       develResults = _.get(res, 'data.testResults.failedTests.testResult') || []
  57.       develResults.forEach(r => {
  58.         const split = r.className.split(';');
  59.         r.featureName = _.kebabCase(split[0]);
  60.         r.scenarioName = _.kebabCase(split[1]);
  61.       });
  62.     } catch(e) {
  63.       Log.error('Failed to get latest devel results')
  64.     }
  65.   }
  66. }
  67.  
  68. const getFeatures = () => glob
  69.   .sync(path.join(featuresPath, '**/*.feature'))
  70.   .map(path => ({
  71.     path,
  72.     parsed: parser.parse(fs.readFileSync(path).toString())
  73.   }))
  74.  
  75. /**
  76.  * Main loop, lists all tests and asks user which test to run
  77.  */
  78. let lastSpec  // reemember last feature/scenario executed
  79. const main = async () => {
  80.   // read features list from local specifications dir
  81.   const features = getFeatures();
  82.   if (!features || !features.length) {
  83.     throw new Error('No specifications found')
  84.   }
  85.  
  86.   // create inquirer tests list from features/scenarios
  87.   const specs = features.reduce((acc, doc) => {
  88.     const feature = doc.parsed.feature
  89.     return acc
  90.       .concat({
  91.         name: `  ${colors.bold((acc.length+1)
  92.           + ' ' + _.kebabCase(feature.name))}`,
  93.         value: doc.path,
  94.       })
  95.       .concat(feature.children
  96.         .filter(children => children.type === 'Scenario')
  97.         .map((scenario, idx) => {
  98.           const featureName = _.kebabCase(feature.name.toLowerCase());
  99.           const scenarioName = _.kebabCase(scenario.name.toLowerCase());
  100.           const failed = !!develResults.find(r =>
  101.             r.featureName === featureName && r.scenarioName === scenarioName);
  102.           const index = acc.length + idx + 1
  103.           return {
  104.             name: `${failed ? colors.red('X') : ' '} ${index+1} ${featureName}/${scenarioName}`,
  105.             value: `${doc.path}:${scenario.location.line}`
  106.           }
  107.         })
  108.       )
  109.   }, [])
  110.  
  111.   // prompt to select test from tests list
  112.   const spec = await inquirer.prompt([{
  113.     type: 'list',
  114.     name: 'value',
  115.     message: `Select scenario or feature spec`,
  116.     choices: specs,
  117.     default: lastSpec || 0,
  118.     pageSize: args.rows || 13
  119.   }])
  120.   .then(res => specs.find(s => s.value === res.value))
  121.   // reemember last selected spec when asking which feature to run
  122.   lastSpec = specs.indexOf(spec)
  123.  
  124.   // prompt action after selecting a test
  125.   await inquirer.prompt([{
  126.     type: 'list',
  127.     name: 'value',
  128.     message: 'Select action',
  129.     default: args.local ? 2 : args.stable ? 1 : 0,
  130.     choices: [{
  131.       name: 'Test Devel',
  132.       value: () => runTest(spec, 'https://devel.goben.rocks/')
  133.     }, {
  134.       name: 'Test Stable',
  135.       value: () => runTest(spec, 'https://stable.goben.rocks/')
  136.     }, {
  137.       name: 'Test Local',
  138.       value: () => runTest(spec, 'http://localhost:4000/')
  139.     }, {
  140.       name: 'Open in VSCode',
  141.       value: () => openVSCode(spec)
  142.     }, {
  143.       name: 'cancel',
  144.       value: () => {}
  145.     }]
  146.   }])
  147.   .then(res => res.value())
  148.  
  149.   // loop main
  150.   await main()
  151. }
  152.  
  153. updateCIResults()
  154.   .then(main)
  155.   .catch(console.error);
  156.  
  157. // -------------------
  158. // COMMANDS
  159. // -------------------
  160. const runTest = (spec, baseUrl) => {
  161.   const command = [
  162.     `node_modules/.bin/chimp chimp.config.js`,
  163.     `${process.argv.slice(3).join(' ')}`,
  164.     `--debugOnError`,
  165.     `--timeout=15000`,
  166.     `--baseUrl=` + baseUrl,
  167.     `--jsonOutput=${jsonPath}`,
  168.     `"${spec.value}"`,
  169.   ]
  170.  
  171.   if (args.rlwrap) {
  172.     command.unshift('rlwrap');
  173.   }
  174.  
  175.   try {
  176.     childProcess.execSync(command.join(' '), { stdio: 'inherit' });
  177.   } catch (err) {
  178.     Log.error(err)
  179.   }
  180. }
  181.  
  182. const openVSCode = (spec) =>
  183.   childProcess.execSync(`code -g "${spec.value}"`, { stdio: 'inherit' });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement