Repository: couchdb-fauxton Updated Branches: refs/heads/master 235d54451 -> 651cd1333
Add Nightwatch functional browser tests to test Fauxton This commit adds a basis for using Nightwatch's functional browser testing environment to test Fauxton. Closes COUCHDB-2369 Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/651cd133 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/651cd133 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/651cd133 Branch: refs/heads/master Commit: 651cd13332809d7aefbcfe35460fbfc3cf71c26e Parents: 235d544 Author: Michelle Phung <[email protected]> Authored: Wed Oct 22 17:49:10 2014 -0400 Committer: Robert Kowalski <[email protected]> Committed: Tue Nov 18 16:24:49 2014 +0100 ---------------------------------------------------------------------- .gitignore | 4 + Gruntfile.js | 27 ++++- .../tests/nightwatch/createsDatabase.js | 29 ++++++ .../databases/tests/nightwatch/createsView.js | 51 ++++++++++ .../tests/nightwatch/deletesDatabase.js | 29 ++++++ .../tests/nightwatch/createsDocument.js | 38 +++++++ .../tests/nightwatch/deletesDocument.js | 30 ++++++ package.json | 42 ++++---- readme.md | 24 +++++ tasks/helper.js | 35 ++++++- .../custom-commands/createDatabase.js | 28 ++++++ .../custom-commands/createDocument.js | 29 ++++++ .../custom-commands/deleteDatabase.js | 27 +++++ .../custom-commands/loginToGUI.js | 17 ++++ .../custom-commands/populateDatabase.js | 36 +++++++ test/nightwatch_tests/helpers/helpers.js | 43 ++++++++ test/nightwatch_tests/nightwatch.json | 100 +++++++++++++++++++ test/nightwatch_tests/nightwatch_README.md | 59 +++++++++++ test/nightwatch_tests/selenium/.gitkeep | 0 19 files changed, 628 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index 71dcf22..7c98c92 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,7 @@ settings.json* !assets/js/plugins/zeroclipboard/ZeroClipboard.swf test/test.config.js app/initialize.js +test/nightwatch_tests/reports/* +test/nightwatch_tests/selenium/* +!test/nightwatch_tests/selenium/.gitkeep +.DS_Store http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/Gruntfile.js ---------------------------------------------------------------------- diff --git a/Gruntfile.js b/Gruntfile.js index f6d2347..be6b2dc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -15,6 +15,9 @@ // configuration file, which you can learn more about here: // https://github.com/cowboy/grunt/blob/master/docs/configuring.md +/*jslint node: true */ +"use strict"; + module.exports = function(grunt) { var helper = require('./tasks/helper').init(grunt), _ = grunt.util._, @@ -394,8 +397,20 @@ module.exports = function(grunt) { mocha_phantomjs: { all: ['test/runner.html'] - } + }, + exec: { + check_selenium: helper.check_selenium, + check_chrome_driver : helper.check_chrome_driver, + start_nightWatch: { + command: __dirname + '/node_modules/nightwatch/bin/nightwatch' + + ' -e chrome -c ' + __dirname + '/test/nightwatch_tests/' + 'nightwatch.json' + } + }, + + selenium_start: { + options: { port: 4444 } + } }); // on watch events configure jshint:all to only run on changed file @@ -440,6 +455,9 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-mocha-phantomjs'); + //Selenium Server + grunt.loadNpmTasks('grunt-selenium-webdriver'); + /* * Default task */ @@ -488,4 +506,11 @@ module.exports = function(grunt) { grunt.registerTask('couchapp_install', ['rmcouchdb:fauxton', 'mkcouchdb:fauxton', 'couchapp:fauxton']); // setup and install fauxton as couchapp grunt.registerTask('couchapp_deploy', ['couchapp_setup', 'couchapp_install']); + + /* + * Nightwatch functional testing + */ + //Start Nightwatch test from terminal, using: $ grunt nightwatch + grunt.registerTask('nightwatch', [ 'exec:check_selenium', 'selenium_start', 'exec:check_chrome_driver', 'exec:start_nightWatch']); + }; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/app/addons/databases/tests/nightwatch/createsDatabase.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/tests/nightwatch/createsDatabase.js b/app/addons/databases/tests/nightwatch/createsDatabase.js new file mode 100644 index 0000000..3cb898f --- /dev/null +++ b/app/addons/databases/tests/nightwatch/createsDatabase.js @@ -0,0 +1,29 @@ +module.exports = { + 'Creates a Database' : function (client) { + var waitTime = 10000, + newDatabaseName = client.globals.testDatabaseName, + baseUrl = client.globals.baseUrl; + + client + .loginToGUI() + .deleteDatabase(newDatabaseName) //need to delete the automatic database 'fauxton-selenium-tests' that has been set up before each test + .url(baseUrl) + .waitForElementPresent('#add-new-database', waitTime, false) + .click('#add-new-database') + .pause(1000) + .waitForElementVisible('#js-new-database-name', waitTime, false) + .setValue('#js-new-database-name', [newDatabaseName]) + .click('#js-create-database') + .waitForElementVisible('#global-notifications div.alert-success', waitTime, false) + .url(baseUrl+'/_all_dbs') + .waitForElementVisible('html', waitTime, false) + .getText('html', function (result) { + var data = result.value, + createdDatabaseIsPresent = data.indexOf(newDatabaseName); + + this.verify.ok(createdDatabaseIsPresent > 0, + 'Checking if new database shows up in _all_dbs.'); + }) + .end(); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/app/addons/databases/tests/nightwatch/createsView.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/tests/nightwatch/createsView.js b/app/addons/databases/tests/nightwatch/createsView.js new file mode 100644 index 0000000..96d77ba --- /dev/null +++ b/app/addons/databases/tests/nightwatch/createsView.js @@ -0,0 +1,51 @@ +module.exports = { + 'Creates a View' : function (client) { + /*jshint multistr: true */ + var waitTime = 10000, + newDatabaseName = client.globals.testDatabaseName, + newDocumentName = 'create_view_doc', + baseUrl = client.globals.baseUrl; + + var indexFunctionString = function (parity) { + return 'function (doc) {' + + ' if (doc.number%2 === '+parity+'){' + + ' emit(doc._id, doc.number);' + + ' }' + + '}'; + }; + + client + .loginToGUI() + .populateDatabase(newDatabaseName) + .url(baseUrl+'/#/database/'+newDatabaseName+'/_all_docs') + .waitForElementPresent('#new-design-docs-button', waitTime, false) + .click('#new-design-docs-button') + .click('#new-design-docs-button a[href="#/database/'+newDatabaseName+'/new_view"]') + .waitForElementPresent('#new-ddoc', waitTime, false) + .setValue('#new-ddoc','test_design_doc') + .clearValue('#index-name') + .setValue('#index-name','even_ids') + .execute('\ + var editor = ace.edit("map-function");\ + editor.getSession().setValue("'+indexFunctionString(0)+'");\ + ') + .click('button.btn.btn-success.save') + .waitForElementPresent('#test_design_doc_even_ids', waitTime, false) + .click('#test_design_doc_even_ids') + .waitForElementPresent('#nav-header-test_design_doc', waitTime, false) + .click('#nav-header-test_design_doc .dropdown-toggle.icon.fonticon-plus-circled') + .waitForElementPresent('#nav-header-test_design_doc', waitTime, false) + .click('#nav-header-test_design_doc a[href="#/database/'+newDatabaseName+'/new_view/test_design_doc"]') + .verify.valueContains('#index-name','newView') + .clearValue('#index-name') + .setValue('#index-name','odd_ids') + .execute('\ + var editor = ace.edit("map-function");\ + editor.getSession().setValue("'+indexFunctionString(1)+'");\ + ') + .click('button.btn.btn-success.save') + .waitForElementPresent('#test_design_doc_even_ids', waitTime, false) + .waitForElementPresent('#test_design_doc_odd_ids', waitTime, false) + .end(); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/app/addons/databases/tests/nightwatch/deletesDatabase.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/tests/nightwatch/deletesDatabase.js b/app/addons/databases/tests/nightwatch/deletesDatabase.js new file mode 100644 index 0000000..d97191f --- /dev/null +++ b/app/addons/databases/tests/nightwatch/deletesDatabase.js @@ -0,0 +1,29 @@ +module.exports = { + 'Deletes a database': function (client) { + var waitTime = 8000, + newDatabaseName = client.globals.testDatabaseName, + baseUrl = client.globals.baseUrl; + + client + .loginToGUI() + .url(baseUrl+'/#/database/'+newDatabaseName+'/_all_docs') + .waitForElementPresent('#header-dropdown-menu a.dropdown-toggle.icon.fonticon-cog', waitTime, false) + .execute('$("#header-dropdown-menu a.dropdown-toggle.icon.fonticon-cog").click();') + .waitForElementPresent('#header-dropdown-menu .fonticon-trash', waitTime, false) + .click('#header-dropdown-menu .fonticon-trash') + .waitForElementVisible('#db_name', waitTime, false) + .click('#db_name') + .setValue('input#db_name', [newDatabaseName, client.Keys.ENTER] ) + .waitForElementVisible('#global-notifications .alert.alert-info', waitTime, false) + .url(baseUrl+'/_all_dbs') + .waitForElementPresent('pre',waitTime, false) + .getText('body', function (result) { + var data = result.value, + createdDatabaseIsNotPresent = data.indexOf(newDatabaseName); + + this.verify.ok(createdDatabaseIsNotPresent === -1, + 'Checking if new database no longer shows up in _all_dbs.'); + }) + .end(); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/app/addons/documents/tests/nightwatch/createsDocument.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/nightwatch/createsDocument.js b/app/addons/documents/tests/nightwatch/createsDocument.js new file mode 100644 index 0000000..7de99b5 --- /dev/null +++ b/app/addons/documents/tests/nightwatch/createsDocument.js @@ -0,0 +1,38 @@ +module.exports = { + 'Creates a document' : function (client) { + /*jshint multistr: true */ + var waitTime = 10000, + newDatabaseName = client.globals.testDatabaseName, + newDocumentName = 'create_doc_document', + baseUrl = client.globals.baseUrl; + + client + .loginToGUI() + .url(baseUrl+'/#/database/'+newDatabaseName+'/_all_docs') + .waitForElementPresent('#new-all-docs-button', waitTime, false) + .click('#new-all-docs-button') + .waitForElementPresent('#new-all-docs-button a[href="#/database/'+newDatabaseName+'/new"]', waitTime, false) + .click('#new-all-docs-button a[href="#/database/'+newDatabaseName+'/new"]') + .waitForElementPresent('#doc', waitTime, false) + .verify.urlEquals(baseUrl+'/#/database/'+ newDatabaseName+'/new') + .execute('\ + var editor = ace.edit("editor-container");\ + editor.gotoLine(2,10);\ + editor.removeWordRight();\ + editor.insert("'+newDocumentName+'");\ + ') + .waitForElementPresent('#doc button.save-doc.btn.btn-success.save', waitTime, false) + .click('#doc button.save-doc.btn.btn-success.save') + .pause(1000) + .url(baseUrl+'/'+newDatabaseName+'/_all_docs') + .waitForElementPresent('body', waitTime, false) + .getText('body', function (result) { + var data = result.value, + createdDocIsPresent = data.indexOf(newDocumentName); + + this.verify.ok(createdDocIsPresent > 0, + 'Checking if new document shows up in _all_docs.'); + }) + .end(); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/app/addons/documents/tests/nightwatch/deletesDocument.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/nightwatch/deletesDocument.js b/app/addons/documents/tests/nightwatch/deletesDocument.js new file mode 100644 index 0000000..4214022 --- /dev/null +++ b/app/addons/documents/tests/nightwatch/deletesDocument.js @@ -0,0 +1,30 @@ +module.exports = { + 'Deletes a document': function (client) { + var waitTime = 10000, + newDatabaseName = client.globals.testDatabaseName, + newDocumentName = 'delete_doc_doc', + baseUrl = client.globals.baseUrl; + + client + .loginToGUI() + .createDocument(newDocumentName, newDatabaseName) + .url(baseUrl) + .waitForElementPresent('#dashboard-content a[href="#/database/'+newDatabaseName+'/_all_docs"]', waitTime, false) + .pause(1000) + .click('#dashboard-content a[href="#/database/'+newDatabaseName+'/_all_docs"]') + .waitForElementPresent('[data-id="'+newDocumentName+'"] .btn.btn-small.btn-danger.delete', waitTime, false) + .execute('$("[data-id=\''+newDocumentName+'\'] .btn.btn-small.btn-danger.delete").click();') + .acceptAlert() + .waitForElementVisible('#global-notifications .alert.alert-info', waitTime, false) + .url(baseUrl+'/'+newDatabaseName+'/_all_docs') + .waitForElementPresent('pre', waitTime, false) + .getText('pre',function (result) { + var data = result.value, + createdDocumentNotPresent = data.indexOf(newDocumentName); + + this.verify.ok(createdDocumentNotPresent === -1, + 'Checking if new document no longer shows up in _all_docs.'); + }) + .end(); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/package.json ---------------------------------------------------------------------- diff --git a/package.json b/package.json index 814dbd0..410fef5 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,24 @@ "test": "test" }, "dependencies": { + }, + "scripts": { + "test": "grunt test", + "couchdebug": "grunt couchdebug", + "couchdb": "grunt couchdb" + }, + "repository": { + "type": "git", + "url": "https://git-wip-us.apache.org/repos/asf/couchdb.git" + }, + "keywords": [ + "couchdb", + "futon", + "fauxton" + ], + "author": "", + "license": "Apache V2", + "devDependencies": { "async": "~0.2.6", "grunt": "~0.4.1", "grunt-cli": "~0.1.6", @@ -29,22 +47,10 @@ "urls": "~0.0.3", "http-proxy": "~1.1.4", "send": "~0.1.1", - "grunt-mocha-phantomjs": "~0.3.0" - }, - "scripts": { - "test": "grunt test", - "couchdebug": "grunt couchdebug", - "couchdb": "grunt couchdb" - }, - "repository": { - "type": "git", - "url": "https://git-wip-us.apache.org/repos/asf/couchdb.git" - }, - "keywords": [ - "couchdb", - "futon", - "fauxton" - ], - "author": "", - "license": "Apache V2" + "grunt-mocha-phantomjs": "~0.3.0", + "nightwatch": "~0.5.33", + "nano": "~5.12.0", + "grunt-chmod": "^1.0.3", + "grunt-selenium-webdriver": "^0.2.431" + } } http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/readme.md ---------------------------------------------------------------------- diff --git a/readme.md b/readme.md index b95678f..95300ee 100644 --- a/readme.md +++ b/readme.md @@ -67,6 +67,30 @@ Browser: make sure the dev server is running, and enter the path (not URL) to yo Refreshing the URL will re-run the tests via PhantomJS and in the browser. +#### Nightwatch Functional Browser Tests + +There is a bit of setup involved before you are able to run the Nightwatch tests. + +In your CouchDB admin accounts, add a user: + +> user: tester +password: testerpass + +Then on the command line: + + npm install + +Start fauxton with + + grunt dev + +And to run the tests (in another terminal tab): + + grunt nightwatch + + + + ### To Deploy Fauxton To deploy to your local [CouchDB instance](http://localhost:5984/fauxton/_design/fauxton/index.html): http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/tasks/helper.js ---------------------------------------------------------------------- diff --git a/tasks/helper.js b/tasks/helper.js index 4b66e55..8da3b6b 100644 --- a/tasks/helper.js +++ b/tasks/helper.js @@ -14,7 +14,8 @@ var fs = require('fs'), path = require('path'); exports.init = function(grunt) { - var _ = grunt.util._; + var _ = grunt.util._, + platform = process.platform; return { readSettingsFile: function () { @@ -40,6 +41,38 @@ exports.init = function(grunt) { } return files }, defaults); + }, + + check_selenium: { + command: 'test -s ./test/nightwatch_tests/selenium/selenium-server-standalone-2.43.1.jar || curl -o ./test/nightwatch_tests/selenium/selenium-server-standalone-2.43.1.jar http://selenium-release.storage.googleapis.com/2.43/selenium-server-standalone-2.43.1.jar' + }, + + check_chrome_driver: { + command: function () { + + var type; + + switch (platform) { + case 'darwin': + type = 'mac32'; + break; + + case 'win32': + type = 'win32'; + break; + + case 'linux': + var os = require('os'); + if (os.arch() === 'x64') { + type = 'linux64'; + }else{ + type = 'linux32'; + } + break; + } + + return 'test -s ./test/nightwatch_tests/selenium/chromedriver || (curl -o ./test/nightwatch_tests/selenium/chromedriver_'+type+'.zip http://chromedriver.storage.googleapis.com/2.9/chromedriver_'+type+'.zip && open ./test/nightwatch_tests/selenium/chromedriver_'+type+'.zip)'; + } } }; }; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/custom-commands/createDatabase.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/custom-commands/createDatabase.js b/test/nightwatch_tests/custom-commands/createDatabase.js new file mode 100644 index 0000000..63004d9 --- /dev/null +++ b/test/nightwatch_tests/custom-commands/createDatabase.js @@ -0,0 +1,28 @@ +var util = require('util'), + events = require('events'), + helpers = require('../helpers/helpers.js'); + +function CreateDatabase () { + events.EventEmitter.call(this); +} + +// inherit from node's event emitter +util.inherits(CreateDatabase, events.EventEmitter); + +CreateDatabase.prototype.command = function (databaseName) { + var that = this, + nano = helpers.getNanoInstance(); + + nano.db.create(databaseName, function (err, body, header) { + if (err) { + console.log('Error in nano CreateDatabase Function: '+ databaseName, err.message); + + } + console.log('nano - created a database: ' + databaseName); + // emit the complete event + that.emit('complete'); + }); + return this; +}; + +module.exports = CreateDatabase; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/custom-commands/createDocument.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/custom-commands/createDocument.js b/test/nightwatch_tests/custom-commands/createDocument.js new file mode 100644 index 0000000..388dc5a --- /dev/null +++ b/test/nightwatch_tests/custom-commands/createDocument.js @@ -0,0 +1,29 @@ +var util = require('util'), + events = require('events'), + helpers = require('../helpers/helpers.js'); + +function CreateDocument () { + events.EventEmitter.call(this); +} + +// inherit from node's event emitter +util.inherits(CreateDocument, events.EventEmitter); + +CreateDocument.prototype.command = function (documentName, databaseName) { + var that = this, + nano = helpers.getNanoInstance(), + database = nano.use(databaseName); + + database.insert({ dummyKey: "testingValue" }, documentName, function (err, body, header) { + + if (err) { + console.log('Error in nano CreateDocument Function: '+documentName+', in database: '+databaseName, err.message); + } + console.log('nano - created a doc: '+documentName+', in database: '+databaseName); + that.emit('complete'); + }); + + return this; +}; + +module.exports = CreateDocument; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/custom-commands/deleteDatabase.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/custom-commands/deleteDatabase.js b/test/nightwatch_tests/custom-commands/deleteDatabase.js new file mode 100644 index 0000000..298ab41 --- /dev/null +++ b/test/nightwatch_tests/custom-commands/deleteDatabase.js @@ -0,0 +1,27 @@ +var util = require('util'), + events = require('events'), + helpers = require('../helpers/helpers.js'); + +function DeleteDatabase () { + events.EventEmitter.call(this); +} + +util.inherits(DeleteDatabase, events.EventEmitter); + +DeleteDatabase.prototype.command = function (databaseName) { + var that = this, + nano = helpers.getNanoInstance(); + + nano.db.destroy(databaseName, function (err, body, header) { + if (err) { + console.log('Error in nano DeleteDatabase Function: '+ databaseName, err.message); + } + console.log('nano - database: '+databaseName+' is deleted: ', body); + // emit the complete event + that.emit('complete'); + }); + + return this; +}; + +module.exports = DeleteDatabase; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/custom-commands/loginToGUI.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/custom-commands/loginToGUI.js b/test/nightwatch_tests/custom-commands/loginToGUI.js new file mode 100644 index 0000000..fb9ac78 --- /dev/null +++ b/test/nightwatch_tests/custom-commands/loginToGUI.js @@ -0,0 +1,17 @@ +exports.command = function () { + + var client = this, + baseUrl = client.globals.baseUrl; + + client + .url(baseUrl+'/#login') + .waitForElementPresent('a[href="#login"]', 8000, false) + .click('a[href="#login"]') + .waitForElementPresent('#username', 8000, false) + .setValue('#username', ['tester']) + .setValue('#password', ['testerpass', client.Keys.ENTER]) + .execute('$("#global-notifications button.close").click();') + .waitForElementPresent('#jump-to-db', 8000, false); + + return this; +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/custom-commands/populateDatabase.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/custom-commands/populateDatabase.js b/test/nightwatch_tests/custom-commands/populateDatabase.js new file mode 100644 index 0000000..ea1cbf8 --- /dev/null +++ b/test/nightwatch_tests/custom-commands/populateDatabase.js @@ -0,0 +1,36 @@ +var util = require('util'), + events = require('events'), + helpers = require('../helpers/helpers.js'), + async = require('async'); + +function PopulateDatabase () { + events.EventEmitter.call(this); +} + +util.inherits(PopulateDatabase, events.EventEmitter); + +PopulateDatabase.prototype.command = function (databaseName) { + var that = this, + nano = helpers.getNanoInstance(), + database = nano.use(databaseName), + i = 0; + + async.whilst( + function () { return i < 20; }, + function (cb) { + i++; + var document_id = 'document_ '+ i; + database.insert({ number: i }, document_id, cb); + }, + function (err) { + if (err) { + console.log('Error in nano populateDatabase Function: ' + + document_id + ', in database: ' + databaseName, err.message); + } + that.emit('complete'); + } + ); + return this; +}; + +module.exports = PopulateDatabase; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/helpers/helpers.js ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/helpers/helpers.js b/test/nightwatch_tests/helpers/helpers.js new file mode 100644 index 0000000..388d5f4 --- /dev/null +++ b/test/nightwatch_tests/helpers/helpers.js @@ -0,0 +1,43 @@ +module.exports = { + username : 'tester', + password : 'testerpass', + baseUrl: 'http://localhost:8000', + testDatabaseName : 'fauxton-selenium-tests', + getNanoInstance : function () { + var nano = require('nano')('http://'+this.username+':'+this.password+'@localhost:5984'); + return nano; + }, + beforeEach: function (done) { + var nano = module.exports.getNanoInstance(), + database = module.exports.testDatabaseName; + + console.log("nano setting up database"); + // clean up the database we created previously + nano.db.destroy(database, function (err, body, header) { + if (err) { + if (err.message != 'Database does not exist.' && err.message != 'missing') { + console.log('Error in setting up '+database, err.message); + } + } + // create a new database + nano.db.create(database, function (err, body, header) { + if (err) { + console.log('Error in setting up '+database, err.message); + } + done(); + }); + }); + }, + afterEach: function (done) { + var nano = module.exports.getNanoInstance(), + database = module.exports.testDatabaseName; + + console.log('nano cleaning up'); + nano.db.destroy(database, function (err, header, body) { + if (err) { + console.log('Error in cleaning up '+database, err.message); + } + done(); + }); + } +}; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/nightwatch.json ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/nightwatch.json b/test/nightwatch_tests/nightwatch.json new file mode 100644 index 0000000..2ad9441 --- /dev/null +++ b/test/nightwatch_tests/nightwatch.json @@ -0,0 +1,100 @@ +{ + "src_folders" : [ + "./app/addons/databases/tests/nightwatch", + "./app/addons/documents/tests/nightwatch" + ], + "output_folder" : "./test/nightwatch_tests/reports", + "custom_commands_path" : "./test/nightwatch_tests/custom-commands", + "custom_assertions_path" : "", + "globals_path" : "./test/nightwatch_tests/helpers/helpers.js", + "live_output" : false, + + "selenium" : { + "start_process" : false, + "server_path" : "", + "log_path" : "", + "host" : "127.0.0.1", + "port" : 4444, + "cli_args" : { + "webdriver.chrome.driver" : "", + "webdriver.ie.driver" : "", + "webdriver.firefox.profile" : "" + } + }, + + "test_settings" : { + "default" : { + "launch_url" : "http://localhost", + "selenium_host" : "127.0.0.1", + "selenium_port" : 4444, + "silent" : true, + "disable_colors": false, + "screenshots" : { + "enabled" : false, + "path" : "" + }, + "desiredCapabilities" : { + "browserName" : "firefox", + "javascriptEnabled" : true, + "acceptSslCerts" : true + } + }, + + "chrome" : { + "desiredCapabilities" : { + "browserName" : "chrome", + "javascriptEnabled" : true, + "acceptSslCerts" : true + } + }, + + + "saucelabs" : { + "selenium_host" : "ondemand.saucelabs.com", + "selenium_port" : 80, + "username" : "${SAUCE_USERNAME}", + "access_key" : "${SAUCE_ACCESS_KEY}", + "use_ssl" : false, + "silent" : true, + "output" : true, + "screenshots" : { + "enabled" : false, + "path" : "" + }, + "desiredCapabilities": { + "name" : "test-example", + "browserName": "firefox" + }, + "globals" : { + "myGlobal" : "some_sauce_global" + }, + "selenium" : { + "start_process" : false + } + }, + + "phantomjs" : { + "desiredCapabilities" : { + "browserName" : "phantomjs", + "javascriptEnabled" : true, + "acceptSslCerts" : true, + "phantomjs.binary.path" : "/path/to/phantomjs" + } + }, + + "browserstack" : { + "selenium" : { + "start_process" : false + }, + "selenium_host" : "hub.browserstack.com", + "selenium_port" : 80, + "silent" : true, + "desiredCapabilities": { + "name" : "test-example", + "browserName": "firefox", + "browserstack.user" : "...", + "browserstack.key" : "..." + } + } + } +} http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/nightwatch_README.md ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/nightwatch_README.md b/test/nightwatch_tests/nightwatch_README.md new file mode 100644 index 0000000..092a094 --- /dev/null +++ b/test/nightwatch_tests/nightwatch_README.md @@ -0,0 +1,59 @@ +## Nightwatch Functional Browser Test + +Hello. + +[Nightwatch Homepage](http://nightwatchjs.org/) +[Nightwatch GitHub Repo](https://github.com/beatfactor/nightwatch) + +There are several nightwatch tests already written for Fauxton. + +Before running the browser tests, you will need to add a user to your CouchDB admin accounts: + +> user: tester +password: testerpass + +Then, to run the the test: + + $ npm install + $ grunt nightwatch + + +##Writing Tests +You can contribute by writing tests for Fauxton as well. + +Please take a look at the existing examples in the `app/addons/documents/tests` or `app/addons/databases/tests` folders. + +Below are a few caveats to writing tests. + +1. When you write a new test, if the component you are testing doesn't have any nightwatch tests already, you will need to create a folder for it, and add it's file path to the list of test folders in `tests/nightwatch_test/nightwatch.json`. +1. Before each test is run, a database called'fauxton-selenium-test' is created, then deleted after each test. +2. Use `.verify()` instead of `.assert()` in your tests. This will allow the tests to continue, even if the browser has failed, and will not exit or skip subsequent tests. +3. `.waitForElementNotPresent()`, `.waitForElementNotVisible()`, `.waitForElementPresent()`, `.waitForElementVisible()`, will exit testing by default if the Element is not found. There is a third argument, 'abortOnFailure', if you set this to 'false', the rest of the tests will continue even if this assertion fails. +4. Sometimes `.click()` doesn't work reliably (most likely if the element you are clicking on doesn't have an individual ID selector). You can use jquery to simulate a click by using `.execute($("#CSS Selector.HERE").click();)` +5. The function `.pause(time)` is sometimes necessary, although we have tried to avoid excessive use of a hard coded pausing. Instead try and make use of the `.waitForElement` functions instead of `.pause(time)`. + +##Nightwatch Files in Fauxton +There are several Nightwatch related files spread out in the couchdb-fauxton folder. + +1. Individual browser tests are kept in + + couchdb-fauxton/app/addons/[component]/test/nightwatch + + where [component] is the area you are testing. For example, there is an individual test located in: + + couchdb-fauxton/app/addons/documents/tests/nightwatch/createsDocument.js + +2. Custom Commands, Global helper functions, and the Configuration are kept in + + couchdb-fauxton/tests/nightwatch_tests + + The configuration file is `nightwatch.json`. + Global helper functions are in `helpers/helpers.js`. + Custom commands are `custom-commands/functionName.js`. + - The custom command name is the name of the file itself, and it needs to follow either the `loginToGUI.js` pattern, or the `createDatabase.js` pattern (for async commands). + + Selenium related files are kept in the `selenium` folder + +3. Node + + The folder `node_modules/nightwatch` contains the program files. You will not need to edit these files, but there are some provided examples in there to look at. http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/651cd133/test/nightwatch_tests/selenium/.gitkeep ---------------------------------------------------------------------- diff --git a/test/nightwatch_tests/selenium/.gitkeep b/test/nightwatch_tests/selenium/.gitkeep new file mode 100644 index 0000000..e69de29
