diff --git a/gradle.properties b/gradle.properties index 72d705f98..d03e54a05 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # Project settings # version=7.16.0-SNAPSHOT -libAdminUiVersion=5.0.0-SNAPSHOT +libAdminUiVersion=5.1.0-SNAPSHOT systemProp.org.gradle.internal.http.connectionTimeout=120000 systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/src/main/resources/admin/tools/main/main.js b/src/main/resources/admin/tools/main/main.js index 34bc0d65e..be4342eaa 100644 --- a/src/main/resources/admin/tools/main/main.js +++ b/src/main/resources/admin/tools/main/main.js @@ -5,8 +5,11 @@ const mustache = require('/lib/mustache'); const portal = require('/lib/xp/portal'); const i18n = require('/lib/xp/i18n'); const assetLib = require('/lib/enonic/asset'); +const authLib = require('/lib/xp/auth'); function getConfigAsJson() { + const user = authLib.getUser(); + return JSON.stringify({ adminUrl: admin.getBaseUri(), appId: app.name, @@ -42,6 +45,8 @@ function getConfigAsJson() { theme: 'dark', } }), + user, + principals: authLib.getMemberships(user.key, true) }, null, 4).replace(/<(\/?script|!--)/gi, "\\u003C$1"); } diff --git a/src/main/resources/assets/js/app/browse/UserBrowsePanel.ts b/src/main/resources/assets/js/app/browse/UserBrowsePanel.ts index 83ae5f1bf..46901bd19 100644 --- a/src/main/resources/assets/js/app/browse/UserBrowsePanel.ts +++ b/src/main/resources/assets/js/app/browse/UserBrowsePanel.ts @@ -56,6 +56,11 @@ export class UserBrowsePanel this.appendUserItemNode(principal, idProvider); this.setRefreshOfFilterRequired(); + // IdProvider type + if (!principal) { + this.treeListBox.resetIdProviders(); + } + /* In case you switch to UserBrowsePanel before this event occured you need to trigger refresh manually Otherwise 'shown' event won't update filter @@ -75,6 +80,7 @@ export class UserBrowsePanel if (!principal) { // IdProvider type userTreeGridItem = builder.setIdProvider(idProvider).setType(UserTreeGridItemType.ID_PROVIDER).build(); + this.treeListBox.resetIdProviders(); } else { // Principal type userTreeGridItem = builder.setPrincipal(principal).setIdProvider(idProvider).setType(UserTreeGridItemType.PRINCIPAL).build(); } @@ -92,6 +98,10 @@ export class UserBrowsePanel this.selectionWrapper.deselect(item); this.findParentList(item).forEach((list) => list.removeItems(item)); } + + if (!item || item.isIdProvider()) { + this.treeListBox.resetIdProviders(); + } }); if (this.treeListBox.isFiltered() && this.treeListBox.getItems().length === 0) { diff --git a/src/main/resources/assets/js/app/browse/UserItemsTreeRootList.ts b/src/main/resources/assets/js/app/browse/UserItemsTreeRootList.ts index 09c4a4155..1e6a7cad2 100644 --- a/src/main/resources/assets/js/app/browse/UserItemsTreeRootList.ts +++ b/src/main/resources/assets/js/app/browse/UserItemsTreeRootList.ts @@ -12,7 +12,7 @@ export class UserItemsTreeRootList extends UserItemsTreeList { private searchString: string; private searchTypes: UserItemType[]; - private latestIdProviders: IdProvider[]; + private cachedIdProviders: IdProvider[]; private constraintItems: string[]; setSearchString(searchString: string): this { @@ -37,11 +37,14 @@ export class UserItemsTreeRootList extends UserItemsTreeList { resetFilter(): void { this.searchString = null; this.searchTypes = null; - this.latestIdProviders = null; this.constraintItems = null; this.load(); } + resetIdProviders(): void { + this.cachedIdProviders = null; + } + protected fetchRoot(): Q.Promise { if (this.isFiltered()) { return this.fetchFilteredItems(); @@ -51,28 +54,21 @@ export class UserItemsTreeRootList extends UserItemsTreeList { } private fetchFilteredItems(): Q.Promise { - // load list of idproviders to set for filtered users/groups - const idProvidersPromise = this.latestIdProviders ? Q.resolve() : new ListIdProvidersRequest().sendAndParse().then((idProviders) => { - this.latestIdProviders = idProviders; - return Q.resolve(); - }).catch(DefaultErrorHandler.handle); - - - return idProvidersPromise.then(() => { - return new ListUserItemsRequest() - .setCount(20) - .setTypes(this.searchTypes) - .setItems(this.constraintItems) - .setQuery(this.searchString) - .setStart(this.getItemCount()) - .sendAndParse() - .then((result) => { - return result.userItems.map(userItem => { + return new ListUserItemsRequest() + .setCount(20) + .setTypes(this.searchTypes) + .setItems(this.constraintItems) + .setQuery(this.searchString) + .setStart(this.getItemCount()) + .sendAndParse() + .then((userItemsResponse) => { + return this.getIdProviders().then((idProviders) => { + return userItemsResponse.userItems.map(userItem => { const builder = new UserTreeGridItemBuilder(); if (userItem instanceof Principal) { - const idProv = this.latestIdProviders.find(idProv => idProv.getKey().equals(userItem.getKey().getIdProvider())); - builder.setPrincipal(userItem).setIdProvider(idProv).setType(UserTreeGridItemType.PRINCIPAL); + const idProv = idProviders.find(idProv => idProv.getKey().equals(userItem.getKey().getIdProvider())); + builder.setPrincipal(userItem).setIdProvider(idProv).setType(UserTreeGridItemType.PRINCIPAL); } else if (userItem instanceof IdProvider) { builder.setIdProvider(userItem).setType(UserTreeGridItemType.ID_PROVIDER); } @@ -80,8 +76,21 @@ export class UserItemsTreeRootList extends UserItemsTreeList { return builder.build(); }); }); - }); + }); + } + private getIdProviders(): Q.Promise { + if (this.cachedIdProviders) { + return Q.resolve(this.cachedIdProviders.slice()); + } + + return new ListIdProvidersRequest().sendAndParse().then((result) => { + this.cachedIdProviders = result; + return this.cachedIdProviders.slice(); + }).catch(() => { + DefaultErrorHandler.handle('Failed to load id providers'); + return []; + }); } isLoadAllowed(): boolean { diff --git a/src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts b/src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts index d3d602145..94c91f19d 100644 --- a/src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts +++ b/src/main/resources/assets/js/app/create/UserItemTypesTreeGrid.ts @@ -9,14 +9,13 @@ import {Group, GroupBuilder} from '../principal/Group'; import {Role, RoleBuilder} from '../principal/Role'; import {PrincipalKey} from '@enonic/lib-admin-ui/security/PrincipalKey'; import {PrincipalType} from '@enonic/lib-admin-ui/security/PrincipalType'; -import {IsAuthenticatedRequest} from '@enonic/lib-admin-ui/security/auth/IsAuthenticatedRequest'; import {IdProviderKey} from '@enonic/lib-admin-ui/security/IdProviderKey'; import {i18n} from '@enonic/lib-admin-ui/util/Messages'; import {DefaultErrorHandler} from '@enonic/lib-admin-ui/DefaultErrorHandler'; -import {LoginResult} from '@enonic/lib-admin-ui/security/auth/LoginResult'; import {UserItem} from '@enonic/lib-admin-ui/security/UserItem'; import {TreeListBox, TreeListBoxParams, TreeListElement, TreeListElementParams} from '@enonic/lib-admin-ui/ui/selector/list/TreeListBox'; import {UserTypesTreeGridItemViewer} from './UserTypesTreeGridItemViewer'; +import {AuthHelper} from '@enonic/lib-admin-ui/auth/AuthHelper'; export class UserItemTypesTreeGrid extends TreeListBox { @@ -76,13 +75,7 @@ export class UserItemTypesTreeGrid } private fetchRoot(): Q.Promise { - return Q.all([new IsAuthenticatedRequest().sendAndParse(), this.fetchIdProviders()]).then( - (result: [LoginResult, IdProvider[]]) => result[0].isUserAdmin(), - reason => { - DefaultErrorHandler.handle(reason); - return false; - } - ).then(userIsAdmin => [ + return this.fetchIdProviders().then(() => [ new UserTypeTreeGridItemBuilder() .setUserItem(new UserBuilder() .setKey(new PrincipalKey(IdProviderKey.SYSTEM, PrincipalType.USER, 'user')) @@ -93,7 +86,7 @@ export class UserItemTypesTreeGrid .setKey(new PrincipalKey(IdProviderKey.SYSTEM, PrincipalType.GROUP, 'user-group')) .setDisplayName(i18n('field.userGroup')) .build()).build(), - ...((this.presetIdProvider || !userIsAdmin) ? [] : [ + ...((this.presetIdProvider || !AuthHelper.isUserAdmin()) ? [] : [ new UserTypeTreeGridItemBuilder() .setUserItem(new IdProviderBuilder() .setKey(IdProviderKey.SYSTEM.toString()) diff --git a/src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts b/src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts index 9972dc716..b44c7f10a 100644 --- a/src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts +++ b/src/main/resources/assets/js/app/view/UserItemStatisticsPanel.ts @@ -13,10 +13,8 @@ import {Principal} from '@enonic/lib-admin-ui/security/Principal'; import {PrincipalType} from '@enonic/lib-admin-ui/security/PrincipalType'; import {PrincipalKey} from '@enonic/lib-admin-ui/security/PrincipalKey'; import {PrincipalViewer} from '@enonic/lib-admin-ui/ui/security/PrincipalViewer'; -import {RoleKeys} from '@enonic/lib-admin-ui/security/RoleKeys'; import {DivEl} from '@enonic/lib-admin-ui/dom/DivEl'; import {Path} from '@enonic/lib-admin-ui/rest/Path'; -import {IsAuthenticatedRequest} from '@enonic/lib-admin-ui/security/auth/IsAuthenticatedRequest'; import {AppHelper} from '@enonic/lib-admin-ui/util/AppHelper'; import {i18n} from '@enonic/lib-admin-ui/util/Messages'; import {DefaultErrorHandler} from '@enonic/lib-admin-ui/DefaultErrorHandler'; @@ -25,10 +23,10 @@ import {CheckboxBuilder} from '@enonic/lib-admin-ui/ui/Checkbox'; import {Element} from '@enonic/lib-admin-ui/dom/Element'; import {Button} from '@enonic/lib-admin-ui/ui/button/Button'; import {UserItemStatisticsHeader} from './UserItemStatisticsHeader'; -import {LoginResult} from '@enonic/lib-admin-ui/security/auth/LoginResult'; import {CONFIG} from '@enonic/lib-admin-ui/util/Config'; import {MembersListing} from './MembersListing'; import {SelectionChange} from '@enonic/lib-admin-ui/util/SelectionChange'; +import {AuthHelper} from '@enonic/lib-admin-ui/auth/AuthHelper'; export class UserItemStatisticsPanel extends ItemStatisticsPanel { @@ -198,9 +196,7 @@ export class UserItemStatisticsPanel } private async createReportGroup(principal: Principal): Promise { - const isAdmin = await new IsAuthenticatedRequest().sendAndParse().then((loginResult: LoginResult) => { - return loginResult.getPrincipals().some(key => key.equals(RoleKeys.ADMIN)); - }); + const isAdmin = AuthHelper.isAdmin(); if(!isAdmin) { return Q(null); } diff --git a/src/main/resources/assets/js/main.ts b/src/main/resources/assets/js/main.ts index 60476eb42..c4a7a7423 100644 --- a/src/main/resources/assets/js/main.ts +++ b/src/main/resources/assets/js/main.ts @@ -19,6 +19,9 @@ import {InputTypeManager} from '@enonic/lib-admin-ui/form/inputtype/InputTypeMan import {Class} from '@enonic/lib-admin-ui/Class'; import {JSONObject} from '@enonic/lib-admin-ui/types'; import {LauncherHelper} from '@enonic/lib-admin-ui/util/LauncherHelper'; +import {AuthContext} from '@enonic/lib-admin-ui/auth/AuthContext'; +import {Principal} from '@enonic/lib-admin-ui/security/Principal'; +import {PrincipalJson} from '@enonic/lib-admin-ui/security/PrincipalJson'; const body = Body.get(); @@ -92,6 +95,8 @@ function startApplication() { const configScriptEl: HTMLElement = document.getElementById(configScriptId); CONFIG.setConfig(JSON.parse(configScriptEl.innerText) as JSONObject); + AuthContext.init(Principal.fromJson(CONFIG.get('user') as PrincipalJson), + (CONFIG.get('principals') as PrincipalJson[]).map(Principal.fromJson)); await i18nInit(CONFIG.getString('apis.i18nUrl')); startApplication(); diff --git a/testing/libs/test.utils.js b/testing/libs/test.utils.js index edf78664e..76a0cb0e3 100644 --- a/testing/libs/test.utils.js +++ b/testing/libs/test.utils.js @@ -61,6 +61,7 @@ module.exports = { let confirmationDialog = new ConfirmationDialog(); await this.findAndSelectItem(name); await browsePanel.waitForDeleteButtonEnabled(); + await browsePanel.pause(1000); await browsePanel.clickOnDeleteButton(); await confirmationDialog.waitForDialogLoaded(); await confirmationDialog.clickOnYesButton(); @@ -199,7 +200,7 @@ module.exports = { } //2. Open New Principal dialog: await browsePanel.waitForNewButtonEnabled(); - await browsePanel.pause(400); + await browsePanel.pause(1000); await browsePanel.clickOnNewButton(); await newPrincipalDialog.waitForDialogLoaded(); //3. Click on Group item in the modal dialog: @@ -266,7 +267,8 @@ module.exports = { await this.findAndSelectItem(displayName); await browsePanel.waitForEditButtonEnabled(); await browsePanel.clickOnEditButton(); - return await roleWizard.waitForLoaded(); + await roleWizard.waitForLoaded(); + await roleWizard.pause(500); } catch (err) { throw new Error("Error when open the role: " + err); } diff --git a/testing/page_objects/browsepanel/userbrowse.panel.js b/testing/page_objects/browsepanel/userbrowse.panel.js index 21496f4f5..1dd94b10d 100644 --- a/testing/page_objects/browsepanel/userbrowse.panel.js +++ b/testing/page_objects/browsepanel/userbrowse.panel.js @@ -99,7 +99,7 @@ class UserBrowsePanel extends Page { isItemDisplayed(itemName) { return this.waitForElementDisplayed(xpath.rowByName(itemName), appConst.mediumTimeout).catch(err => { - console.log("item is not displayed:" + itemName + +" " + err); + console.log("item is not displayed: " + itemName); return false; }); } @@ -178,7 +178,8 @@ class UserBrowsePanel extends Page { async clickOnDeleteButton() { await this.waitForDeleteButtonEnabled(); - return await this.clickOnElement(this.deleteButton); + await await this.clickOnElement(this.deleteButton); + await this.pause(500); } isSearchButtonDisplayed() { @@ -198,7 +199,8 @@ class UserBrowsePanel extends Page { async waitForDeleteButtonEnabled() { try { - await this.waitForElementEnabled(this.deleteButton, appConst.mediumTimeout) + await this.waitForElementEnabled(this.deleteButton, appConst.mediumTimeout); + await this.pause(400); } catch (err) { let screenshot = await this.saveScreenshotUniqueName('err_delete_button_not_enabled'); throw new Error(`Delete button is not enabled ! Screenshot: ${screenshot} ` + err); diff --git a/testing/page_objects/confirmation.dialog.js b/testing/page_objects/confirmation.dialog.js index 5e302b525..2b9753677 100644 --- a/testing/page_objects/confirmation.dialog.js +++ b/testing/page_objects/confirmation.dialog.js @@ -38,10 +38,14 @@ class ConfirmationDialog extends Page { return this.clickOnElement(this.noButton); } - waitForDialogLoaded() { - return this.waitForElementDisplayed(XPATH.container, appConst.mediumTimeout).catch(err => { + async waitForDialogLoaded() { + try { + await this.waitForElementDisplayed(XPATH.container, appConst.mediumTimeout); + await this.pause(300); + } catch (err) { + let screenshot = await this.saveScreenshotUniqueName('err_confirmation_dialog'); throw new Error("Confirmation dialog was not loaded! " + err); - }) + } } isDialogLoaded() { diff --git a/testing/page_objects/wizardpanel/provider-config/first.idprovider.configurator.dialog.js b/testing/page_objects/wizardpanel/provider-config/first.idprovider.configurator.dialog.js index 43ca6e0d7..556ba782b 100644 --- a/testing/page_objects/wizardpanel/provider-config/first.idprovider.configurator.dialog.js +++ b/testing/page_objects/wizardpanel/provider-config/first.idprovider.configurator.dialog.js @@ -57,8 +57,9 @@ class FirstIdProviderConfiguratorDialog extends Page { return this.clickOnElement(this.applyButton); } - waitForApplyButtonEnabled() { - return this.waitForElementEnabled(this.applyButton, appConst.mediumTimeout); + async waitForApplyButtonEnabled() { + await this.waitForElementEnabled(this.applyButton, appConst.mediumTimeout); + await this.pause(200); } waitForApplyButtonDisabled() { @@ -77,10 +78,13 @@ class FirstIdProviderConfiguratorDialog extends Page { return this.isElementEnabled(this.domainInput); } - waitForClosed() { - return this.waitForElementNotDisplayed(XPATH.container, appConst.mediumTimeout).catch(error => { - throw new Error('ID Provider config Dialog was not closed'); - }); + async waitForClosed() { + try { + await this.waitForElementNotDisplayed(XPATH.container, appConst.mediumTimeout) + } catch (err) { + let screenshot = await this.saveScreenshotUniqueName('err_close_id_provider_config_dialog'); + throw new Error(`ID Provider config Dialog was not closed, screenshot:${screenshot} ` + err); + } } typeInDomainInput(domain) { diff --git a/testing/page_objects/wizardpanel/wizard.panel.js b/testing/page_objects/wizardpanel/wizard.panel.js index ecf6c9244..34a5dce8c 100644 --- a/testing/page_objects/wizardpanel/wizard.panel.js +++ b/testing/page_objects/wizardpanel/wizard.panel.js @@ -68,7 +68,7 @@ class WizardPanel extends Page { try { await this.waitForSaveButtonEnabled(); await this.clickOnElement(this.saveButton); - return await this.pause(900); + return await this.pause(700); } catch (err) { let screenshot = await this.saveScreenshotUniqueName('err_save_button'); throw new Error(`Error occurred during clicking on Save button ! ${screenshot} ` + err); diff --git a/testing/tests/idprovider.delete.spec.js b/testing/tests/idprovider.delete.spec.js index 261a0ccc6..89db614bc 100644 --- a/testing/tests/idprovider.delete.spec.js +++ b/testing/tests/idprovider.delete.spec.js @@ -109,7 +109,7 @@ describe("Confirm and delete 'Id Provider' in wizard and in browse panel", funct // Select the provider and click on Delete button: await testUtils.selectAndDeleteItem(ID_PROVIDER.displayName); let actualMessage = await userBrowsePanel.waitForNotificationMessage(); - await testUtils.saveScreenshot('store_deleted_notification_mes2'); + await testUtils.saveScreenshot('idprovider_deleted_notification_mes2'); let expectedMessage = appConst.providerDeletedMessage(ID_PROVIDER.displayName); // Expected message: Id Provider "${displayName}" is deleted assert.strictEqual(actualMessage, expectedMessage, 'expected notification message should be displayed'); diff --git a/testing/tests/idprovider.with.required.inputs.spec.js b/testing/tests/idprovider.with.required.inputs.spec.js index 41fc91087..63b29834a 100644 --- a/testing/tests/idprovider.with.required.inputs.spec.js +++ b/testing/tests/idprovider.with.required.inputs.spec.js @@ -160,9 +160,9 @@ describe('Id Provider, provider-dialog specification', function () { // 1. Select an existing provider with configurator then click on Create User menu item in the modal dialog: await testUtils.selectIdProviderAndClickOnMenuItem(TEST_ID_PROVIDER_NAME, 'User'); // 2. Verify the actual notification message - The application does not allow to create users - let actualMessage = await userBrowsePanel.waitForNotificationMessage(); + let actualMessages = await userBrowsePanel.waitForNotificationMessage(); await testUtils.saveScreenshot('app_does_not_allow_users'); - assert.equal(actualMessage, NOTIFICATION_MESSAGE, "The application does not allow to create users"); + assert.ok(actualMessages.includes(NOTIFICATION_MESSAGE), "The application does not allow to create users"); }); it(`GIVEN id provider with a configuration is selected WHEN Create New User Group menu item has been clicked THEN expected notification message should appear`, @@ -177,8 +177,9 @@ describe('Id Provider, provider-dialog specification', function () { await groupWizard.waitAndClickOnSave(); await testUtils.saveScreenshot('group_saved_in_provider'); // 4. Verify that group is saved: - let message = await groupWizard.waitForNotificationMessage(); - assert.equal(message, appConst.NOTIFICATION_MESSAGE.GROUP_WAS_CREATED, "Group was created - message should be displayed"); + let messages = await groupWizard.waitForNotificationMessage(); + assert.ok(messages.includes(appConst.NOTIFICATION_MESSAGE.GROUP_WAS_CREATED), + "Group was created - message should be displayed"); }); // Verify Error in group selector inside ID providers config form #940 diff --git a/testing/tests/role.delete.spec.js b/testing/tests/role.delete.spec.js index 8359bb7c0..fb6ccf3a4 100644 --- a/testing/tests/role.delete.spec.js +++ b/testing/tests/role.delete.spec.js @@ -98,7 +98,7 @@ describe('Deleting of a role - confirm and delete it in wizard and in browse pan await testUtils.clickOnRolesFolderAndOpenWizard(); await roleWizard.typeData(TEST_ROLE); await roleWizard.waitAndClickOnSave(); - await roleWizard.pause(500); + await roleWizard.pause(1000); // 2. Click on Delete and confirm the deleting: await roleWizard.clickOnDelete(); await testUtils.confirmDelete(); diff --git a/testing/tests/role.wizard.spec.js b/testing/tests/role.wizard.spec.js index 6ea8e7c80..8306973cb 100644 --- a/testing/tests/role.wizard.spec.js +++ b/testing/tests/role.wizard.spec.js @@ -23,7 +23,7 @@ describe('Role Wizard and Statistics Panel spec', function () { it(`WHEN Administrator role is opened THEN remove icon should not be displayed for SU in Members form`, async () => { let roleWizard = new RoleWizard(); - // 1. Open Administrator role: + // 1. Open 'Administrator' role: await testUtils.selectRoleAndOpenWizard(appConst.ROLES_NAME.ADMINISTRATOR); // 2. ADMINISTRATOR role should be with members: let members = await roleWizard.getMembers(); @@ -43,10 +43,11 @@ describe('Role Wizard and Statistics Panel spec', function () { await userBrowsePanel.clickOnNewButton(); await roleWizard.waitForLoaded(); await roleWizard.typeData(TEST_ROLE); + await roleWizard.pause(500); await roleWizard.waitAndClickOnSave(); // Verify the notification message: let actualMessage = await roleWizard.waitForNotificationMessage(); - assert.equal(actualMessage, 'Role was created', "Expected and actual messages are equal"); + assert.equal(actualMessage, 'Role was created', "'Role was created' message should appear"); }); // verifies: xp-apps#93 Incorrect message appears when try to create a role with name that already in use #93 @@ -57,15 +58,17 @@ describe('Role Wizard and Statistics Panel spec', function () { await testUtils.clickOnRolesFolderAndOpenWizard(); // 2. Type existing name: await roleWizard.typeDisplayName(TEST_ROLE.displayName); + await roleWizard.pause(1000); await roleWizard.waitAndClickOnSave(); - let errorMessage = await roleWizard.waitForErrorNotificationMessage(); + await testUtils.saveScreenshot('role_already_exists_notification'); + let errorMessages = await roleWizard.waitForErrorNotificationMessage(); // 3. Error message should appear: let expectedMsg = `Principal [role:` + TEST_ROLE.displayName + `] could not be created. A principal with that name already exists`; - assert.strictEqual(errorMessage, expectedMsg, 'expected notification message should appear'); + assert.ok(errorMessages.includes(expectedMsg), 'expected notification message should appear'); }); - it(`GIVEN existing 'Role' WHEN 'Super User' has been added in members THEN expected selected option should appear in members form`, + it(`GIVEN existing 'Role' is opened WHEN 'Super User' has been added in members THEN 'Super User' selected option should appear in the members form in the wizard`, async () => { let roleWizard = new RoleWizard(); let userBrowsePanel = new UserBrowsePanel(); @@ -75,14 +78,15 @@ describe('Role Wizard and Statistics Panel spec', function () { await roleWizard.waitForLoaded(); // 2. Add SU in members: await roleWizard.filterOptionsAndAddMember(appConst.SUPER_USER_DISPLAY_NAME); + await roleWizard.pause(700); // 3.click on Save: await roleWizard.waitAndClickOnSave(); // 4. Get selected options in members: let selectedOptions = await roleWizard.getMembers(); - assert.equal(selectedOptions[0], appConst.SUPER_USER_DISPLAY_NAME, "SU should be in selected options"); + assert.equal(selectedOptions[0], appConst.SUPER_USER_DISPLAY_NAME, "Super User should be in selected options"); }); - it(`WHEN existing 'role' is opened THEN expected description should be present`, + it(`WHEN existing 'role' is opened THEN expected description should be displayed`, async () => { let roleWizard = new RoleWizard(); let userBrowsePanel = new UserBrowsePanel(); @@ -95,7 +99,7 @@ describe('Role Wizard and Statistics Panel spec', function () { assert.equal(actualDescription, TEST_ROLE.description, "Actual and expected descriptions should be equal"); }); - it(`WHEN a system 'role' is opened THEN 'Delete' button should be disabled`, + it(`WHEN a system 'role' is opened THEN 'Delete' button should be disabled in the wizard toolbar`, async () => { let roleWizard = new RoleWizard(); let userBrowsePanel = new UserBrowsePanel(); @@ -108,7 +112,7 @@ describe('Role Wizard and Statistics Panel spec', function () { await roleWizard.waitForDeleteButtonDisabled(); }); - it(`GIVEN existing 'Role' with a member WHEN it has been selected THEN expected info should be present in the 'statistics panel'`, + it(`GIVEN existing 'Role' with a member WHEN the role has been selected THEN expected role-info should be present in the 'statistics panel'`, async () => { let roleStatisticsPanel = new RoleStatisticsPanel(); // 1.Type the name and select the role in browse panel: @@ -121,18 +125,18 @@ describe('Role Wizard and Statistics Panel spec', function () { assert.equal(actualItemPath, '/roles/' + TEST_ROLE.displayName, "Expected and actual path should be equal"); }); - it(`GIVEN existing 'role' with a member is opened WHEN member has been removed THEN Members should be updated in the Statistics Panel`, + it(`GIVEN existing 'role' with a member is opened WHEN the only one member has been removed in wizard THEN Members should be cleared in the Statistics Panel`, async () => { let roleWizard = new RoleWizard(); let roleStatisticsPanel = new RoleStatisticsPanel(); - // 1. Open existing role and remove the member: + // 1. Open the existing role and remove the member: await testUtils.selectRoleAndOpenWizard(TEST_ROLE.displayName); await roleWizard.removeMember(appConst.SUPER_USER_DISPLAY_NAME); // 2. role has been saved and the wizard closed await testUtils.saveAndCloseWizard(TEST_ROLE.displayName); - // 3. Members should be updated in the Statistics Panel + // 3. Members should be cleared in Statistics Panel let members = await roleStatisticsPanel.getDisplayNameOfMembers(); - assert.ok(members.length === 0); + assert.ok(members.length === 0, 'Members should be cleared in the Statistics Panel'); }); beforeEach(() => testUtils.navigateToUsersApp()); diff --git a/testing/tests/user.delete.spec.js b/testing/tests/user.delete.spec.js index cf46672ad..4076bf604 100644 --- a/testing/tests/user.delete.spec.js +++ b/testing/tests/user.delete.spec.js @@ -46,6 +46,7 @@ describe("user.delete.spec:User - confirm and delete it in the wizard and in the await testUtils.clickOnSystemOpenUserWizard(); await userWizard.typeData(TEST_USER); await userWizard.waitAndClickOnSave(); + await userWizard.waitForNotificationMessage(); // 2. click on Delete and confirm: await userWizard.clickOnDelete(); await testUtils.confirmDelete(); diff --git a/testing/tests/wizard.toolbar.shortcut.spec.js b/testing/tests/wizard.toolbar.shortcut.spec.js index 915083031..645c9d74d 100644 --- a/testing/tests/wizard.toolbar.shortcut.spec.js +++ b/testing/tests/wizard.toolbar.shortcut.spec.js @@ -38,12 +38,13 @@ describe(`wizard.toolbar.shortcut.spec, wizard's toolbar shortcut specification` await userWizard.clickOnSetPasswordButton(); await userWizard.typePassword(PASSWORD); await userWizard.waitForSaveButtonEnabled(); + await userWizard.pause(700); // 3. keyboard shortcut to Save button has been pressed: await userWizard.hotKeySave(); await testUtils.saveScreenshot('user_shortcut_save'); // 4. Verify the notification message: - let messages = await userWizard.waitForNotificationMessages(); - assert.ok(messages.includes(appConst.NOTIFICATION_MESSAGE.USER_WAS_CREATED), 'User was created - message should appear'); + let message = await userWizard.waitForNotificationMessage(); + assert.equal(message, appConst.NOTIFICATION_MESSAGE.USER_WAS_CREATED, 'User was created - message should appear'); }); it(`GIVEN existing user is opened WHEN 'Ctrl+del' has been pressed THEN confirmation modal dialog should appear`, @@ -76,8 +77,8 @@ describe(`wizard.toolbar.shortcut.spec, wizard's toolbar shortcut specification` await groupWizard.hotKeySave(); await testUtils.saveScreenshot('group_shortcut_save'); // 4. Verify the notification message - let message = await groupWizard.waitForNotificationMessage(); - assert.equal(message, appConst.NOTIFICATION_MESSAGE.GROUP_WAS_CREATED, "Group was created - message should appear"); + let messages = await groupWizard.waitForNotificationMessages(); + assert.ok(messages.includes(appConst.NOTIFICATION_MESSAGE.GROUP_WAS_CREATED), "Group was created - message should appear"); }); it(`GIVEN existing group is opened WHEN 'Ctrl+del' has been pressed THEN confirmation modal dialog should appear`, @@ -103,12 +104,13 @@ describe(`wizard.toolbar.shortcut.spec, wizard's toolbar shortcut specification` // 2. Role's data has been typed: await roleWizard.typeDisplayName(TEST_ROLE.displayName); await roleWizard.waitForSaveButtonEnabled(); + await roleWizard.pause(1000); // 3. keyboard shortcut to Save button has been pressed: await roleWizard.hotKeySave(); await testUtils.saveScreenshot('role_shortcut_save'); // 4. Verify the notification message: - let message = await roleWizard.waitForNotificationMessage(); - assert.equal(message, appConst.NOTIFICATION_MESSAGE.ROLE_WAS_CREATED, 'Role was created - message should appear'); + let messages = await roleWizard.waitForNotificationMessages(); + assert.ok(messages.includes(appConst.NOTIFICATION_MESSAGE.ROLE_WAS_CREATED), 'Role was created - message should appear'); }); it(`GIVEN existing role is opened WHEN 'Ctrl+del' has been pressed THEN confirmation modal dialog should appear`, @@ -134,7 +136,8 @@ describe(`wizard.toolbar.shortcut.spec, wizard's toolbar shortcut specification` // 2. data has been typed: await idProviderWizard.typeDisplayName(TEST_PROVIDER.displayName); await idProviderWizard.waitForSaveButtonEnabled(); - // 3. keyboard shortcut to Save button has been pressed: + await idProviderWizard.pause(700); + // 3. keyboard shortcut to 'Save' button has been pressed: await idProviderWizard.hotKeySave(); await testUtils.saveScreenshot('provider_shortcut_save'); // 4. Verify the notification message: