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.
This commit is contained in:
Vincent Petry 2014-09-03 16:32:55 +02:00
parent 90f66e0f8d
commit 56eedca2c3
4 changed files with 304 additions and 9 deletions

View File

@ -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',
},

View File

@ -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);
});
});
});

View File

@ -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() {
var Page = function() {
};
};
Page.prototype.moveMouseTo = function(locator) {
var ele = element(locator);
return browser.actions().mouseMove(ele).perform();
};
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();
};
module.exports = Page;
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
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);
});
});
});
return d.promise;
};
module.exports = Page;
})();

View File

@ -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;
})();