diff --git a/e2e/actions/APS-cloud/apiservice.ts b/e2e/actions/APS-cloud/apiservice.ts new file mode 100644 index 0000000000..6bec7287af --- /dev/null +++ b/e2e/actions/APS-cloud/apiservice.ts @@ -0,0 +1,64 @@ +/*! + * @license + * Copyright 2016 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 AlfrescoApi = require('alfresco-js-api-node'); +import TestConfig = require('../../test.config'); + +export class ApiService { + + HOST_SSO = TestConfig.adf.hostSso; + + apiService = new AlfrescoApi({ + provider: 'BPM', + authType: 'OAUTH', + oauth2: { + host: `${this.HOST_SSO}/auth/realms/springboot`, + authType: '/protocol/openid-connect/token', + clientId: 'activiti', + scope: 'openid', + secret: '', + implicitFlow: false, + silentLogin: false, + redirectUri: '/', + redirectUriLogout: '/logout' + } + + }); + + async login(username, password) { + await this.apiService.login(username, password); + } + + async performBpmOperation(path, method, queryParams, postBody) { + const uri = this.HOST_SSO + path; + const pathParams = {}, formParams = {}; + const authNames = []; + const contentTypes = ['application/json']; + const accepts = ['application/json']; + + const headerParams = { + 'Authorization': 'bearer ' + this.apiService.oauth2Auth.token + }; + + return this.apiService.bpmClient.callCustomApi(uri, method, pathParams, queryParams, headerParams, formParams, postBody, + authNames, contentTypes, accepts, {}) + .catch(error => { + throw (error); + }); + } + +} diff --git a/e2e/actions/APS-cloud/tasks.ts b/e2e/actions/APS-cloud/tasks.ts new file mode 100644 index 0000000000..6c973ec3e7 --- /dev/null +++ b/e2e/actions/APS-cloud/tasks.ts @@ -0,0 +1,64 @@ +/*! + * @license + * Copyright 2016 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 { ApiService } from './apiservice'; + +export class Tasks { + + api: ApiService = new ApiService(); + + constructor() { + } + + async init(username, password) { + await this.api.login(username, password); + } + + async createStandaloneTask(taskName, appName) { + const path = '/' + appName + '-rb/v1/tasks'; + const method = 'POST'; + + const queryParams = {}, postBody = { + 'name': taskName, + 'payloadType': 'CreateTaskPayload' + }; + + const data = await this.api.performBpmOperation(path, method, queryParams, postBody); + return data; + } + + async completeTask(taskId, appName) { + const path = '/' + appName + '-rb/v1/tasks/' + taskId + '/complete'; + const method = 'POST'; + + const queryParams = {}, postBody = {'payloadType': 'CompleteTaskPayload'}; + + const data = await this.api.performBpmOperation(path, method, queryParams, postBody); + return data; + } + + async claimTask(taskId, appName) { + const path = '/' + appName + '-rb/v1/tasks/' + taskId + '/claim'; + const method = 'POST'; + + const queryParams = {}, postBody = {}; + + const data = await this.api.performBpmOperation(path, method, queryParams, postBody); + return data; + } + +} diff --git a/e2e/pages/adf/demo-shell/tasksCloudDemoPage.ts b/e2e/pages/adf/demo-shell/tasksCloudDemoPage.ts new file mode 100644 index 0000000000..dfd2f87ca8 --- /dev/null +++ b/e2e/pages/adf/demo-shell/tasksCloudDemoPage.ts @@ -0,0 +1,64 @@ +/*! + * @license + * Copyright 2016 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 Util = require('../../../util/util'); + +import { TaskFiltersCloudComponent } from '../process_cloud/taskFiltersCloudComponent'; +import { TaskListCloudComponent } from '../process_cloud/taskListCloudComponent'; +import { element, by } from 'protractor'; + +export class TasksCloudDemoPage { + + myTasks = element(by.css('span[data-automation-id="My Tasks_filter"]')); + cancelledTasks = element(by.css('span[data-automation-id="Cancelled Tasks_filter"]')); + completedTasks = element(by.css('span[data-automation-id="Completed Tasks_filter"]')); + suspendedTasks = element(by.css('span[data-automation-id="Suspended Tasks_filter"]')); + activeFilter = element(by.css("mat-list-item[class*='active'] span")); + + taskFiltersCloudComponent(filter) { + return new TaskFiltersCloudComponent(filter); + } + + taskListCloudComponent() { + return new TaskListCloudComponent(); + } + + myTasksFilter() { + return new TaskFiltersCloudComponent(this.myTasks); + } + + cancelledTasksFilter() { + return new TaskFiltersCloudComponent(this.cancelledTasks); + } + + completedTasksFilter() { + return new TaskFiltersCloudComponent(this.completedTasks); + } + + suspendedTasksFilter() { + return new TaskFiltersCloudComponent(this.suspendedTasks); + } + + customTaskFilter(filterName) { + return new TaskFiltersCloudComponent(element(by.css(`span[data-automation-id="${filterName}_filter"]`))); + } + + checkActiveFilterActive () { + Util.waitUntilElementIsVisible(this.activeFilter); + return this.activeFilter.getText(); + } +} diff --git a/e2e/pages/adf/navigationBarPage.ts b/e2e/pages/adf/navigationBarPage.ts index 5b84f3fc3d..01840e4a0c 100644 --- a/e2e/pages/adf/navigationBarPage.ts +++ b/e2e/pages/adf/navigationBarPage.ts @@ -19,6 +19,7 @@ import Util = require('../../util/util'); import TestConfig = require('../../test.config'); import { element, by } from 'protractor'; import { ProcessServicesPage } from './process_services/processServicesPage'; +import { AppListCloudComponent } from './process_cloud/appListCloudComponent'; export class NavigationBarPage { @@ -26,7 +27,7 @@ export class NavigationBarPage { taskListButton = element(by.css("a[data-automation-id='Task List']")); configEditorButton = element(by.css('a[data-automation-id="Configuration Editor"]')); processServicesButton = element(by.css('a[data-automation-id="Process Services"]')); - processCloudButton = element(by.css('a[data-automation-id="Process Cloud"]')); + processServicesCloudButton = element(by.css('a[data-automation-id="Process Cloud"]')); loginButton = element(by.css('a[data-automation-id="Login"]')); trashcanButton = element(by.css('a[data-automation-id="Trashcan"]')); userProfileButton = element(by.css('button[data-automation-id="adf-user-profile"]')); @@ -50,12 +51,6 @@ export class NavigationBarPage { this.taskListButton.click(); } - clickProcessCloudButton() { - Util.waitUntilElementIsVisible(this.processCloudButton); - this.processCloudButton.click(); - - } - clickConfigEditorButton() { Util.waitUntilElementIsVisible(this.configEditorButton); this.configEditorButton.click(); @@ -67,6 +62,12 @@ export class NavigationBarPage { return new ProcessServicesPage(); } + navigateToProcessServicesCloudPage() { + Util.waitUntilElementIsVisible(this.processServicesCloudButton); + this.processServicesCloudButton.click(); + return new AppListCloudComponent(); + } + clickLoginButton() { Util.waitUntilElementIsVisible(this.loginButton); this.loginButton.click(); @@ -171,6 +172,6 @@ export class NavigationBarPage { } checkContentServicesButtonIsDisplayed() { - Util.waitUntilElementIsVisible(contentServicesButton); + Util.waitUntilElementIsVisible(this.contentServicesButton); } } diff --git a/e2e/pages/adf/process_services_cloud/appListCloudComponent.ts b/e2e/pages/adf/process_cloud/appListCloudComponent.ts similarity index 100% rename from e2e/pages/adf/process_services_cloud/appListCloudComponent.ts rename to e2e/pages/adf/process_cloud/appListCloudComponent.ts diff --git a/e2e/pages/adf/process_cloud/taskFiltersCloudComponent.ts b/e2e/pages/adf/process_cloud/taskFiltersCloudComponent.ts new file mode 100644 index 0000000000..b236be3dba --- /dev/null +++ b/e2e/pages/adf/process_cloud/taskFiltersCloudComponent.ts @@ -0,0 +1,57 @@ +/*! + * @license + * Copyright 2016 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 Util = require('../../../util/util'); +import { by } from 'protractor'; + +export class TaskFiltersCloudComponent { + + filter; + taskIcon = by.xpath("ancestor::div[@class='mat-list-item-content']/mat-icon"); + + constructor(filter) { + this.filter = filter; + } + + checkTaskFilterIsDisplayed() { + Util.waitUntilElementIsVisible(this.filter); + return this; + } + + getTaskFilterIcon() { + Util.waitUntilElementIsVisible(this.filter); + let icon = this.filter.element(this.taskIcon); + Util.waitUntilElementIsVisible(icon); + return icon.getText(); + } + + checkTaskFilterHasNoIcon() { + Util.waitUntilElementIsVisible(this.filter); + Util.waitUntilElementIsNotOnPage(this.filter.element(this.taskIcon)); + } + + clickTaskFilter() { + Util.waitUntilElementIsVisible(this.filter); + return this.filter.click(); + } + + checkTaskFilterNotDisplayed() { + Util.waitUntilElementIsNotVisible(this.filter); + return this.filter; + } + +} diff --git a/e2e/pages/adf/process_cloud/taskListCloudComponent.ts b/e2e/pages/adf/process_cloud/taskListCloudComponent.ts new file mode 100644 index 0000000000..9b485cbd8b --- /dev/null +++ b/e2e/pages/adf/process_cloud/taskListCloudComponent.ts @@ -0,0 +1,43 @@ +/*! + * @license + * Copyright 2016 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 Util = require('../../../util/util'); +import DataTablePage = require('../dataTablePage'); +import { element, by } from 'protractor'; + +export class TaskListCloudComponent { + + taskList = element(by.css('adf-tasklist')); + noTasksFound = element(by.css("p[class='adf-empty-content__title']")); + + dataTable = new DataTablePage(this.taskList); + + getDataTable() { + return this.dataTable; + } + + checkTaskListIsLoaded() { + Util.waitUntilElementIsVisible(this.taskList); + return this; + } + + getNoTasksFoundMessage() { + Util.waitUntilElementIsVisible(this.noTasksFound); + return this.noTasksFound.getText(); + } + +} diff --git a/e2e/process-services-cloud/apps_section_cloud.e2e.ts b/e2e/process-services-cloud/apps_section_cloud.e2e.ts index f76fe3867c..15734d3eeb 100644 --- a/e2e/process-services-cloud/apps_section_cloud.e2e.ts +++ b/e2e/process-services-cloud/apps_section_cloud.e2e.ts @@ -17,7 +17,7 @@ import { LoginAPSPage } from '../pages/adf/loginApsPage'; import { SettingsPage } from '../pages/adf/settingsPage'; -import { AppListCloudComponent } from '../pages/adf/process_services_cloud/appListCloudComponent'; +import { AppListCloudComponent } from '../pages/adf/process_cloud/appListCloudComponent'; import TestConfig = require('../test.config'); import { browser } from 'protractor'; import { NavigationBarPage } from '../pages/adf/navigationBarPage'; @@ -36,7 +36,7 @@ describe('Applications list', () => { await settingsPage.setProviderBpmSso(TestConfig.adf.hostSso, TestConfig.adf.hostSso + path); browser.ignoreSynchronization = true; await loginApsPage.loginAPS(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); - await navigationBarPage.clickProcessCloudButton(); + await navigationBarPage.navigateToProcessServicesCloudPage(); appListCloudComponent.checkApsContainer(); diff --git a/e2e/process-services-cloud/task_filters_cloud.e2e.ts b/e2e/process-services-cloud/task_filters_cloud.e2e.ts new file mode 100644 index 0000000000..06b24fb57f --- /dev/null +++ b/e2e/process-services-cloud/task_filters_cloud.e2e.ts @@ -0,0 +1,126 @@ +/*! + * @license + * Copyright 2016 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 TestConfig = require('../test.config'); +import resources = require('../util/resources'); + +import { LoginAPSPage } from '../pages/adf/loginApsPage'; +import { SettingsPage } from '../pages/adf/settingsPage'; +import { NavigationBarPage } from '../pages/adf/navigationBarPage'; +import TasksListPage = require('../pages/adf/process_services/tasksListPage'); +import { TasksCloudDemoPage } from '../pages/adf/demo-shell/tasksCloudDemoPage'; +import { AppListCloudComponent } from '../pages/adf/process_cloud/appListCloudComponent'; + +import AlfrescoApi = require('alfresco-js-api-node'); +import { Tasks } from '../actions/APS-cloud/tasks'; +import { browser } from 'protractor'; + +describe('Task filters cloud', () => { + + describe('Filters', () => { + const settingsPage = new SettingsPage(); + const loginApsPage = new LoginAPSPage(); + const navigationBarPage = new NavigationBarPage(); + let appListCloudComponent = new AppListCloudComponent(); + let tasksCloudDemoPage = new TasksCloudDemoPage(); + const tasksService: Tasks = new Tasks(); + + const path = '/auth/realms/springboot'; + let silentLogin; + const newTask = 'newTask', completedTask = 'completedTask1', myTask = 'myTask'; + const simpleApp = 'simple-app'; + const user = 'devopsuser', password = 'password'; + + beforeAll(async () => { + silentLogin = false; + await settingsPage.setProviderBpmSso(TestConfig.adf.hostSso, TestConfig.adf.hostSso + path, silentLogin); + await loginApsPage.clickOnSSOButton(); + browser.ignoreSynchronization = true; + await loginApsPage.loginAPS(user, password); + }); + + beforeEach(async (done) => { + await navigationBarPage.navigateToProcessServicesCloudPage(); + await appListCloudComponent.checkApsContainer(); + await appListCloudComponent.goToApp(simpleApp); + done(); + }); + + it('[C290011] Should display default filters when an app is deployed', () => { + tasksCloudDemoPage.cancelledTasksFilter().checkTaskFilterIsDisplayed(); + tasksCloudDemoPage.myTasksFilter().checkTaskFilterIsDisplayed(); + tasksCloudDemoPage.suspendedTasksFilter().checkTaskFilterIsDisplayed(); + tasksCloudDemoPage.completedTasksFilter().checkTaskFilterIsDisplayed(); + }); + + it('[C290009] Should display default filters and created task', async() => { + await tasksService.init(user, password); + await tasksService.createStandaloneTask(newTask, simpleApp); + + tasksCloudDemoPage.suspendedTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Suspended Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(newTask); + + tasksCloudDemoPage.cancelledTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Cancelled Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(newTask); + + tasksCloudDemoPage.completedTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Completed Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(newTask); + + tasksCloudDemoPage.myTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('My Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsDisplayed(newTask); + }); + + // failing due to ACTIVITI-2463 + xit('[C289955] Should display task in Complete Tasks List when task is completed', async() => { + await tasksService.init(user, password); + let task = await tasksService.createStandaloneTask(completedTask, simpleApp); + + await tasksService.claimTask(task.entry.id, simpleApp); + await tasksService.completeTask(task.entry.id, simpleApp); + + tasksCloudDemoPage.myTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('My Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(completedTask); + + tasksCloudDemoPage.cancelledTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Cancelled Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(completedTask); + + tasksCloudDemoPage.suspendedTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Suspended Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsNotDisplayed(completedTask); + + tasksCloudDemoPage.completedTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('Completed Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsDisplayed(completedTask); + }); + + it('[C289957] Should display task filter results when task filter is selected', async () => { + await tasksService.init(user, password); + let task = await tasksService.createStandaloneTask(myTask, simpleApp); + + tasksCloudDemoPage.myTasksFilter().clickTaskFilter(); + expect(tasksCloudDemoPage.checkActiveFilterActive()).toBe('My Tasks'); + tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkContentIsDisplayed(myTask); + }); + }); + +});