Merge pull request #4 from wodka/features/security_updates
improve security
This commit is contained in:
commit
6d75c011a9
@ -23,8 +23,7 @@ var smtpTransport = nodemailer.createTransport(config.mailer.options);
|
||||
*/
|
||||
exports.deleteSubmissions = function(req, res) {
|
||||
|
||||
var submission_id_list = req.body.deleted_submissions,
|
||||
form = req.form;
|
||||
var submission_id_list = req.body.deleted_submissions;
|
||||
|
||||
FormSubmission.remove({ form: req.form, _id: {$in: submission_id_list} }, function(err){
|
||||
|
||||
@ -121,9 +120,7 @@ exports.createSubmission = function(req, res) {
|
||||
* Get List of Submissions for a given Form
|
||||
*/
|
||||
exports.listSubmissions = function(req, res) {
|
||||
var _form = req.form;
|
||||
|
||||
FormSubmission.find({ form: _form._id }).sort('created').lean().exec(function(err, _submissions) {
|
||||
FormSubmission.find({ form: req.form._id }).sort('created').lean().exec(function(err, _submissions) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return res.status(500).send({
|
||||
@ -357,11 +354,10 @@ var readForRender = exports.readForRender = function(req, res) {
|
||||
* Update a form
|
||||
*/
|
||||
exports.update = function(req, res) {
|
||||
|
||||
var form = req.form;
|
||||
var updatedForm = req.body.form;
|
||||
|
||||
if(!form.analytics && req.body.form.analytics){
|
||||
if(!form.analytics){
|
||||
form.analytics = {
|
||||
visitors: [],
|
||||
gaCode: ''
|
||||
@ -376,7 +372,7 @@ exports.update = function(req, res) {
|
||||
});
|
||||
} else {
|
||||
if(!updatedForm){
|
||||
res.status(400).send({
|
||||
return res.status(400).send({
|
||||
message: 'Updated Form is empty'
|
||||
});
|
||||
}
|
||||
@ -426,7 +422,9 @@ exports.delete = function(req, res) {
|
||||
message: errorHandler.getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.json(form);
|
||||
res.json(
|
||||
helpers.removeSensitiveModelData('private_form', form)
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -513,8 +511,7 @@ exports.formByID = function(req, res, next, id) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
//Remove sensitive information from User object
|
||||
req.form = helpers.removeSensitiveModelData('private_form', form.toJSON());
|
||||
req.form = form;
|
||||
return next();
|
||||
}
|
||||
});
|
||||
@ -542,7 +539,7 @@ exports.formByIDFast = function(req, res, next, id) {
|
||||
}
|
||||
else {
|
||||
//Remove sensitive information from User object
|
||||
req.form = helpers.removeSensitiveModelData('public_form', form);
|
||||
req.form = form;
|
||||
return next();
|
||||
}
|
||||
});
|
||||
@ -555,7 +552,7 @@ exports.formByIDFast = function(req, res, next, id) {
|
||||
*/
|
||||
exports.hasAuthorization = function(req, res, next) {
|
||||
var form = req.form;
|
||||
if (req.form.admin.id !== req.user.id && req.user.roles.indexOf('admin') < 0) {
|
||||
if (!req.form.admin || req.form.admin.id !== req.user.id && req.user.roles.indexOf('admin') < 0) {
|
||||
return res.status(403).send({
|
||||
message: 'User '+req.user.username+' is not authorized to edit Form: '+form.title
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@ var validFormats = ['combined', 'common', 'dev', 'short', 'tiny'];
|
||||
|
||||
// Instantiating the default winston application logger with the Console
|
||||
// transport
|
||||
var logger = new winston.Logger({
|
||||
var logger = new winston.createLogger({
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
level: 'info',
|
||||
@ -49,7 +49,7 @@ logger.setupFileLogger = function setupFileLogger() {
|
||||
// Check first if the configured path is writable and only then
|
||||
// instantiate the file logging transport
|
||||
if (fs.openSync(fileLoggerTransport.filename, 'a+')) {
|
||||
logger.add(winston.transports.File, fileLoggerTransport);
|
||||
logger.add(new winston.transports.File(), fileLoggerTransport);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -74,7 +74,7 @@ logger.getLogOptions = function getLogOptions() {
|
||||
|
||||
var _config = _.clone(config, true);
|
||||
var configFileLogger = _config.log.fileLogger;
|
||||
|
||||
|
||||
if (process.env.NODE_ENV !== 'test' && !_.has(_config, 'log.fileLogger.directoryPath') || !_.has(_config, 'log.fileLogger.fileName')) {
|
||||
console.log('unable to find logging file configuration');
|
||||
return false;
|
||||
@ -120,13 +120,13 @@ logger.getMorganOptions = function getMorganOptions() {
|
||||
logger.getLogFormat = function getLogFormat() {
|
||||
var format = config.log && config.log.format ? config.log.format.toString() : 'combined';
|
||||
|
||||
if (!_.includes(validFormats, format)) {
|
||||
if (!_.includes(validFormats, format)) {
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
console.log();
|
||||
console.log(chalk.yellow('Warning: An invalid format was provided. The logger will use the default format of "' + format + '"'));
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
}
|
||||
return format;
|
||||
};
|
||||
|
||||
|
||||
11804
package-lock.json
generated
11804
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
128
package.json
128
package.json
@ -21,98 +21,98 @@
|
||||
"init": "node scripts/setup.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^1.4.2",
|
||||
"async": "^2.6.3",
|
||||
"body-parser": "^1.19.0",
|
||||
"bower": "^1.8.8",
|
||||
"chalk": "^1.1.3",
|
||||
"chalk": "^2.4.2",
|
||||
"compression": "^1.7.4",
|
||||
"connect": "^3.4.1",
|
||||
"connect-mongo": "^2.0.0",
|
||||
"connect": "^3.7.0",
|
||||
"connect-mongo": "^3.0.0",
|
||||
"consolidate": "~0.14.5",
|
||||
"cookie-parser": "~1.4.0",
|
||||
"deep-diff": "^0.3.4",
|
||||
"dotenv": "^2.0.0",
|
||||
"cookie-parser": "^1.4.4",
|
||||
"deep-diff": "^1.0.2",
|
||||
"dotenv": "^8.0.0",
|
||||
"email-verification": "github:tellform/node-email-verification",
|
||||
"envfile": "^2.1.1",
|
||||
"express": "^4.16.4",
|
||||
"express-session": "^1.16.1",
|
||||
"glob": "^7.0.3",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-concurrent": "~2.3.0",
|
||||
"grunt-contrib-csslint": "~1.0.0",
|
||||
"grunt-contrib-cssmin": "~1.0.1",
|
||||
"grunt-contrib-jshint": "~1.0.0",
|
||||
"grunt-contrib-uglify": "~0.11.0",
|
||||
"grunt-env": "~0.4.1",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.16.2",
|
||||
"glob": "^7.1.4",
|
||||
"grunt": "^1.0.4",
|
||||
"grunt-concurrent": "^3.0.0",
|
||||
"grunt-contrib-csslint": "^2.0.0",
|
||||
"grunt-contrib-cssmin": "^3.0.0",
|
||||
"grunt-contrib-jshint": "^2.1.0",
|
||||
"grunt-contrib-uglify": "^4.0.1",
|
||||
"grunt-env": "^0.4.4",
|
||||
"grunt-html2js": "^0.6.0",
|
||||
"grunt-ng-annotate": "~1.0.1",
|
||||
"helmet": "^3.16.0",
|
||||
"grunt-ng-annotate": "^3.0.0",
|
||||
"helmet": "^3.18.0",
|
||||
"i18n": "^0.8.3",
|
||||
"jit-grunt": "^0.9.1",
|
||||
"jsdom": "^15.1.1",
|
||||
"lodash": "^4.17.13",
|
||||
"lodash": "^4.17.14",
|
||||
"main-bower-files": "^2.13.1",
|
||||
"method-override": "~2.3.0",
|
||||
"method-override": "^3.0.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mongoose": "^5.6.4",
|
||||
"morgan": "^1.9.1",
|
||||
"nodemailer": "~4.0.0",
|
||||
"passport": "~0.3.0",
|
||||
"nodemailer": "^6.3.0",
|
||||
"passport": "^0.4.0",
|
||||
"passport-anonymous": "^1.0.1",
|
||||
"passport-local": "~1.0.0",
|
||||
"passport-localapikey-update": "^0.5.0",
|
||||
"path-exists": "^2.1.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"passport-localapikey-update": "^0.6.0",
|
||||
"path-exists": "^4.0.0",
|
||||
"prerender-node": "^2.2.1",
|
||||
"pug": "^2.0.3",
|
||||
"pug": "^2.0.4",
|
||||
"random-js": "^1.0.8",
|
||||
"raven": "^0.9.0",
|
||||
"request": "^2.88.0",
|
||||
"socket.io": "^1.4.6",
|
||||
"socket.io-redis": "^1.0.0",
|
||||
"swig": "~1.4.1",
|
||||
"uuid-token-generator": "^0.5.0",
|
||||
"winston": "^2.3.1"
|
||||
"socket.io": "^1.7.4",
|
||||
"socket.io-redis": "^5.2.0",
|
||||
"swig": "^1.4.2",
|
||||
"uuid-token-generator": "^1.0.0",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"all-contributors-cli": "^4.3.0",
|
||||
"chromedriver": "^2.25.1",
|
||||
"coveralls": "^2.11.4",
|
||||
"cross-spawn": "^5.0.0",
|
||||
"del": "^2.2.2",
|
||||
"grunt-cli": "~0.1.13",
|
||||
"grunt-closure-compiler": "0.0.21",
|
||||
"all-contributors-cli": "^6.7.0",
|
||||
"chromedriver": "^75.1.0",
|
||||
"coveralls": "^3.0.5",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"del": "^5.0.0",
|
||||
"grunt-cli": "^1.3.2",
|
||||
"grunt-closure-compiler": "^0.0.21",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-contrib-uglify": "^0.11.1",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-contrib-uglify": "^4.0.1",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
"grunt-execute": "^0.2.2",
|
||||
"grunt-i18nlint": "github:jwarby/grunt-i18nlint",
|
||||
"grunt-karma": "~0.12.1",
|
||||
"grunt-mocha-istanbul": "^3.0.1",
|
||||
"grunt-mocha-test": "~0.12.1",
|
||||
"grunt-newer": "~1.1.1",
|
||||
"grunt-nodemon": "~0.4.0",
|
||||
"grunt-karma": "^3.0.2",
|
||||
"grunt-mocha-istanbul": "^5.0.2",
|
||||
"grunt-mocha-test": "^0.13.3",
|
||||
"grunt-newer": "^1.3.0",
|
||||
"grunt-nodemon": "^0.4.2",
|
||||
"grunt-usemin": "^3.1.1",
|
||||
"grunt-wiredep": "^3.0.1",
|
||||
"istanbul": "^0.4.0",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"karma": "~0.13.14",
|
||||
"karma-chrome-launcher": "~0.2.1",
|
||||
"karma-coverage": "~0.5.3",
|
||||
"karma-firefox-launcher": "~0.1.7",
|
||||
"karma-jasmine": "^0.3.6",
|
||||
"karma-jasmine-html-reporter": "^0.1.8",
|
||||
"karma-mocha-reporter": "^1.1.1",
|
||||
"karma-ng-html2js-preprocessor": "^0.2.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"jasmine-core": "^3.4.0",
|
||||
"karma": "^4.2.0",
|
||||
"karma-chrome-launcher": "^3.0.0",
|
||||
"karma-coverage": "^1.1.2",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
"karma-jasmine": "^2.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.2",
|
||||
"karma-mocha-reporter": "^2.2.5",
|
||||
"karma-ng-html2js-preprocessor": "^1.0.0",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"mocha": "^3.1.2",
|
||||
"mocha-lcov-reporter": "^1.0.0",
|
||||
"nightwatch": "^0.9.8",
|
||||
"phantomjs": "^1.9.18",
|
||||
"selenium-server": "^3.0.1",
|
||||
"should": "~7.1.1",
|
||||
"supertest": "~1.2.0",
|
||||
"supertest-session": "~2.0.1",
|
||||
"mocha": "^6.1.4",
|
||||
"mocha-lcov-reporter": "^1.3.0",
|
||||
"nightwatch": "^1.1.13",
|
||||
"phantomjs": "^2.1.7",
|
||||
"selenium-server": "^3.141.59",
|
||||
"should": "^13.2.3",
|
||||
"supertest": "^4.0.2",
|
||||
"supertest-session": "^4.0.0",
|
||||
"wiredep": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
# Apply for all files
|
||||
[*]
|
||||
|
||||
charset = utf-8
|
||||
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
9
selenium/.gitignore
vendored
9
selenium/.gitignore
vendored
@ -1,9 +0,0 @@
|
||||
.DS_Store
|
||||
.idea
|
||||
node_modules
|
||||
npm-debug.log
|
||||
uirecorder.log
|
||||
reports
|
||||
screenshots/**/*.png
|
||||
screenshots/**/*.html
|
||||
screenshots/**/*.json
|
||||
27
selenium/.vscode/launch.json
vendored
27
selenium/.vscode/launch.json
vendored
@ -1,27 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible Node.js debug attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug UIRecorder Local",
|
||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": ["--reporter", "mochawesome-uirecorder", "${file}"],
|
||||
"env": {
|
||||
"webdriver": "127.0.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug UIRecorder Default",
|
||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": ["--reporter", "mochawesome-uirecorder", "${file}"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
UI Recorder test sample project
|
||||
================
|
||||
|
||||
It's a UI Recorder test sample project.
|
||||
|
||||
Save your test code here.
|
||||
|
||||
Get more info: [http://uirecorder.com/](http://uirecorder.com/)
|
||||
|
||||
How to run test case?
|
||||
================
|
||||
|
||||
1. npm install
|
||||
2. source run.sh ( Linux|Mac ) or run.bat ( Windows )
|
||||
|
||||
How to dock jenkins?
|
||||
================
|
||||
|
||||
1. Add commands
|
||||
|
||||
source ./install.sh
|
||||
source ./run.sh
|
||||
|
||||
2. Add reports
|
||||
|
||||
> JUnit: reports/index.xml
|
||||
|
||||
> HTML: reports/
|
||||
@ -1 +0,0 @@
|
||||
Please save common test case here.
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"webdriver": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "4444",
|
||||
"browsers": "chrome"
|
||||
},
|
||||
"vars": {
|
||||
"LoginUsername": "root",
|
||||
"LoginPassword": "root",
|
||||
"ShortTextTitle": "SeleniumShortText",
|
||||
"Profile_NewFirstName": "SeleniumUser_FirstName",
|
||||
"Profile_NewLastName": "SeleniumUser_LastName",
|
||||
"Profile_OldFirstName": "Admin",
|
||||
"Profile_OldLastName": "Account",
|
||||
"Profile_NewInvalidEmail": "SeleniumInvalidEmail"
|
||||
},
|
||||
"recorder": {
|
||||
"pathAttrs": "data-id,data-name,type,data-type,role,data-role,data-value",
|
||||
"attrValueBlack": "",
|
||||
"classValueBlack": "",
|
||||
"hideBeforeExpect": ""
|
||||
}
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
ls ~/nvm || git clone https://github.com/creationix/nvm.git ~/nvm
|
||||
source ~/nvm/nvm.sh
|
||||
nvm install v7.10.0
|
||||
npm install
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "uirecorderTest",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "",
|
||||
"dependencies": {
|
||||
"chai": "3.5.0",
|
||||
"jwebdriver": "2.2.4",
|
||||
"mocha": "3.1.2",
|
||||
"mocha-parallel-tests": "1.2.4",
|
||||
"mochawesome-uirecorder": "1.5.22",
|
||||
"resemblejs-node": "1.0.0",
|
||||
"selenium-standalone": "6.x.x"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"installdriver": "./node_modules/.bin/selenium-standalone install --drivers.firefox.baseURL=http://npm.taobao.org/mirrors/geckodriver --baseURL=http://npm.taobao.org/mirrors/selenium --drivers.chrome.baseURL=http://npm.taobao.org/mirrors/chromedriver --drivers.ie.baseURL=http://npm.taobao.org/mirrors/selenium",
|
||||
"server": "./node_modules/.bin/selenium-standalone start",
|
||||
"test": "./node_modules/.bin/mocha \"*/**/*.spec.js\" --reporter mochawesome-uirecorder --bail",
|
||||
"singletest": "./node_modules/.bin/mocha --reporter mochawesome-uirecorder --bail",
|
||||
"paralleltest": "./node_modules/.bin/mocha-parallel-tests \"*/**/*.spec.js\" --reporter mochawesome-uirecorder --max-parallel 5 --bail"
|
||||
},
|
||||
"author": ""
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
@echo off
|
||||
|
||||
if "%1" neq "" (
|
||||
npm run singletest %1 %2
|
||||
) else (
|
||||
npm run paralleltest
|
||||
)
|
||||
@ -1,5 +0,0 @@
|
||||
if [ "$1" = "" ]; then
|
||||
npm run paralleltest
|
||||
else
|
||||
npm run singletest $1 $2
|
||||
fi
|
||||
@ -1,378 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const chai = require("chai");
|
||||
const should = chai.should();
|
||||
const JWebDriver = require('jwebdriver');
|
||||
chai.use(JWebDriver.chaiSupportChainPromise);
|
||||
const resemble = require('resemblejs-node');
|
||||
resemble.outputSettings({
|
||||
errorType: 'flatDifferenceIntensity'
|
||||
});
|
||||
|
||||
const rootPath = getRootPath();
|
||||
|
||||
module.exports = function(){
|
||||
|
||||
let driver, testVars;
|
||||
|
||||
before(function(){
|
||||
let self = this;
|
||||
driver = self.driver;
|
||||
testVars = self.testVars;
|
||||
});
|
||||
|
||||
it('url: http://localhost:5000', async function(){
|
||||
await driver.url(_(`http://localhost:5000`));
|
||||
});
|
||||
|
||||
it('waitBody: ', async function(){
|
||||
await driver.sleep(500).wait('body', 30000).html().then(function(code){
|
||||
isPageError(code).should.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('insertVar: username ( #username, {{LoginUsername}} )', async function(){
|
||||
await driver.sleep(300).wait('#username', 30000)
|
||||
.val(_(`{{LoginUsername}}`));
|
||||
});
|
||||
|
||||
it('insertVar: password ( #password, {{LoginUsername}} )', async function(){
|
||||
await driver.sleep(300).wait('#password', 30000)
|
||||
.val(_(`{{LoginUsername}}`));
|
||||
});
|
||||
|
||||
it('expect: displayed, .btn-signup, equal, true', async function(){
|
||||
await driver.sleep(300).wait('.btn-signup', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('click: Sign in ( button, 174, 18, 0 )', async function(){
|
||||
await driver.sleep(300).wait('button.btn-signup', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('expect: displayed, div.new-button, equal, true', async function(){
|
||||
await driver.sleep(300).wait('div.new-button', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('expect: displayed, a.dropdown-toggle, equal, true', async function(){
|
||||
await driver.sleep(300).wait('a.dropdown-toggle', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('click: My Settings ( a.dropdown-toggle )', async function(){
|
||||
await driver.sleep(300).wait('a.dropdown-toggle', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('× expect: display, ul.dropdown-menu > li:nth-child(1) > a.ng-binding, equal, true', async function(){
|
||||
await driver.sleep(300).wait('ul.dropdown-menu > li:nth-child(1) > a.ng-binding', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('× expect: display, ul.dropdown-menu > li:nth-child(3) > a.ng-binding, equal, true', async function(){
|
||||
await driver.sleep(300).wait('ul.dropdown-menu > li:nth-child(3) > a.ng-binding', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('click: Edit Profile ( ul.dropdown-menu > li:nth-child(1) > a.ng-binding )', async function(){
|
||||
await driver.sleep(300).wait('ul.dropdown-menu > li:nth-child(1) > a.ng-binding', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('waitBody: ', async function(){
|
||||
await driver.sleep(500).wait('body', 30000).html().then(function(code){
|
||||
isPageError(code).should.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('× insertVar: firstName ( #firstName, {{Profile_NewFirstName}} )', async function(){
|
||||
await driver.sleep(300).wait('#firstName', 30000)
|
||||
.val(_(`{{Profile_NewFirstName}}`));
|
||||
});
|
||||
|
||||
it('× insertVar: lastName ( #lastName, {{Profile_NewLastName}} )', async function(){
|
||||
await driver.sleep(300).wait('#lastName', 30000)
|
||||
.val(_(`{{Profile_NewLastName}}`));
|
||||
});
|
||||
|
||||
it('× click: Save Changes ( button.btn-signup )', async function(){
|
||||
await driver.sleep(300).wait('button.btn-signup', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('× expect: displayed, div.text-success, equal, true', async function(){
|
||||
await driver.sleep(300).wait('div.text-success', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
it('× expect: displayed, .text-danger, notEqual, true', async function(){
|
||||
await driver.sleep(300).wait('.text-danger', 300)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.not.equal(_(true));
|
||||
});
|
||||
|
||||
/*
|
||||
** Revert back to expected names
|
||||
*/
|
||||
|
||||
it('× insertVar: firstName ( #firstName, {{Profile_OldFirstName}} )', async function(){
|
||||
await driver.sleep(300).wait('#firstName', 30000)
|
||||
.val(_(`{{Profile_OldFirstName}}`));
|
||||
});
|
||||
|
||||
it('× insertVar: lastName ( #lastName, {{Profile_OldLastName}} )', async function(){
|
||||
await driver.sleep(300).wait('#lastName', 30000)
|
||||
.val(_(`{{Profile_OldLastName}}`));
|
||||
});
|
||||
|
||||
it('× click: Save Changes ( button.btn-signup, 95, 10, 0 )', async function(){
|
||||
await driver.sleep(300).wait('button.btn-signup', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('× expect: displayed, .text-danger, notEqual, true', async function(){
|
||||
await driver.sleep(300).wait('.text-danger', 300)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.not.equal(_(true));
|
||||
});
|
||||
|
||||
|
||||
//Check that we can't save an invalid email
|
||||
it('× insertVar: email ( #email, {{Profile_NewInvalidEmail}} )', async function(){
|
||||
await driver.sleep(300).wait('#email', 30000)
|
||||
.val(_(`{{Profile_NewInvalidEmail}}`));
|
||||
});
|
||||
|
||||
it('× click: Save Changes ( button.btn-signup )', async function(){
|
||||
await driver.sleep(300).wait('button.btn-signup', 30000)
|
||||
.sleep(300).click();
|
||||
});
|
||||
|
||||
it('url: http://localhost:5000/#!/settings/profile', async function(){
|
||||
await driver.url(_(`http://localhost:5000/#!/settings/profile`));
|
||||
});
|
||||
|
||||
it('waitBody: ', async function(){
|
||||
await driver.sleep(500).wait('body', 30000).html().then(function(code){
|
||||
isPageError(code).should.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('expect: text, #email, notEqual, {{Profile_NewInvalidEmail}}', async function(){
|
||||
await driver.sleep(300).wait('#email', 300)
|
||||
.text()
|
||||
.should.not.be.a('error')
|
||||
.should.not.equal(_(`{{Profile_NewInvalidEmail}}`));
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
** Logout
|
||||
*/
|
||||
it('click: Signout ( //a[text()="Signout"], 31, 31, 0 )', async function(){
|
||||
await driver.sleep(300).wait('//a[text()="Signout"]', 30000)
|
||||
.sleep(300).mouseMove(31, 31).click(0);
|
||||
});
|
||||
|
||||
it('expect: displayed, button.btn-signup, equal, true', async function(){
|
||||
await driver.sleep(300).wait('button.btn-signup', 30000)
|
||||
.displayed()
|
||||
.should.not.be.a('error')
|
||||
.should.equal(_(true));
|
||||
});
|
||||
|
||||
function _(str){
|
||||
if(typeof str === 'string'){
|
||||
return str.replace(/\{\{(.+?)\}\}/g, function(all, key){
|
||||
return testVars[key] || '';
|
||||
});
|
||||
}
|
||||
else{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if(module.parent && /mocha\.js/.test(module.parent.id)){
|
||||
runThisSpec();
|
||||
}
|
||||
|
||||
function runThisSpec(){
|
||||
// read config
|
||||
let webdriver = process.env['webdriver'] || '';
|
||||
let proxy = process.env['wdproxy'] || '';
|
||||
let config = require(rootPath + '/config.json');
|
||||
let webdriverConfig = Object.assign({},config.webdriver);
|
||||
let host = webdriverConfig.host;
|
||||
let port = webdriverConfig.port || 4444;
|
||||
let match = webdriver.match(/([^\:]+)(?:\:(\d+))?/);
|
||||
if(match){
|
||||
host = match[1] || host;
|
||||
port = match[2] || port;
|
||||
}
|
||||
let testVars = config.vars;
|
||||
let browsers = webdriverConfig.browsers;
|
||||
browsers = browsers.replace(/^\s+|\s+$/g, '');
|
||||
delete webdriverConfig.host;
|
||||
delete webdriverConfig.port;
|
||||
delete webdriverConfig.browsers;
|
||||
|
||||
// read hosts
|
||||
let hostsPath = rootPath + '/hosts';
|
||||
let hosts = '';
|
||||
if(fs.existsSync(hostsPath)){
|
||||
hosts = fs.readFileSync(hostsPath).toString();
|
||||
}
|
||||
let specName = path.relative(rootPath, __filename).replace(/\\/g,'/').replace(/\.js$/,'');
|
||||
|
||||
browsers.split(/\s*,\s*/).forEach(function(browserName){
|
||||
let caseName = specName + ' : ' + browserName;
|
||||
|
||||
let browserInfo = browserName.split(' ');
|
||||
browserName = browserInfo[0];
|
||||
let browserVersion = browserInfo[1];
|
||||
|
||||
describe(caseName, function(){
|
||||
|
||||
this.timeout(600000);
|
||||
this.slow(1000);
|
||||
|
||||
let driver;
|
||||
before(function(){
|
||||
let self = this;
|
||||
let driver = new JWebDriver({
|
||||
'host': host,
|
||||
'port': port
|
||||
});
|
||||
let sessionConfig = Object.assign({}, webdriverConfig, {
|
||||
'browserName': browserName,
|
||||
'version': browserVersion,
|
||||
'ie.ensureCleanSession': true,
|
||||
'chromeOptions': {
|
||||
'args': ['--enable-automation']
|
||||
}
|
||||
});
|
||||
if(proxy){
|
||||
sessionConfig.proxy = {
|
||||
'proxyType': 'manual',
|
||||
'httpProxy': proxy,
|
||||
'sslProxy': proxy
|
||||
}
|
||||
}
|
||||
else if(hosts){
|
||||
sessionConfig.hosts = hosts;
|
||||
}
|
||||
self.driver = driver.session(sessionConfig).maximize().config({
|
||||
pageloadTimeout: 30000, // page onload timeout
|
||||
scriptTimeout: 5000, // sync script timeout
|
||||
asyncScriptTimeout: 10000 // async script timeout
|
||||
});
|
||||
self.testVars = testVars;
|
||||
let casePath = path.dirname(caseName);
|
||||
self.screenshotPath = rootPath + '/screenshots/' + casePath;
|
||||
self.diffbasePath = rootPath + '/diffbase/' + casePath;
|
||||
self.caseName = caseName.replace(/.*\//g, '').replace(/\s*[:\.\:\-\s]\s*/g, '_');
|
||||
mkdirs(self.screenshotPath);
|
||||
mkdirs(self.diffbasePath);
|
||||
self.stepId = 0;
|
||||
return self.driver;
|
||||
});
|
||||
|
||||
module.exports();
|
||||
|
||||
beforeEach(function(){
|
||||
let self = this;
|
||||
self.stepId ++;
|
||||
if(self.skipAll){
|
||||
self.skip();
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async function(){
|
||||
let self = this;
|
||||
let currentTest = self.currentTest;
|
||||
let title = currentTest.title;
|
||||
if(currentTest.state === 'failed' && /^(url|waitBody|switchWindow|switchFrame):/.test(title)){
|
||||
self.skipAll = true;
|
||||
}
|
||||
if(!/^(closeWindow):/.test(title)){
|
||||
let filepath = self.screenshotPath + '/' + self.caseName + '_' + self.stepId;
|
||||
let driver = self.driver;
|
||||
try{
|
||||
// catch error when get alert msg
|
||||
await driver.getScreenshot(filepath + '.png');
|
||||
let url = await driver.url();
|
||||
let html = await driver.source();
|
||||
html = '<!--url: '+url+' -->\n' + html;
|
||||
fs.writeFileSync(filepath + '.html', html);
|
||||
let cookies = await driver.cookies();
|
||||
fs.writeFileSync(filepath + '.cookie', JSON.stringify(cookies));
|
||||
}
|
||||
catch(e){}
|
||||
}
|
||||
});
|
||||
|
||||
after(function(){
|
||||
return this.driver.close();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getRootPath(){
|
||||
let rootPath = path.resolve(__dirname);
|
||||
while(rootPath){
|
||||
if(fs.existsSync(rootPath + '/config.json')){
|
||||
break;
|
||||
}
|
||||
rootPath = rootPath.substring(0, rootPath.lastIndexOf(path.sep));
|
||||
}
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
function mkdirs(dirname){
|
||||
if(fs.existsSync(dirname)){
|
||||
return true;
|
||||
}else{
|
||||
if(mkdirs(path.dirname(dirname))){
|
||||
fs.mkdirSync(dirname);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function callSpec(name){
|
||||
try{
|
||||
require(rootPath + '/' + name)();
|
||||
}
|
||||
catch(e){
|
||||
console.log(e)
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function isPageError(code){
|
||||
return code == '' || / jscontent="errorCode" jstcache="\d+"|diagnoseConnectionAndRefresh|dnserror_unavailable_header|id="reportCertificateErrorRetry"|400 Bad Request|403 Forbidden|404 Not Found|500 Internal Server Error|502 Bad Gateway|503 Service Temporarily Unavailable|504 Gateway Time-out/i.test(code);
|
||||
}
|
||||
|
||||
function catchError(error){
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user