diff --git a/e2e/process-services/attach-file-content-service.e2e.ts b/e2e/process-services/attach-file-content-service.e2e.ts index 45c4c5ca0e..5da85aed8c 100644 --- a/e2e/process-services/attach-file-content-service.e2e.ts +++ b/e2e/process-services/attach-file-content-service.e2e.ts @@ -26,7 +26,8 @@ import { UploadActions, UserModel, UsersActions, - Widget + Widget, + SearchService } from '@alfresco/adf-testing'; import { TasksPage } from './pages/tasks.page'; import { browser } from 'protractor'; @@ -54,6 +55,7 @@ describe('Attach File - Content service', () => { const apiService = new ApiService({ provider: 'ALL' }); const integrationService = new IntegrationService(apiService); const applicationService = new ApplicationsUtil(apiService); + const searchService = new SearchService(apiService); const uploadActions = new UploadActions(apiService); const usersActions = new UsersActions(apiService); @@ -97,7 +99,8 @@ describe('Attach File - Content service', () => { await uploadActions.uploadFile(pdfFileTwo.location, pdfFileTwo.name, '-my-'); await applicationService.importPublishDeployApp(app.file_path); - await browser.sleep(browser.params.testConfig.timeouts.index_search); // wait search index previous file/folder uploaded + await searchService.isSearchable(pdfFileTwo.name); + await searchService.isSearchable(externalFile); }); afterAll(async () => { @@ -107,6 +110,8 @@ describe('Attach File - Content service', () => { beforeEach(async () => { await loginPage.login(user.email, user.password); + await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); + await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); }); afterEach(async () => { @@ -115,9 +120,6 @@ describe('Attach File - Content service', () => { it('[C315268] Attach file - Able to upload more than one file (both ACS and local)', async () => { const name = 'Attach local and acs file'; - await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); - await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); - await taskPage.createTask({ name, formName: app.UPLOAD_FILE_FORM_CS.formName }); await widget.attachFileWidget().attachFile(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id, pdfFileOne.location); @@ -127,6 +129,7 @@ describe('Attach File - Content service', () => { await widget.attachFileWidget().selectUploadSource(csIntegrations[0]); await contentNodeSelector.checkDialogIsDisplayed(); + await searchService.isSearchable(pdfFileTwo.name); await contentNodeSelector.searchAndSelectResult(pdfFileTwo.name, pdfFileTwo.name); await contentNodeSelector.clickMoveCopyButton(); @@ -135,9 +138,6 @@ describe('Attach File - Content service', () => { it('[C246522] Attach file - Local file', async () => { const name = 'Attach local file'; - await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); - await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); - await taskPage.createTask({ name, formName: app.UPLOAD_FILE_FORM_CS.formName }); await widget.attachFileWidget().attachFile(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id, pdfFileOne.location); @@ -148,9 +148,6 @@ describe('Attach File - Content service', () => { it('[C299040] Should display the login screen right, when user has access to 2 alfresco repositiories', async () => { const name = 'Attach file'; - await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); - await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); - await taskPage.createTask({ name, formName: app.UPLOAD_FILE_FORM_CS.formName }); await widget.attachFileWidget().clickUploadButton(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id); @@ -161,6 +158,7 @@ describe('Attach File - Content service', () => { await externalNodeSelector.login(user.email, user.password); await externalNodeSelector.checkDialogIsDisplayed(); + await searchService.isSearchable(externalFile); await externalNodeSelector.searchAndSelectResult(externalFile, externalFile); await externalNodeSelector.clickMoveCopyButton(); await widget.attachFileWidget().checkFileIsAttached(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id, externalFile); @@ -168,14 +166,13 @@ describe('Attach File - Content service', () => { it('[C286516] Able to upload a file when user has more than two alfresco repositories', async () => { const name = 'Attach file - multiple repo'; - await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); - await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); await taskPage.createTask({ name, formName: app.UPLOAD_FILE_FORM_CS.formName }); await widget.attachFileWidget().clickUploadButton(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id); await widget.attachFileWidget().selectUploadSource(csIntegrations[0]); await contentNodeSelector.checkDialogIsDisplayed(); + await searchService.isSearchable(pdfFileTwo.name); await contentNodeSelector.searchAndSelectResult(pdfFileTwo.name, pdfFileTwo.name); await contentNodeSelector.clickMoveCopyButton(); @@ -192,6 +189,7 @@ describe('Attach File - Content service', () => { await externalNodeSelector.waitForLogInDialog(); await externalNodeSelector.login(user.email, user.password); + await searchService.isSearchable(externalFile); await externalNodeSelector.searchAndSelectResult(externalFile, externalFile); await externalNodeSelector.clickMoveCopyButton(); await widget.attachFileWidget().checkFileIsAttached(app.UPLOAD_FILE_FORM_CS.FIELD.widget_id, externalFile); diff --git a/e2e/process-services/attach-folder.e2e.ts b/e2e/process-services/attach-folder.e2e.ts index 04ee7f9437..3b1fbd99ec 100644 --- a/e2e/process-services/attach-folder.e2e.ts +++ b/e2e/process-services/attach-folder.e2e.ts @@ -22,9 +22,12 @@ import { IntegrationService, LocalStorageUtil, LoginPage, + StringUtil, UserModel, UsersActions, - Widget + UploadActions, + Widget, + SearchService } from '@alfresco/adf-testing'; import { TasksPage } from './pages/tasks.page'; import { browser } from 'protractor'; @@ -35,6 +38,7 @@ describe('Attach Folder', () => { const app = browser.params.resources.Files.WIDGET_CHECK_APP; const apiService = new ApiService({ provider: 'ALL' }); + const searchService = new SearchService(apiService); const integrationService = new IntegrationService(apiService); const applicationService = new ApplicationsUtil(apiService); const usersActions = new UsersActions(apiService); @@ -46,6 +50,7 @@ describe('Attach Folder', () => { const contentNodeSelector = new ContentNodeSelectorDialogPage(); let user: UserModel; + const folderName = StringUtil.generateRandomString(5); beforeAll(async () => { await LocalStorageUtil.setStorageItem('providers', 'ALL'); @@ -60,6 +65,8 @@ describe('Attach Folder', () => { }); await apiService.getInstance().login(user.email, user.password); await applicationService.importPublishDeployApp(app.file_path); + await new UploadActions(apiService).createFolder(folderName, '-my-'); + await searchService.isSearchable(folderName); await loginPage.login(user.email, user.password); }); @@ -76,28 +83,40 @@ describe('Attach Folder', () => { const contentFileWidget = widget.attachFolderWidget(); await contentFileWidget.clickWidget(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id); - await contentNodeSelector.searchAndSelectResult(user.email, user.email); + await searchService.isSearchable(folderName); + await contentNodeSelector.searchAndSelectResult(folderName, folderName); await expect(await contentNodeSelector.checkCancelButtonIsEnabled()).toBe(true); await expect(await contentNodeSelector.checkCopyMoveButtonIsEnabled()).toBe(true); + await searchService.isSearchable('Meeting Notes'); await contentNodeSelector.searchAndSelectResult('Meeting Notes', 'Meeting Notes'); await expect(await contentNodeSelector.checkCancelButtonIsEnabled()).toBe(true); await expect(await contentNodeSelector.checkCopyMoveButtonIsEnabled()).toBe(false); await contentNodeSelector.clickCancelButton(); - await widget.attachFolderWidget().checkFolderIsNotAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, user.email); + await widget.attachFolderWidget().checkFolderIsNotAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, folderName); await contentFileWidget.clickWidget(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id); await contentNodeSelector.checkDialogIsDisplayed(); - await contentNodeSelector.searchAndSelectResult(user.email, user.email); + await contentNodeSelector.searchAndSelectResult(folderName, folderName); await expect(await contentNodeSelector.checkCancelButtonIsEnabled()).toBe(true); await expect(await contentNodeSelector.checkCopyMoveButtonIsEnabled()).toBe(true); await contentNodeSelector.clickMoveCopyButton(); - await widget.attachFolderWidget().checkFolderIsAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, user.email); - await widget.attachFolderWidget().removeFolder(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, user.email); + await widget.attachFolderWidget().checkFolderIsAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, folderName); + await widget.attachFolderWidget().removeFolder(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, folderName); await taskPage.formFields().checkWidgetIsVisible(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id); - await widget.attachFolderWidget().checkFolderIsNotAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, user.email); + await widget.attachFolderWidget().checkFolderIsNotAttached(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id, folderName); + + await contentFileWidget.clickWidget(app.UPLOAD_FOLDER_FORM_CS.FIELD.widget_id); + await contentNodeSelector.checkDialogIsDisplayed(); + + await searchService.isSearchable(folderName); + await contentNodeSelector.searchAndSelectResult(folderName, folderName); + await contentNodeSelector.checkCancelButtonIsEnabled(); + await contentNodeSelector.checkCopyMoveButtonIsEnabled(); + await contentNodeSelector.clickMoveCopyButton(); + await taskPage.taskDetails().clickCompleteFormTask(); }); }); diff --git a/e2e/protractor.excludes.json b/e2e/protractor.excludes.json index 09e2b7e605..fe1aead005 100644 --- a/e2e/protractor.excludes.json +++ b/e2e/protractor.excludes.json @@ -6,7 +6,5 @@ "C260051": "login problem APS not basic", "C279932": "login problem APS not basic", "C279931": "login problem APS not basic", - "C279930": "login problem APS not basic", - "C246534": "https://issues.alfresco.com/jira/browse/ADF-5236" + "C279930": "login problem APS not basic" } - diff --git a/lib/testing/src/lib/content-services/dialog/content-node-selector-dialog.page.ts b/lib/testing/src/lib/content-services/dialog/content-node-selector-dialog.page.ts index fac8e8966b..9fe63c39ab 100644 --- a/lib/testing/src/lib/content-services/dialog/content-node-selector-dialog.page.ts +++ b/lib/testing/src/lib/content-services/dialog/content-node-selector-dialog.page.ts @@ -156,6 +156,7 @@ export class ContentNodeSelectorDialogPage { async searchAndSelectResult(searchText: string, name: string) { await this.typeIntoNodeSelectorSearchField(searchText); await this.contentListPage().dataTablePage().waitTillContentLoaded(); + await this.contentListPage().dataTablePage().waitForFirstRow(); try { await this.contentListPage().dataTablePage().checkRowContentIsDisplayed(name); } catch (e) { diff --git a/lib/testing/src/lib/core/actions/api.service.ts b/lib/testing/src/lib/core/actions/api.service.ts index ed349862f4..c83a444660 100644 --- a/lib/testing/src/lib/core/actions/api.service.ts +++ b/lib/testing/src/lib/core/actions/api.service.ts @@ -122,4 +122,22 @@ export class ApiService { .catch((err) => reject(err)); }); } + + async performECMOperation(path: string, method: string, queryParams: any, postBody: any): Promise { + return new Promise((resolve, reject) => { + const uri = this.config.hostEcm + path; + const pathParams = {}, formParams = {}; + const contentTypes = ['application/json']; + const accepts = ['application/json']; + + const headerParams = { + Authorization: 'bearer ' + this.apiService.oauth2Auth.token + }; + + this.apiService.contentClient + .callCustomApi(uri, method, pathParams, queryParams, headerParams, formParams, postBody, contentTypes, accepts, Object) + .then((data) => resolve(data)) + .catch((err) => reject(err)); + }); + } } diff --git a/lib/testing/src/lib/core/actions/public-api.ts b/lib/testing/src/lib/core/actions/public-api.ts index a7e39b5397..3a7be01bc3 100644 --- a/lib/testing/src/lib/core/actions/public-api.ts +++ b/lib/testing/src/lib/core/actions/public-api.ts @@ -22,3 +22,4 @@ export * from './users.actions'; export * from './api'; export * from './api.util'; export * from './e2e-request-api.helper'; +export * from './search.service'; diff --git a/lib/testing/src/lib/core/actions/search.service.ts b/lib/testing/src/lib/core/actions/search.service.ts new file mode 100644 index 0000000000..ff7b16d8f4 --- /dev/null +++ b/lib/testing/src/lib/core/actions/search.service.ts @@ -0,0 +1,83 @@ +/*! + * @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 { ApiService } from './api.service'; +import { ResultSetPaging } from '@alfresco/js-api'; +import { Logger } from '../utils/logger'; +import { ApiUtil } from './api.util'; + +export class SearchService { + apiService: ApiService; + + constructor(apiService: ApiService) { + this.apiService = apiService; + } + + async isSearchable(name: string): Promise { + const query = this.createSearchQuery(name); + + const predicate = (result: ResultSetPaging) => { + return result.list && result.list.entries.length > 0 && !!result.list.entries.find(({ entry }) => entry.name === name); + }; + + const apiCall = async () => { + try { + const path = '/alfresco/api/-default-/public/search/versions/1/search'; + const method = 'POST'; + + const queryParams = {}, + postBody = JSON.parse(query); + + return this.apiService.performECMOperation(path, method, queryParams, postBody); + } catch (error) { + Logger.error('Failed to search folder'); + } + }; + + return ApiUtil.waitForApi(apiCall, predicate); + } + + private createSearchQuery(name: string) { + return `{ + "query": { + "query": "${name}*" + }, + "include": [ + "path", + "allowableOperations", + "properties" + ], + "paging": { + "maxItems": 20, + "skipCount": 0 + }, + "filterQueries": [ + { + "query": "TYPE:'cm:folder' OR TYPE:'cm:content'" + }, + { + "query": "NOT cm:creator:System" + } + ], + "scope": { + "locations": [ + "nodes" + ] + } + }`; + } +}