mirror of
https://github.com/wassname/talk.git
synced 2026-07-17 11:33:39 +08:00
First isolated e2e
This commit is contained in:
@@ -119,7 +119,7 @@ const CONFIG = {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Port to bind to.
|
||||
PORT: process.env.TALK_PORT || process.env.PORT || '3000',
|
||||
PORT: process.env.TALK_PORT || process.env.PORT || process.env.NODE_ENV === 'test' ? '3001' : '3000',
|
||||
|
||||
// The URL for this Talk Instance as viewable from the outside.
|
||||
ROOT_URL: process.env.TALK_ROOT_URL || null,
|
||||
@@ -182,12 +182,13 @@ const CONFIG = {
|
||||
// CONFIG VALIDATION
|
||||
//==============================================================================
|
||||
|
||||
if (CONFIG.ROOT_URL_MOUNT_PATH && !CONFIG.ROOT_URL) {
|
||||
throw new Error('TALK_ROOT_URL must be specified if TALK_ROOT_URL_MOUNT_PATH is set to TRUE');
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'test' && !CONFIG.ROOT_URL) {
|
||||
CONFIG.ROOT_URL = 'http://localhost:3000';
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
if (!CONFIG.ROOT_URL) {
|
||||
CONFIG.ROOT_URL = 'http://localhost:3001';
|
||||
}
|
||||
if (!CONFIG.STATIC_URL) {
|
||||
CONFIG.STATIC_URI = 'http://localhost:3001';
|
||||
}
|
||||
} else if (!CONFIG.ROOT_URL) {
|
||||
throw new Error('TALK_ROOT_URL must be provided');
|
||||
}
|
||||
|
||||
+36
-32
@@ -1,42 +1,46 @@
|
||||
const {
|
||||
ROOT_URL
|
||||
} = require('./config');
|
||||
|
||||
module.exports = {
|
||||
'src_folders': './test/e2e/specs/',
|
||||
'output_folder': './test/e2e/tests_output',
|
||||
'page_objects_path': './test/e2e/page_objects',
|
||||
'globals_path': './test/e2e/globals',
|
||||
'selenium': {
|
||||
'start_process': true,
|
||||
'server_path': 'node_modules/selenium-standalone/.selenium/selenium-server/3.5.3-server.jar',
|
||||
'log_path': './test/e2e/reports',
|
||||
'host': '127.0.0.1',
|
||||
'port': 6666,
|
||||
'cli_args': {
|
||||
src_folders: './test/e2e/specs/',
|
||||
output_folder: './test/e2e/tests_output',
|
||||
page_objects_path: './test/e2e/page_objects',
|
||||
globals_path: './test/e2e/globals',
|
||||
selenium: {
|
||||
start_process: true,
|
||||
server_path: 'node_modules/selenium-standalone/.selenium/selenium-server/3.5.3-server.jar',
|
||||
log_path: './test/e2e/reports',
|
||||
host: '127.0.0.1',
|
||||
port: 6666,
|
||||
cli_args: {
|
||||
'webdriver.chrome.driver': 'node_modules/selenium-standalone/.selenium/chromedriver/2.32-x64-chromedriver'
|
||||
}
|
||||
},
|
||||
'test_settings': {
|
||||
'default': {
|
||||
'launch_url' : 'http://localhost:3000',
|
||||
'selenium_port': 6666,
|
||||
'selenium_host': 'localhost',
|
||||
'silent': true,
|
||||
'desiredCapabilities': {
|
||||
'browserName': 'chrome',
|
||||
'javascriptEnabled': true,
|
||||
'acceptSslCerts': true,
|
||||
'webStorageEnabled': true,
|
||||
'databaseEnabled': true,
|
||||
'applicationCacheEnabled': false,
|
||||
'nativeEvents': true
|
||||
test_settings: {
|
||||
default: {
|
||||
launch_url: ROOT_URL,
|
||||
selenium_port: 6666,
|
||||
selenium_host: 'localhost',
|
||||
silent: true,
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
javascriptEnabled: true,
|
||||
acceptSslCerts: true,
|
||||
webStorageEnabled: true,
|
||||
databaseEnabled: true,
|
||||
applicationCacheEnabled: false,
|
||||
nativeEvents: true
|
||||
},
|
||||
'screenshots' : {
|
||||
'enabled': true,
|
||||
'on_failure': true,
|
||||
'on_error': true,
|
||||
'path': './test/e2e/tests_output'
|
||||
screenshots : {
|
||||
enabled: true,
|
||||
on_failure: true,
|
||||
on_error: true,
|
||||
path: './test/e2e/tests_output'
|
||||
},
|
||||
},
|
||||
'integration': {
|
||||
'launch_url': 'http://localhost:3000'
|
||||
integration: {
|
||||
launch_url: 'http://localhost:3000'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+10
-8
@@ -1,27 +1,29 @@
|
||||
const {
|
||||
ROOT_URL
|
||||
} = require('./config');
|
||||
|
||||
const nightwatch_config = {
|
||||
src_folders: './test/e2e/specs/',
|
||||
output_folder: './test/e2e/tests_output',
|
||||
page_objects_path: './test/e2e/page_objects',
|
||||
globals_path: './test/e2e/globals',
|
||||
|
||||
selenium : {
|
||||
'start_process': false,
|
||||
'host': 'hub-cloud.browserstack.com',
|
||||
'port': 80
|
||||
start_process: false,
|
||||
host: 'hub-cloud.browserstack.com',
|
||||
port: 80
|
||||
},
|
||||
|
||||
test_settings: {
|
||||
default: {
|
||||
globals: {
|
||||
waitForConditionTimeout: 5000,
|
||||
},
|
||||
launch_url: process.env.TALK_ROOT_URL || 'http://localhost:3000',
|
||||
launch_url: ROOT_URL,
|
||||
desiredCapabilities: {
|
||||
'browserstack.user': process.env.BROWSERSTACK_USER || 'coralproject2',
|
||||
'browserstack.key': process.env.BROWSERSTACK_KEY,
|
||||
'browserstack.local': true,
|
||||
'browser': 'chrome',
|
||||
'browserstack.debug': true,
|
||||
'browserstack.networkLogs': true,
|
||||
'browser': 'chrome',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
"lint": "yamllint locales/*.yml && eslint --ext=.js --ext=.json bin/* .",
|
||||
"lint-fix": "yarn lint --fix",
|
||||
"jest-watch": "TEST_MODE=unit NODE_ENV=test jest --watch",
|
||||
"e2e": "./scripts/e2e.js",
|
||||
"e2e": "NODE_ENV=test ./scripts/e2e.js",
|
||||
"pree2e-local": "./scripts/e2e-local.sh",
|
||||
"e2e-local": "nightwatch --config nightwatch-local.conf.js",
|
||||
"test": "TEST_MODE=unit NODE_ENV=test jest && TEST_MODE=unit NODE_ENV=test mocha -R ${MOCHA_REPORTER:-spec}",
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const debug = require('debug')('talk:e2e:serve');
|
||||
const app = require('../app');
|
||||
const errors = require('../errors');
|
||||
const {createServer} = require('http');
|
||||
const scraper = require('../services/scraper');
|
||||
const mailer = require('../services/mailer');
|
||||
const SetupService = require('../services/setup');
|
||||
const kue = require('../services/kue');
|
||||
const mongoose = require('../services/mongoose');
|
||||
const util = require('../bin/util');
|
||||
const cache = require('../services/cache');
|
||||
const MigrationService = require('../services/migration');
|
||||
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 serve() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
debug(`Websocket Server Listening on ${port}`);
|
||||
|
||||
// Mount the subscriptions server on the application server.
|
||||
createSubscriptionManager(server);
|
||||
});
|
||||
|
||||
// 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([
|
||||
() => kue.Task.shutdown(),
|
||||
() => mongoose.disconnect(),
|
||||
() => server.close()
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = serve;
|
||||
+40
-30
@@ -2,40 +2,50 @@
|
||||
|
||||
const Nightwatch = require('nightwatch');
|
||||
const browserstack = require('browserstack-local');
|
||||
const {onshutdown} = require('../bin/util');
|
||||
|
||||
try {
|
||||
const bs_local = new browserstack.Local();
|
||||
process.mainModule.filename = './node_modules/.bin/nightwatch';
|
||||
async function start() {
|
||||
try {
|
||||
const bs_local = new browserstack.Local();
|
||||
process.mainModule.filename = './node_modules/.bin/nightwatch';
|
||||
|
||||
// Code to start browserstack local before start of test
|
||||
console.log('Connecting local');
|
||||
Nightwatch.bs_local = bs_local;
|
||||
bs_local.start({
|
||||
'key': process.env.BROWSERSTACK_KEY,
|
||||
'logFile': './test/e2e/bslocal.log'
|
||||
}, function(error) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
// Code to start browserstack local before start of test
|
||||
console.log('Connecting local');
|
||||
Nightwatch.bs_local = bs_local;
|
||||
|
||||
console.log('Connected. Now testing...');
|
||||
Nightwatch.cli(function(argv) {
|
||||
Nightwatch.CliRunner(argv)
|
||||
.setup(null, function(){
|
||||
bs_local.start({
|
||||
'key': process.env.BROWSERSTACK_KEY,
|
||||
'logFile': './test/e2e/bslocal.log'
|
||||
}, function(error) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Code to stop browserstack local after end of parallel test
|
||||
bs_local.stop(function(){});
|
||||
})
|
||||
.runTests(function(){
|
||||
console.log('Connected. Now testing...');
|
||||
Nightwatch.cli(function(argv) {
|
||||
Nightwatch.CliRunner(argv)
|
||||
.setup(null, function(){
|
||||
|
||||
// Code to stop browserstack local after end of single test
|
||||
bs_local.stop(function(){});
|
||||
});
|
||||
// Code to stop browserstack local after end of parallel test
|
||||
bs_local.stop(function(){});
|
||||
})
|
||||
.runTests(function(){
|
||||
|
||||
// Code to stop browserstack local after end of single test
|
||||
bs_local.stop(function(){});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} catch (ex) {
|
||||
console.log('There was an error while starting the test runner:\n\n');
|
||||
process.stderr.write(`${ex.stack}\n`);
|
||||
process.exit(2);
|
||||
|
||||
onshutdown([
|
||||
() => bs_local.stop(function(){}),
|
||||
]);
|
||||
} catch (ex) {
|
||||
console.log('There was an error while starting the test runner:\n\n');
|
||||
process.stderr.write(`${ex.stack}\n`);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
start();
|
||||
|
||||
+17
-7
@@ -1,14 +1,24 @@
|
||||
const uuid = require('uuid');
|
||||
const {murmur3} = require('murmurhash-js');
|
||||
const rHash = murmur3(uuid.v4());
|
||||
const serve = require('../../scripts/e2e-serve');
|
||||
const mongoose = require('../../services/mongoose');
|
||||
const {shutdown} = require('../../bin/util');
|
||||
|
||||
module.exports = {
|
||||
before: async (done) => {
|
||||
await mongoose.connection.dropDatabase();
|
||||
await serve();
|
||||
done();
|
||||
},
|
||||
after: (done) => {
|
||||
shutdown();
|
||||
done();
|
||||
},
|
||||
waitForConditionTimeout: 5000,
|
||||
testData: {
|
||||
admin: {
|
||||
email: 'admin@test.com',
|
||||
username: 'admin',
|
||||
password: 'testtest',
|
||||
},
|
||||
organizationName: 'Coral',
|
||||
email: `test_${rHash}@test.test`,
|
||||
username: `test${rHash}`,
|
||||
password: `testpassword${rHash}`,
|
||||
domain: 'http://localhost:3000'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports = {
|
||||
},
|
||||
ready() {
|
||||
return this
|
||||
.waitForElementVisible('body', 2000);
|
||||
.waitForElementVisible('body');
|
||||
},
|
||||
}],
|
||||
elements: {
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports = {
|
||||
},
|
||||
ready() {
|
||||
return this
|
||||
.waitForElementVisible('body', 2000);
|
||||
.waitForElementVisible('body');
|
||||
}
|
||||
}],
|
||||
elements: {
|
||||
@@ -20,7 +20,7 @@ module.exports = {
|
||||
'step3ConfirmPasswordInput': '.talk-install-step-3 #confirmPassword',
|
||||
'step3saveButton': '.talk-install-step-3-save-button',
|
||||
'step4': '.talk-install-step-4',
|
||||
'step4DomainInput': '.talk-install-step-4-permited-domains-input',
|
||||
'step4DomainInput': '.talk-install-step-4-permited-domains-input input',
|
||||
'step4saveButton': '.talk-install-step-4-save-button',
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ module.exports = {
|
||||
'@tags': ['install'],
|
||||
'User goes to install': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
|
||||
|
||||
installPage
|
||||
.navigate()
|
||||
.ready();
|
||||
@@ -10,14 +10,14 @@ module.exports = {
|
||||
},
|
||||
'User clicks get started button': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@getStartedButton')
|
||||
.click('@getStartedButton');
|
||||
},
|
||||
'User should see step 2 - Add Organization Name': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@step2');
|
||||
},
|
||||
@@ -33,38 +33,37 @@ module.exports = {
|
||||
},
|
||||
'User should see step 3 - Create your account': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@step3');
|
||||
},
|
||||
'User fills step 3': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
const {testData} = client.globals;
|
||||
const {testData: {admin}} = client.globals;
|
||||
|
||||
installPage
|
||||
.setValue('@step3EmailInput', testData.email)
|
||||
.setValue('@step3UsernameInput', testData.username)
|
||||
.setValue('@step3PasswordInput', testData.password)
|
||||
.setValue('@step3ConfirmPasswordInput', testData.password)
|
||||
.setValue('@step3EmailInput', admin.email)
|
||||
.setValue('@step3UsernameInput', admin.username)
|
||||
.setValue('@step3PasswordInput', admin.password)
|
||||
.setValue('@step3ConfirmPasswordInput', admin.password)
|
||||
.waitForElementVisible('@step3saveButton')
|
||||
.click('@step3saveButton');
|
||||
},
|
||||
'User should see step 4 - Domain Whitelist': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@step4');
|
||||
},
|
||||
'User fills step 4': (client) => {
|
||||
const installPage = client.page.installPage();
|
||||
const testData = client.page.getTestData();
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@step4DomainInput')
|
||||
.setValue('@step4DomainInput', testData.domain);
|
||||
.setValue('@step4DomainInput', client.launchUrl);
|
||||
|
||||
client.keys(client.Keys.ENTER);
|
||||
|
||||
|
||||
installPage
|
||||
.waitForElementVisible('@step4saveButton')
|
||||
.click('@step4saveButton');
|
||||
|
||||
@@ -2,13 +2,14 @@ module.exports = {
|
||||
'@tags': ['admin', 'login'],
|
||||
'Admin logs in': (client) => {
|
||||
const adminPage = client.page.adminPage();
|
||||
const {testData} = client.globals;
|
||||
|
||||
const {testData: {admin}} = client.globals;
|
||||
|
||||
adminPage
|
||||
.navigate()
|
||||
.waitForElementVisible('@loginLayout')
|
||||
.waitForElementVisible('@signInForm')
|
||||
.setValue('@emailInput', testData.email)
|
||||
.setValue('@passwordInput', testData.password)
|
||||
.setValue('@emailInput', admin.email)
|
||||
.setValue('@passwordInput', admin.password)
|
||||
.waitForElementVisible('@signInButton')
|
||||
.click('@signInButton');
|
||||
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
const uuid = require('uuid');
|
||||
const {murmur3} = require('murmurhash-js');
|
||||
|
||||
module.exports = {
|
||||
'Creates a new asset': (client) => {
|
||||
const asset = `test@${murmur3(uuid.v4())}`;
|
||||
const asset = 'newAssetTest';
|
||||
const embedStream = client.page.embedStream();
|
||||
|
||||
embedStream
|
||||
.navigateToAsset(asset)
|
||||
.assert.title(asset)
|
||||
.getEmbedSection();
|
||||
|
||||
client
|
||||
.end();
|
||||
},
|
||||
|
||||
'not logged in user clicks my profile tab': (client) => {
|
||||
@@ -27,8 +22,9 @@ module.exports = {
|
||||
|
||||
profile
|
||||
.assert.visible('@notLoggedIn');
|
||||
|
||||
client
|
||||
.end();
|
||||
},
|
||||
|
||||
after: (client) => {
|
||||
client.end();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user