diff --git a/e2e/actions/ACS/node.actions.ts b/e2e/actions/ACS/node.actions.ts index 29510cc8f6..ee0768f5fb 100644 --- a/e2e/actions/ACS/node.actions.ts +++ b/e2e/actions/ACS/node.actions.ts @@ -25,4 +25,16 @@ export class NodeActions { }); } + async getNodesDisplayed(alfrescoJsApi, idList, numberOfElements) { + + let promises = []; + let nodeList; + + for (let i = 0; i < (numberOfElements - 1) ; i++ ) { + promises.push(alfrescoJsApi.core.nodesApi.getNode(idList[i])); + } + nodeList = await Promise.all(promises); + return nodeList; + } + } diff --git a/e2e/actions/ACS/upload.actions.ts b/e2e/actions/ACS/upload.actions.ts index e91126b7d2..ebc1541635 100644 --- a/e2e/actions/ACS/upload.actions.ts +++ b/e2e/actions/ACS/upload.actions.ts @@ -53,7 +53,7 @@ export class UploadActions { }); } - async uploadFolder(alfrescoJsApi, folderName, parentFolderId) { + async createFolder(alfrescoJsApi, folderName, parentFolderId) { return alfrescoJsApi.nodes.addNode(parentFolderId, { 'name': folderName, 'nodeType': 'cm:folder' @@ -64,7 +64,7 @@ export class UploadActions { return alfrescoJsApi.nodes.deleteNode(folderId, { permanent: true } ); } - async uploadFolderFiles(alfrescoJsApi, sourcePath, folder) { + async uploadFolder(alfrescoJsApi, sourcePath, folder) { let absolutePath = '../../' + sourcePath; let files = fs.readdirSync(path.join(__dirname, absolutePath)); let uploadedFiles; diff --git a/e2e/content-services/document-list/document_list_actions.e2e.ts b/e2e/content-services/document-list/document_list_actions.e2e.ts index 0683124e10..5dc6f9163a 100644 --- a/e2e/content-services/document-list/document_list_actions.e2e.ts +++ b/e2e/content-services/document-list/document_list_actions.e2e.ts @@ -66,7 +66,7 @@ describe('Document List Component - Actions', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); pdfUploadedNode = await uploadActions.uploadFile(this.alfrescoJsApi, pdfFileModel.location, pdfFileModel.name, '-my-'); testFileNode = await uploadActions.uploadFile(this.alfrescoJsApi, testFileModel.location, testFileModel.name, '-my-'); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -153,8 +153,8 @@ describe('Document List Component - Actions', () => { await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); - secondUploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, secondFolderName, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); + secondUploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, secondFolderName, '-my-'); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); diff --git a/e2e/content-services/document-list/document_list_component.e2e.ts b/e2e/content-services/document-list/document_list_component.e2e.ts index ab6034c87f..9c7ab8c723 100644 --- a/e2e/content-services/document-list/document_list_component.e2e.ts +++ b/e2e/content-services/document-list/document_list_component.e2e.ts @@ -83,7 +83,7 @@ describe('Document List Component', () => { privateSite = await this.alfrescoJsApi.core.sitesApi.createSite(privateSiteBody); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, privateSite.entry.guid); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, privateSite.entry.guid); done(); }); @@ -153,7 +153,7 @@ describe('Document List Component', () => { await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); pdfUploadedNode = await uploadActions.uploadFile(this.alfrescoJsApi, pdfFileModel.location, pdfFileModel.name, '-my-'); docxUploadedNode = await uploadActions.uploadFile(this.alfrescoJsApi, docxFileModel.location, docxFileModel.name, '-my-'); done(); @@ -339,7 +339,7 @@ describe('Document List Component', () => { await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); contentServicesPage.checkContentIsDisplayed(uploadedFolder.entry.name); @@ -371,7 +371,7 @@ describe('Document List Component', () => { await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.clickOnContentServices(); let lineHeight = await contentServicesPage.getStyleValueForRowText(folderName, 'line-height'); @@ -388,8 +388,8 @@ describe('Document List Component', () => { await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderNameA, '-my-'); - uploadedFolderExtra = await uploadActions.uploadFolder(this.alfrescoJsApi, folderNameB, '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, folderNameA, '-my-'); + uploadedFolderExtra = await uploadActions.createFolder(this.alfrescoJsApi, folderNameB, '-my-'); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); contentServicesPage.checkContentIsDisplayed(folderNameA); @@ -437,7 +437,7 @@ describe('Document List Component', () => { let folder = null; for (let i = 0; i < 20; i++) { folderName = `MEESEEKS_000${i}`; - folder = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + folder = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); folderCreated.push(folder); } done(); @@ -489,7 +489,7 @@ describe('Document List Component', () => { filePdfNode = await uploadActions.uploadFile(this.alfrescoJsApi, pdfFile.location, pdfFile.name, '-my-'); fileTestNode = await uploadActions.uploadFile(this.alfrescoJsApi, testFile.location, testFile.name, '-my-'); fileDocxNode = await uploadActions.uploadFile(this.alfrescoJsApi, docxFile.location, docxFile.name, '-my-'); - folderNode = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + folderNode = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); done(); }); @@ -594,7 +594,7 @@ describe('Document List Component', () => { filePdfNode = await uploadActions.uploadFile(this.alfrescoJsApi, pdfFile.location, pdfFile.name, '-my-'); fileTestNode = await uploadActions.uploadFile(this.alfrescoJsApi, testFile.location, testFile.name, '-my-'); fileDocxNode = await uploadActions.uploadFile(this.alfrescoJsApi, docxFile.location, docxFile.name, '-my-'); - folderNode = await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + folderNode = await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); filePDFSubNode = await uploadActions.uploadFile(this.alfrescoJsApi, pdfFile.location, pdfFile.name, folderNode.entry.id); done(); diff --git a/e2e/content-services/document-list/document_list_pagination.e2e.ts b/e2e/content-services/document-list/document_list_pagination.e2e.ts index 20eae4a24d..e3f3763a26 100644 --- a/e2e/content-services/document-list/document_list_pagination.e2e.ts +++ b/e2e/content-services/document-list/document_list_pagination.e2e.ts @@ -76,8 +76,8 @@ describe('Document List - Pagination', function () { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - let folderThreeUploadedModel = await uploadActions.uploadFolder(this.alfrescoJsApi, folderThreeModel.name, '-my-'); - let newFolderUploadedModel = await uploadActions.uploadFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); + let folderThreeUploadedModel = await uploadActions.createFolder(this.alfrescoJsApi, folderThreeModel.name, '-my-'); + let newFolderUploadedModel = await uploadActions.createFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); await uploadActions.createEmptyFiles(this.alfrescoJsApi, fileNames, newFolderUploadedModel.entry.id); @@ -265,34 +265,34 @@ describe('Document List - Pagination', function () { paginationPage.selectItemsPerPage(itemsPerPage.twenty); contentServicesPage.checkAcsContainer(); contentServicesPage.waitForTableBody(); - contentServicesPage.getElementsDisplayed().then(function (list) { - contentServicesPage.checkElementsSortedByNameAsc(list); + contentServicesPage.getElementsDisplayedName().then(function (list) { + contentServicesPage.checkElementsSortedAsc(list); }); contentServicesPage.sortByName(false); - contentServicesPage.getElementsDisplayed().then(function (list) { - contentServicesPage.checkElementsSortedByNameDesc(list); + contentServicesPage.getElementsDisplayedName().then(function (list) { + contentServicesPage.checkElementsSortedDesc(list); }); paginationPage.selectItemsPerPage(itemsPerPage.five); contentServicesPage.checkAcsContainer(); contentServicesPage.waitForTableBody(); - contentServicesPage.getElementsDisplayed().then(function (list) { - contentServicesPage.checkElementsSortedByNameDesc(list); + contentServicesPage.getElementsDisplayedName().then(function (list) { + contentServicesPage.checkElementsSortedDesc(list); }); paginationPage.clickOnNextPage(); contentServicesPage.checkAcsContainer(); contentServicesPage.waitForTableBody(); - contentServicesPage.getElementsDisplayed().then(function (list) { - contentServicesPage.checkElementsSortedByNameDesc(list); + contentServicesPage.getElementsDisplayedName().then(function (list) { + contentServicesPage.checkElementsSortedDesc(list); }); paginationPage.selectItemsPerPage(itemsPerPage.ten); contentServicesPage.checkAcsContainer(); contentServicesPage.waitForTableBody(); - contentServicesPage.getElementsDisplayed().then(function (list) { - contentServicesPage.checkElementsSortedByNameDesc(list); + contentServicesPage.getElementsDisplayedName().then(function (list) { + contentServicesPage.checkElementsSortedDesc(list); }); }); diff --git a/e2e/content-services/trashcan_pagination.e2e.ts b/e2e/content-services/trashcan_pagination.e2e.ts index 963ee44cee..13a29a08d6 100644 --- a/e2e/content-services/trashcan_pagination.e2e.ts +++ b/e2e/content-services/trashcan_pagination.e2e.ts @@ -73,7 +73,7 @@ describe('Trashcan - Pagination', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - let folderUploadedModel = await uploadActions.uploadFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); + let folderUploadedModel = await uploadActions.createFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); let emptyFiles = await uploadActions.createEmptyFiles(this.alfrescoJsApi, fileNames, folderUploadedModel.entry.id); await emptyFiles.list.entries.forEach(async (node) => { diff --git a/e2e/core/card-view/metadata-smoke-tests.e2e.ts b/e2e/core/card-view/metadata-smoke-tests.e2e.ts index 2e008cbc7d..d62ac1739c 100644 --- a/e2e/core/card-view/metadata-smoke-tests.e2e.ts +++ b/e2e/core/card-view/metadata-smoke-tests.e2e.ts @@ -78,7 +78,7 @@ describe('Metadata component', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - await uploadActions.uploadFolder(this.alfrescoJsApi, folderName, '-my-'); + await uploadActions.createFolder(this.alfrescoJsApi, folderName, '-my-'); let pngUploadedFile = await uploadActions.uploadFile(this.alfrescoJsApi, pngFileModel.location, pngFileModel.name, '-my-'); diff --git a/e2e/core/infinite_scrolling.e2e.ts b/e2e/core/infinite_scrolling.e2e.ts index da0168abc4..884149c34b 100644 --- a/e2e/core/infinite_scrolling.e2e.ts +++ b/e2e/core/infinite_scrolling.e2e.ts @@ -63,7 +63,7 @@ describe('Enable infinite scrolling', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - let folderUploadedModel = await uploadActions.uploadFolder(this.alfrescoJsApi, folderModel.name, '-my-'); + let folderUploadedModel = await uploadActions.createFolder(this.alfrescoJsApi, folderModel.name, '-my-'); await uploadActions.createEmptyFiles(this.alfrescoJsApi, fileNames, folderUploadedModel.entry.id); diff --git a/e2e/core/login/redirection.e2e.ts b/e2e/core/login/redirection.e2e.ts index 304bc0c943..945512020d 100644 --- a/e2e/core/login/redirection.e2e.ts +++ b/e2e/core/login/redirection.e2e.ts @@ -62,7 +62,7 @@ describe('Login component - Redirect', () => { await this.alfrescoJsApi.login(user.id, user.password); - uploadedFolder = await uploadActions.uploadFolder(this.alfrescoJsApi, 'protecteFolder' + Util.generateRandomString(), '-my-'); + uploadedFolder = await uploadActions.createFolder(this.alfrescoJsApi, 'protecteFolder' + Util.generateRandomString(), '-my-'); done(); }); diff --git a/e2e/core/pagination_empty_current_page.e2e.ts b/e2e/core/pagination_empty_current_page.e2e.ts index da41452680..5a7a448eec 100644 --- a/e2e/core/pagination_empty_current_page.e2e.ts +++ b/e2e/core/pagination_empty_current_page.e2e.ts @@ -66,7 +66,7 @@ describe('Pagination - returns to previous page when current is empty', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - let folderUploadedModel = await uploadActions.uploadFolder(this.alfrescoJsApi, folderModel.name, '-my-'); + let folderUploadedModel = await uploadActions.createFolder(this.alfrescoJsApi, folderModel.name, '-my-'); await uploadActions.createEmptyFiles(this.alfrescoJsApi, fileNames, folderUploadedModel.entry.id); diff --git a/e2e/core/viewer/viewer_component.e2e.ts b/e2e/core/viewer/viewer_component.e2e.ts index f293c43b1b..550949b099 100644 --- a/e2e/core/viewer/viewer_component.e2e.ts +++ b/e2e/core/viewer/viewer_component.e2e.ts @@ -134,9 +134,9 @@ describe('Viewer', () => { let archiveFolderUploaded; beforeAll(async (done) => { - archiveFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, archiveFolderInfo.name, '-my-'); + archiveFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, archiveFolderInfo.name, '-my-'); - uploadedArchives = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, archiveFolderInfo.location, archiveFolderUploaded.entry.id); + uploadedArchives = await uploadActions.uploadFolder(this.alfrescoJsApi, archiveFolderInfo.location, archiveFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -169,9 +169,9 @@ describe('Viewer', () => { let excelFolderUploaded; beforeAll(async (done) => { - excelFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, excelFolderInfo.name, '-my-'); + excelFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, excelFolderInfo.name, '-my-'); - uploadedExcels = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, excelFolderInfo.location, excelFolderUploaded.entry.id); + uploadedExcels = await uploadActions.uploadFolder(this.alfrescoJsApi, excelFolderInfo.location, excelFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -204,9 +204,9 @@ describe('Viewer', () => { let pptFolderUploaded; beforeAll(async (done) => { - pptFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, pptFolderInfo.name, '-my-'); + pptFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, pptFolderInfo.name, '-my-'); - uploadedPpt = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, pptFolderInfo.location, pptFolderUploaded.entry.id); + uploadedPpt = await uploadActions.uploadFolder(this.alfrescoJsApi, pptFolderInfo.location, pptFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -239,9 +239,9 @@ describe('Viewer', () => { let textFolderUploaded; beforeAll(async (done) => { - textFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, textFolderInfo.name, '-my-'); + textFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, textFolderInfo.name, '-my-'); - uploadedTexts = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, textFolderInfo.location, textFolderUploaded.entry.id); + uploadedTexts = await uploadActions.uploadFolder(this.alfrescoJsApi, textFolderInfo.location, textFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -274,9 +274,9 @@ describe('Viewer', () => { let wordFolderUploaded; beforeAll(async (done) => { - wordFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, wordFolderInfo.name, '-my-'); + wordFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, wordFolderInfo.name, '-my-'); - uploadedWords = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, wordFolderInfo.location, wordFolderUploaded.entry.id); + uploadedWords = await uploadActions.uploadFolder(this.alfrescoJsApi, wordFolderInfo.location, wordFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -309,9 +309,9 @@ describe('Viewer', () => { let otherFolderUploaded; beforeAll(async (done) => { - otherFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, otherFolderInfo.name, '-my-'); + otherFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, otherFolderInfo.name, '-my-'); - uploadedOthers = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, otherFolderInfo.location, otherFolderUploaded.entry.id); + uploadedOthers = await uploadActions.uploadFolder(this.alfrescoJsApi, otherFolderInfo.location, otherFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); @@ -344,9 +344,9 @@ describe('Viewer', () => { let imgFolderUploaded; beforeAll(async (done) => { - imgFolderUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, imgFolderInfo.name, '-my-'); + imgFolderUploaded = await uploadActions.createFolder(this.alfrescoJsApi, imgFolderInfo.name, '-my-'); - uploadedImages = await uploadActions.uploadFolderFiles(this.alfrescoJsApi, imgFolderInfo.location, imgFolderUploaded.entry.id); + uploadedImages = await uploadActions.uploadFolder(this.alfrescoJsApi, imgFolderInfo.location, imgFolderUploaded.entry.id); loginPage.loginToContentServicesUsingUserModel(acsUser); contentServicesPage.goToDocumentList(); diff --git a/e2e/models/APS/AppPublish.js b/e2e/models/APS/AppPublish.js index 546accb1de..2d24c29fed 100644 --- a/e2e/models/APS/AppPublish.js +++ b/e2e/models/APS/AppPublish.js @@ -28,4 +28,4 @@ var AppPublish = function (details) { Object.assign(this, details); }; -module.exports = AppPublish; \ No newline at end of file +module.exports = AppPublish; diff --git a/e2e/pages/adf/contentServicesPage.ts b/e2e/pages/adf/contentServicesPage.ts index dff9f3410c..912a5f03e9 100644 --- a/e2e/pages/adf/contentServicesPage.ts +++ b/e2e/pages/adf/contentServicesPage.ts @@ -20,6 +20,7 @@ import { Util } from '../../util/util'; import { ContentListPage } from './dialog/contentListPage'; import { CreateFolderDialog } from './dialog/createFolderDialog'; import { NavigationBarPage } from './navigationBarPage'; +import { NodeActions } from '../../actions/ACS/node.actions'; import { by, element, protractor, $$, browser } from 'protractor'; import path = require('path'); @@ -28,6 +29,7 @@ export class ContentServicesPage { contentList = new ContentListPage(); createFolderDialog = new CreateFolderDialog(); + nodeActions = new NodeActions(); uploadBorder = element(by.id('document-list-container')); tableBody = element.all(by.css('adf-document-list div[class="adf-datatable-body"]')).first(); contentServices = element(by.css('a[data-automation-id="Content Services"]')); @@ -59,13 +61,88 @@ export class ContentServicesPage { searchInputElement = element(by.css('input[data-automation-id="content-node-selector-search-input"]')); shareNodeButton = element(by.cssContainingText('mat-icon', ' share ')); - getElementsDisplayed() { + getElementsDisplayedCreated() { let deferred = protractor.promise.defer(); - let fileNameLocator = by.css("div[id*='document-list-container'] div[class*='adf-datatable-row'] div[title='Display name'] span[class='adf-datatable-cell-value']"); + let fileCreatedLocator = this.contentList.getColumnLocator('Created'); + Util.waitUntilElementIsVisible(element.all(fileCreatedLocator).first()); + let initialList = []; + + element.all(fileCreatedLocator).each((item) => { + item.getAttribute('title').then((dateText) => { + if (dateText !== '') { + let date = new Date(dateText); + initialList.push(date); + } + }); + }).then(function () { + deferred.fulfill(initialList); + }); + + return deferred.promise; + } + + getElementsDisplayedSize() { + let deferred = protractor.promise.defer(); + let fileSizeLocator = this.contentList.getColumnLocator('Size'); + Util.waitUntilElementIsVisible(element.all(fileSizeLocator).first()); + let initialList = []; + + element.all(fileSizeLocator).each(function (item) { + item.getAttribute('title').then((sizeText) => { + if (sizeText !== '') { + let size = Number(sizeText); + initialList.push(size); + } + }); + }).then(function () { + deferred.fulfill(initialList); + }); + + return deferred.promise; + } + + getElementsDisplayedAuthor(alfrescoJsApi) { + let deferred = protractor.promise.defer(); + this.nodeActions.getNodesDisplayed(alfrescoJsApi).then((nodes) => { + let initialList = []; + + nodes.forEach((item) => { + if (item.entry.createdByUser.id !== '') { + initialList.push(item.entry.createdByUser.id); + } + }); + deferred.fulfill(initialList); + }); + + return deferred.promise; + } + + getElementsDisplayedName() { + let deferred = protractor.promise.defer(); + let fileNameLocator = this.contentList.getColumnLocator('Display name'); Util.waitUntilElementIsVisible(element.all(fileNameLocator).first()); let initialList = []; - element.all(fileNameLocator).each(function (item) { + element.all(fileNameLocator).each((item) => { + item.getText().then(function (name) { + if (name !== '') { + initialList.push(name); + } + }); + }).then(function () { + deferred.fulfill(initialList); + }); + + return deferred.promise; + } + + getElementsDisplayedId() { + let deferred = protractor.promise.defer(); + let fileIdLocator = this.contentList.getColumnLocator('Node id'); + Util.waitUntilElementIsVisible(element.all(fileIdLocator).first()); + let initialList = []; + + element.all(fileIdLocator).each((item) => { item.getText().then(function (text) { if (text !== '') { initialList.push(text); @@ -78,24 +155,28 @@ export class ContentServicesPage { return deferred.promise; } - checkElementsSortedByNameAsc(elements) { - browser.controlFlow().execute(async () => { - let numberOfElements = await this.numberOfResultsDisplayed(); - for (let i = 0; i < (numberOfElements - 1); i++) { - expect(JSON.stringify(elements[i]) <= JSON.stringify(elements[i + 1])).toEqual(true); + checkElementsSortedAsc(elements) { + let sorted = true; + let i = 0; + while (elements.length > 1 && sorted === true && i < (elements.length - 1)) { + if (JSON.stringify(elements[i]) > JSON.stringify(elements[i + 1])) { + sorted = false; } - }); - return this; + i++; + } + return sorted; } - checkElementsSortedByNameDesc(elements) { - browser.controlFlow().execute(async () => { - let numberOfElements = await this.numberOfResultsDisplayed(); - for (let i = 0; i < (numberOfElements - 1); i++) { - expect(JSON.stringify(elements[i]) >= JSON.stringify(elements[i + 1])).toEqual(true); + checkElementsSortedDesc(elements) { + let sorted = true; + let i = 0; + while (elements.length > 1 && sorted === true && i < (elements.length - 1)) { + if (elements[i] < elements[i + 1]) { + sorted = false; } - }); - return this; + i++; + } + return sorted; } getContentList() { diff --git a/e2e/pages/adf/content_services/search/components/search-sortingPicker.page.ts b/e2e/pages/adf/content_services/search/components/search-sortingPicker.page.ts new file mode 100644 index 0000000000..68b573f5e5 --- /dev/null +++ b/e2e/pages/adf/content_services/search/components/search-sortingPicker.page.ts @@ -0,0 +1,102 @@ +/*! + * @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 { browser, by, element, protractor } from 'protractor'; +import { Util } from '../../../../../util/util'; + +export class SearchSortingPickerPage { + + sortingSelector = element(by.css('adf-sorting-picker div[class="mat-select-arrow"]')); + orderArrow = element(by.css('adf-sorting-picker button mat-icon')); + optionsDropdown = element(by.css('div[class*="mat-select-panel"]')); + + sortBy(sortOrder, sortType) { + Util.waitUntilElementIsClickable(this.sortingSelector); + this.sortingSelector.click(); + + let selectedSortingOption = element(by.cssContainingText('span[class="mat-option-text"]', sortType)); + Util.waitUntilElementIsClickable(selectedSortingOption); + selectedSortingOption.click(); + + this.sortByOrder(sortOrder); + } + + sortByOrder(sortOrder) { + Util.waitUntilElementIsVisible(this.orderArrow); + this.orderArrow.getText().then((result) => { + if (sortOrder === true) { + if (result !== 'arrow_upward') { + browser.executeScript(`document.querySelector('adf-sorting-picker button mat-icon').click();`); + } + } else { + if (result === 'arrow_upward') { + browser.executeScript(`document.querySelector('adf-sorting-picker button mat-icon').click();`); + } + } + }); + } + + clickSortingOption(option) { + let selectedSortingOption = element(by.cssContainingText('span[class="mat-option-text"]', option)); + Util.waitUntilElementIsClickable(selectedSortingOption); + selectedSortingOption.click(); + return this; + } + + clickSortingSelector() { + Util.waitUntilElementIsClickable(this.sortingSelector); + this.sortingSelector.click(); + return this; + } + + checkOptionIsDisplayed(option) { + let optionSelector = this.optionsDropdown.element(by.cssContainingText('span[class="mat-option-text"]', option)); + Util.waitUntilElementIsVisible(optionSelector); + return this; + } + + checkOptionIsNotDisplayed(option) { + let optionSelector = this.optionsDropdown.element(by.cssContainingText('span[class="mat-option-text"]', option)); + Util.waitUntilElementIsNotVisible(optionSelector); + return this; + } + + checkOptionsDropdownIsDisplayed() { + Util.waitUntilElementIsVisible(this.optionsDropdown); + return this; + } + + checkSortingSelectorIsDisplayed() { + Util.waitUntilElementIsVisible(this.sortingSelector); + return this; + } + + checkOrderArrowIsDownward() { + let deferred = protractor.promise.defer(); + Util.waitUntilElementIsVisible(this.orderArrow); + this.orderArrow.getText().then((result) => { + deferred.fulfill(result !== 'arrow_upward'); + }); + return deferred.promise; + } + + checkOrderArrowIsDisplayed() { + Util.waitUntilElementIsVisible(this.orderArrow); + return this; + } + +} diff --git a/e2e/pages/adf/dialog/contentListPage.ts b/e2e/pages/adf/dialog/contentListPage.ts index 90e4d8a3fe..1e0edfb09d 100644 --- a/e2e/pages/adf/dialog/contentListPage.ts +++ b/e2e/pages/adf/dialog/contentListPage.ts @@ -39,9 +39,13 @@ export class ContentListPage { createdColumnHeader = by.css('div[data-automation-id*="auto_id_createdAt"]'); rows = by.css('div[id="document-list-container"] div[class*="adf-datatable-body"] div[class*="adf-datatable-row"]'); emptyFolderMessage = element(by.css('div[class="adf-empty-folder-this-space-is-empty"]')); - table = element(by.css('div[class*="upload-border"]')); + table = element.all(by.css('adf-datatable')).first(); tableBody = element.all(by.css('adf-document-list div[class="adf-datatable-body"]')).first(); + getColumnLocator(column) { + return by.css(`div[id*='document-list-container'] div[class*='adf-datatable-row'] div[title='${column}'] span`); + } + getTooltip(nodeName) { return this.getRowByRowName(nodeName).element(by.css(`#document-list-container span[title="${nodeName}"]`)).getAttribute('title'); } diff --git a/e2e/pages/adf/dialog/searchDialog.ts b/e2e/pages/adf/dialog/searchDialog.ts index d71d90c203..f8734aba01 100644 --- a/e2e/pages/adf/dialog/searchDialog.ts +++ b/e2e/pages/adf/dialog/searchDialog.ts @@ -21,8 +21,8 @@ import { browser, by, element, protractor } from 'protractor'; export class SearchDialog { searchIcon = element(by.css(`button[class*='adf-search-button']`)); - searchBar = element(by.css(`adf-search-control div[style*='translateX(0%)'] input`)); - searchBarNotExpanded = element(by.css(`adf-search-control div[style*='translateX(81%)'] input`)); + searchBar = element(by.css(`adf-search-control input`)); + searchBarExpanded = element(by.css(`adf-search-control mat-form-field[class*="mat-focused"] input`)); noResultMessage = element(by.css(`p[class*='adf-search-fixed-text']`)); rowsAuthor = by.css(`div[class='mat-list-text'] p[class*='adf-search-fixed-text']`); completeName = by.css(`h4[class*='adf-search-fixed-text']`); @@ -51,12 +51,13 @@ export class SearchDialog { } checkSearchBarIsNotVisible() { - browser.sleep(400); - Util.waitUntilElementIsVisible(this.searchBarNotExpanded); + Util.waitUntilElementIsVisible(this.searchBar); + Util.waitUntilElementIsNotVisible(this.searchBarExpanded); return this; } checkNoResultMessageIsDisplayed() { + browser.driver.sleep(500); Util.waitUntilElementIsVisible(this.noResultMessage); return this; } diff --git a/e2e/pages/adf/material/formControllersPage.ts b/e2e/pages/adf/material/formControllersPage.ts index 051a2931f9..ed0bd019f0 100644 --- a/e2e/pages/adf/material/formControllersPage.ts +++ b/e2e/pages/adf/material/formControllersPage.ts @@ -16,6 +16,7 @@ */ import { Util } from '../../../util/util'; +import { by } from 'protractor'; export class FormControllersPage { @@ -23,8 +24,8 @@ export class FormControllersPage { Util.waitUntilElementIsVisible(toggle); toggle.getAttribute('class').then((check) => { if (check.indexOf('mat-checked') < 0) { - Util.waitUntilElementIsClickable(toggle.element(by.css('div'))); - toggle.element(by.css('div')).click(); + Util.waitUntilElementIsClickable(toggle.all(by.css('div')).first()); + toggle.all(by.css('div')).first().click(); } }); } diff --git a/e2e/pages/adf/searchResultsPage.ts b/e2e/pages/adf/searchResultsPage.ts index 26ab772be8..59d75c3ba4 100644 --- a/e2e/pages/adf/searchResultsPage.ts +++ b/e2e/pages/adf/searchResultsPage.ts @@ -18,16 +18,17 @@ import { Util } from '../../util/util'; import { ContentListPage } from './dialog/contentListPage'; import { DataTablePage } from './dataTablePage'; -import { element, by, protractor, browser } from 'protractor'; +import { SearchSortingPickerPage } from './content_services/search/components/search-sortingPicker.page'; +import { element, by, protractor } from 'protractor'; +import { ContentServicesPage } from './contentServicesPage'; export class SearchResultsPage { noResultsMessage = element(by.css('div[class="adf-no-result-message"]')); - noResultsMessageBy = element(by.css('div[class="adf-no-result-message"]')); contentList = new ContentListPage(); dataTable = new DataTablePage(); - sortArrowLocator = by.css('adf-sorting-picker button mat-icon'); - sortingArrow = element(by.css('adf-sorting-picker div[class="mat-select-arrow"]')); + searchSortingPicker = new SearchSortingPickerPage(); + contentServices = new ContentServicesPage(); tableIsLoaded() { this.contentList.tableIsLoaded(); @@ -55,7 +56,7 @@ export class SearchResultsPage { } checkNoResultMessageIsDisplayed() { - Util.waitUntilElementIsVisible(this.noResultsMessageBy); + Util.waitUntilElementIsVisible(this.noResultsMessage); return this; } @@ -79,76 +80,108 @@ export class SearchResultsPage { } sortByName(sortOrder) { - this.sortBy(sortOrder, 'Name'); - } - - sortBy(sortOrder, sortType) { - Util.waitUntilElementIsClickable(this.sortingArrow); - this.sortingArrow.click(); - - let selectedSortingOption = element(by.cssContainingText('span[class="mat-option-text"]', sortType)); - Util.waitUntilElementIsClickable(selectedSortingOption); - selectedSortingOption.click(); - - this.sortByOrder(sortOrder); - } - - sortByOrder(sortOrder) { - Util.waitUntilElementIsVisible(element(this.sortArrowLocator)); - return element(this.sortArrowLocator).getText().then((result) => { - if (sortOrder === true) { - if (result !== 'arrow_upward') { - browser.executeScript(`document.querySelector('adf-sorting-picker button mat-icon').click();`); - } - } else { - if (result === 'arrow_upward') { - browser.executeScript(`document.querySelector('adf-sorting-picker button mat-icon').click();`); - } - } - - return Promise.resolve(); - }); + this.searchSortingPicker.sortBy(sortOrder, 'Name'); } sortByAuthor(sortOrder) { - this.sortBy(sortOrder, 'Author'); + this.searchSortingPicker.sortBy(sortOrder, 'Author'); } sortByCreated(sortOrder) { - this.sortBy(sortOrder, 'Created'); + this.searchSortingPicker.sortBy(sortOrder, 'Created'); } sortBySize(sortOrder) { - this.sortBy(sortOrder, 'Size'); + this.searchSortingPicker.sortBy(sortOrder, 'Size'); return this; } sortAndCheckListIsOrderedByName(sortOrder) { + let deferred = protractor.promise.defer(); this.sortByName(sortOrder); this.dataTable.waitForTableBody(); - let deferred = protractor.promise.defer(); - this.contentList.checkListIsOrderedByNameColumn(sortOrder).then((result) => { - deferred.fulfill(result); - }); + if (sortOrder === true) { + this.checkListIsOrderedByNameAsc().then((result) => { + deferred.fulfill(result); + }); + } else { + this.checkListIsOrderedByNameDesc().then((result) => { + deferred.fulfill(result); + }); + } return deferred.promise; } - sortAndCheckListIsOrderedByAuthor(sortOrder) { - this.sortByAuthor(sortOrder); + async checkListIsOrderedByNameAsc() { + let list = await this.contentServices.getElementsDisplayedName(); + return this.contentServices.checkElementsSortedAsc(list); + } + + async checkListIsOrderedByNameDesc() { + let list = await this.contentServices.getElementsDisplayedName(); + return this.contentServices.checkElementsSortedDesc(list); + } + + sortAndCheckListIsOrderedByAuthor(alfrescoJsApi, sortOrder) { let deferred = protractor.promise.defer(); - this.contentList.checkListIsOrderedByAuthorColumn(sortOrder).then((result) => { - deferred.fulfill(result); - }); + this.sortByAuthor(sortOrder); + this.dataTable.waitForTableBody(); + if (sortOrder === true) { + this.checkListIsOrderedByAuthorAsc(alfrescoJsApi).then((result) => { + deferred.fulfill(result); + }); + } else { + this.checkListIsOrderedByAuthorDesc(alfrescoJsApi).then((result) => { + deferred.fulfill(result); + }); + } return deferred.promise; } + async checkListIsOrderedByAuthorAsc(alfrescoJsApi) { + let list = await this.contentServices.getElementsDisplayedAuthor(alfrescoJsApi); + return this.contentServices.checkElementsSortedAsc(list); + } + + async checkListIsOrderedByAuthorDesc(alfrescoJsApi) { + let list = await this.contentServices.getElementsDisplayedAuthor(alfrescoJsApi); + return this.contentServices.checkElementsSortedDesc(list); + } + sortAndCheckListIsOrderedByCreated(sortOrder) { - this.sortByCreated(sortOrder); let deferred = protractor.promise.defer(); - this.contentList.checkListIsOrderedByCreatedColumn(sortOrder).then((result) => { - deferred.fulfill(result); - }); + this.sortByCreated(sortOrder); + this.dataTable.waitForTableBody(); + if (sortOrder === true) { + this.checkListIsOrderedByCreatedAsc().then((result) => { + deferred.fulfill(result); + }); + } else { + this.checkListIsOrderedByCreatedDesc().then((result) => { + deferred.fulfill(result); + }); + } return deferred.promise; } + async checkListIsOrderedByCreatedAsc() { + let list = await this.contentServices.getElementsDisplayedCreated(); + return this.contentServices.checkElementsSortedAsc(list); + } + + async checkListIsOrderedByCreatedDesc() { + let list = await this.contentServices.getElementsDisplayedCreated(); + return this.contentServices.checkElementsSortedDesc(list); + } + + async checkListIsOrderedBySizeAsc() { + let list = await this.contentServices.getElementsDisplayedSize(); + return this.contentServices.checkElementsSortedAsc(list); + } + + async checkListIsOrderedBySizeDesc() { + let list = await this.contentServices.getElementsDisplayedSize(); + return this.contentServices.checkElementsSortedDesc(list); + } + } diff --git a/e2e/search/components/search-date-range.e2e.ts b/e2e/search/components/search-date-range.e2e.ts index e9538be00d..b847ff4d71 100644 --- a/e2e/search/components/search-date-range.e2e.ts +++ b/e2e/search/components/search-date-range.e2e.ts @@ -211,7 +211,7 @@ describe('Search Date Range Filter', () => { navigationBar.clickConfigEditorButton(); configEditor.clickSearchConfiguration(); configEditor.clickClearButton(); - configEditor.enterConfiguration(JSON.stringify(jsonFile)); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); configEditor.clickSaveButton(); searchDialog.clickOnSearchIcon().enterTextAndPressEnter('*'); diff --git a/e2e/search/components/search-slider.e2e.ts b/e2e/search/components/search-slider.e2e.ts index bbc5de0824..25e8c87704 100644 --- a/e2e/search/components/search-slider.e2e.ts +++ b/e2e/search/components/search-slider.e2e.ts @@ -157,7 +157,7 @@ describe('Search Number Range Filter', () => { navigationBar.clickConfigEditorButton(); configEditor.clickSearchConfiguration(); configEditor.clickClearButton(); - configEditor.enterConfiguration(JSON.stringify(jsonFile)).clickSaveButton(); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)).clickSaveButton(); searchDialog.checkSearchIconIsVisible() .clickOnSearchIcon() @@ -177,7 +177,7 @@ describe('Search Number Range Filter', () => { navigationBar.clickConfigEditorButton(); configEditor.clickSearchConfiguration(); configEditor.clickClearButton(); - configEditor.enterConfiguration(JSON.stringify(jsonFile)).clickSaveButton(); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)).clickSaveButton(); searchDialog.checkSearchIconIsVisible() .clickOnSearchIcon() @@ -199,7 +199,7 @@ describe('Search Number Range Filter', () => { navigationBar.clickConfigEditorButton(); configEditor.clickSearchConfiguration(); configEditor.clickClearButton(); - configEditor.enterConfiguration(JSON.stringify(jsonFile)).clickSaveButton(); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)).clickSaveButton(); searchDialog.checkSearchIconIsVisible() .clickOnSearchIcon() @@ -221,7 +221,7 @@ describe('Search Number Range Filter', () => { navigationBar.clickConfigEditorButton(); configEditor.clickSearchConfiguration(); configEditor.clickClearButton(); - configEditor.enterConfiguration(JSON.stringify(jsonFile)).clickSaveButton(); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)).clickSaveButton(); searchDialog.checkSearchIconIsVisible() .clickOnSearchIcon() diff --git a/e2e/search/components/search-sorting-picker.e2e.ts b/e2e/search/components/search-sorting-picker.e2e.ts new file mode 100644 index 0000000000..75647c5296 --- /dev/null +++ b/e2e/search/components/search-sorting-picker.e2e.ts @@ -0,0 +1,351 @@ +/*! + * @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 { LoginPage } from '../../pages/adf/loginPage'; +import { SearchDialog } from '../../pages/adf/dialog/searchDialog'; +import { SearchResultsPage } from '../../pages/adf/searchResultsPage'; +import { NavigationBarPage } from '../../pages/adf/navigationBarPage'; +import { ConfigEditorPage } from '../../pages/adf/configEditorPage'; +import { SearchFiltersPage } from '../../pages/adf/searchFiltersPage'; +import { ContentServicesPage } from '../../pages/adf/contentServicesPage'; +import { NodeActions } from '../../actions/ACS/node.actions'; + +import TestConfig = require('../../test.config'); + +import AlfrescoApi = require('alfresco-js-api-node'); +import { UploadActions } from '../../actions/ACS/upload.actions'; +import { AcsUserModel } from '../../models/ACS/acsUserModel'; +import { browser } from 'protractor'; +import resources = require('../../util/resources'); +import { SearchConfiguration } from '../search.config'; +import { SearchSortingPickerPage } from '../../pages/adf/content_services/search/components/search-sortingPicker.page'; + +describe('Search Sorting Picker', () => { + + const loginPage = new LoginPage(); + const searchDialog = new SearchDialog(); + const searchFilters = new SearchFiltersPage(); + const searchResults = new SearchResultsPage(); + const navigationBar = new NavigationBarPage(); + const configEditor = new ConfigEditorPage(); + const searchSortingPicker = new SearchSortingPickerPage(); + const contentServices = new ContentServicesPage(); + const nodeActions = new NodeActions(); + + const acsUser = new AcsUserModel(); + + const pngAModel = { + 'name': resources.Files.ADF_DOCUMENTS.PNG.file_name, + 'location': resources.Files.ADF_DOCUMENTS.PNG.file_location + }; + + const pngDModel = { + 'name': resources.Files.ADF_DOCUMENTS.PNG_D.file_name, + 'location': resources.Files.ADF_DOCUMENTS.PNG_D.file_location + }; + + let pngA, pngD; + const uploadActions = new UploadActions(); + const search = '_png_file.png'; + let jsonFile; + + beforeAll(async (done) => { + + this.alfrescoJsApi = new AlfrescoApi({ + provider: 'ECM', + hostEcm: TestConfig.adf.url + }); + + await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); + + await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser); + + await this.alfrescoJsApi.login(acsUser.id, acsUser.password); + + pngA = await uploadActions.uploadFile(this.alfrescoJsApi, pngAModel.location, pngAModel.name, '-my-'); + await browser.driver.sleep(3000); + pngD = await uploadActions.uploadFile(this.alfrescoJsApi, pngDModel.location, pngDModel.name, '-my-'); + await browser.driver.sleep(12000); + + loginPage.loginToContentServices(acsUser.id, acsUser.password); + + done(); + }); + + afterAll(async (done) => { + await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, pngA.entry.id); + await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, pngD.entry.id); + done(); + }); + + beforeEach(async (done) => { + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + done(); + }); + + afterEach(async (done) => { + await browser.get(TestConfig.adf.url); + done(); + }); + + it(`[C277269] Should see the "sort by" option when search results are displayed in search results page`, () => { + searchSortingPicker.checkSortingSelectorIsDisplayed(); + }); + + it(`[C277270] Should see the icon for ASC and DESC sort when search results are displayed in the search results page`, () => { + searchSortingPicker.checkOrderArrowIsDisplayed(); + }); + + it('[C277271] Should be able to add a custom search sorter in the "sort by" option', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options.push({ 'key': 'Modifier', 'label': 'Modifier', 'type': 'FIELD', 'field': 'cm:modifier', 'ascending': true }); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .clickSortingSelector() + .checkOptionsDropdownIsDisplayed() + .checkOptionIsDisplayed('Modifier'); + }); + + it('[C277272] Should be able to exclude a standard search sorter from the sorting option', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + let removedOption = jsonFile.sorting.options.splice(0, 1); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .clickSortingSelector() + .checkOptionsDropdownIsDisplayed() + .checkOptionIsNotDisplayed(removedOption[0].label); + }); + + it('[C277273] Should be able to set a default order for a search sorting option', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options[0].ascending = false; + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .clickSortingSelector() + .checkOptionIsDisplayed('Name') + .clickSortingOption('Name'); + expect(searchSortingPicker.checkOrderArrowIsDownward()).toBe(true); + }); + + it('[C277280] Should be able to sort the search results by "Name" ASC', () => { + searchFilters.checkSearchFiltersIsDisplayed(); + searchFilters.creatorCheckListFiltersPage().filterBy(`${acsUser.firstName} ${acsUser.lastName}`); + expect(searchResults.sortAndCheckListIsOrderedByName(true)).toBe(true); + }); + + it('[C277281] Should be able to sort the search results by "Name" DESC', () => { + searchFilters.checkSearchFiltersIsDisplayed(); + searchFilters.creatorCheckListFiltersPage().filterBy(`${acsUser.firstName} ${acsUser.lastName}`); + expect(searchResults.sortAndCheckListIsOrderedByName(false)).toBe(true); + }); + + it('[C277282] Should be able to sort the search results by "Author" ASC', () => { + expect(searchResults.sortAndCheckListIsOrderedByAuthor(this.alfrescoJsApi, true)).toBe(true); + }); + + it('[C277283] Should be able to sort the search results by "Author" DESC', () => { + expect(searchResults.sortAndCheckListIsOrderedByAuthor(this.alfrescoJsApi, false)).toBe(true); + }); + + it('[C277284] Should be able to sort the search results by "Modifier" ASC', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options.push({ 'key': 'Modifier', 'label': 'Modifier', 'type': 'FIELD', 'field': 'cm:modifier', 'ascending': true }); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .sortBy(true, 'Modifier'); + + browser.controlFlow().execute(async () => { + let idList = await contentServices.getElementsDisplayedId(); + let numberOfElements = await contentServices.numberOfResultsDisplayed(); + + let nodeList = await nodeActions.getNodesDisplayed(this.alfrescoJsApi, idList, numberOfElements); + let modifierList = []; + for (let i = 0; i < nodeList.length; i++) { + modifierList.push(nodeList[i].entry.modifiedByUser.id); + } + expect(contentServices.checkElementsSortedAsc(modifierList)).toBe(true); + }); + }); + + it('[C277285] Should be able to sort the search results by "Modifier" DESC', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options.push({ 'key': 'Modifier', 'label': 'Modifier', 'type': 'FIELD', 'field': 'cm:modifier', 'ascending': true }); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .sortBy(false, 'Modifier'); + + browser.controlFlow().execute(async () => { + let idList = await contentServices.getElementsDisplayedId(); + let numberOfElements = await contentServices.numberOfResultsDisplayed(); + + let nodeList = await nodeActions.getNodesDisplayed(this.alfrescoJsApi, idList, numberOfElements); + let modifierList = []; + for (let i = 0; i < nodeList.length; i++) { + modifierList.push(nodeList[i].entry.modifiedByUser.id); + } + expect(contentServices.checkElementsSortedDesc(modifierList)).toBe(true); + }); + }); + + it('[C277286] Should be able to sort the search results by "Created Date" ASC', () => { + expect(searchResults.sortAndCheckListIsOrderedByCreated(true)).toBe(true); + }); + + it('[C277287] Should be able to sort the search results by "Created Date" DESC', () => { + expect(searchResults.sortAndCheckListIsOrderedByCreated(false)).toBe(true); + }); + + it('[C277288] Should be able to sort the search results by "Modified Date" ASC', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options.push({ 'key': 'Modified Date', 'label': 'Modified Date', 'type': 'FIELD', 'field': 'cm:modified', 'ascending': true }); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .sortBy(true, 'Modified Date'); + + browser.controlFlow().execute(async () => { + let idList = await contentServices.getElementsDisplayedId(); + let numberOfElements = await contentServices.numberOfResultsDisplayed(); + + let nodeList = await nodeActions.getNodesDisplayed(this.alfrescoJsApi, idList, numberOfElements); + let modifiedDateList = []; + for (let i = 0; i < nodeList.length; i++) { + modifiedDateList.push(new Date(nodeList[i].entry.modifiedAt)); + } + expect(contentServices.checkElementsSortedAsc(modifiedDateList)).toBe(true); + }); + }); + + it('[C277289] Should be able to sort the search results by "Modified Date" DESC', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.options.push({ 'key': 'Modified Date', 'label': 'Modified Date', 'type': 'FIELD', 'field': 'cm:modified', 'ascending': true }); + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed() + .sortBy(false, 'Modified Date'); + + browser.controlFlow().execute(async () => { + let idList = await contentServices.getElementsDisplayedId(); + let numberOfElements = await contentServices.numberOfResultsDisplayed(); + + let nodeList = await nodeActions.getNodesDisplayed(this.alfrescoJsApi, idList, numberOfElements); + let modifiedDateList = []; + for (let i = 0; i < nodeList.length; i++) { + modifiedDateList.push(new Date(nodeList[i].entry.modifiedAt)); + } + expect(contentServices.checkElementsSortedAsc(modifiedDateList)).toBe(false); + }); + }); + + it('[C277290] Should be able to sort the search results by "Size" ASC', () => { + searchResults.sortBySize(true); + expect(searchResults.checkListIsOrderedBySizeAsc()).toBe(true); + }); + + it('[C277291] Should be able to sort the search results by "Size" DESC', () => { + searchResults.sortBySize(false); + expect(searchResults.checkListIsOrderedBySizeDesc()).toBe(true); + }); + + it('[C277301] Should be able to change default sorting option for the search results', () => { + let searchConfiguration = new SearchConfiguration(); + jsonFile = searchConfiguration.getConfiguration(); + navigationBar.clickConfigEditorButton(); + configEditor.clickSearchConfiguration(); + configEditor.clickClearButton(); + jsonFile.sorting.defaults[0] = { 'key': 'Size', 'label': 'Size', 'type': 'FIELD', 'field': 'content.size', 'ascending': true }; + configEditor.enterBigConfigurationText(JSON.stringify(jsonFile)); + configEditor.clickSaveButton(); + + searchDialog.checkSearchIconIsVisible() + .clickOnSearchIcon() + .enterTextAndPressEnter(search); + + searchSortingPicker.checkSortingSelectorIsDisplayed(); + expect(searchResults.checkListIsOrderedBySizeAsc()).toBe(true); + }); +}); diff --git a/e2e/search/search_component.e2e.ts b/e2e/search/search_component.e2e.ts index 31905f3c0f..a1fb29862a 100644 --- a/e2e/search/search_component.e2e.ts +++ b/e2e/search/search_component.e2e.ts @@ -15,14 +15,13 @@ * limitations under the License. */ -import { browser } from 'protractor'; +import { browser, protractor } from 'protractor'; import { LoginPage } from '../pages/adf/loginPage'; import { SearchDialog } from '../pages/adf/dialog/searchDialog'; import { ContentServicesPage } from '../pages/adf/contentServicesPage'; import { FilePreviewPage } from '../pages/adf/filePreviewPage'; import { SearchResultsPage } from '../pages/adf/searchResultsPage'; -import { SearchFiltersPage } from '../../pages/adf/searchFiltersPage'; import { AcsUserModel } from '../models/ACS/acsUserModel'; import { FileModel } from '../models/ACS/fileModel'; @@ -34,7 +33,7 @@ import { Util } from '../util/util'; import AlfrescoApi = require('alfresco-js-api-node'); import { UploadActions } from '../actions/ACS/upload.actions'; -xdescribe('Search component - Search Bar', () => { +describe('Search component - Search Bar', () => { let search = { inactive: { @@ -50,7 +49,6 @@ xdescribe('Search component - Search Bar', () => { let searchDialog = new SearchDialog(); let searchResultPage = new SearchResultsPage(); let filePreviewPage = new FilePreviewPage(); - const searchFilters = new SearchFiltersPage(); let acsUser = new AcsUserModel(); @@ -91,9 +89,9 @@ xdescribe('Search component - Search Bar', () => { let firstFileUploaded = await uploadActions.uploadFile(this.alfrescoJsApi, firstFileModel.location, firstFileModel.name, '-my-'); Object.assign(firstFileModel, firstFileUploaded.entry); - filesToDelete.push(await uploadActions.uploadFolder(this.alfrescoJsApi, firstFolderModel.name, '-my-')); - filesToDelete.push(await uploadActions.uploadFolder(this.alfrescoJsApi, secondFolder.name, '-my-')); - filesToDelete.push(await uploadActions.uploadFolder(this.alfrescoJsApi, thirdFolder.name, '-my-')); + filesToDelete.push(await uploadActions.createFolder(this.alfrescoJsApi, firstFolderModel.name, '-my-')); + filesToDelete.push(await uploadActions.createFolder(this.alfrescoJsApi, secondFolder.name, '-my-')); + filesToDelete.push(await uploadActions.createFolder(this.alfrescoJsApi, thirdFolder.name, '-my-')); await browser.driver.sleep(15000); // wait search index previous file/folder uploaded @@ -113,8 +111,9 @@ xdescribe('Search component - Search Bar', () => { done(); }); - beforeEach(() => { - contentServicesPage.goToDocumentList(); + afterEach(async (done) => { + await browser.get(TestConfig.adf.url); + done(); }); it('[C272798] Search bar should be visible', () => { @@ -127,8 +126,9 @@ xdescribe('Search component - Search Bar', () => { .checkSearchBarIsVisible() .checkSearchIconIsVisible(); + browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); + searchDialog - .clickOnSearchIcon() .checkSearchBarIsNotVisible() .checkSearchIconIsVisible(); }); @@ -138,13 +138,6 @@ xdescribe('Search component - Search Bar', () => { .checkSearchIconIsVisible() .clickOnSearchIcon() .enterText(firstFolderModel.shortName); - - searchDialog - .clickOnSearchIcon() - .checkSearchBarIsNotVisible() - .checkSearchIconIsVisible(); - - contentServicesPage.checkAcsContainer(); }); it('[C260255] Should display message when searching for an inexistent file', () => { @@ -154,9 +147,6 @@ xdescribe('Search component - Search Bar', () => { .checkNoResultMessageIsNotDisplayed() .enterText(search.inactive.name) .checkNoResultMessageIsDisplayed(); - - searchDialog.clearText(); - searchDialog.checkSearchBarIsNotVisible(); }); it('[C260256] Should display file/folder in search suggestion when typing first characters', () => { @@ -172,7 +162,6 @@ xdescribe('Search component - Search Bar', () => { expect(searchDialog.getSpecificRowsCompleteName(firstFolderModel.name)).toEqual(firstFolderModel.name); searchDialog.clearText(); - searchDialog.checkSearchBarIsNotVisible(); searchDialog.clickOnSearchIcon().enterText(firstFileModel.shortName); searchDialog.resultTableContainsRow(firstFileModel.name); @@ -181,9 +170,6 @@ xdescribe('Search component - Search Bar', () => { expect(searchDialog.getSpecificRowsAuthor(firstFileModel.name)).toEqual(acsUser.firstName + ' ' + acsUser.lastName); expect(searchDialog.getSpecificRowsCompleteName(firstFileModel.name)).toEqual(firstFileModel.name); - - searchDialog.clearText(); - searchDialog.checkSearchBarIsNotVisible(); }); it('[C272800] Should display file/folder in search suggestion when typing name', () => { @@ -199,7 +185,6 @@ xdescribe('Search component - Search Bar', () => { expect(searchDialog.getSpecificRowsCompleteName(firstFolderModel.name)).toEqual(firstFolderModel.name); searchDialog.clearText(); - searchDialog.checkSearchBarIsNotVisible(); searchDialog.clickOnSearchIcon().enterText(firstFileModel.name); searchDialog.resultTableContainsRow(firstFileModel.name); @@ -207,9 +192,6 @@ xdescribe('Search component - Search Bar', () => { expect(searchDialog.getSpecificRowsHighlightName(firstFileModel.name)).toEqual(firstFileModel.name); expect(searchDialog.getSpecificRowsAuthor(firstFileModel.name)).toEqual(acsUser.firstName + ' ' + acsUser.lastName); expect(searchDialog.getSpecificRowsCompleteName(firstFileModel.name)).toEqual(firstFileModel.name); - - searchDialog.clearText(); - searchDialog.checkSearchBarIsNotVisible(); }); it('[C260257] Should display content when clicking on folder from search suggestions', () => { @@ -221,14 +203,8 @@ xdescribe('Search component - Search Bar', () => { searchDialog.resultTableContainsRow(firstFolderModel.name); searchDialog.clickOnSpecificRow(firstFolderModel.name); - contentServicesPage - .checkAcsContainer() - .waitForTableBody(); - expect(contentServicesPage.currentFolderName()).toEqual(firstFolderModel.name); - contentServicesPage.goToDocumentList(); - searchDialog .checkSearchIconIsVisible() .clickOnSearchIcon() @@ -280,7 +256,7 @@ xdescribe('Search component - Search Bar', () => { .enterText(secondFolder.shortName) .pressDownArrowAndEnter(); - contentServicesPage.checkAcsContainer(); + searchResultPage.tableIsLoaded(); expect(contentServicesPage.currentFolderName()).toEqual(secondFolder.name); }); diff --git a/e2e/search/search_page_component.e2e.ts b/e2e/search/search_page_component.e2e.ts index a6fe2d2e69..6f586f62d8 100644 --- a/e2e/search/search_page_component.e2e.ts +++ b/e2e/search/search_page_component.e2e.ts @@ -86,8 +86,8 @@ describe('Search component - Search Page', () => { await this.alfrescoJsApi.login(acsUser.id, acsUser.password); - await uploadActions.uploadFolder(this.alfrescoJsApi, emptyFolderModel.name, '-my-'); - let newFolderModelUploaded = await uploadActions.uploadFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); + await uploadActions.createFolder(this.alfrescoJsApi, emptyFolderModel.name, '-my-'); + let newFolderModelUploaded = await uploadActions.createFolder(this.alfrescoJsApi, newFolderModel.name, '-my-'); await uploadActions.createEmptyFiles(this.alfrescoJsApi, fileNames, newFolderModelUploaded.entry.id); @@ -97,7 +97,7 @@ describe('Search component - Search Page', () => { await uploadActions.createEmptyFiles(this.alfrescoJsApi, adminFileNames, newFolderModelUploaded.entry.id); - browser.driver.sleep(12000); + browser.driver.sleep(15000); loginPage.loginToContentServicesUsingUserModel(acsUser); @@ -181,15 +181,18 @@ describe('Search component - Search Page', () => { describe('Sorting', () => { + beforeEach(() => { + searchDialog + .clickOnSearchIcon() + .enterTextAndPressEnter(search.active.base); + }); + afterEach(async (done) => { await browser.refresh(); done(); }); it('[C272803] Should be able to sort results by name (Ascending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); searchResultPage.sortAndCheckListIsOrderedByName(true).then((result) => { @@ -198,9 +201,6 @@ describe('Search component - Search Page', () => { }); it('[C272804] Should be able to sort results by name (Descending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); searchResultPage.sortAndCheckListIsOrderedByName(false).then((result) => { @@ -209,32 +209,23 @@ describe('Search component - Search Page', () => { }); it('[C272805] Should be able to sort results by author (Ascending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); - searchResultPage.sortAndCheckListIsOrderedByAuthor(true).then((result) => { + searchResultPage.sortAndCheckListIsOrderedByAuthor(this.alfrescoJsApi, true).then((result) => { expect(result).toEqual(true); }); }); it('[C272806] Should be able to sort results by author (Descending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); - searchResultPage.sortAndCheckListIsOrderedByAuthor(false).then((result) => { + searchResultPage.sortAndCheckListIsOrderedByAuthor(this.alfrescoJsApi, false).then((result) => { expect(result).toEqual(true); }); }); it('[C272807] Should be able to sort results by date (Ascending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); searchResultPage.sortAndCheckListIsOrderedByCreated(true).then((result) => { @@ -243,9 +234,6 @@ describe('Search component - Search Page', () => { }); it('[C260260] Should be able to sort results by date (Descending)', () => { - searchDialog - .clickOnSearchIcon() - .enterTextAndPressEnter(search.active.base); searchResultPage.checkContentIsDisplayed(search.active.secondFile); searchResultPage.sortAndCheckListIsOrderedByCreated(false).then((result) => {