diff --git a/.gitignore b/.gitignore index 0ab845e4e..d30e961bd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,10 @@ client/coral-framework/graphql/introspection.json *.DS_STORE coverage/ +test/e2e/reports/ +test/e2e/bslocal.log +test/e2e/selenium-debug.log +browserstack.err plugins.json plugins/* diff --git a/bin/cli-serve b/bin/cli-serve index b04714690..4324cac92 100755 --- a/bin/cli-serve +++ b/bin/cli-serve @@ -1,161 +1,7 @@ #!/usr/bin/env node const program = require('./commander'); -const app = require('../app'); -const debug = require('debug')('talk:cli:serve'); -const errors = require('../errors'); -const {createServer} = require('http'); -const scraper = require('../services/scraper'); -const mailer = require('../services/mailer'); -const MigrationService = require('../services/migration'); -const SetupService = require('../services/setup'); -const kue = require('../services/kue'); -const mongoose = require('../services/mongoose'); -const util = require('./util'); -const cache = require('../services/cache'); -const {createSubscriptionManager} = require('../graph/subscriptions'); -const { - PORT -} = require('../config'); - -/** -* Get port from environment and store in Express. -*/ - -const port = normalizePort(PORT); -app.set('port', port); - -/** -* Create HTTP server. -*/ -const server = createServer(app); - -/** - * Event listener for HTTP server "error" event. - */ -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - let bind = typeof port === 'string' - ? `Pipe ${port}` - : `Port ${port}`; - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(`${bind} requires elevated privileges`); - break; - case 'EADDRINUSE': - console.error(`${bind} is already in use`); - break; - } - - throw error; -} - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - let port = parseInt(val, 10); - - if (isNaN(port)) { - - // named pipe - return val; - } - - if (port >= 0) { - - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "listening" event. - */ - -async function onListening() { - - // Start the cache instance. - await cache.init(); - - let addr = server.address(); - let bind = typeof addr === 'string' - ? `pipe ${addr}` - : `port ${addr.port}`; - debug(`API Server Listening on ${bind}`); -} - -/** - * Start the app. - */ -async function startApp(program) { - - try { - - // Check to see if the application is installed. If the application - // has been installed, then it will throw errors.ErrSettingsNotInit, this - // just means we don't have to check that the migrations have run. - await SetupService.isAvailable(); - - debug('setup is currently available, migrations not being checked'); - - } catch (e) { - - // Check the error. - switch (e) { - case errors.ErrInstallLock, errors.ErrSettingsInit: - - debug('setup is not currently available, migrations now being checked'); - - // The error was expected, just continue. - break; - default: - - // The error was not expected, throw the error! - throw e; - } - - // Now try and check the migration status. - try { - - // Verify that the minimum migration version is met. - await MigrationService.verify(); - - } catch (e) { - console.error(e); - process.exit(1); - } - - debug('migrations do not have to be run'); - } - - /** - * Listen on provided port, on all network interfaces. - */ - server.on('error', onError); - server.on('listening', onListening); - server.on('listening', () => { - - }); - server.listen(port, () => { - - // Mount the websocket server if requested. - if (program.websockets) { - debug(`Websocket Server Listening on ${port}`); - - // Mount the subscriptions server on the application server. - createSubscriptionManager(server); - } - }); -} +const serve = require('../serve'); //============================================================================== // Setting up the program command line arguments. @@ -166,24 +12,6 @@ program .option('-w, --websockets', 'enable the websocket (subscriptions) handler on this thread') .parse(process.argv); -// Start the application serving. -startApp(program); +// Start serving. +serve({jobs: program.jobs, websockets: program.websockets}); -// Enable job processing on the thread if enabled. -if (program.jobs) { - - // Start the scraper processor. - scraper.process(); - - // Start the mail processor. - mailer.process(); -} - -// Define a safe shutdown function to call in the event we need to shutdown -// because the node hooks are below which will interrupt the shutdown process. -// Shutdown the mongoose connection, the app server, and the scraper. -util.onshutdown([ - () => program.jobs ? kue.Task.shutdown() : null, - () => mongoose.disconnect(), - () => server.close() -]); diff --git a/circle.yml b/circle.yml index 874c78b4e..9f35736c6 100644 --- a/circle.yml +++ b/circle.yml @@ -7,9 +7,7 @@ machine: environment: PATH: "${PATH}:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin" NODE_ENV: "test" - -dependencies: - override: + pre: # TODO: use the following to add in support for MongoDB 3.4. # # Upgrade the database version to 3.4. # - sudo apt-get purge mongodb-org* @@ -19,10 +17,20 @@ dependencies: # - sudo apt-get install -y mongodb-org # - sudo service mongod restart + # Install chromium for e2e and remove old google-chrome + - sudo rm -rf /opt/google/chrome + - sudo rm -f /usr/bin/google-chrome* + - sudo apt-get update + - sudo apt-get install chromium-browser + +dependencies: + override: + # Install node dependencies. - yarn --version - yarn global add node-gyp nsp --force - yarn + post: # Build the static assets. - yarn build @@ -42,6 +50,7 @@ test: - MOCHA_FILE=$CIRCLE_TEST_REPORTS/junit/test-results.xml MOCHA_REPORTER=mocha-junit-reporter yarn test # Check dependancies using nsp. - nsp check + - yarn e2e-ci deployment: release: diff --git a/client/coral-admin/src/components/AdminLogin.js b/client/coral-admin/src/components/AdminLogin.js index be8dd8b09..d195ad72b 100644 --- a/client/coral-admin/src/components/AdminLogin.js +++ b/client/coral-admin/src/components/AdminLogin.js @@ -4,6 +4,7 @@ import Layout from 'coral-admin/src/components/ui/Layout'; import styles from './NotFound.css'; import {Button, TextField, Alert, Success} from 'coral-ui'; import Recaptcha from 'react-recaptcha'; +import cn from 'classnames'; class AdminLogin extends React.Component { @@ -34,19 +35,22 @@ class AdminLogin extends React.Component { render () { const {errorMessage, loginMaxExceeded, recaptchaPublic} = this.props; const signInForm = ( -