From 46b95dee29704b68dc3e7edbdc839f187d9772ec Mon Sep 17 00:00:00 2001 From: Carrie Price Date: Fri, 21 Oct 2016 17:06:09 -0400 Subject: [PATCH] e2e tests (#241) --- .gitignore | 1 + .travis.yml | 2 +- e2e_tests/jest.config.json | 5 ++ e2e_tests/pkg.json | 9 +++ e2e_tests/tests/cli.test.js | 145 ++++++++++++++++++++++++++++++++++++ package.json | 4 +- utils/psKill.js | 22 ++++++ 7 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 e2e_tests/jest.config.json create mode 100644 e2e_tests/pkg.json create mode 100644 e2e_tests/tests/cli.test.js create mode 100644 utils/psKill.js diff --git a/.gitignore b/.gitignore index c2620cad7..bb2002aa8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ node_modules # OS-specific temporary files Thumbs.db .DS_Store +cli-test diff --git a/.travis.yml b/.travis.yml index 1aad78e8e..04793d98d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: node_js node_js: - 6.0 -script: npm run lint && npm test +script: npm run lint && npm test && npm run e2e diff --git a/e2e_tests/jest.config.json b/e2e_tests/jest.config.json new file mode 100644 index 000000000..98b4b3379 --- /dev/null +++ b/e2e_tests/jest.config.json @@ -0,0 +1,5 @@ +{ + "testPathDirs": [ + "/e2e_tests" + ] +} diff --git a/e2e_tests/pkg.json b/e2e_tests/pkg.json new file mode 100644 index 000000000..5e2245f4d --- /dev/null +++ b/e2e_tests/pkg.json @@ -0,0 +1,9 @@ +{ + "name": "kyt-test", + "version": "1.0.0", + "dependencies": { + "kyt": "file:../." + }, + "author": "", + "license": "ISC" +} diff --git a/e2e_tests/tests/cli.test.js b/e2e_tests/tests/cli.test.js new file mode 100644 index 000000000..31ed13e76 --- /dev/null +++ b/e2e_tests/tests/cli.test.js @@ -0,0 +1,145 @@ +const path = require('path'); +const shell = require('shelljs'); +const kill = require('../../utils/psKill'); + +const pkgJsonPath = path.join(__dirname, './../pkg.json'); + +describe('KYT CLI', () => { + it('installs kyt', () => { + if (shell.test('-d', 'cli-test')) { + shell.rm('-rf', 'cli-test'); + } + shell.mkdir('cli-test'); + shell.cd('cli-test'); + shell.cp(pkgJsonPath, 'package.json'); + const output = shell.exec('npm install'); + if (output.code !== 0) { + process.exit(); + } + + expect(shell.test('-f', 'package.json')).toBe(true); + expect(shell.test('-d', 'node_modules')).toBe(true); + }); + it('sets up a starter-kyt', () => { + let setupURL = 'git@github.com:NYTimes/kyt-starter-test.git'; + if (process.env.TEST_TOKEN) { + setupURL = `https://${process.env.TEST_TOKEN}@github.com/NYTimes/kyt-starter-test.git`; + } + const output = shell.exec(`node_modules/.bin/kyt setup -r ${setupURL}`); + expect(output.code).toBe(0); + const setupArr = output.stdout.split('\n'); + expect(setupArr.includes('🔥 Setting up starter-kyt')).toBe(true); + expect(setupArr.includes('👍 Added kyt scripts into your package.json scripts')).toBe(true); + expect(setupArr.includes('👍 Added new dependencies to package.json')).toBe(true); + expect(setupArr.includes('👍 Installed new modules')).toBe(true); + expect(setupArr.includes('👍 Created .eslintrc.json file')).toBe(true); + expect(setupArr.includes('👍 Created .stylelintrc.json file')).toBe(true); + expect(setupArr.includes('👍 Created kyt.config.js file')).toBe(true); + expect(setupArr.includes('👍 Created .editorconfig file')).toBe(true); + expect(setupArr.includes('👍 Created .gitignore file')).toBe(true); + expect(setupArr.includes('👍 Created src directory')).toBe(true); + }); + it('sets up with the correct files', () => { + expect(shell.test('-d', 'src')).toBe(true); + expect(shell.test('-f', 'kyt.config.js')).toBe(true); + expect(shell.test('-f', '.editorconfig')).toBe(true); + expect(shell.test('-f', '.eslintrc.json')).toBe(true); + expect(shell.test('-f', '.stylelintrc.json')).toBe(true); + expect(shell.test('-f', 'prototype.js')).toBe(true); + }); + it('sets up the package json scripts', () => { + // eslint-disable-next-line import/no-unresolved + const userPackageJSON = require.requireActual('../../cli-test/package.json'); + const scripts = userPackageJSON.scripts; + expect(scripts.dev).toBe('kyt dev'); + expect(scripts.build).toBe('kyt build'); + expect(scripts.test).toBe('kyt test'); + expect(scripts.lint).toBe('kyt lint'); + expect(scripts['lint-style']).toBe('kyt lint-style'); + expect(scripts.proto).toBe('kyt proto'); + expect(scripts['kyt:help']).toBe('kyt --help'); + }); + + it('runs the lint command', () => { + expect(true).toBe(true); + const output = shell.exec('npm run lint'); + expect(output.code).toBe(0); + const outputArr = output.stdout.split('\n'); + expect(outputArr.includes('✅ Your JS looks great ✨')).toBe(true); + }); + + it('runs the lint-style command', () => { + const output = shell.exec('node_modules/.bin/kyt lint-style'); + expect(output.code).toBe(0); + const outputArr = output.stdout.split('\n'); + expect(outputArr.includes('✅ Your styles look good! ✨')).toBe(true); + }); + + it('runs the tests command', () => { + const output = shell.exec('npm run test'); + expect(output.code).toBe(0); + }); + + it('runs the build command', () => { + const output = shell.exec('npm run build'); + expect(output.code).toBe(0); + expect(shell.test('-d', 'build')).toBe(true); + expect(shell.test('-d', 'build/server')).toBe(true); + expect(shell.test('-f', 'build/publicAssets.json')).toBe(true); + expect(shell.test('-d', 'build/public')).toBe(true); + }); + + // eslint-disable-next-line + window.jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000000; + + it('starts the app', (done) => { + shell.exec('npm run build'); + const child = shell.exec('npm run start', () => { + done(); + }); + child.stdout.on('data', (data) => { + if (data.includes('Server running')) { + shell.exec('sleep 3'); + const output = shell.exec('curl -I localhost:3100'); + expect(output.includes('200')); + kill(child.pid); + } + }); + }); + + + it('dev', (done) => { + const child = shell.exec('npm run dev', () => { + done(); + }); + child.stdout.on('data', (data) => { + if (data.includes('✅ Development started')) { + shell.exec('sleep 2'); + const output = shell.exec('curl -I localhost:3100'); + expect(output.includes('200')); + kill(child.pid); + } + }); + }); + + it('proto', (done) => { + const child = shell.exec('npm run proto', () => { + done(); + }); + let stillAlive = true; + child.stdout.on('data', (data) => { + if (data.includes('webpack: bundle is now VALID.') && stillAlive) { + stillAlive = false; + shell.exec('sleep 2'); + const output = shell.exec('curl -I localhost:3102/prototype'); + expect(output.includes('200')); + kill(child.pid); + } + }); + }); + + afterAll(() => { + shell.cd('..'); + shell.rm('-rf', 'cli-test'); + }); +}); diff --git a/package.json b/package.json index fbb7d9fa7..6cb366f13 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "scripts": { "lint": "eslint .", - "test": "jest", + "test": "jest --testPathPattern /__tests__/", + "e2e": "jest --config ./e2e_tests/jest.config.json --verbose --no-cache", "test-watch": "jest --watch", "test-coverage": "jest --coverage" }, @@ -61,6 +62,7 @@ "node-sass": "3.10.1", "nodemon": "1.10.2", "postcss-loader": "0.13.0", + "ps-tree": "1.1.0", "ramda": "0.22.1", "react-hot-loader": "3.0.0-beta.5", "sass-loader": "4.0.2", diff --git a/utils/psKill.js b/utils/psKill.js new file mode 100644 index 000000000..fa0886a3b --- /dev/null +++ b/utils/psKill.js @@ -0,0 +1,22 @@ +const psTree = require('ps-tree'); + +// Loops through processes and kills them +module.exports = (pid, signal, callback) => { + signal = signal || 'SIGKILL'; + callback = callback || function () {}; + psTree(pid, (err, children) => { + let arr = [pid].concat( + children.map(p => p.PID) + ); + arr = arr.filter((item, poss) => arr.indexOf(item) === poss); + arr.forEach((tpid) => { + try { + process.kill(tpid, signal); + } catch (ex) { + const logger = console; + logger.log('Could not kill process', tpid, ex); + } + }); + callback(); + }); +};