diff options
author | Vincent Petry <pvince81@owncloud.com> | 2014-09-03 16:32:55 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2014-09-03 16:32:55 +0200 |
commit | 56eedca2c3102ede8f17d48a57ef0cb4f89cc892 (patch) | |
tree | 7ba59cfe21d3eeff48cfdb14cc707210d689b465 /tests | |
parent | 90f66e0f8dd3be1133c89a61ba09a8c3e0de7d07 (diff) | |
download | nextcloud-server-56eedca2c3102ede8f17d48a57ef0cb4f89cc892.tar.gz nextcloud-server-56eedca2c3102ede8f17d48a57ef0cb4f89cc892.zip |
Added acceptance tests for enabling apps
This tests whether a user can see navigation entries after enabling
apps. This includes the app's group restriction.
This currently expects that a group "group1" exists until we have code
to auto-generate groups.
This commit also provides a utility function
Page.multiselectSetSelection() to make it possible to select entries
inside a multiselect.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/acceptance/protractor_conf.js | 3 | ||||
-rw-r--r-- | tests/acceptance/tests/apps/apps_spec.js | 87 | ||||
-rw-r--r-- | tests/acceptance/tests/helper/page.js | 102 | ||||
-rw-r--r-- | tests/acceptance/tests/pages/apps.page.js | 121 |
4 files changed, 304 insertions, 9 deletions
diff --git a/tests/acceptance/protractor_conf.js b/tests/acceptance/protractor_conf.js index d50ec88913e..e89e79e5478 100644 --- a/tests/acceptance/protractor_conf.js +++ b/tests/acceptance/protractor_conf.js @@ -19,13 +19,14 @@ exports.config = { baseUrl: "http://127.0.0.1/", login: { user: 'admin', - password: 'password' + password: 'password' } }, suites: { install: 'tests/install/**/*_spec.js', login: 'tests/login/**/*_spec.js', + apps: 'tests/apps/**/*_spec.js', files: 'tests/files/**/*_spec.js', share: 'tests/share/**/*_spec.js', }, diff --git a/tests/acceptance/tests/apps/apps_spec.js b/tests/acceptance/tests/apps/apps_spec.js new file mode 100644 index 00000000000..0b7937f97ab --- /dev/null +++ b/tests/acceptance/tests/apps/apps_spec.js @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global element, browser, require */ +var Page = require('../helper/page.js'); +var AppsPage = require('../pages/apps.page.js'); +var LoginPage = require('../pages/login.page.js'); + +describe('Enabling apps', function() { + var testApp; + var params = browser.params; + var loginPage; + var appsPage; + var testGroup; + + beforeEach(function() { + isAngularSite(false); + // app to test, must have a navigation entry and allow group restriction + testApp = 'calendar'; + // group to test, additionally to "admin" + testGroup = 'group1'; + loginPage = new LoginPage(params.baseUrl); + appsPage = new AppsPage(params.baseUrl); + + loginPage.get(); + loginPage.login(params.login.user, params.login.password); + appsPage.get(); + }); + + afterEach(function() { + Page.logout(); + }); + + it('user should see enabled app', function() { + appsPage.enableApp(testApp, true, null).then(function() { + // reload page + appsPage.get(); + Page.toggleAppsMenu(); + expect(element(Page.appMenuEntryId(testApp + '_index')).isPresent()).toBe(true); + }); + }); + + it('user should not see disabled app', function() { + appsPage.enableApp(testApp, false, null).then(function() { + // reload page + appsPage.get(); + Page.toggleAppsMenu(); + expect(element(Page.appMenuEntryId(testApp + '_index')).isPresent()).toBe(false); + }); + }); + + it('group member should see app when enabled in that group', function() { + appsPage.enableApp(testApp, true, ['admin']).then(function() { + // reload page + appsPage.get(); + Page.toggleAppsMenu(); + expect(element(Page.appMenuEntryId(testApp + '_index')).isPresent()).toBe(true); + }); + }); + + it('group member should not see app when enabled in another group', function() { + appsPage.enableApp(testApp, true, ['group1']).then(function() { + // reload page + appsPage.get(); + Page.toggleAppsMenu(); + expect(element(Page.appMenuEntryId(testApp + '_index')).isPresent()).toBe(false); + }); + }); + + it('group member should see app when all groups deselected (all case)', function() { + // when selecting no groups, it will show "All" even though the checkboxes + // are not checked + appsPage.enableApp(testApp, true, []).then(function() { + // reload page + appsPage.get(); + Page.toggleAppsMenu(); + expect(element(Page.appMenuEntryId(testApp + '_index')).isPresent()).toBe(false); + }); + }); +}); diff --git a/tests/acceptance/tests/helper/page.js b/tests/acceptance/tests/helper/page.js index 9a86e95d929..98545032bea 100644 --- a/tests/acceptance/tests/helper/page.js +++ b/tests/acceptance/tests/helper/page.js @@ -1,14 +1,100 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global protractor, module, element, by, browser */ (function() { + var Page = function() { + + }; + + Page.prototype.moveMouseTo = function(locator) { + var ele = element(locator); + return browser.actions().mouseMove(ele).perform(); + }; + + Page.toggleAppsMenu = function() { + var el = element(this.appsMenuId()); + return el.click(); + }; + + Page.logout = function() { + element(Page.settingsMenuId()).click(); + element(by.id('logout')).click(); + browser.sleep(300); + }; + + //================ LOCATOR FUNCTIONS ====================================// + Page.appsMenuId = function() { + return by.css('#header .menutoggle'); + }; + + Page.appMenuEntryId = function(appId) { + return by.css('nav #apps [data-id=\'' + appId + '\']'); + }; + + Page.settingsMenuId = function() { + return by.css('#header #settings'); + }; + + //================ UTILITY FUNCTIONS ====================================// + + /** + * Sets the selection of a multiselect element + * + * @param el select element of the multiselect + * @param {Array} id of the values to select + */ + Page.multiSelectSetSelection = function(el, selection) { + var d = protractor.promise.defer(); + var dropDownEl = element(by.css('.multiselectoptions.down')); + + el.click(); + + function processEntry(entry) { + entry.isSelected().then(function(selected) { + entry.getAttribute('id').then(function(inputId) { + // format is "ms0-option-theid", we extract that id + var dataId = inputId.split('-')[2]; + var mustBeSelected = selection.indexOf(dataId) >= 0; + // if state doesn't match what we want, toggle - - var Page = function() { + if (selected !== mustBeSelected) { + // need to click on the label, not input + entry.element(by.xpath('following-sibling::label')).click(); + // confirm that the checkbox was set + browser.wait(function() { + return entry.isSelected().then(function(newSelection) { + return newSelection === mustBeSelected; + }); + }); + } + }); + }); + } - }; + browser.wait(function() { + return dropDownEl.isPresent(); + }, 1000).then(function() { + dropDownEl.all(by.css('[type=checkbox]')).then(function(entries) { + for (var i = 0; i < entries.length; i++) { + processEntry(entries[i]); + } + // give it some time to save changes + browser.sleep(300).then(function() { + d.fulfill(true); + }); + }); + }); - Page.prototype.moveMouseTo = function(locator) { - var ele = element(locator); - return browser.actions().mouseMove(ele).perform(); - } + return d.promise; + }; - module.exports = Page; + module.exports = Page; })(); diff --git a/tests/acceptance/tests/pages/apps.page.js b/tests/acceptance/tests/pages/apps.page.js new file mode 100644 index 00000000000..eb018979c90 --- /dev/null +++ b/tests/acceptance/tests/pages/apps.page.js @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global module, protractor, element, by, browser, require */ +(function() { + var Page = require('../helper/page.js'); + + var AppsPage = function(baseUrl) { + this.baseUrl = baseUrl; + this.path = 'index.php/settings/apps'; + this.url = baseUrl + this.path; + + this.appList = element(by.css('#app-navigation .applist')); + }; + + //================ LOCATOR FUNCTIONS ====================================// + AppsPage.prototype.appId = function(appId) { + return by.css('#app-navigation .applist [data-id=\'' + appId + '\']'); + }; + + AppsPage.prototype.enableButtonId = function() { + return by.css('#app-content .appinfo .enable'); + }; + + AppsPage.prototype.groupsEnableCheckboxId = function() { + return by.id('groups_enable'); + }; + + AppsPage.prototype.groupsEnableListId = function() { + return by.css('#app-content .multiselect.button'); + }; + //================ SHARED ===============================================// + + AppsPage.prototype.get = function() { + browser.get(this.url); + + var appList = this.appList; + browser.wait(function() { + return appList.isDisplayed(); + }, 5000, 'load app page'); + }; + + /** + * Enables or disables the given app. + * + * @param {String} appId app id + * @param {bool} [state] true (default) to enable the app, false otherwise + * @param {Array} [groups] groups for which to enable the app or null to disable + * group selection. If not specified (undefined), the group checkbox, if it exists, + * will be left as is. + */ + AppsPage.prototype.enableApp = function(appId, state, groups) { + var d = protractor.promise.defer(); + if (state === undefined) { + state = true; + } + + var enableButton = element(this.enableButtonId()); + + element(this.appId(appId)).click(); + browser.wait(function() { + return enableButton.isPresent(); + }, 800); + + // an app is already enabled if the button value is "Disable" + enableButton.getAttribute('value').then(function(attr) { + if (state !== (attr === 'Disable')) { + enableButton.click(); + } + }); + + // wait for the button to change its attribute + browser.wait(function() { + return enableButton.getAttribute('value').then(function(attr) { + return attr === state ? 'Disable' : 'Enable'; + }); + }, 800); + + if (state && groups !== undefined) { + var groupsCheckbox = element(this.groupsEnableCheckboxId()); + var hasGroups = false; + + if (groups && groups.length > 0) { + hasGroups = true; + } + + // check/uncheck checkbox to match desired state + groupsCheckbox.isSelected().then(function(checkboxState) { + if (hasGroups !== checkboxState) { + groupsCheckbox.click(); + } + }); + + // wait for checkbox to change state + browser.wait(function() { + return groupsCheckbox.isSelected().then(function(checkboxState) { + return hasGroups === checkboxState; + }); + }, 800); + + if (hasGroups) { + var groupsList = element(this.groupsEnableListId()); + Page.multiSelectSetSelection(groupsList, groups).then(function() { + d.fulfill(true); + }); + } else { + d.fulfill(true); + } + } + return d.promise; + }; + + module.exports = AppsPage; +})(); |