From 5158ef8387f4c05ba220b75cbfe29adb4dfaf7fe Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Thu, 3 Mar 2016 11:00:33 +0100 Subject: Add selenium tests --- test/test.js | 164 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 131 insertions(+), 33 deletions(-) mode change 100755 => 100644 test/test.js (limited to 'test') diff --git a/test/test.js b/test/test.js old mode 100755 new mode 100644 index fe6ff61..8b1bcdc --- a/test/test.js +++ b/test/test.js @@ -4,37 +4,127 @@ var execSync = require('child_process').execSync, expect = require('expect.js'), - fs = require('fs'), - os = require('os'), path = require('path'), - superagent = require('superagent'); + fs = require('fs'), + superagent = require('superagent'), + webdriver = require('selenium-webdriver'); + +var by = webdriver.By, + Keys = webdriver.Key, + until = webdriver.until; process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; +if (!process.env.USERNAME || !process.env.PASSWORD) { + console.log('USERNAME and PASSWORD env vars need to be set'); + process.exit(1); +} + describe('Application life cycle test', function () { this.timeout(0); - var LOCATION = 'surfertest'; - var app, testFile = os.tmpdir() + '/surfer-test.txt'; - var username = process.env.USERNAME; - var password = process.env.PASSWORD; + + var firefox = require('selenium-webdriver/firefox'); + var server, browser = new firefox.Driver(); before(function (done) { - if (!process.env.USERNAME) return done(new Error('USERNAME env var not set')); - if (!process.env.PASSWORD) return done(new Error('PASSWORD env var not set')); + var seleniumJar= require('selenium-server-standalone-jar'); + var SeleniumServer = require('selenium-webdriver/remote').SeleniumServer; + server = new SeleniumServer(seleniumJar.path, { port: 4444 }); + server.start(); done(); }); after(function (done) { + browser.quit(); + server.stop(); done(); }); + var LOCATION = 'rctest'; + var TEST_TIMEOUT = 10000; + var TEST_FILE_NAME_0 = 'index.html'; + var TEST_FILE_NAME_1 = 'test.txt'; + var app; + + // tests which are used more than once + function login(done) { + browser.manage().deleteAllCookies(); + browser.get('https://' + app.fqdn + '/_admin'); + + browser.wait(until.elementLocated(by.id('inputUsername')), TEST_TIMEOUT).then(function () { + browser.wait(until.elementIsVisible(browser.findElement(by.id('inputUsername'))), TEST_TIMEOUT).then(function () { + browser.findElement(by.id('inputUsername')).sendKeys(process.env.USERNAME); + browser.findElement(by.id('inputPassword')).sendKeys(process.env.PASSWORD); + browser.findElement(by.id('loginForm')).submit(); + + browser.wait(until.elementIsVisible(browser.findElement(by.id('logoutButton'))), TEST_TIMEOUT).then(function () { + done(); + }); + }); + }); + } + + function logout(done) { + browser.get('https://' + app.fqdn + '/_admin'); + + browser.wait(until.elementLocated(by.id('logoutButton')), TEST_TIMEOUT).then(function () { + browser.wait(until.elementIsVisible(browser.findElement(by.id('logoutButton'))), TEST_TIMEOUT).then(function () { + browser.findElement(by.id('logoutButton')).click(); + + browser.wait(until.elementIsVisible(browser.findElement(by.id('inputPassword'))), TEST_TIMEOUT).then(function () { + done(); + }); + }); + }); + } + + function checkFileIsListed(name, done) { + browser.get('https://' + app.fqdn + '/_admin'); + + browser.wait(until.elementLocated(by.xpath('//*[text()="' + name + '"]')), TEST_TIMEOUT).then(function () { + done(); + }); + } + + function checkFileIsPresent(done) { + browser.get('https://' + app.fqdn + '/' + TEST_FILE_NAME_0); + + browser.wait(until.elementLocated(by.xpath('//*[text()="test"]')), TEST_TIMEOUT).then(function () { + done(); + }); + } + + function checkIndexFileIsServedUp(done) { + browser.get('https://' + app.fqdn); + + browser.wait(until.elementLocated(by.xpath('//*[text()="test"]')), TEST_TIMEOUT).then(function () { + done(); + }); + } + + function checkFileIsGone(name, done) { + superagent.get('https://' + app.fqdn + '/' + name).end(function (error, result) { + expect(error).to.be.an('object'); + expect(result.statusCode).to.equal(404); + done(); + }); + } + + function uploadFile(name, done) { + // File upload can't be tested with selenium, since the file input is not visible and thus can't be interacted with :-( + + fs.writeFileSync(process.env.HOME + '/.surfer.json', JSON.stringify({ server: 'https://' + app.fqdn, username: process.env.USERNAME, password: process.env.PASSWORD })); + execSync(path.join(__dirname, '/../cli/surfer.js') + ' put ' + path.join(__dirname, name), { stdio: 'inherit' } ); + done(); + } + it('build app', function () { execSync('cloudron build', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); }); it('install app', function () { - execSync('cloudron install --new --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); + execSync('cloudron install --new --wait --location ' + LOCATION, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); }); it('can get app information', function () { @@ -45,25 +135,20 @@ describe('Application life cycle test', function () { expect(app).to.be.an('object'); }); - it('can get the main page', function (done) { - superagent.get('https://' + app.fqdn).end(function (error, result) { - expect(error).to.be(null); - expect(result.status).to.eql(200); - - done(); - }); - }); - - it('can login using cli', function () { - // execSync(__dirname + '/../cli/surfer.js login https://' + app.fqdn, { input: username + '\n' + password + '\n' }); - fs.writeFileSync(process.env.HOME + '/.surfer.json', JSON.stringify({ server: 'https://' + app.fqdn, username: username, password: password })); - }); - - it('can upload file', function (done) { - fs.writeFileSync(testFile, 'surfer'); - execSync(__dirname + '/../cli/surfer.js put ' + testFile, { stdio: 'inherit' } ); + it('can login', login); + it('can upload file', uploadFile.bind(null, TEST_FILE_NAME_0)); + it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0)); + it('file is served up', checkFileIsPresent); + it('file is served up', checkIndexFileIsServedUp); + it('can upload second file', uploadFile.bind(null, TEST_FILE_NAME_1)); + it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_1)); + it('can delete second file with cli', function (done) { + fs.writeFileSync(process.env.HOME + '/.surfer.json', JSON.stringify({ server: 'https://' + app.fqdn, username: process.env.USERNAME, password: process.env.PASSWORD })); + execSync(path.join(__dirname, '/../cli/surfer.js') + ' del ' + TEST_FILE_NAME_1, { stdio: 'inherit' } ); done(); }); + it('second file is gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1)); + it('can logout', logout); it('backup app', function () { execSync('cloudron backup --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); @@ -73,15 +158,28 @@ describe('Application life cycle test', function () { execSync('cloudron restore --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); }); - it('can get the uploaded file', function (done) { - var contents = execSync(__dirname + '/../cli/surfer.js get surfer-test.txt').toString('utf8'); - expect(contents).to.be('surfer'); - done(); + it('can login', login); + it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0)); + it('file is served up', checkFileIsPresent); + it('file is served up', checkIndexFileIsServedUp); + it('second file is still gone', checkFileIsGone.bind(null, TEST_FILE_NAME_1)); + it('can logout', logout); + + it('move to different location', function () { + browser.manage().deleteAllCookies(); + execSync('cloudron install --location ' + LOCATION + '2', { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); + var inspect = JSON.parse(execSync('cloudron inspect')); + app = inspect.apps.filter(function (a) { return a.location === LOCATION + '2'; })[0]; + expect(app).to.be.an('object'); }); + it('can login', login); + it('file is listed', checkFileIsListed.bind(null, TEST_FILE_NAME_0)); + it('file is served up', checkFileIsPresent); + it('file is served up', checkIndexFileIsServedUp); + it('can logout', logout); + it('uninstall app', function () { execSync('cloudron uninstall --app ' + app.id, { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }); - fs.unlinkSync(process.env.HOME + '/.surfer.json'); - fs.unlinkSync(testFile); }); }); -- cgit v1.2.3