From 50ae19cc5cbd6e1f8875100a7a7c9701da98865c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=B6hm?= Date: Fri, 29 Aug 2014 12:16:00 +0200 Subject: [PATCH] add bunch of acceptance tests --- tests/acceptance/package.json | 19 ++ tests/acceptance/protractor_conf.js | 102 ++++++ tests/acceptance/readme.md | 35 ++ tests/acceptance/screenshots/.gitignore | 3 + tests/acceptance/tests/files/folder_spec.js | 86 +++++ tests/acceptance/tests/files/rename_spec.js | 140 ++++++++ tests/acceptance/tests/files/restore_spec.js | 151 +++++++++ tests/acceptance/tests/files/search_spec.js | 26 ++ tests/acceptance/tests/files/sort_spec.js | 35 ++ tests/acceptance/tests/files/txt_spec.js | 36 ++ tests/acceptance/tests/helper/page.js | 14 + tests/acceptance/tests/helper/screenshot.js | 16 + .../acceptance/tests/install/install_spec.js | 63 ++++ .../tests/login/authentication_spec.js | 85 +++++ .../tests/login/change_password_spec.js | 104 ++++++ tests/acceptance/tests/login/new_user_spec.js | 43 +++ .../tests/login/username_cases_spec.js | 88 +++++ tests/acceptance/tests/pages/files.page.js | 317 ++++++++++++++++++ .../tests/pages/firstRunWizard.page.js | 36 ++ tests/acceptance/tests/pages/install.page.js | 52 +++ tests/acceptance/tests/pages/login.page.js | 45 +++ tests/acceptance/tests/pages/personal.page.js | 57 ++++ tests/acceptance/tests/pages/shareApi.page.js | 84 +++++ tests/acceptance/tests/pages/user.page.js | 114 +++++++ .../acceptance/tests/pages/webdav_api.page.js | 0 .../acceptance/tests/share/share_api_spec.js | 50 +++ tests/acceptance/tests/share/share_spec.js | 198 +++++++++++ 27 files changed, 1999 insertions(+) create mode 100644 tests/acceptance/package.json create mode 100644 tests/acceptance/protractor_conf.js create mode 100644 tests/acceptance/readme.md create mode 100644 tests/acceptance/screenshots/.gitignore create mode 100644 tests/acceptance/tests/files/folder_spec.js create mode 100644 tests/acceptance/tests/files/rename_spec.js create mode 100644 tests/acceptance/tests/files/restore_spec.js create mode 100644 tests/acceptance/tests/files/search_spec.js create mode 100644 tests/acceptance/tests/files/sort_spec.js create mode 100644 tests/acceptance/tests/files/txt_spec.js create mode 100644 tests/acceptance/tests/helper/page.js create mode 100644 tests/acceptance/tests/helper/screenshot.js create mode 100644 tests/acceptance/tests/install/install_spec.js create mode 100644 tests/acceptance/tests/login/authentication_spec.js create mode 100644 tests/acceptance/tests/login/change_password_spec.js create mode 100644 tests/acceptance/tests/login/new_user_spec.js create mode 100644 tests/acceptance/tests/login/username_cases_spec.js create mode 100644 tests/acceptance/tests/pages/files.page.js create mode 100644 tests/acceptance/tests/pages/firstRunWizard.page.js create mode 100644 tests/acceptance/tests/pages/install.page.js create mode 100644 tests/acceptance/tests/pages/login.page.js create mode 100644 tests/acceptance/tests/pages/personal.page.js create mode 100644 tests/acceptance/tests/pages/shareApi.page.js create mode 100644 tests/acceptance/tests/pages/user.page.js create mode 100644 tests/acceptance/tests/pages/webdav_api.page.js create mode 100644 tests/acceptance/tests/share/share_api_spec.js create mode 100644 tests/acceptance/tests/share/share_spec.js diff --git a/tests/acceptance/package.json b/tests/acceptance/package.json new file mode 100644 index 0000000000..5173a87d2b --- /dev/null +++ b/tests/acceptance/package.json @@ -0,0 +1,19 @@ +{ + "name": "specs", + "version": "0.0.0", + "description": "ownCloud specs for automated acceptance tests", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Felix Böhm", + "dependencies": { + "protractor": "^1.0.0", + "request": "^2.40.0", + "xml2js": "^0.4.4", + "jasmine-spec-reporter": "^0.6.0", + "phantomjs": "^1.9.7-15" + }, + "devDependencies": { + } +} diff --git a/tests/acceptance/protractor_conf.js b/tests/acceptance/protractor_conf.js new file mode 100644 index 0000000000..d50ec88913 --- /dev/null +++ b/tests/acceptance/protractor_conf.js @@ -0,0 +1,102 @@ +// An example configuration file. +exports.config = { + // Do not start a Selenium Standalone sever - only run this using chrome. + chromeOnly: true, + chromeDriver: './node_modules/protractor/selenium/chromedriver', + + // Capabilities to be passed to the webdriver instance. + // See https://sites.google.com/a/chromium.org/chromedriver/capabilities + capabilities: { + 'browserName': 'chrome', + 'chromeOptions': { + 'args': ['show-fps-counter=true', '--test-type', '--ignore-certificate-errors'] + } + }, + + // Use on Commmandline: + // protractor ... --params.login.user=abc --params.login.password=123 + params: { + baseUrl: "http://127.0.0.1/", + login: { + user: 'admin', + password: 'password' + } + }, + + suites: { + install: 'tests/install/**/*_spec.js', + login: 'tests/login/**/*_spec.js', + files: 'tests/files/**/*_spec.js', + share: 'tests/share/**/*_spec.js', + }, + + // seleniumAddress: 'http://0.0.0.0:4444/wd/hub', + + // Options to be passed to Jasmine-node. + jasmineNodeOpts: { + silent: true, + showColors: true, + onComplete: null, + isVerbose: true, + includeStackTrace: true, + defaultTimeoutInterval: 180000 + }, + + onPrepare: function(){ + global.isAngularSite = function(flag){ + browser.ignoreSynchronization = !flag; + }; + browser.driver.manage().window().setSize(1000, 800); + browser.driver.manage().window().maximize(); + + require('jasmine-spec-reporter'); + // add jasmine spec reporter + var spec_reporter = new jasmine.SpecReporter({ + displayStacktrace: false, // display stacktrace for each failed assertion + displayFailuresSummary: false, // display summary of all failures after execution + displaySuccessfulSpec: true, // display each successful spec + displayFailedSpec: true, // display each failed spec + displaySkippedSpec: false, // display each skipped spec + displaySpecDuration: true, // display each spec duration + colors: { + success: 'green', + failure: 'red', + skipped: 'cyan' + }, + prefixes: { + success: '✓ ', + failure: '✗ ', + skipped: '- ' + } + }); + global.display = spec_reporter.display; + jasmine.getEnv().addReporter(spec_reporter); + } +}; + + +// Headless testing with Phantomjs +// capabilities: { +// 'browserName': 'phantomjs', +// +// /* +// * Can be used to specify the phantomjs binary path. +// * This can generally be ommitted if you installed phantomjs globally. +// */ +// 'phantomjs.binary.path':'./node_modules/phantomjs/bin/phantomjs', +// +// /* +// * Command line arugments to pass to phantomjs. +// * Can be ommitted if no arguments need to be passed. +// * Acceptable cli arugments: https://github.com/ariya/phantomjs/wiki/API-Reference#wiki-command-line-options +// */ +// 'phantomjs.cli.args':['--logfile=PATH', '--loglevel=DEBUG'] +// }, + +// TODO: Mobile? See: https://github.com/angular/protractor/blob/master/docs/browser-setup.md#setting-up-protractor-with-appium---androidchrome +// multiCapabilities: [{ +// 'browserName': 'firefox' +// }, { +// 'browserName': 'chrome' +// }] + diff --git a/tests/acceptance/readme.md b/tests/acceptance/readme.md new file mode 100644 index 0000000000..9819715cff --- /dev/null +++ b/tests/acceptance/readme.md @@ -0,0 +1,35 @@ +ownCloud Acceptance Tests +========================= + + +Setup +----- + +Install node.js and run the following to install the dependencies + +``` +npm install +./node_modules/protractor/bin/webdriver-manager update +``` + +Install as global commands +``` +npm install -g protractor +``` + +Run +--- + +Run the tests with protractor + +``` +protractor protractor.conf.js +``` + +Run only a specific test suite or spec + +``` +protractor protractor.conf.js --suite install +protractor protractor_conf.js --params.baseUrl="http://127.0.0.1/ownClouds/test-community-7.0.1/" --suite=login +protractor protractor_conf.js --params.baseUrl="http://127.0.0.1/ownClouds/test-community-7.0.1/" --specs tests/login/newUser_spec.js +``` diff --git a/tests/acceptance/screenshots/.gitignore b/tests/acceptance/screenshots/.gitignore new file mode 100644 index 0000000000..bc7947beb6 --- /dev/null +++ b/tests/acceptance/screenshots/.gitignore @@ -0,0 +1,3 @@ +* + +!.gitignore \ No newline at end of file diff --git a/tests/acceptance/tests/files/folder_spec.js b/tests/acceptance/tests/files/folder_spec.js new file mode 100644 index 0000000000..0b143ea0d3 --- /dev/null +++ b/tests/acceptance/tests/files/folder_spec.js @@ -0,0 +1,86 @@ +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); + + +// ============================ FOLDERS ============================================================== // +// =================================================================================================== // + +describe('Folders', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should create a new folder', function() { + filesPage.createNewFolder('testFolder'); + expect(filesPage.listFiles()).toContain('testFolder'); + }); + + it('should not create new folder if foldername already exists', function() { + filesPage.createNewFolder('testFolder'); + var warning = by.css('.tipsy-inner'); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + it('should delete a folder', function() { + filesPage.get(); // TODO: reload cause warning alerts don't disappear + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.deleteFile('testFolder'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('testFolder'); + }); +}); + +// ============================== SUB FOLDERS ======================================================== // +// =================================================================================================== // + +describe('Subfolders', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + + it('should go into folder and create subfolder', function() { + var folder = 'hasSubFolder'; + filesPage.createNewFolder(folder); + filesPage.goInToFolder(folder); + filesPage.createNewFolder('SubFolder'); + filesPage.createNewFolder('SubFolder2'); + expect(filesPage.listFiles()).toContain('SubFolder', 'SubFolder2'); + }); + + it('should rename a subfolder', function() { + filesPage.renameFile('SubFolder2', 'NewSubFolder'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('NewSubFolder'); + }); + + it('should delete a subfolder', function() { + filesPage.deleteFile('SubFolder'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('SubFolder'); + }); + + it('should delete a folder containing a subfolder', function() { + filesPage.get(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.deleteFile('hasSubFolder'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('hasSubFolder'); + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/files/rename_spec.js b/tests/acceptance/tests/files/rename_spec.js new file mode 100644 index 0000000000..a4dfdfa961 --- /dev/null +++ b/tests/acceptance/tests/files/rename_spec.js @@ -0,0 +1,140 @@ +var Page = require('../helper/page.js') +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); + +// =============================================== RENAME FOLDER =================================== // +// ================================================================================================= // + +describe('Rename Folder', function() { + var params = browser.params; + var page; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + page = new Page(); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should rename a folder', function() { + filesPage.createNewFolder('testFolder'); + filesPage.renameFile('testFolder', 'newFolder'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('newFolder'); + }); + + it('should show alert message if foldername already in use', function() { + filesPage.createNewFolder('testFolder'); + filesPage.renameFile('testFolder', 'newFolder'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + it('should show alert message if using forbidden characters', function() { + filesPage.renameFile('newFolder', 'new:Folder'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + it('should rename a file using special characters', function() { + filesPage.get(); // TODO: reload cause warning alerts don't disappear + filesPage.renameFile('testFolder', 'sP€c!@L B-)'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('sP€c!@L B-)'); + }); + + it('should show alert message if newName is empty', function() { + filesPage.renameFile('newFolder', ""); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + filesPage.deleteFile('newFolder'); + filesPage.deleteFile('sP€c!@L B-)'); + }); +}); + +// =============================================== RENAME FILES ==================================== // +// ================================================================================================= // + +describe('Rename Files', function() { + var params = browser.params; + var page; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + page = new Page(); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should rename a txt file', function() { + filesPage.createNewTxtFile('testText'); + filesPage.renameFile('testText.txt', 'newText.txt'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('newText'); + }); + + it('should show alert message if filename is already in use', function() { + filesPage.createNewTxtFile('testText'); + filesPage.renameFile('testText.txt', 'newText.txt'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + // it('should rename a file with the same name but changed capitalization', function() { + // browser.takeScreenshot().then(function (png) { + + // new Screenshot(png, 'SameNameCapitalization1.png'); + // filesPage.renameFile('testText.txt', 'NewText.txt'); + // browser.wait(function() { + // return(filesPage.listFiles()); + // }, 3000); + // }); + // browser.takeScreenshot().then(function (png) { + // new Screenshot(png, 'SameNameCapitalization2.png'); + // }); + // expect(filesPage.listFiles()).toContain('NewText.txt'); + // }); + + it('should rename a file using special characters', function() { + filesPage.renameFile('newText.txt', 'sP€c!@L B-).txt'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('sP€c!@L B-)'); + }); + + it('should show alert message if newName is empty', function() { + filesPage.get(); // TODO: reload cause warning alerts don't disappear + filesPage.renameFile('sP€c!@L B-).txt', ''); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + it('should rename a file by taking off the file extension', function() { + filesPage.renameFile('testText.txt', 'Without Subfix'); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + expect(filesPage.listFiles()).toContain('Without Subfix'); + filesPage.deleteFile('Without Subfix'); + filesPage.deleteFile('sP€c!@L B-).txt'); + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/files/restore_spec.js b/tests/acceptance/tests/files/restore_spec.js new file mode 100644 index 0000000000..3179c92835 --- /dev/null +++ b/tests/acceptance/tests/files/restore_spec.js @@ -0,0 +1,151 @@ +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); + +// ============================ RESTORE FOLDERS ====================================================== // +// =================================================================================================== // + +describe('Restore Folders', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + + it('should restore a emtpy folder that has been deleted', function() { + filesPage.createNewFolder('Empty'); + filesPage.deleteFile('Empty'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return filesPage.listFiles(); + }, 5000); + filesPage.restoreFile(0); + filesPage.get(); + + + expect(filesPage.listFiles()).toContain('Empty'); + filesPage.deleteFile('Empty'); + }); + + it('should restore a folder including special characters', function() { + filesPage.createNewFolder('Sp€c!@l FölD€r'); + filesPage.deleteFile('Sp€c!@l FölD€r'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + + filesPage.restoreFile(0); + filesPage.get(); + + expect(filesPage.listFiles()).toContain('Sp€c!@l FölD€r'); + filesPage.deleteFile('Sp€c!@l FölD€r'); + }); + + it('should restore a non empty folder that has been deleted', function() { + filesPage.createNewFolder('nonEmpty'); + filesPage.createSubFolder('nonEmpty', 'Subfolder'); + filesPage.createNewTxtFile('TextFile'); + filesPage.get(); + filesPage.deleteFile('nonEmpty'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(0); + filesPage.get(); + expect(filesPage.listFiles()).toContain('nonEmpty'); + }); + + it('should restore a folder whose name is currently in use', function() { + + // create and delete non empty folder + filesPage.createNewFolder('sameFolderName'); + filesPage.deleteFile('sameFolderName'); + filesPage.createNewFolder('sameFolderName'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(0); + filesPage.get(); + expect(filesPage.listFiles()).toContain('sameFolderName (Wiederhergestellt)'); //for german ownclouds + filesPage.deleteFile('sameFolderName'); + filesPage.deleteFile('sameFolderName (Wiederhergestellt)'); + }); + + it('should restore a sub folder when the root folder has been deleted separately', function() { + filesPage.getSubFolder('nonEmpty', 'Subfolder'); + filesPage.createNewTxtFile('IsInSub'); + filesPage.getFolder('nonEmpty'); + filesPage.deleteFile('Subfolder'); + filesPage.get() + filesPage.deleteFile('nonEmpty'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(1); + filesPage.get(); + expect(filesPage.listFiles()).toContain('Subfolder'); + }); +}); + + +// ============================ RESTORE FOLDERS ====================================================== // +// =================================================================================================== // + +describe('Restore Files', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should restore a file thas has been deleted', function() { + filesPage.createNewTxtFile('restoreMe'); + filesPage.deleteFile('restoreMe.txt'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(0); + filesPage.get(); + expect(filesPage.listFiles()).toContain('restoreMe'); + filesPage.deleteFile('restoreMe.txt'); + }); + + it('should restore a file including special characters', function() { + filesPage.createNewTxtFile('Sp€c!@L RésTör€'); + filesPage.deleteFile('Sp€c!@L RésTör€.txt'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(0); + filesPage.get(); + expect(filesPage.listFiles()).toContain('Sp€c!@L RésTör€'); + filesPage.deleteFile('Sp€c!@L RésTör€.txt'); + }); + + it('should restore a file whose name is currently in use', function() { + filesPage.createNewTxtFile('sameFileName'); + filesPage.deleteFile('sameFileName.txt'); + filesPage.createNewTxtFile('sameFileName'); + filesPage.trashbinButton.click(); + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.restoreFile(0); + filesPage.get(); + expect(filesPage.listFiles()).toContain('sameFileName (Wiederhergestellt)'); //for german ownclouds + filesPage.deleteFile('sameFileName.txt'); + filesPage.deleteFile('sameFileName (Wiederhergestellt).txt'); + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/files/search_spec.js b/tests/acceptance/tests/files/search_spec.js new file mode 100644 index 0000000000..4df5415612 --- /dev/null +++ b/tests/acceptance/tests/files/search_spec.js @@ -0,0 +1,26 @@ +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); + +// ============================ SEARCH =============================================================== // +// =================================================================================================== // + +describe('Search', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should search files by name', function() { + filesPage.createNewTxtFile('searchFile'); + filesPage.createNewFolder('searchFolder'); + filesPage.searchInput.click(); + filesPage.searchInput.sendKeys('search'); + expect(filesPage.listSelctedFiles()).toContain('searchFile', 'searchFolder'); + filesPage.deleteFile('searchFile.txt'); + filesPage.deleteFile('searchFolder'); + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/files/sort_spec.js b/tests/acceptance/tests/files/sort_spec.js new file mode 100644 index 0000000000..b2abce59a3 --- /dev/null +++ b/tests/acceptance/tests/files/sort_spec.js @@ -0,0 +1,35 @@ +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); + +// ============================ SORT ================================================================= // +// =================================================================================================== // + +describe('Sort', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('shloud sort files by name', function() { + expect(filesPage.firstListElem == element(filesPage.fileListElemId("documents"))).toBeTruthy; + filesPage.nameSortArrow.click(); + expect(filesPage.firstListElem == element(filesPage.fileListElemId("ownCloudUserManual.pdf"))).toBeTruthy; + }); + + it('should sort files by size', function() { + expect(filesPage.firstListElem == element(filesPage.fileListElemId("documents"))).toBeTruthy; + filesPage.sizeSortArrow.click(); + expect(filesPage.firstListElem == element(filesPage.fileListElemId("music"))).toBeTruthy; + }); + + it('should sort files by modified date', function() { + expect(filesPage.firstListElem == element(filesPage.fileListElemId("documents"))).toBeTruthy; + filesPage.createNewTxtFile('newText') + filesPage.modifiedSortArrow.click(); + expect(filesPage.firstListElem == element(filesPage.fileListElemId("newText.txt"))).toBeTruthy; + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/files/txt_spec.js b/tests/acceptance/tests/files/txt_spec.js new file mode 100644 index 0000000000..4e0165b18d --- /dev/null +++ b/tests/acceptance/tests/files/txt_spec.js @@ -0,0 +1,36 @@ +var LoginPage = require('../pages/login.page.js'); +var FilesPage = require('../pages/files.page.js'); +var Screenshot = require('../helper/screenshot.js'); + +// ============================ TXT FILES ============================================================ // +// =================================================================================================== // + +describe('Txt Files', function() { + var params = browser.params; + var filesPage; + + beforeEach(function() { + isAngularSite(false); + filesPage = new FilesPage(params.baseUrl); + filesPage.getAsUser(params.login.user, params.login.password); + }); + + it('should create a new txt file', function() { + filesPage.createNewTxtFile('testText'); + expect(filesPage.listFiles()).toContain('testText'); + }); + + it('should not create new file if filename already exists', function() { + filesPage.createNewTxtFile('testText'); + expect(filesPage.alertWarning.isDisplayed()).toBeTruthy(); + }); + + it('should delete a txt file', function() { + browser.wait(function() { + return(filesPage.listFiles()); + }, 3000); + filesPage.deleteFile('testText.txt'); + filesPage.get(); + expect(filesPage.listFiles()).not.toContain('testText') + }); +}); \ No newline at end of file diff --git a/tests/acceptance/tests/helper/page.js b/tests/acceptance/tests/helper/page.js new file mode 100644 index 0000000000..9a86e95d92 --- /dev/null +++ b/tests/acceptance/tests/helper/page.js @@ -0,0 +1,14 @@ +(function() { + + + var Page = function() { + + }; + + Page.prototype.moveMouseTo = function(locator) { + var ele = element(locator); + return browser.actions().mouseMove(ele).perform(); + } + + module.exports = Page; +})(); diff --git a/tests/acceptance/tests/helper/screenshot.js b/tests/acceptance/tests/helper/screenshot.js new file mode 100644 index 0000000000..cd3a38b314 --- /dev/null +++ b/tests/acceptance/tests/helper/screenshot.js @@ -0,0 +1,16 @@ +(function() { + + var fs = require('fs'); + + var Screenshot = function(data, filename) { + this.screenshotPath = __dirname + '/../../screenshots/'; + + display.log('Created screenshot: ' + this.screenshotPath + filename); + var stream = fs.createWriteStream(this.screenshotPath + filename); + + stream.write(new Buffer(data, 'base64')); + stream.end(); + }; + + module.exports = Screenshot; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/install/install_spec.js b/tests/acceptance/tests/install/install_spec.js new file mode 100644 index 0000000000..ffb4e678df --- /dev/null +++ b/tests/acceptance/tests/install/install_spec.js @@ -0,0 +1,63 @@ +var InstallPage = require('../pages/install.page.js'); +var Screenshot = require('../helper/screenshot.js'); + +describe('Installation', function() { + var params = browser.params; + var installPage; + + beforeEach(function() { + isAngularSite(false); + installPage = new InstallPage(params.baseUrl); + installPage.get(); + }); + + it('should load the install page with logo', function() { + expect(installPage.installField.getAttribute('name')).toEqual("install"); + expect(installPage.installField.getAttribute('value')).toEqual('true'); + + expect(element(by.css('.logo'))).toBeDefined(); + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'InstallPage.png'); + }); + }); + + it('should not show any warnings or errors', function() { + if (installPage.warningField.isDisplayed()) { + installPage.warningField.getText().then(function(text) { + display.log(text); + }); + } + expect(installPage.warningField.isDisplayed()).toBeFalsy(); + }); + + it('should show more config after clicking the advanced config link ', function() { + // TODO: Check not displayed in a proper way + // expect(installPage.dataDirectoryConfig.isDisplayed()).toBeFalsy(); + // expect(installPage.dbConfig.isDisplayed()).toBeFalsy(); + + installPage.advancedConfigLink.click(); + + expect(installPage.dataDirectoryConfig.isDisplayed()).toBeTruthy(); + expect(installPage.dbConfig.isDisplayed()).toBeTruthy(); + + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'InstallConfig.png'); + }); + }); + + it('should install as admin with sqlite', function() { + installPage.fillAdminAccount(params.login.user, params.login.password); + + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'Credentials.png'); + }); + + installPage.installButton.click().then(function() { + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'InstallFinished.png'); + }); + }); + }); + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/login/authentication_spec.js b/tests/acceptance/tests/login/authentication_spec.js new file mode 100644 index 0000000000..f331e33fdc --- /dev/null +++ b/tests/acceptance/tests/login/authentication_spec.js @@ -0,0 +1,85 @@ +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); +var FirstRunWizardPage = require('../pages/firstRunWizard.page.js'); +var Screenshot = require('../helper/screenshot.js'); + +describe('Authentication', function() { + var params = browser.params; + var loginPage; + + beforeEach(function() { + isAngularSite(false); + loginPage = new LoginPage(params.baseUrl); + browser.manage().deleteAllCookies(); // logout the hard way + loginPage.get(); + + // Skip tests after first failed test + // if (this.results_.failedCount > 0) { + // // Hack: Quit by filtering upcoming tests + // this.env.specFilter = function(spec) { + // return false; + // }; + // } + }); + + it('should show a logo', function() { + expect(element(by.css('.logo'))).toBeDefined(); + }); + + it('should load the login page', function() { + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'LoginPage.png'); + }); + + expect(loginPage.isLoginPage()).toBeTruthy(); + }); + + it('should meet the locator dependencies', function() { + expect(loginPage.loginForm.isDisplayed()).toBeTruthy(); + expect(loginPage.userInput.isDisplayed()).toBeTruthy(); + expect(loginPage.passwordInput.isDisplayed()).toBeTruthy(); + expect(loginPage.loginButton.isDisplayed()).toBeTruthy(); + }); + + it('should not load the files page url', function() { + expect(browser.getCurrentUrl()).not.toContain('index.php/apps/files/'); + }); + + it('should login admin user', function() { + // Assumes FirstRunWizard to be disabled + loginPage.login(params.login.user, params.login.password); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with admin account', function() { + loginPage.login(params.login.user, params.login.password); + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'LoginAsAdmin.png'); + }); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should return to the login page after logout', function() { + loginPage.login(params.login.user, params.login.password); + expect(browser.getCurrentUrl()).not.toEqual(loginPage.url); + + loginPage.logout(); + expect(browser.getCurrentUrl()).toEqual(loginPage.url); + }); + + it('should not login with wrong credentials', function() { + loginPage.login('wrongName', 'wrongPass'); + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'LoginWrong.png'); + }); + expect(browser.getCurrentUrl()).not.toContain('index.php/apps/files/'); + }); + + it('should have rights to visit user management after admin login', function() { + loginPage.login(params.login.user, params.login.password); + userPage = new UserPage(params.baseUrl); + userPage.get(); + expect(browser.getCurrentUrl()).toEqual(userPage.url); + }); + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/login/change_password_spec.js b/tests/acceptance/tests/login/change_password_spec.js new file mode 100644 index 0000000000..8eef444aad --- /dev/null +++ b/tests/acceptance/tests/login/change_password_spec.js @@ -0,0 +1,104 @@ +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); +var PersonalPage = require('../pages/personal.page.js'); + +describe('Change Password - Valid Usernames', function() { + var params = browser.params; + var loginPage; + var long_pass = 'newNEW123!"§$%&()=?öüß'; + var special_pass = 'special%&@/1234!-+='; + + beforeEach(function() { + isAngularSite(false); + loginPage = new LoginPage(params.baseUrl); + browser.manage().deleteAllCookies(); // logout the hard way + loginPage.get(); + }); + + it('should login as admin and create a test users ', function() { + loginPage.fillUserCredentilas(params.login.user, params.login.password); + loginPage.loginButton.click(); + userPage = new UserPage(params.baseUrl); + userPage.get(); + userPage.createNewUser('demo', 'password'); + userPage.get(); + expect(userPage.listUser()).toContain('demo'); + }); + + it('should login test user', function() { + // workaround: Test needed to close firstrunwizard + loginPage.login('demo', 'password'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login and change password in personal settings', function() { + loginPage.login('demo', 'password'); + var personalPage = new PersonalPage(params.baseUrl); + personalPage.get(); + personalPage.changePassword('password', 'newpassword') + + expect(personalPage.passwordChanged.isDisplayed()).toBeTruthy(); + expect(personalPage.passwordError.isDisplayed()).toBeFalsy(); + }); + + it('should login and change password to super save password in personal settings', function() { + loginPage.login('demo', 'newpassword'); + var personalPage = new PersonalPage(params.baseUrl); + personalPage.get(); + personalPage.changePassword('newpassword', long_pass); + browser.wait(function () { + return personalPage.passwordChanged.isDisplayed(); + }, 3000); + expect(personalPage.passwordChanged.isDisplayed()).toBeTruthy(); + expect(personalPage.passwordError.isDisplayed()).toBeFalsy(); + }); + + it('should login and not change password with wrong old password in personal settings', function() { + loginPage.login('demo', long_pass); + var personalPage = new PersonalPage(params.baseUrl); + personalPage.get(); + personalPage.changePassword('wrongpassword', 'newpassword'); + expect(personalPage.passwordChanged.isDisplayed()).toBeFalsy(); + expect(personalPage.passwordError.isDisplayed()).toBeTruthy(); + }); + + // %, &, @ and / + it('should change password including specialcharacters in personal settings', function() { + loginPage.login('demo', long_pass); + var personalPage = new PersonalPage(params.baseUrl); + personalPage.get(); + personalPage.changePassword(long_pass, special_pass); + expect(personalPage.passwordChanged.isDisplayed()).toBeTruthy(); + expect(personalPage.passwordError.isDisplayed()).toBeFalsy(); + }); + + it('should login with password including specialcharacters', function() { + loginPage.login('demo', special_pass); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login as admin and change password for test users ', function() { + loginPage.login(params.login.user, params.login.password); + userPage = new UserPage(params.baseUrl); + userPage.get(); + element(by.css('#userlist tr[data-displayname="demo"] td.password')).click().then(function() { + element(by.css('#userlist tr[data-displayname="demo"] td.password input')).sendKeys("password"); + element(by.css('#userlist tr[data-displayname="demo"] td.password input')).sendKeys(protractor.Key.ENTER); + }); + }); + + it('should login with password changed by admin', function() { + loginPage.login('demo', 'password'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login as admin and delete test user', function() { + // Cleanup prev tests + loginPage.login(params.login.user, params.login.password); + userPage.get(); + userPage.deleteUser('demo'); + userPage.get(); + expect(userPage.listUser()).not.toContain('demo'); + }); + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/login/new_user_spec.js b/tests/acceptance/tests/login/new_user_spec.js new file mode 100644 index 0000000000..06df5d69ea --- /dev/null +++ b/tests/acceptance/tests/login/new_user_spec.js @@ -0,0 +1,43 @@ +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); +var Screenshot = require('../helper/screenshot.js'); + +describe('New User', function() { + var params = browser.params; + var loginPage; + + beforeEach(function() { + isAngularSite(false); + loginPage = new LoginPage(params.baseUrl); + browser.manage().deleteAllCookies(); // logout the hard way + loginPage.get(); + }); + + it('should login as admin and create a new user ', function() { + loginPage.login(params.login.user, params.login.password); + userPage = new UserPage(params.baseUrl); + userPage.get(); + userPage.createNewUser('demo', 'demo'); + userPage.get(); + expect(userPage.listUser()).toContain('demo'); + }); + + it('should login with a new user', function() { + loginPage.login('demo', 'demo'); + + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + browser.takeScreenshot().then(function (png) { + new Screenshot(png, 'LoginAsNewUser.png'); + }); + }); + + it('should login as admin and delete new user', function() { + // Cleanup prev test + loginPage.login(params.login.user, params.login.password); + userPage.get(); + userPage.deleteUser('demo'); + userPage.get(); + expect(userPage.listUser()).not.toContain('demo'); + }); + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/login/username_cases_spec.js b/tests/acceptance/tests/login/username_cases_spec.js new file mode 100644 index 0000000000..fe7e95b02b --- /dev/null +++ b/tests/acceptance/tests/login/username_cases_spec.js @@ -0,0 +1,88 @@ +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); + +describe('Username Cases', function() { + var params = browser.params; + var loginPage; + + beforeEach(function() { + isAngularSite(false); + loginPage = new LoginPage(params.baseUrl); + browser.manage().deleteAllCookies(); // logout the hard way + loginPage.get(); + }); + + it('should login as admin and create test users ', function() { + loginPage.fillUserCredentilas(params.login.user, params.login.password); + loginPage.loginButton.click(); + userPage = new UserPage(params.baseUrl); + userPage.get(); + userPage.createNewUser('demo1', 'demo'); + userPage.createNewUser('Demo2', 'demo'); + userPage.createNewUser('DEMO3', 'demo'); + + userPage.get(); + expect(userPage.listUser()).toContain('demo1'); + expect(userPage.listUser()).toContain('Demo2'); + expect(userPage.listUser()).toContain('DEMO3' ); + }); + + it('should login lowercase username with test user in lowercase', function() { + loginPage.login('demo1', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login camelcase username with test user in lowercase', function() { + loginPage.login('demo2', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login uppercase username with test user in lowercase', function() { + loginPage.login('demo3', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with lowercase username in camelcase', function() { + loginPage.login('Demo1', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with camelcase username in camelcase', function() { + loginPage.login('Demo2', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with uppercase username in camelcase', function() { + loginPage.login('Demo3', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with lowercase username in uppercase', function() { + loginPage.login('DEMO1', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with lowercase username in uppercase', function() { + loginPage.login('DEMO2', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login with lowercase username in uppercase', function() { + loginPage.login('DEMO3', 'demo'); + expect(browser.getCurrentUrl()).toContain('index.php/apps/files/'); + }); + + it('should login as admin and delete test user', function() { + // Cleanup prev tests + loginPage.login(params.login.user, params.login.password); + userPage.get(); + userPage.deleteUser('demo1'); + userPage.deleteUser('Demo2'); + userPage.deleteUser('DEMO3'); + userPage.get(); + expect(userPage.listUser()).not.toContain('demo1'); + expect(userPage.listUser()).not.toContain('Demo2'); + expect(userPage.listUser()).not.toContain('DEMO3' ); + }); + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/files.page.js b/tests/acceptance/tests/pages/files.page.js new file mode 100644 index 0000000000..8efe33ee99 --- /dev/null +++ b/tests/acceptance/tests/pages/files.page.js @@ -0,0 +1,317 @@ +(function() { + var Page = require('../helper/page.js'); + var LoginPage = require('../pages/login.page.js'); + + var FilesPage = function(baseUrl) { + this.baseUrl = baseUrl; + this.path = 'index.php/apps/files'; + this.url = baseUrl + this.path; + + var url = this.url + this.folderUrl = function(folder) { + return url + '/?dir=%2F' + folder + } + + // topbar + this.UserActionDropdown = element(by.id("expandDisplayName")); + + // filelist + this.selectedFileListId = by.css('tr.searchresult td.filename .innernametext'); + this.firstListElem = element(by.css('#fileList tr:first-child')); + + // new Button and sublist + this.newButton = element(by.css('#new a')); + this.newTextButton = element(by.css('li.icon-filetype-text.svg')); + this.newFolderButton = element(by.css('li.icon-filetype-folder.svg')); + this.newTextnameForm = element(by.css('li.icon-filetype-text form input')); + this.newFoldernameForm = element(by.css('li.icon-filetype-folder form input')); + + this.alertWarning = element(by.css('.tipsy-inner')); + + this.trashbinButton = element(by.css('#app-navigation li.nav-trashbin a')); + + // sort arrows + this.nameSortArrow = element(by.css('a.name.sort')); + this.sizeSortArrow = element(by.css('a.size.sort')); + this.modifiedSortArrow = element(by.id('modified')); + + this.searchInput = element(by.id('searchbox')); + + this.shareWithForm = element(by.id('shareWith')); + this.sharedWithDropdown = element(by.id('ui-id-1')); + // this.textArea = element(by.css('.ace_content')); + // this.textLine = element(by.css('.ace_content .ace_line')); + // this.saveButton = element(by.id('editor_save')); + }; + +//================ LOCATOR FUNCTIONS ====================================// + FilesPage.prototype.fileListId = function() { + return by.css('td.filename .innernametext'); + } + + FilesPage.prototype.fileListElemId = function(fileName) { + return by.css("tr[data-file='" + fileName + "']"); + }; + + FilesPage.prototype.fileListElemNameId = function(fileName) { + return by.css("tr[data-file='" + fileName + "'] span.innernametext"); + }; + + FilesPage.prototype.restoreListElemId = function(id) { + return (by.css("#fileList tr[data-id='" + id + "']")); + }; + + FilesPage.prototype.restoreButtonId = function(id) { + return (by.css("#fileList tr[data-id='" + id + "'] .action.action-restore")); + }; + + FilesPage.prototype.renameButtonId = function(fileName) { + return by.css("tr[data-file='" + fileName + "'] .action.action-rename"); + }; + + FilesPage.prototype.renameFormId = function(fileName) { + return by.css("tr[data-file='" + fileName + "'] form input"); + }; + + FilesPage.prototype.shareButtonId = function(fileName) { + return by.css("tr[data-file='" + fileName + "'] .action.action-share"); + }; + + FilesPage.prototype.deleteButtonId = function(fileName) { + return by.css("tr[data-file='" + fileName + "'] .action.delete.delete-icon"); + }; + +//================ SHARED ===============================================// + + FilesPage.prototype.isLoggedIn = function() { + return this.UserActionDropdown.isPresent().then(function(isLoggedIn) { + return isLoggedIn; + }); + } + + FilesPage.prototype.get = function() { + browser.get(this.url); + + var button = this.newButton; + browser.wait(function() { + return button.isDisplayed(); + }, 5000, 'load files content'); + }; + + FilesPage.prototype.getAsUser = function(name, pass) { + var loginPage; + loginPage = new LoginPage(this.baseUrl); + + this.isLoggedIn().then(function(isLoggedIn) { + if(isLoggedIn) { + // console.log('isLoggedIn: ' + isLoggedIn); + return false + } else { + console.log('isLoggedIn: ' + isLoggedIn); + browser.manage().deleteAllCookies(); // logout the hard way + loginPage.get(); + loginPage.login(name, pass); + } + }); + }; + + FilesPage.prototype.getFolder = function(folder) { + folderUrl = this.folderUrl(folder); + browser.get(folderUrl); + var button = this.newButton; + browser.wait(function() { + return button.isDisplayed(); + }, 5000, 'load files content'); + } + FilesPage.prototype.getSubFolder = function(folder, subFolder) { + folderUrl = this.folderUrl(folder) + '%2F' + subFolder; + console.log(folderUrl); + browser.get(folderUrl); + var button = this.newButton; + browser.wait(function() { + return button.isDisplayed(); + }, 5000, 'load files content'); + } + + FilesPage.prototype.listFiles = function() { + // TODO: waiting to avoid "index out of bound error" + browser.sleep(800); + return element.all(this.fileListId()).map(function(filename) { + return filename.getText(); + }); + }; + + FilesPage.prototype.listSelctedFiles = function() { + return element.all(this.selectedFileListId).map(function(filename) { + return filename.getText(); + }); + }; + +//================ SHARED ACTIONS ========================================// + + // FilesPage.prototype.setCurrentListElem = function(name) { + // this.setCurrentListElem = element(by.css("tr[data-file='" + name + "']")); + // } + + FilesPage.prototype.openRenameForm = function(fileName) { + var page = new Page(); + var renameButton = element(this.renameButtonId(fileName)); + + return page.moveMouseTo(this.fileListElemId(fileName)).then(function() { + return renameButton.click(); + }) + }; + + FilesPage.prototype.renameFile = function(fileName, newFileName) { + var renameForm = element(this.renameFormId(fileName)); + return this.openRenameForm(fileName).then(function() { + for(var i=0; i<5; i++) { + renameForm.sendKeys(protractor.Key.DELETE) + }; + renameForm + .sendKeys(newFileName) + .sendKeys(protractor.Key.ENTER) + }); + }; + + FilesPage.prototype.deleteFile = function(fileName) { + var page = new Page(); + + page.moveMouseTo(this.fileListElemId(fileName)); + return element(this.deleteButtonId(fileName)).click(); + }; + + FilesPage.prototype.openShareForm = function(fileName) { + var page = new Page(); + + page.moveMouseTo(this.fileListElemId(fileName)); + return element(this.shareButtonId(fileName)).click(); + }; + + FilesPage.prototype.shareFile = function(fileName, userName) { + this.openShareForm(fileName); + this.shareWithForm.sendKeys(userName); + var dropdown = this.sharedWithDropdown + browser.wait(function(){ + return dropdown.isDisplayed(); + }, 3000); + this.shareWithForm.sendKeys(protractor.Key.ENTER); + } + + FilesPage.prototype.disableReshare = function(fileName, userName) { + var disableReshareButton = element(by.css("li[title='" + userName + "'] label input[name='share']")); + var dropdown = this.sharedWithDropdown + + // this.openShareForm(fileName); + + // TODO: find correct wait trigger + // browser.wait(function(){ + // return dropdown.isDisplayed(); + // }, 3000);s + + // TODO: Timing Workaround + browser.sleep(800); + disableReshareButton.click(); + }; + + FilesPage.prototype.checkReshareability = function(fileName) { + var page = new Page(); + var shareButtonLocator = this.shareButtonId(fileName); + + return page.moveMouseTo(this.fileListElemId(fileName)).then(function() { + return element(shareButtonLocator).isPresent(); + }); + }; + + // FilesPage.prototype.showFileVersions = function(name) { + // this.moveMouseTo("tr[data-file='"+name+"']"); + // var versionId = by.css("tr[data-file='"+name+"'] a.action.action-versions"); + // return element(versionId).click(); + // }; + + // FilesPage.prototype.downloadFile = function(name) { + // this.moveMouseTo("tr[data-file='"+name+"']"); + // var downloadId = by.css("tr[data-file='"+name+"'] a.action.action-download"); + // return element(downloadId).click(); + // }; + + FilesPage.prototype.restoreFile = function(id) { + var page = new Page(); + page.moveMouseTo(this.restoreListElemId(id)); + return element(this.restoreButtonId(id)).click(); + }; + +//================ TXT FILES ============================================// + + FilesPage.prototype.createNewTxtFile = function(name) { + this.newButton.click(); + this.newTextButton.click(); + this.newTextnameForm.sendKeys(name); + this.newTextnameForm.sendKeys(protractor.Key.ENTER); + + // TODO: find correct wait trigger + // browser.wait(function() { + // // return + // }); + + // TODO: Timing Workaround + browser.sleep(800); + }; + +//================ FOLDERS ==============================================// + + FilesPage.prototype.createNewFolder = function(name) { + this.newButton.click() + this.newFolderButton.click(); + this.newFoldernameForm.sendKeys(name); + this.newFoldernameForm.sendKeys(protractor.Key.ENTER); + + // TODO: find correct wait trigger + // browser.wait(function() { + // // return + // }); + + // TODO: Timing Workaround + browser.sleep(800); + }; + + FilesPage.prototype.goInToFolder = function(fileName) { + var page = new Page(); + + page.moveMouseTo(this.fileListElemId(fileName)); + element(this.fileListElemNameId(fileName)).click(); + var button = this.newButton; + browser.wait(function() { + return button.isDisplayed(); + }, 5000, 'load files content'); + }; + + FilesPage.prototype.createSubFolder = function(folderName, subFolderName) { + this.goInToFolder(folderName); + this.createNewFolder(subFolderName); + }; + +//================ NOT WORKING STUFF ====================================// + + // FilesPage.prototype.editFile = function(file) { + // var listElement = element(by.css("tr[data-file='testText.txt'] span.innernametext")); + // listElement.click(); + // var textArea = this.textArea; + // browser.pause(); + // browser.wait(function() { + // return(textArea.isDisplayed()); + // }, 3000, 'load textEditPage'); + // }; + + // FilesPage.prototype.writeInFile = function(text) { + // // this.textArea.click(); + // this.textLine.sendKeys(text); + // }; + + // FilesPage.prototype.saveFile = function() { + // this.saveButton.click(); + // }; + + + module.exports = FilesPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/firstRunWizard.page.js b/tests/acceptance/tests/pages/firstRunWizard.page.js new file mode 100644 index 0000000000..c8f728e7f2 --- /dev/null +++ b/tests/acceptance/tests/pages/firstRunWizard.page.js @@ -0,0 +1,36 @@ +(function() { + var FirstRunWizardPage = function(baseUrl) { + this.firstRunWizardId = by.id('firstrunwizard'); + this.firstRunWizard = element(this.firstRunWizardId); + this.closeLink = element(by.id('cboxOverlay')); + }; + + FirstRunWizardPage.prototype.waitForDisplay = function() { + browser.wait(function() { + console.log(by.id('closeWizard')); + return by.id('closeWizard'); + // return by.id('firstrunwizard'); + }, 8000); + }; + + FirstRunWizardPage.prototype.isFirstRunWizardPage = function() { + this.waitForDisplay(); + return !!this.firstRunWizardId; + }; + + FirstRunWizardPage.prototype.waitForClose = function() { + browser.wait(function () { + return element(by.id('cboxOverlay')).isDisplayed().then(function(displayed) { + return !displayed; // Do a little Promise/Boolean dance here, since wait will resolve promises. + }); + }, 3000, 'firstrunwizard should dissappear'); + } + + FirstRunWizardPage.prototype.close = function() { + browser.executeScript('$("#closeWizard").click();'); + browser.executeScript('$("#cboxOverlay").click();'); + this.waitForClose(); + }; + + module.exports = FirstRunWizardPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/install.page.js b/tests/acceptance/tests/pages/install.page.js new file mode 100644 index 0000000000..67c66577d6 --- /dev/null +++ b/tests/acceptance/tests/pages/install.page.js @@ -0,0 +1,52 @@ +(function() { + var InstallPage = function(baseUrl) { + this.baseUrl = baseUrl; + + this.installField = element(by.name('install')); + this.warningField = element(by.css('.warning')); + + this.adminAccount = element(by.id('adminaccount')); + this.adminInput = this.adminAccount.element(by.id('adminlogin')); + this.passwordInput = this.adminAccount.element(by.id('adminpass')); + this.installButton = element(by.css('form .buttons input[type="submit"]')); + + this.advancedConfigLink = element(by.id('showAdvanced')); + this.dataDirectoryConfig = element(by.id('datadirContent')); + this.dbConfig = element(by.id('databaseBackend')); + }; + + InstallPage.prototype.get = function() { + browser.get(this.baseUrl); + }; + + InstallPage.prototype.isInstallPage = function() { + return !!this.installField; + }; + + InstallPage.prototype.fillAdminAccount = function(user, pass) { + this.adminInput.sendKeys(user); + this.passwordInput.sendKeys(pass); + }; + + InstallPage.prototype.isAdvancedConfigOpen = function() { + return this.databaseBackend.isDisplayed() && this.dbConfig.isDisplayed(); + }; + + InstallPage.prototype.openAdvancedConfig = function() { + if (! this.isAdvancedConfigOpen()) { + this.advancedConfigLink.click(); + } + }; + + InstallPage.prototype.closeAdvancedConfig = function() { + if (this.isAdvancedConfigOpen()) { + this.advancedConfigLink.click(); + } + }; + + InstallPage.prototype.configDatabase = function(dbConfig) { + + }; + + module.exports = InstallPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/login.page.js b/tests/acceptance/tests/pages/login.page.js new file mode 100644 index 0000000000..5244a7f094 --- /dev/null +++ b/tests/acceptance/tests/pages/login.page.js @@ -0,0 +1,45 @@ +(function() { + var LoginPage = function(baseUrl) { + this.baseUrl = baseUrl; + this.url = baseUrl; + + this.loginForm = element(by.name('login')); + this.userInput = this.loginForm.element(by.id('user')); + this.passwordInput = this.loginForm.element(by.id('password')); + this.loginButton = element(by.id('submit')); + + // On Page when logged in + this.menuButton = element(by.id('expand')); + this.logoutButton = element(by.id('logout')); + this.newButton = element(by.css('#new a')); + }; + + LoginPage.prototype.get = function() { + browser.get(this.url); + }; + + LoginPage.prototype.isLoginPage = function() { + return !!this.loginForm; + }; + + LoginPage.prototype.fillUserCredentilas = function(user, pass) { + this.userInput.sendKeys(user); + this.passwordInput.sendKeys(pass); + }; + + LoginPage.prototype.login = function(user, pass) { + this.fillUserCredentilas(user, pass); + this.loginButton.click(); + var button = this.newButton; + browser.wait(function() { + return button.isDisplayed(); + }, 5000, 'load files content'); + }; + + LoginPage.prototype.logout = function() { + this.menuButton.click(); + this.logoutButton.click(); + }; + + module.exports = LoginPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/personal.page.js b/tests/acceptance/tests/pages/personal.page.js new file mode 100644 index 0000000000..aa552335a3 --- /dev/null +++ b/tests/acceptance/tests/pages/personal.page.js @@ -0,0 +1,57 @@ +(function() { + var PersonalPage = function(baseUrl) { + this.baseUrl = baseUrl; + this.path = 'index.php/settings/personal'; + this.url = baseUrl + this.path; + + this.passwordForm = element(by.css('form#passwordform')); + this.oldPasswordInput = element(by.id('pass1')); + this.newPasswordInput = element(by.id('pass2')); + this.newPasswordButton = element(by.id('passwordbutton')); + + this.passwordChanged = element(by.id('passwordchanged')); + this.passwordError = element(by.id('passworderror')); + + this.displaynameForm = element(by.id('displaynameform')); + this.displaynameInput = this.displaynameForm.element(by.id('displayName')); + + }; + + PersonalPage.prototype.get = function() { + browser.get(this.url); + }; + + PersonalPage.prototype.isUserPage = function() { + return browser.driver.getCurrentUrl() == this.url; + }; + + PersonalPage.prototype.ensurePersonalPage = function() { + // console.log(this.isUserPage()); + // if (! this.isUserPage()) { + // display.log('Warning: Auto loading UserPage'); + // this.get(); + // } + }; + + PersonalPage.prototype.changePassword = function(oldPass, newPass) { + this.ensurePersonalPage(); + this.oldPasswordInput.sendKeys(oldPass); + this.newPasswordInput.sendKeys(newPass); + this.newPasswordButton.click(); + + // result need some time to display + var changed = this.passwordChanged; + var error = this.passwordError; + var ready = false; + browser.wait(function () { + changed.isDisplayed().then(function(c) { + error.isDisplayed().then(function(e) { + ready = c || e; + }); + }); + return ready; + }, 8000, 'personal password change result not displayed'); + }; + + module.exports = PersonalPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/shareApi.page.js b/tests/acceptance/tests/pages/shareApi.page.js new file mode 100644 index 0000000000..a1a3be8f88 --- /dev/null +++ b/tests/acceptance/tests/pages/shareApi.page.js @@ -0,0 +1,84 @@ +(function() { + var request = require('request'); + var parseString = require('xml2js').parseString; + process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" // Avoids DEPTH_ZERO_SELF_SIGNED_CERT error for self-signed certs + + var ShareApi = function(baseUrl) { + this.baseUrl = baseUrl; + this.path = 'ocs/v1.php/apps/files_sharing/api/v1/shares'; + this.url = baseUrl + this.path; + + this.request = { + method: "GET" + }; + }; + ShareApi.prototype.get = function () { + var url = this.url; + + var defer = protractor.promise.defer(); + console.log("Calling", this.url); + + request({ + method: "GET", + uri: url, + followRedirect: true, + auth: { + user: "admin", + password: "password", + } + }, + function(error, response) { + console.log("Done call to", url, "status:", response.statusCode); + if (error || response.statusCode >= 400) { + defer.reject({ + error : error, + response : response + }); + } else { + defer.fulfill(response); + } + }); + return defer.promise; + }; + + ShareApi.prototype.create = function (path, shareWith, shareType) { + var url = this.url; + + var defer = protractor.promise.defer(); + console.log("Calling", this.url); + + request({ + method: "POST", + uri: url, + followRedirect: true, + form: { + path: path, + shareWith: shareWith, + shareType: shareType + }, + auth: { + user: "admin", + password: "password", + } + }, + function(error, response) { + console.log("Done call to", url, "status:", response.statusCode); + if (error || response.statusCode >= 400) { + defer.reject({ + error : error, + response : response + }); + } else { + defer.fulfill(response); + } + }); + return defer.promise; + + }; + + module.exports = ShareApi; + +})(); + + + diff --git a/tests/acceptance/tests/pages/user.page.js b/tests/acceptance/tests/pages/user.page.js new file mode 100644 index 0000000000..9a973bd42c --- /dev/null +++ b/tests/acceptance/tests/pages/user.page.js @@ -0,0 +1,114 @@ +(function() { + var UserPage = function(baseUrl) { + this.baseUrl = baseUrl; + this.path = 'index.php/settings/users'; + this.url = baseUrl + this.path; + + this.newUserNameInput = element(by.id('newusername')); + this.newUserPasswordInput = element(by.id('newuserpassword')); + this.createNewUserButton = element(by.css('#newuser input[type="submit"]')); + + this.newGroupButton = element(by.css('#newgroup-init a')); + this.newGroupNameInput = element(by.css('#newgroup-form input#newgroupname')); + + }; + + UserPage.prototype.get = function() { + browser.get(this.url); + }; + + UserPage.prototype.isUserPage = function() { + return browser.driver.getCurrentUrl() == this.url; + }; + + UserPage.prototype.ensureUserPage = function() { + // console.log(this.isUserPage()); + // if (! this.isUserPage()) { + // display.log('Warning: Auto loading UserPage'); + // this.get(); + // } + }; + + UserPage.prototype.fillNewUserInput = function(user, pass) { + this.ensureUserPage(); + this.newUserNameInput.sendKeys(user); + this.newUserPasswordInput.sendKeys(pass); + }; + + UserPage.prototype.createNewUser = function(user, pass) { + this.ensureUserPage(); + this.fillNewUserInput(user, pass); + this.createNewUserButton.click(); + }; + + UserPage.prototype.deleteUser = function(user) { + this.ensureUserPage(); + + var removeId = by.css('#userlist tr[data-displayname="' + user + '"] td.remove a'); + var filter = browser.findElement(removeId); + var scrollIntoView = function () { + arguments[0].scrollIntoView(); + } + browser.executeScript(scrollIntoView, filter).then(function () { + browser.actions().mouseMove(browser.findElement(removeId)).perform(); + element(removeId).click(); + }); + }; + + UserPage.prototype.setCurrentListElem = function(name) { + return element(by.css("tr[data-uid='" + name + "']")); + } + + UserPage.prototype.renameDisplayName = function(name, newName) { + var renameDisplayNameButton = element(by.css("tr[data-uid='" + name + "'] td.displayName")); + renameDisplayNameButton.click(); + var renameDisplayNameForm = element(by.css("tr[data-uid='" + name + "'] td.displayName input")); + renameDisplayNameForm.sendKeys(newName); + renameDisplayNameForm.sendKeys(protractor.Key.ENTER); + }; + + UserPage.prototype.listUser = function() { + this.ensureUserPage(); + return element.all(by.css('td.displayName')).map(function(user) { + return user.getText(); + }); + }; + + UserPage.prototype.createNewGroup = function(name) { + this.newGroupButton.click(); + var newGroupNameInput = this.newGroupNameInput; + browser.wait(function() { + return newGroupNameInput.isDisplayed(); + }, 3000); + this.newGroupNameInput.sendKeys(name); + this.newGroupNameInput.sendKeys(protractor.Key.ENTER); + }; + +///// NOT WORKING, CLICK ON CHECKBOX RESEIVES AN OTHER ELEMENT ////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // UserPage.prototype.setUserGroup = function(userName, groupName) { + // var renameDisplayNameButton = element(by.css("tr[data-uid='" + userName + "'] td.groups .multiselect.button")); + // renameDisplayNameButton.click(); + + // var a = 'tr[data-uid="' + userName + '"] ul.multiselectoptions.down'; + + // var dropdown = element(by.css(a)); + // browser.wait(function() { + // return dropdown.isDisplayed(); + // }, 3000); + // browser.pause(); + // var checkboxId = by.css('tr[data-uid="' + userName + '"] ul.multiselectoptions.down label'); + // element.all(checkboxId).each(function(checkbox) { + // checkbox.getText().then(function(text) { + // console.log(checkboxId); + // console.log(text); + // if(text == groupName) { + // return checkbox.click(); + // } + // }) + // }); + // }; + + module.exports = UserPage; +})(); \ No newline at end of file diff --git a/tests/acceptance/tests/pages/webdav_api.page.js b/tests/acceptance/tests/pages/webdav_api.page.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/acceptance/tests/share/share_api_spec.js b/tests/acceptance/tests/share/share_api_spec.js new file mode 100644 index 0000000000..59274cde25 --- /dev/null +++ b/tests/acceptance/tests/share/share_api_spec.js @@ -0,0 +1,50 @@ +var ShareApi = require('../pages/shareApi.page.js'); +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); +var FilesPage = require('../pages/files.page.js'); +var parseXml = require('xml2js').parseString; + +var flow = protractor.promise.controlFlow(); + +ddescribe('Share Api', function() { + var params = browser.params; + var shareApi; + var loginPage; + var userPage + var filesPage; + var firstRunWizardPage; + + + beforeEach(function() { + isAngularSite(false); + shareApi = new ShareApi(params.baseUrl); + }); + + it('should get all shares', function() { + var get = function () { + return shareApi.get(); + }; + + flow.execute(get).then(function(res){ + parseXml(res.body, function (err, result) { + console.dir(result.ocs.data); + }); + expect(res.statusCode).toEqual(200); + }); + }); + + it('should create a new share', function() { + var create = function () { + return shareApi.create('asdf.txt', 'demo2', 0); + }; + + flow.execute(create).then(function(res){ + parseXml(res.body, function (err, result) { + console.log(result.ocs.data, result.ocs.meta); + expect(result.ocs.meta[0].statuscode[0]).toEqual('100'); + }); + }); + }); + + +}); \ No newline at end of file diff --git a/tests/acceptance/tests/share/share_spec.js b/tests/acceptance/tests/share/share_spec.js new file mode 100644 index 0000000000..0dc12ad506 --- /dev/null +++ b/tests/acceptance/tests/share/share_spec.js @@ -0,0 +1,198 @@ +var LoginPage = require('../pages/login.page.js'); +var UserPage = require('../pages/user.page.js'); +var FilesPage = require('../pages/files.page.js'); + + +describe('Share', function() { + var params = browser.params; + var loginPage; + var userPage + var filesPage; + + beforeEach(function() { + isAngularSite(false); + loginPage = new LoginPage(params.baseUrl); + userPage = new UserPage(params.baseUrl); + filesPage = new FilesPage(params.baseUrl); + }); + + it('should login as admin and create 4 new users', function() { + filesPage.getAsUser(params.login.user, params.login.password); + // userPage.get(); + // userPage.createNewGroup('test_specGroup_1'); + userPage.get(); + // userPage.createNewGroup('test_specGroup_2'); + userPage.createNewUser('demo', 'password'); + userPage.createNewUser('demo2', 'password'); + userPage.createNewUser('demo3', 'password'); + userPage.createNewUser('demo4', 'password'); + userPage.get(); + userPage.renameDisplayName('demo2', ' display2'); + userPage.renameDisplayName('demo3', ' display3'); + userPage.renameDisplayName('demo4', ' display4'); + // setting Group to User fails cause click receives an other element + // userPage.setUserGroup('demo2', 'test_specGroup_1'); + // userPage.setUserGroup('demo3', 'test_specGroup_1'); + // userPage.setUserGroup('demo4', 'test_specGroup_2'); + expect(userPage.listUser()).toContain('demo', 'demo2', 'demo3', 'demo4'); + }); + + + it('should share a folder with another user by username', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewFolder('toShare_1'); + browser.sleep(500); + filesPage.shareFile('toShare_1', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + expect(filesPage.listFiles()).toContain('toShare_1'); + }); + + it('should share a folder including special characters', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewFolder('sP€c!@L'); + browser.sleep(500); + filesPage.shareFile('sP€c!@L', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + expect(filesPage.listFiles()).toContain('sP€c!@L'); + }); + + it('should share a folder with 3 another user by display name', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewFolder('toShare_2'); + browser.sleep(500); + filesPage.shareFile('toShare_2', 'display2'); + + filesPage.shareWithForm.sendKeys(protractor.Key.DELETE); + filesPage.shareWithForm.sendKeys('display3'); + browser.wait(function(){ + return filesPage.sharedWithDropdown.isDisplayed(); + }, 3000); + filesPage.shareWithForm.sendKeys(protractor.Key.ENTER); + + filesPage.shareWithForm.sendKeys(protractor.Key.DELETE); + filesPage.shareWithForm.sendKeys('display4'); + browser.wait(function(){ + return filesPage.sharedWithDropdown.isDisplayed(); + }, 3000); + filesPage.shareWithForm.sendKeys(protractor.Key.ENTER); + + loginPage.logout(); + loginPage.login('demo2', 'password'); + expect(filesPage.listFiles()).toContain('toShare_2'); + + loginPage.logout(); + loginPage.login('demo3', 'password'); + expect(filesPage.listFiles()).toContain('toShare_2'); + + loginPage.logout(); + loginPage.login('demo4', 'password'); + expect(filesPage.listFiles()).toContain('toShare_2'); + }); + + it('should grant second users CRUDS rights to their folder', function() { + filesPage.getAsUser('demo2', 'password'); + filesPage.getFolder('toShare_2'); + + //create file + filesPage.createNewTxtFile('inSharedBySecond'); + filesPage.createNewTxtFile('toBeDeleted'); + expect(filesPage.listFiles()).toContain('inSharedBySecond' ,'toBeDeleted'); + + //delete file + filesPage.deleteFile('toBeDeleted.txt'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('toBeDeleted'); + + + //share file + filesPage.shareFile('inSharedBySecond.txt', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + filesPage.renameFile('inSharedBySecond.txt', 'renamedBySecond.txt') + expect(filesPage.listFiles()).toContain('renamedBySecond'); + filesPage.deleteFile('renamedBySecond.txt'); + }); + + it('should delete the root folder shared with a user account by another user', function() { + filesPage.getAsUser('demo2', 'password'); + filesPage.deleteFile('toShare_2'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('toShare_2'); + + loginPage.logout(); + loginPage.login(params.login.user, params.login.password); + expect(filesPage.listFiles()).toContain('toShare_2'); + }); + + it('should delete a file shared with a user, only form user if user deletes it', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewTxtFile('toDeleteByUser'); + filesPage.shareFile('toDeleteByUser.txt', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + filesPage.deleteFile('toDeleteByUser.txt'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('inSharedBySecond'); + + loginPage.logout(); + loginPage.login(params.login.user, params.login.password); + expect(filesPage.listFiles()).toContain('toDeleteByUser'); + filesPage.deleteFile('toDeleteByUser.txt'); + }); + + it('should delete a file in a shared folder, from all', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.getFolder('toShare_1'); + filesPage.createNewTxtFile('toDeleteFromAll'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + filesPage.getFolder('toShare_1'); + filesPage.deleteFile('toDeleteFromAll.txt'); + browser.sleep(800); + expect(filesPage.listFiles()).not.toContain('toDeleteFormAll'); + + loginPage.logout(); + loginPage.login(params.login.user, params.login.password); + filesPage.getFolder('toShare_1'); + expect(filesPage.listFiles()).not.toContain('toDeleteFromAll'); + }); + + it('should delete a file shared with a user, form all if owner deletes it', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewTxtFile('toDeleteByOwner'); + filesPage.shareFile('toDeleteByOwner.txt', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + expect(filesPage.listFiles()).toContain('toDeleteByOwner'); + + loginPage.logout(); + loginPage.login(params.login.user, params.login.password); + filesPage.deleteFile('toDeleteByOwner.txt'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + expect(filesPage.listFiles()).not.toContain('toDeleteByOwner'); + + }); + + it('should not be possible to reshare a folder, if the "re-share" option is removed', function() { + filesPage.getAsUser(params.login.user, params.login.password); + filesPage.createNewFolder('noReshare'); + filesPage.shareFile('noReshare', 'demo'); + filesPage.disableReshare('noReshare', 'demo'); + + loginPage.logout(); + loginPage.login('demo', 'password'); + + expect(filesPage.checkReshareability('noReshare')).toBeFalsy(); + }); + +}); \ No newline at end of file