diff --git a/e2e/process-services-cloud/form-field/dropdown-widget.e2e.ts b/e2e/process-services-cloud/form-field/dropdown-widget.e2e.ts index c613d773e3e..24b7ae019b8 100644 --- a/e2e/process-services-cloud/form-field/dropdown-widget.e2e.ts +++ b/e2e/process-services-cloud/form-field/dropdown-widget.e2e.ts @@ -49,33 +49,30 @@ describe('Form Field Component - Dropdown Widget', () => { const dropdown = widget.dropdown(); - let runningProcessInstance, runningProcessInstanceMultiselect, testUser, groupInfo, tasklist, tasklistMulti, taskMulti, task; + let testUser: { idIdentityService: string, username: string, password: string }; + const runningTasks = {}; const simpleApp = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name; beforeAll(async () => { const { processes } = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP; + let runningProcessInstance: Record; await apiService.loginWithProfile('identityAdmin'); - testUser = await identityService.createIdentityUserWithRole( [identityService.ROLES.ACTIVITI_USER]); - - groupInfo = await groupIdentityService.getGroupInfoByGroupName('hr'); + testUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]); + const groupInfo = await groupIdentityService.getGroupInfoByGroupName('hr'); await identityService.addUserToGroup(testUser.idIdentityService, groupInfo.id); await apiService.login(testUser.username, testUser.password); - const processDefinition = await processDefinitionService.getProcessDefinitionByName(processes.dropdownOptionsProcess, simpleApp); - const processDefinitionMultiselect = await processDefinitionService.getProcessDefinitionByName(processes['multiselect-dropdown'], simpleApp); - - await processInstancesService.createProcessInstance(processDefinition.entry.key, simpleApp); - await processInstancesService.createProcessInstance(processDefinitionMultiselect.entry.key, simpleApp); - runningProcessInstance = await processInstancesService.createProcessInstance(processDefinition.entry.key, simpleApp); - runningProcessInstanceMultiselect = await processInstancesService.createProcessInstance(processDefinitionMultiselect.entry.key, simpleApp); + const processesData = ['dropdownOptionsProcess', 'multiselect-dropdown', 'dropdown-search']; - tasklist = await queryService.getProcessInstanceTasks(runningProcessInstance.entry.id, simpleApp); - task = await tasklist.list.entries[0]; - tasklistMulti = await queryService.getProcessInstanceTasks(runningProcessInstanceMultiselect.entry.id, simpleApp); - taskMulti = await tasklistMulti.list.entries[0]; - await tasksService.claimTask(task.entry.id, simpleApp); - await tasksService.claimTask(taskMulti.entry.id, simpleApp); + for (const process of processesData) { + const processDef = await processDefinitionService.getProcessDefinitionByName(processes[process], simpleApp); + await processInstancesService.createProcessInstance(processDef.entry.key, simpleApp); + runningProcessInstance = await processInstancesService.createProcessInstance(processDef.entry.key, simpleApp); + const tasklist = await queryService.getProcessInstanceTasks(runningProcessInstance.entry.id, simpleApp); + await tasksService.claimTask(tasklist.list.entries[0].entry.id, simpleApp); + runningTasks[process] = tasklist.list.entries[0].entry; + } await loginSSOPage.login(testUser.username, testUser.password); }); @@ -91,18 +88,20 @@ describe('Form Field Component - Dropdown Widget', () => { await appListCloudComponent.goToApp(simpleApp); }); - it('Should be able to finish task with mulitselect dropdown form field', async () => { + it('[C601606] Should be able to finish task with multiselect dropdown form field', async () => { const optionsToSelect = ['First', 'Third']; + const { name: multiselectTaskName } = runningTasks['multiselect-dropdown']; + await taskFilter.clickTaskFilter('my-tasks'); await taskList.getDataTable().waitTillContentLoaded(); - await taskList.checkContentIsDisplayedByName(taskMulti.entry.name); - await taskList.selectRow(taskMulti.entry.name); + await taskList.checkContentIsDisplayedByName(multiselectTaskName); + await taskList.selectRow(multiselectTaskName); await taskHeaderCloudPage.checkTaskPropertyListIsDisplayed(); await dropdown.openDropdown('#DropdownMultiselect'); await dropdown.selectMultipleOptions(optionsToSelect); - await dropdown.closeDropdown(); + await dropdown.closeDropdownFor('DropdownMultiselect'); const optionsSelected = [await dropdown.getSelectedOptionText('DropdownMultiselect')]; @@ -111,8 +110,8 @@ describe('Form Field Component - Dropdown Widget', () => { await taskFilter.clickTaskFilter('completed-tasks'); await taskList.getDataTable().waitTillContentLoaded(); - await taskList.checkContentIsDisplayedByName(taskMulti.entry.name); - await taskList.selectRow(taskMulti.entry.name); + await taskList.checkContentIsDisplayedByName(multiselectTaskName); + await taskList.selectRow(multiselectTaskName); await taskFormCloudComponent.formFields().checkFormIsDisplayed(); await taskFormCloudComponent.formFields().checkWidgetIsVisible('DropdownMultiselect'); @@ -123,11 +122,12 @@ describe('Form Field Component - Dropdown Widget', () => { }); it('[C309878] Should be able to select a dropdown option, save and complete the task form', async () => { + const { name: dropdownOptionTaskName } = runningTasks['dropdownOptionsProcess']; await taskFilter.clickTaskFilter('my-tasks'); await taskList.getDataTable().waitTillContentLoaded(); - await taskList.checkContentIsDisplayedByName(task.entry.name); - await taskList.selectRow(task.entry.name); + await taskList.checkContentIsDisplayedByName(dropdownOptionTaskName); + await taskList.selectRow(dropdownOptionTaskName); await taskHeaderCloudPage.checkTaskPropertyListIsDisplayed(); @@ -147,14 +147,14 @@ describe('Form Field Component - Dropdown Widget', () => { await expect(await taskFilter.getActiveFilterName()).toBe('My Tasks'); - await taskList.checkContentIsNotDisplayedByName(task.entry.name); + await taskList.checkContentIsNotDisplayedByName(dropdownOptionTaskName); await notificationHistoryPage.checkNotifyContains('Task has been saved successfully'); await taskFilter.clickTaskFilter('completed-tasks'); await taskList.getDataTable().waitTillContentLoaded(); - await taskList.checkContentIsDisplayedByName(task.entry.name); - await taskList.selectRow(task.entry.name); + await taskList.checkContentIsDisplayedByName(dropdownOptionTaskName); + await taskList.selectRow(dropdownOptionTaskName); await taskFormCloudComponent.formFields().checkFormIsDisplayed(); await taskFormCloudComponent.formFields().checkWidgetIsVisible('DropdownOptions'); @@ -163,4 +163,68 @@ describe('Form Field Component - Dropdown Widget', () => { await taskFormCloudComponent.checkCompleteButtonIsNotDisplayed(); }); + + it('[C601606] Should be able to search and select multiple options from multiple choice dropdown', async () => { + const { name: dropdownOptionTaskName } = runningTasks['dropdown-search']; + const expectedOptions = ['Albania', 'Colombia', 'Italy', 'Poland', 'United Kingdom of Great Britain and Northern Ireland']; + const dropdownId = 'DropdownCountriesMultiple'; + + await taskFilter.clickTaskFilter('my-tasks'); + await taskList.getDataTable().waitTillContentLoaded(); + + await taskList.checkContentIsDisplayedByName(dropdownOptionTaskName); + await taskList.selectRow(dropdownOptionTaskName); + + await taskHeaderCloudPage.checkTaskPropertyListIsDisplayed(); + + await taskFormCloudComponent.formFields().checkFormIsDisplayed(); + await dropdown.openDropdown(`#${dropdownId}`); + await dropdown.searchAndChooseOptionsFromList(...expectedOptions); + await dropdown.closeDropdownFor(dropdownId); + + const actualSelectedOptions = await dropdown.getSelectedOptionText(dropdownId); + await expect(actualSelectedOptions).toEqual(expectedOptions.join(', ')); + }); + + it('[C601606] Should be able to search and select single options from the single choice dropdown', async () => { + const { name: dropdownOptionTaskName } = runningTasks['dropdown-search']; + const firstOption = 'Mauritius'; + const expectedOption = 'Namibia'; + const dropdownId = 'DropdownCountriesSingle'; + + await taskFilter.clickTaskFilter('my-tasks'); + await taskList.getDataTable().waitTillContentLoaded(); + + await taskList.checkContentIsDisplayedByName(dropdownOptionTaskName); + await taskList.selectRow(dropdownOptionTaskName); + + await taskHeaderCloudPage.checkTaskPropertyListIsDisplayed(); + + await taskFormCloudComponent.formFields().checkFormIsDisplayed(); + await dropdown.openDropdown(`#${dropdownId}`); + await dropdown.searchAndChooseOptionFromList(firstOption); + await dropdown.openDropdown(`#${dropdownId}`); + await dropdown.searchAndChooseOptionFromList(expectedOption); + + const actualSelectedOptions = await dropdown.getSelectedOptionText(dropdownId); + await expect(actualSelectedOptions).toEqual(expectedOption); + }); + + it('[C601606] Should not be able to search if there is less than 6 options to choose', async () => { + const { name: dropdownOptionTaskName } = runningTasks['dropdown-search']; + const dropdownId = 'DropdownSingleFive'; + await taskFilter.clickTaskFilter('my-tasks'); + await taskList.getDataTable().waitTillContentLoaded(); + + await taskList.checkContentIsDisplayedByName(dropdownOptionTaskName); + await taskList.selectRow(dropdownOptionTaskName); + + await taskHeaderCloudPage.checkTaskPropertyListIsDisplayed(); + + await taskFormCloudComponent.formFields().checkFormIsDisplayed(); + await dropdown.openDropdown(`#${dropdownId}`); + + const searchDropdownFieldIsPresent = await dropdown.searchElementLocator.isPresent(1000); + await expect(searchDropdownFieldIsPresent).toBeFalsy(); + }); }); diff --git a/e2e/resources/activiti7/simpleapp.zip b/e2e/resources/activiti7/simpleapp.zip index 483e6b8ef0a..3c22b58ba1c 100644 Binary files a/e2e/resources/activiti7/simpleapp.zip and b/e2e/resources/activiti7/simpleapp.zip differ diff --git a/lib/testing/src/lib/protractor/core/pages/form/widgets/dropdown-widget.page.ts b/lib/testing/src/lib/protractor/core/pages/form/widgets/dropdown-widget.page.ts index 0402f40b02b..896d21d20ed 100644 --- a/lib/testing/src/lib/protractor/core/pages/form/widgets/dropdown-widget.page.ts +++ b/lib/testing/src/lib/protractor/core/pages/form/widgets/dropdown-widget.page.ts @@ -16,50 +16,70 @@ */ import { FormFields } from '../form-fields'; -import { by, element, $, protractor } from 'protractor'; -import { BrowserVisibility, BrowserActions } from '../../../utils/public-api'; +import { $, by, protractor } from 'protractor'; import { TestElement } from '../../../test-element'; export class DropdownWidgetPage { formFields: FormFields = new FormFields(); - getSelectedOptionText(fieldId: string = 'dropdown'): Promise { + readonly searchElementLocator = TestElement.byCss('[aria-label="Search options"]'); + + async getSelectedOptionText(fieldId: string = 'dropdown'): Promise { return this.formFields.getFieldText(fieldId, by.css(`mat-select[id="${fieldId}"] span span`)); } async selectOption(option: string, locator: string = '#dropdown'): Promise { await this.openDropdown(locator); - const row = element(by.cssContainingText('mat-option span', option)); - await BrowserActions.click(row); + const row = TestElement.byText('mat-option span', option); + await row.click(); } async selectMultipleOptions(options: string[]): Promise { for (const option of options) { - await TestElement.byText('mat-option span', option).click(); + await this.clickOption(option); } } - async closeDropdown(): Promise { + async closeDropdownFor(dropdownId: string): Promise { + const dropdownElement = TestElement.byCss(`#${dropdownId}-panel`); await $('body').sendKeys(protractor.Key.ESCAPE); + await dropdownElement.waitNotPresent(); } async openDropdown(locator: string = '#dropdown'): Promise { await this.checkDropdownIsDisplayed(locator); - const dropdown = locator ? $(`${locator}`) : $(`#dropdown`); - await BrowserActions.click(dropdown); + const dropdown = TestElement.byCss(`${locator}`); + await dropdown.click(); + } + + async searchAndChooseOptionFromList(name: string): Promise { + await this.searchElementLocator.typeText(name); + await this.clickOption(name); + } + + async searchAndChooseOptionsFromList(...names: string[]): Promise { + for (const name of names) { + await this.searchElementLocator.typeText(name); + await this.clickOption(name); + } } async checkDropdownIsDisplayed(locator: string = '#dropdown'): Promise { - const dropdown = $(`${locator}`); - await BrowserVisibility.waitUntilElementIsVisible(dropdown); + const dropdown = TestElement.byCss(`${locator}`); + await dropdown.waitVisible(); } - async isWidgetVisible(fieldId): Promise { + async isWidgetVisible(fieldId: string): Promise { await this.formFields.checkWidgetIsVisible(fieldId); } - async isWidgetHidden(fieldId): Promise { + async isWidgetHidden(fieldId: string): Promise { await this.formFields.checkWidgetIsHidden(fieldId); } + + private async clickOption(name: string): Promise { + const optionLocator = TestElement.byText('mat-option span', name); + await optionLocator.click(); + } } diff --git a/lib/testing/src/lib/protractor/process-services-cloud/resources/resources.ts b/lib/testing/src/lib/protractor/process-services-cloud/resources/resources.ts index a7b84892d98..e846adc10f5 100644 --- a/lib/testing/src/lib/protractor/process-services-cloud/resources/resources.ts +++ b/lib/testing/src/lib/protractor/process-services-cloud/resources/resources.ts @@ -129,6 +129,7 @@ export const ACTIVITI_CLOUD_APPS = { multiinstancemanualtask: 'multiinstance-manualtask', multiinstancesubprocess: 'multiinstance-subprocess', 'multiselect-dropdown': 'multiselect-dropdown', + 'dropdown-search': 'dropdown-search', calledprocess: 'calledprocess', booleanvisibilityprocess: 'booleanvisibilityprocess', numbervisibilityprocess: 'numbervisibilityprocess',