Merge branch 'master' into reportedComments

This commit is contained in:
Kim Gardner
2017-10-31 17:12:02 +00:00
committed by GitHub
14 changed files with 208 additions and 35 deletions
+1 -1
View File
@@ -50,7 +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
- yarn e2e-ci
deployment:
release:
+20 -2
View File
@@ -26,18 +26,29 @@ const nightwatch_config = {
// Disable this, as it makes bs slow and brittle.
'browserstack.networkLogs': false,
}
'browserstack.resolution': '1600x1200',
},
screenshots : {
enabled: true,
on_failure: true,
on_error: true,
path: process.env.REPORTS_FOLDER || './test/e2e/reports',
},
},
chrome: {
desiredCapabilities: {
browser: 'chrome',
browser_version: '62',
os: 'Windows',
os_version: '10',
},
},
firefox: {
desiredCapabilities: {
browser: 'firefox',
browser_version: '56',
os: 'Windows',
os_version: '10',
},
},
safari: {
@@ -52,14 +63,21 @@ const nightwatch_config = {
desiredCapabilities: {
browser: 'internet explorer',
os: 'Windows',
os_version: '8.1',
os_version: '10',
browser_version: '11',
// The x64 bit IEDriver that is used by IE 11 has a known issue with sendKeys where
// it may enter incorrect keys (shift + key).
// This adds a delay for each character as temporary fix as advised from the browserstack support.
'browserstack.customSendKeys': 800,
},
},
edge: {
desiredCapabilities: {
browser: 'edge',
browser_version: '15',
os: 'Windows',
os_version: '10',
},
},
}
+4 -4
View File
@@ -9,13 +9,13 @@ module.exports = {
globals_path: './test/e2e/globals',
selenium: {
start_process: true,
server_path: 'node_modules/selenium-standalone/.selenium/selenium-server/3.5.3-server.jar',
server_path: 'node_modules/selenium-standalone/.selenium/selenium-server/3.6.0-server.jar',
log_path: './test/e2e/',
host: '127.0.0.1',
port: 6666,
cli_args: {
'webdriver.chrome.driver': 'node_modules/selenium-standalone/.selenium/chromedriver/2.32-x64-chromedriver',
'webdriver.gecko.driver': 'node_modules/selenium-standalone/.selenium/geckodriver/0.18.0-x64-geckodriver',
'webdriver.chrome.driver': 'node_modules/selenium-standalone/.selenium/chromedriver/2.33-x64-chromedriver',
'webdriver.gecko.driver': 'node_modules/selenium-standalone/.selenium/geckodriver/0.19.0-x64-geckodriver',
}
},
test_settings: {
@@ -43,7 +43,7 @@ module.exports = {
'chrome-headless': {
desiredCapabilities: {
chromeOptions : {
args: ['--headless', '--disable-gpu', 'window-size=1280,800'],
args: ['--headless', '--disable-gpu', 'window-size=1600,1200'],
},
},
},
+1 -1
View File
@@ -172,7 +172,7 @@
"redux": "^3.6.0",
"redux-thunk": "^2.1.0",
"resolve": "^1.4.0",
"selenium-standalone": "6.9.0",
"selenium-standalone": "^6.11.0",
"semver": "^5.4.1",
"simplemde": "^1.11.2",
"smoothscroll-polyfill": "^0.3.5",
+66 -11
View File
@@ -1,32 +1,87 @@
#!/bin/bash
CIRCLE_TEST_REPORTS=${CIRCLE_TEST_REPORTS:-./test/e2e/reports}
CIRCLE_BRANCH=${CIRCLE_BRANCH:-master}
# Amount of retries before failure.
E2E_MAX_RETRIES=${E2E_MAX_RETRIES:-1}
# Amount of seconds between tests.
E2E_SLEEP_BETWEEN_TESTS=${E2E_SLEEP_BETWEEN_TESTS:-1}
# Safari >= 8 has issues connecting to browserstack-local. Safari < 8 is too old.
BROWSERS="chrome firefox ie edge" #safari
if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
# List of failed browsers.
failedBrowsers=
# List of succeeded browsers.
succeededBrowsers=
exitCode=0
browserstack() {
REPORTS_FOLDER="$CIRCLE_TEST_REPORTS/$1" yarn e2e-browserstack -- --env "$1"
# Current number of tries.
try=${2:-0}
echo "-- Start e2e for $1 #$try --"
REPORTS_FOLDER="$CIRCLE_TEST_REPORTS/$1" yarn e2e-browserstack --env "$1"
# Determine exit code.
result=$?
if [ "$result" -gt "0" ]
then
if [ "$result" -ne "0" ]; then
echo "-- Failed e2e for $1 #$try --"
# Try again until E2E_MAX_RETRIES is reached.
if [ "$try" -lt "$E2E_MAX_RETRIES" ]; then
let try=try+1
# Sleep a bit to let browserstack-local close properly.
sleep "$E2E_SLEEP_BETWEEN_TESTS"
browserstack "$1" "$try"
return
fi
# Failed, add to list of failed browsers.
failedBrowsers="$failedBrowsers $1"
# Remember exit code.
exitCode=$result
else
echo "-- Success e2e for $1 #$try --"
# Succeeded, add to list of succeeded browsers.
succeededBrowsers="$succeededBrowsers $1"
eval "browser_${1}_succeeded_at=$try"
fi
# Sleep a bit to let browserstack-local to close properly.
sleep 2
# Sleep a bit to let browserstack-local close properly.
sleep "$E2E_SLEEP_BETWEEN_TESTS"
}
# Test using browserstack.
browserstack chrome
browserstack firefox
browserstack ie
browserstack edge
for browser in $BROWSERS
do
browserstack "$browser"
done
# Safari >= 8 has issues connecting to browserstack-local. Safari < 8 is too old.
# browserstack safari
# Print information about succeeded browsers.
for x in $succeededBrowsers
do
echo "Succeeded $x at try #$(eval "echo \$browser_${x}_succeeded_at")"
done
# Print information about failed browsers.
for x in $failedBrowsers
do
echo "Failed $x"
done
exit $exitCode
else
# When browserstack is not available test locally using chrome headless.
+1
View File
@@ -0,0 +1 @@
<%= body.replace(/\n/g, '<br />') %>
+1
View File
@@ -0,0 +1 @@
<%= body %>
+20 -1
View File
@@ -398,7 +398,7 @@ module.exports = class UsersService {
// TODO: current updating status behavior is weird.
// once a user has been `APPROVED` its status cannot be
// changed anymore.
return UserModel.findOneAndUpdate({
const user = await UserModel.findOneAndUpdate({
id,
status: {
$ne: 'APPROVED'
@@ -410,6 +410,25 @@ module.exports = class UsersService {
}, {
new: true,
});
if (status === 'BANNED') {
let localProfile = user.profiles.find((profile) => profile.provider === 'local');
if (localProfile) {
const options =
{
template: 'banned', // needed to know which template to render!
locals: { // specifies the template locals.
body: 'In accordance with The Coral Projects community guidelines, your account has been banned. You are now longer allowed to comment, flag or engage with our community.'
},
subject: 'Your account has been banned',
to: localProfile.id // This only works if the user has registered via e-mail.
// We may want a standard way to access a user's e-mail address in the future
};
await MailerService.sendSimple(options);
}
}
return user;
}
/**
+7
View File
@@ -8,6 +8,11 @@ module.exports = {
},
getEmbedSection: function() {
this.waitForElementVisible('@iframe');
// Pause a bit to let iframe initialize in the hope that it'll
// fix https://www.browserstack.com/automate/builds/96419cf46e3d6376a36ae6d3f90934112df1ed91/sessions/224f1a1566c1c8c7859e2e76ece51862200f0173#automate_button
this.api.pause(200);
this.api.frame(iframeId);
this.expect.section('@embed').to.be.present;
return this.section.embed;
@@ -23,11 +28,13 @@ module.exports = {
embed: {
commands: [{
getProfileSection: function() {
this.waitForElementVisible('@profileTabButton');
this.click('@profileTabButton');
this.expect.section('@profile').to.be.present;
return this.section.profile;
},
getCommentsSection: function() {
this.waitForElementVisible('@commentsTabButton');
this.click('@commentsTabButton');
this.expect.section('@comments').to.be.present;
return this.section.comments;
+2 -4
View File
@@ -1,9 +1,9 @@
module.exports = {
'@tags': ['admin', 'login'],
beforeEach: (client) => {
client.resizeWindow(1024, 800);
},
},
'Admin logs in': (client) => {
const adminPage = client.page.admin();
const {testData: {admin}} = client.globals;
@@ -17,8 +17,6 @@ module.exports = {
.waitForElementVisible('@signInButton')
.click('@signInButton');
client.pause(3000);
adminPage
.waitForElementVisible('@moderationContainer');
},
+21 -7
View File
@@ -1,3 +1,5 @@
const SortedWindowHandler = require('../utils/SortedWindowHandler');
module.exports = {
'@tags': ['embedStream', 'login'],
'creates a new asset': (client) => {
@@ -18,16 +20,19 @@ module.exports = {
.navigate()
.getEmbedSection();
const windowHandler = new SortedWindowHandler(client);
embed
.waitForElementVisible('@signInButton')
.click('@signInButton');
client.pause(3000);
// Wait for window to be created
// https://www.browserstack.com/automate/builds/1ceccf4efb4683b7feb890f45a32b5922b40ed3f/sessions/17b1a79682bef2498cb0be86eac317a08c976b0a#automate_button
client.pause(200);
// Focusing on the Login PopUp
client.windowHandles((result) => {
const handle = result.value[1];
client.switchWindow(handle);
windowHandler.windowHandles((handles) => {
client.switchWindow(handles[1]);
});
const login = client.page.login();
@@ -45,10 +50,19 @@ module.exports = {
.waitForElementVisible('@loginButton')
.click('@loginButton');
// Give a tiny bit of time to let popup close.
client.pause(50);
if (client.capabilities.browserName === 'MicrosoftEdge') {
// More time for edge.
// https://www.browserstack.com/automate/builds/1ceccf4efb4683b7feb890f45a32b5922b40ed3f/sessions/7393dbfda8387e43b6d5851f359b0c07db414973
client.pause(1000);
}
// Focusing on the Embed Window
client.windowHandles((result) => {
const handle = result.value[0];
client.switchWindow(handle);
windowHandler.windowHandles((handles) => {
client.switchWindow(handles[0]);
});
},
'user posts a comment': (client) => {
+41
View File
@@ -0,0 +1,41 @@
/**
* SortedWindowHandler assists in making e2e tests more robust by returning
* deterministic window handles. An instance must be created before new windows
* are created and windowHandles must be called each time a window was created or
* closed.
*/
class SortedWindowHandler {
/**
* Constructor, must be called before new windows were created.
*/
constructor(client) {
this.client = client;
this.client.windowHandles((result) => {
this.handles = result.value;
if (this.handles.length > 2) {
throw new Error('SortedWindowHandler must be created before new windows were created.');
}
});
}
/**
* windowHandles will call given `callback` with an array of window handles.
*/
windowHandles(callback) {
this.client.windowHandles((result) => {
this.handles = this.handles.filter((handle) => result.value.includes(handle));
const remaining = result.value.filter((handle) => !this.handles.includes(handle));
if (remaining.length === 1) {
this.handles.push(remaining[0]);
}
if (remaining.length > 1) {
throw new Error('Cannot detect new window handle, because more than one windows was created.');
}
callback(this.handles);
});
}
}
module.exports = SortedWindowHandler;
+20 -1
View File
@@ -1,8 +1,11 @@
const UsersService = require('../../../services/users');
const SettingsService = require('../../../services/settings');
const MailerService = require('../../../services/mailer');
const chai = require('chai');
chai.use(require('chai-as-promised'));
const sinon = require('sinon');
chai.use(require('sinon-chai'));
const expect = chai.expect;
describe('services.UsersService', () => {
@@ -15,7 +18,7 @@ describe('services.UsersService', () => {
mockUsers = await UsersService.createLocalUsers([{
email: 'stampi@gmail.com',
username: 'Stampi',
password: '1Coral!-'
password: '1Coral!-',
}, {
email: 'sockmonster@gmail.com',
username: 'Sockmonster',
@@ -25,6 +28,12 @@ describe('services.UsersService', () => {
username: 'Marvel',
password: '3Coral!3'
}]);
sinon.spy(MailerService, 'sendSimple');
});
afterEach(() => {
MailerService.sendSimple.restore();
});
describe('#findById()', () => {
@@ -149,7 +158,11 @@ describe('services.UsersService', () => {
.then(() => UsersService.findById(mockUsers[0].id))
.then((user) => {
expect(user).to.have.property('status', 'ACTIVE');
})
.then(() => {
expect(MailerService.sendSimple).to.not.have.been.called;
});
});
});
@@ -188,6 +201,12 @@ describe('services.UsersService', () => {
.then(() => UsersService.findById(mockUsers[0].id))
.then((user) => {
expect(user).to.have.property('status', 'BANNED');
})
.then(() => {
expect(MailerService.sendSimple).to.have.been.calledWithMatch({
template: 'banned',
to: mockUsers[0].profiles[0].id
});
});
});
+3 -3
View File
@@ -7953,9 +7953,9 @@ select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
selenium-standalone@6.9.0:
version "6.9.0"
resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-6.9.0.tgz#5805f403c82b48b4e136d8a97f1832aad7852bd5"
selenium-standalone@^6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-6.11.0.tgz#eb21ff65f3b2ece75061b35d4f9e7572ac0280c2"
dependencies:
async "^2.1.4"
commander "^2.9.0"