diff --git a/e2e/pages/adf/demo-shell/process-services-cloud/processDetailsCloudDemoPage.ts b/e2e/pages/adf/demo-shell/process-services-cloud/processDetailsCloudDemoPage.ts new file mode 100644 index 0000000000..f97570fcad --- /dev/null +++ b/e2e/pages/adf/demo-shell/process-services-cloud/processDetailsCloudDemoPage.ts @@ -0,0 +1,33 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DataTableComponentPage } from '@alfresco/adf-testing'; + +export class ProcessDetailsCloudDemoPage { + + dataTable = new DataTableComponentPage(); + + checkTaskIsDisplayed(taskName: string) { + this.dataTable.checkContentIsDisplayed('Name', taskName); + return this; + } + + selectProcessTaskByName(taskName: string) { + this.dataTable.selectRow('Name', taskName); + return this; + } +} diff --git a/e2e/process-services-cloud/config/start-process-cloud.config.ts b/e2e/process-services-cloud/config/start-process-cloud.config.ts new file mode 100644 index 0000000000..488adcf93c --- /dev/null +++ b/e2e/process-services-cloud/config/start-process-cloud.config.ts @@ -0,0 +1,39 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class StartProcessCloudConfiguration { + + getConfiguration() { + return { + 'name': 'processwithstarteventform', + 'values': [ + { + 'name': 'FirstName', + 'value': 'sample name' + }, + { + 'name': 'Number07vyx9', + 'value': 17 + } + ], + 'variables': { + 'my-key1': 'myvalue', + 'my-key2': 'myvalue2' + } + }; + } +} diff --git a/e2e/process-services-cloud/start-process-cloud.e2e.ts b/e2e/process-services-cloud/start-process-cloud.e2e.ts index b4f8c31aae..aee66a6203 100644 --- a/e2e/process-services-cloud/start-process-cloud.e2e.ts +++ b/e2e/process-services-cloud/start-process-cloud.e2e.ts @@ -36,7 +36,7 @@ describe('Start Process', () => { browser.params.config.bpmHost, browser.params.config.oauth2.host, browser.params.config.providers ); - const processDefinitionWithoutName = 'process-bc59fd64-d0b1-4eda-8b02-2ef38062cf39'; + const processDefinitionWithoutName = 'process-'; const processName = StringUtil.generateRandomString(10); const processName255Characters = StringUtil.generateRandomString(255); const processNameBiggerThen255Characters = StringUtil.generateRandomString(256); @@ -84,7 +84,7 @@ describe('Start Process', () => { startProcessPage.clearField(startProcessPage.processNameInput); startProcessPage.blur(startProcessPage.processNameInput); startProcessPage.checkValidationErrorIsDisplayed(requiredError); - startProcessPage.checkStartProcessButtonIsDisabled(); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); startProcessPage.clickCancelProcessButton(); }); @@ -93,12 +93,12 @@ describe('Start Process', () => { appListCloudComponent.goToApp(simpleApp); processCloudDemoPage.openNewProcessForm(); startProcessPage.enterProcessName(processName255Characters); - startProcessPage.checkStartProcessButtonIsEnabled(); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(true); startProcessPage.enterProcessName(processNameBiggerThen255Characters); startProcessPage.blur(startProcessPage.processNameInput); startProcessPage.checkValidationErrorIsDisplayed(lengthValidationError); - startProcessPage.checkStartProcessButtonIsDisabled(); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); }); it('[C291860] Should be able to start a process', () => { @@ -107,7 +107,7 @@ describe('Start Process', () => { processCloudDemoPage.openNewProcessForm(); startProcessPage.clearField(startProcessPage.processNameInput); startProcessPage.enterProcessName(processName); - startProcessPage.checkStartProcessButtonIsEnabled(); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(true); startProcessPage.clickStartProcessButton(); processCloudDemoPage.clickOnProcessFilters(); @@ -124,7 +124,7 @@ describe('Start Process', () => { startProcessPage.clearField(startProcessPage.processNameInput); startProcessPage.enterProcessName(processName); startProcessPage.selectFromProcessDropdown(processDefinitionWithoutName); - startProcessPage.checkStartProcessButtonIsEnabled(); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(true); }); }); diff --git a/e2e/process-services-cloud/start-task-form-cloud.e2e.ts b/e2e/process-services-cloud/start-task-form-cloud.e2e.ts new file mode 100644 index 0000000000..12e70eae4d --- /dev/null +++ b/e2e/process-services-cloud/start-task-form-cloud.e2e.ts @@ -0,0 +1,211 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { browser } from 'protractor'; +import { NavigationBarPage } from '../pages/adf/navigationBarPage'; +import { TasksCloudDemoPage } from '../pages/adf/demo-shell/process-services/tasksCloudDemoPage'; +import { + LoginSSOPage, + AppListCloudPage, + StringUtil, + StartTasksCloudPage, + ApiService, + IdentityService, + SettingsPage, + GroupIdentityService, + TaskFormCloudComponent, + Widget, LocalStorageUtil, StartProcessCloudPage, TaskHeaderCloudPage, ProcessHeaderCloudPage, TasksService +} from '@alfresco/adf-testing'; +import resources = require('../util/resources'); +import { StartProcessCloudConfiguration } from './config/start-process-cloud.config'; +import { ProcessCloudDemoPage } from '../pages/adf/demo-shell/process-services/processCloudDemoPage'; +import { ProcessDetailsCloudDemoPage } from '../pages/adf/demo-shell/process-services-cloud/processDetailsCloudDemoPage'; + +describe('Start Task Form', () => { + + const loginSSOPage = new LoginSSOPage(); + const taskFormCloudComponent = new TaskFormCloudComponent(); + const navigationBarPage = new NavigationBarPage(); + const appListCloudComponent = new AppListCloudPage(); + const tasksCloudDemoPage = new TasksCloudDemoPage(); + const startTask = new StartTasksCloudPage(); + const processDetailsCloudDemoPage = new ProcessDetailsCloudDemoPage(); + const settingsPage = new SettingsPage(); + const widget = new Widget(); + const startProcessPage = new StartProcessCloudPage(); + const processCloudDemoPage = new ProcessCloudDemoPage(); + const taskHeaderCloudPage = new TaskHeaderCloudPage(); + const processHeaderCloud = new ProcessHeaderCloudPage(); + const apiService = new ApiService( + browser.params.config.oauth2.clientId, + browser.params.config.bpmHost, browser.params.config.oauth2.host, browser.params.config.providers + ); + const startProcessCloudConfiguration = new StartProcessCloudConfiguration(); + const startProcessCloudConfig = startProcessCloudConfiguration.getConfiguration(); + + const standaloneTaskName = StringUtil.generateRandomString(5); + const startEventFormProcess = StringUtil.generateRandomString(5); + let testUser, groupInfo, processId, taskId; + const candidateBaseApp = resources.ACTIVITI7_APPS.CANDIDATE_BASE_APP.name; + + let identityService: IdentityService; + let groupIdentityService: GroupIdentityService; + + beforeAll(async (done) => { + await apiService.login(browser.params.identityAdmin.email, browser.params.identityAdmin.password); + + identityService = new IdentityService(apiService); + groupIdentityService = new GroupIdentityService(apiService); + testUser = await identityService.createIdentityUserWithRole(apiService, [identityService.roles.aps_user]); + groupInfo = await groupIdentityService.getGroupInfoByGroupName('hr'); + await identityService.addUserToGroup(testUser.idIdentityService, groupInfo.id); + await apiService.login(testUser.email, testUser.password); + + await settingsPage.setProviderBpmSso( + browser.params.config.bpmHost, + browser.params.config.oauth2.host, + browser.params.config.identityHost); + loginSSOPage.loginSSOIdentityService(testUser.email, testUser.password); + await LocalStorageUtil.setConfigField('adf-cloud-start-process', JSON.stringify(startProcessCloudConfig)); + done(); + }); + + afterAll(async (done) => { + try { + await apiService.login(testUser.email, testUser.password); + const tasksService = new TasksService(apiService); + const taskID = await tasksService.getTaskId(standaloneTaskName, candidateBaseApp); + await tasksService.deleteTask(taskID, candidateBaseApp); + await apiService.login(browser.params.identityAdmin.email, browser.params.identityAdmin.password); + await identityService.deleteIdentityUser(testUser.idIdentityService); + } catch (error) { + } + done(); + }); + + describe('StandaloneTask with form', () => { + + beforeEach(() => { + navigationBarPage.navigateToProcessServicesCloudPage(); + appListCloudComponent.checkApsContainer(); + appListCloudComponent.checkAppIsDisplayed(candidateBaseApp); + appListCloudComponent.goToApp(candidateBaseApp); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().waitForTableBody(); + }); + + it('[C307976] Should be able to start and save a task with a form', () => { + tasksCloudDemoPage.openNewTaskForm(); + startTask.checkFormIsDisplayed(); + startTask.addName(standaloneTaskName); + startTask.selectFormDefinition('StartEventForm'); + startTask.clickStartButton(); + tasksCloudDemoPage.taskListCloudComponent().checkContentIsDisplayedByName(standaloneTaskName); + tasksCloudDemoPage.taskListCloudComponent().selectRow(standaloneTaskName); + taskFormCloudComponent.formFields().checkFormIsDisplayed(); + taskFormCloudComponent.formFields().checkWidgetIsVisible('FirstName'); + taskFormCloudComponent.formFields().checkWidgetIsVisible('Number07vyx9'); + widget.textWidget().setValue('FirstName', 'sample'); + widget.numberWidget().setFieldValue('Number07vyx9', 26); + taskFormCloudComponent.checkSaveButtonIsDisplayed().clickSaveButton(); + expect(widget.textWidget().getFieldValue('FirstName')).toBe('sample'); + expect(widget.numberWidget().getFieldValue('Number07vyx9')).toBe('26'); + + navigationBarPage.navigateToProcessServicesCloudPage(); + appListCloudComponent.checkApsContainer(); + appListCloudComponent.checkAppIsDisplayed(candidateBaseApp); + appListCloudComponent.goToApp(candidateBaseApp); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().waitForTableBody(); + + expect(tasksCloudDemoPage.getActiveFilterName()).toBe('My Tasks'); + tasksCloudDemoPage.taskListCloudComponent().checkContentIsDisplayedByName(standaloneTaskName); + tasksCloudDemoPage.taskListCloudComponent().selectRow(standaloneTaskName); + taskFormCloudComponent.formFields().checkFormIsDisplayed(); + expect(widget.textWidget().getFieldValue('FirstName')).toBe('sample'); + expect(widget.numberWidget().getFieldValue('Number07vyx9')).toBe('26'); + taskFormCloudComponent.checkCompleteButtonIsDisplayed(); + }); + + }); + + describe('Start a process with a start event form', () => { + + beforeEach(() => { + navigationBarPage.navigateToProcessServicesCloudPage(); + appListCloudComponent.checkApsContainer(); + appListCloudComponent.checkAppIsDisplayed(candidateBaseApp); + appListCloudComponent.goToApp(candidateBaseApp); + processCloudDemoPage.openNewProcessForm(); + startProcessPage.clearField(startProcessPage.processNameInput); + startProcessPage.enterProcessName(startEventFormProcess); + startProcessPage.selectFromProcessDropdown('processwithstarteventform'); + startProcessPage.formFields().checkFormIsDisplayed(); + }); + it('[C311277] Should be able to start a process with a start event form - default values', async () => { + + expect(widget.textWidget().getFieldValue('FirstName')).toBe('sample name'); + expect(widget.numberWidget().getFieldValue('Number07vyx9')).toBe('17'); + }); + + it('[C311277] Should be able to start a process with a start event form - form validation', async () => { + + expect(widget.textWidget().getErrorMessage('FirstName')).toBe('Enter no more than 10 characters'); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); + + widget.textWidget().setValue('FirstName', 'Sam'); + expect(widget.textWidget().getErrorMessage('FirstName')).toBe('Enter at least 5 characters'); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); + widget.numberWidget().setFieldValue('Number07vyx9', 9); + expect(widget.numberWidget().getErrorMessage('Number07vyx9')).toBe('Can\'t be less than 10'); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); + widget.numberWidget().setFieldValue('Number07vyx9', 99999); + expect(widget.numberWidget().getErrorMessage('Number07vyx9')).toBe('Can\'t be greater than 1,000'); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(false); + }); + + it('[C311277] Should be able to start a process with a start event form - claim and complete the process', async () => { + + widget.textWidget().setValue('FirstName', 'Sample'); + widget.numberWidget().setFieldValue('Number07vyx9', 100); + expect(startProcessPage.checkStartProcessButtonIsEnabled()).toBe(true); + startProcessPage.clickStartProcessButton(); + processCloudDemoPage.clickOnProcessFilters(); + processCloudDemoPage.runningProcessesFilter().clickProcessFilter(); + expect(processCloudDemoPage.getActiveFilterName()).toBe('Running Processes'); + processCloudDemoPage.editProcessFilterCloudComponent().clickCustomiseFilterHeader().setProperty('processName', startEventFormProcess); + processCloudDemoPage.processListCloudComponent().getDataTable().waitTillContentLoaded(); + processCloudDemoPage.processListCloudComponent().checkContentIsDisplayedByName(startEventFormProcess); + + processCloudDemoPage.processListCloudComponent().getDataTable().selectRow('Name', startEventFormProcess); + processDetailsCloudDemoPage.checkTaskIsDisplayed('StartEventFormTask'); + processId = await processHeaderCloud.getId(); + processDetailsCloudDemoPage.selectProcessTaskByName('StartEventFormTask'); + taskFormCloudComponent.clickClaimButton(); + taskId = await taskHeaderCloudPage.getId(); + taskFormCloudComponent.checkCompleteButtonIsDisplayed().clickCompleteButton(); + expect(tasksCloudDemoPage.getActiveFilterName()).toBe('My Tasks'); + tasksCloudDemoPage.taskListCloudComponent().checkContentIsNotDisplayedById(taskId); + + tasksCloudDemoPage.completedTasksFilter().clickTaskFilter(); + tasksCloudDemoPage.taskListCloudComponent().checkContentIsDisplayedById(taskId); + processCloudDemoPage.clickOnProcessFilters(); + processCloudDemoPage.completedProcessesFilter().clickProcessFilter(); + processCloudDemoPage.processListCloudComponent().checkContentIsDisplayedById(processId); + + }); + + }); +}); diff --git a/lib/testing/src/lib/core/pages/form/widgets/numberWidget.ts b/lib/testing/src/lib/core/pages/form/widgets/numberWidget.ts index a86ecaf5de..7645446e0c 100644 --- a/lib/testing/src/lib/core/pages/form/widgets/numberWidget.ts +++ b/lib/testing/src/lib/core/pages/form/widgets/numberWidget.ts @@ -28,6 +28,10 @@ export class NumberWidget { return BrowserActions.getText(label); } + getFieldValue(fieldId) { + return this.formFields.getFieldValue(fieldId); + } + setFieldValue(fieldId, value) { return this.formFields.setValueInInputById(fieldId, value); } diff --git a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts index 8d83771fa2..e88ef1a72e 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts @@ -18,6 +18,7 @@ import { by, element, Key, protractor, browser } from 'protractor'; import { BrowserVisibility } from '../../core/utils/browser-visibility'; import { BrowserActions } from '../../core/utils/browser-actions'; +import { FormFields } from '../../core/pages/form/formFields'; export class StartProcessCloudPage { @@ -83,11 +84,7 @@ export class StartProcessCloudPage { checkStartProcessButtonIsEnabled() { BrowserVisibility.waitUntilElementIsClickable(this.startProcessButton); - expect(this.startProcessButton.isEnabled()).toBe(true); - } - - checkStartProcessButtonIsDisabled() { - expect(this.startProcessButton.isEnabled()).toBe(false); + return this.startProcessButton.isEnabled(); } clickStartProcessButton() { @@ -114,4 +111,8 @@ export class StartProcessCloudPage { } }); } + + formFields() { + return new FormFields(); + } } diff --git a/lib/testing/src/lib/process-services-cloud/pages/start-tasks-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/start-tasks-cloud-component.page.ts index 0deb5396a0..791fe45259 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/start-tasks-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/start-tasks-cloud-component.page.ts @@ -29,6 +29,7 @@ export class StartTasksCloudPage { startButtonEnabled = element(by.css('button[id="button-start"]:not(disabled)')); cancelButton = element(by.css('button[id="button-cancel"]')); form = element.all(by.css('adf-cloud-start-task form')).first(); + formDefinitionSelector = element(by.css('.adf-form-definition-selector')); checkFormIsDisplayed() { BrowserVisibility.waitUntilElementIsVisible(this.form); @@ -102,4 +103,10 @@ export class StartTasksCloudPage { clearField(locator) { BrowserActions.clearSendKeys(locator, ''); } + + selectFormDefinition(option: string) { + BrowserActions.click(this.formDefinitionSelector); + const row = element(by.cssContainingText('mat-option span', option)); + BrowserActions.click(row); + } } diff --git a/lib/testing/src/lib/process-services-cloud/pages/task-form-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/task-form-cloud-component.page.ts index 5baddee6d3..90fe1c809a 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/task-form-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/task-form-cloud-component.page.ts @@ -26,6 +26,7 @@ export class TaskFormCloudComponent { completeButton = element(by.css('button[id="adf-form-complete"]')); releaseButton = element(by.css('button[adf-cloud-unclaim-task]')); saveButton = element(by.css('button[id="adf-form-save"]')); + claimButton = element(by.css('button[adf-cloud-claim-task]')); form = element(by.css('adf-cloud-form')); checkCompleteButtonIsDisplayed() { @@ -48,6 +49,11 @@ export class TaskFormCloudComponent { return this; } + clickClaimButton() { + BrowserActions.click(this.claimButton); + return this; + } + formFields() { return new FormFields(); } diff --git a/lib/testing/src/lib/process-services-cloud/pages/task-list-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/task-list-cloud-component.page.ts index 6a92067480..8fae156284 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/task-list-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/task-list-cloud-component.page.ts @@ -87,6 +87,10 @@ export class TaskListCloudComponentPage { return this.dataTable.checkContentIsDisplayed(column.id, taskId); } + checkContentIsNotDisplayedById(taskId) { + return this.dataTable.checkContentIsNotDisplayed(column.id, taskId); + } + checkContentIsDisplayedByProcessInstanceId(taskName) { return this.dataTable.checkContentIsDisplayed(column.processInstanceId, taskName); }