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:
parent
90f66e0f8d
commit
56eedca2c3
|
@ -26,6 +26,7 @@ exports.config = {
|
||||||
suites: {
|
suites: {
|
||||||
install: 'tests/install/**/*_spec.js',
|
install: 'tests/install/**/*_spec.js',
|
||||||
login: 'tests/login/**/*_spec.js',
|
login: 'tests/login/**/*_spec.js',
|
||||||
|
apps: 'tests/apps/**/*_spec.js',
|
||||||
files: 'tests/files/**/*_spec.js',
|
files: 'tests/files/**/*_spec.js',
|
||||||
share: 'tests/share/**/*_spec.js',
|
share: 'tests/share/**/*_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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,6 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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() {
|
(function() {
|
||||||
|
|
||||||
|
|
||||||
var Page = function() {
|
var Page = function() {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -8,7 +17,84 @@
|
||||||
Page.prototype.moveMouseTo = function(locator) {
|
Page.prototype.moveMouseTo = function(locator) {
|
||||||
var ele = element(locator);
|
var ele = element(locator);
|
||||||
return browser.actions().mouseMove(ele).perform();
|
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
|
||||||
|
|
||||||
|
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;
|
module.exports = Page;
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -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;
|
||||||
|
})();
|
Loading…
Reference in New Issue