From 43b020ca5179f57aaebd5a6d54cf76f4c7744538 Mon Sep 17 00:00:00 2001 From: Adina Parpalita Date: Mon, 4 Dec 2017 06:10:23 +0200 Subject: [PATCH] [ACA-990] add tests for Recent Files, Shared Files and location redirect (#105) * add tests for Recent Files and Shared Files list views add tests for location redirect * small fix --- e2e/components/data-table/data-table.ts | 11 ++ e2e/components/toolbar/toolbar-breadcrumb.ts | 20 ++- e2e/suites/list-views/favorites.test.ts | 35 ++++- e2e/suites/list-views/file-libraries.test.ts | 9 +- e2e/suites/list-views/personal-files.test.ts | 44 ++---- e2e/suites/list-views/recent-files.test.ts | 141 ++++++++++++++++++ e2e/suites/list-views/shared-files.test.ts | 147 +++++++++++++++++++ e2e/suites/list-views/trash.test.ts | 47 ++++-- 8 files changed, 403 insertions(+), 51 deletions(-) create mode 100644 e2e/suites/list-views/recent-files.test.ts create mode 100644 e2e/suites/list-views/shared-files.test.ts diff --git a/e2e/components/data-table/data-table.ts b/e2e/components/data-table/data-table.ts index d44b62965..85919770f 100644 --- a/e2e/components/data-table/data-table.ts +++ b/e2e/components/data-table/data-table.ts @@ -34,6 +34,7 @@ export class DataTable extends Component { row: 'tr', selectedRow: 'tr.is-selected', cell: 'td', + locationLink: 'app-location-link', emptyListContainer: 'td.adf-no-content-container', emptyFolderDragAndDrop: '.adf-empty-list_template .adf-empty-folder', @@ -45,6 +46,7 @@ export class DataTable extends Component { head: ElementFinder = this.component.element(by.css(DataTable.selectors.head)); body: ElementFinder = this.component.element(by.css(DataTable.selectors.body)); cell = by.css(DataTable.selectors.cell); + locationLink = by.css(DataTable.selectors.locationLink); emptyList: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListContainer)); emptyFolderDragAndDrop: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyFolderDragAndDrop)); emptyListTitle: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListTitle)); @@ -142,6 +144,15 @@ export class DataTable extends Component { }); } + getItemLocation(name: string) { + const rowLocator = by.cssContainingText(DataTable.selectors.row, name); + return this.body.element(rowLocator).element(this.locationLink); + } + + clickItemLocation(name: string) { + return this.getItemLocation(name).click(); + } + // empty state methods isEmptyList(): promise.Promise { return this.emptyList.isPresent(); diff --git a/e2e/components/toolbar/toolbar-breadcrumb.ts b/e2e/components/toolbar/toolbar-breadcrumb.ts index 8eac821f2..5a832891a 100644 --- a/e2e/components/toolbar/toolbar-breadcrumb.ts +++ b/e2e/components/toolbar/toolbar-breadcrumb.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { ElementFinder, ElementArrayFinder, by } from 'protractor'; +import { ElementFinder, ElementArrayFinder, by, promise } from 'protractor'; import { Menu } from '../menu/menu'; import { Component } from '../component'; @@ -34,4 +34,22 @@ export class ToolbarBreadcrumb extends Component { getNthItem(nth: number): ElementFinder { return this.items.get(nth - 1); } + + getItemsCount(): promise.Promise { + return this.items.count(); + } + + getFirstItemName(): promise.Promise { + return this.items.get(0).getAttribute('title'); + } + + getCurrentItem(): promise.Promise { + return this.getItemsCount() + .then(count => this.getNthItem(count)); + } + + getCurrentItemName(): promise.Promise { + return this.getCurrentItem() + .then(node => node.getAttribute('title')); + } } diff --git a/e2e/suites/list-views/favorites.test.ts b/e2e/suites/list-views/favorites.test.ts index 869f16340..6b0e76bfd 100644 --- a/e2e/suites/list-views/favorites.test.ts +++ b/e2e/suites/list-views/favorites.test.ts @@ -40,6 +40,7 @@ describe('Favorites', () => { const logoutPage = new LogoutPage(); const favoritesPage = new BrowsingPage(); const { dataTable } = favoritesPage; + const { breadcrumb } = favoritesPage.toolbar; beforeAll(done => { apis.admin.people.createUser(username) @@ -64,7 +65,7 @@ describe('Favorites', () => { afterAll(done => { Promise.all([ - apis.admin.sites.deleteSite(siteName, true), + apis.admin.sites.deleteSite(siteName), apis.user.nodes.deleteNodes([ folderName ]), logoutPage.load() ]) @@ -113,4 +114,36 @@ describe('Favorites', () => { }); }); + it('Location column redirect - item in user Home', () => { + dataTable.clickItemLocation(folderName) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); + + it('Location column redirect - file in folder', () => { + dataTable.clickItemLocation(fileName2) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(folderName); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); + + it('Location column redirect - file in site', () => { + dataTable.clickItemLocation(fileName1) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(siteName); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('File Libraries'); + }); + }); + }); diff --git a/e2e/suites/list-views/file-libraries.test.ts b/e2e/suites/list-views/file-libraries.test.ts index b5cdac85d..b324cbd37 100644 --- a/e2e/suites/list-views/file-libraries.test.ts +++ b/e2e/suites/list-views/file-libraries.test.ts @@ -54,6 +54,7 @@ describe('File Libraries', () => { .then(() => apis.admin.sites.addSiteMember(sitePublic, username, SITE_ROLES.SITE_CONSUMER)) .then(() => apis.admin.sites.addSiteMember(siteModerated, username, SITE_ROLES.SITE_MANAGER)) .then(() => apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_CONTRIBUTOR)) + .then(() => loginPage.load()) .then(() => loginPage.loginWith(username)) .then(done); @@ -67,10 +68,10 @@ describe('File Libraries', () => { afterAll(done => { Promise.all([ - apis.admin.sites.deleteSite(sitePublic, true), - apis.admin.sites.deleteSite(siteModerated, true), - apis.admin.sites.deleteSite(sitePrivate, true), - apis.admin.sites.deleteSite(adminSite, true), + apis.admin.sites.deleteSite(sitePublic), + apis.admin.sites.deleteSite(siteModerated), + apis.admin.sites.deleteSite(sitePrivate), + apis.admin.sites.deleteSite(adminSite), logoutPage.load() ]) .then(done); diff --git a/e2e/suites/list-views/personal-files.test.ts b/e2e/suites/list-views/personal-files.test.ts index 5048c7d8a..052afe77f 100644 --- a/e2e/suites/list-views/personal-files.test.ts +++ b/e2e/suites/list-views/personal-files.test.ts @@ -17,24 +17,23 @@ import { browser } from 'protractor'; -import { APP_ROUTES } from '../../configs'; +import { SIDEBAR_LABELS } from '../../configs'; import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; import { Utils } from '../../utilities/utils'; -import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; +import { RepoClient } from '../../utilities/repo-client/repo-client'; describe('Personal Files', () => { const username = `user-${Utils.random()}`; - const password = username; const apis = { admin: new RepoClient(), - user: new RepoClient(username, password) + user: new RepoClient(username, username) }; const loginPage = new LoginPage(); const logoutPage = new LogoutPage(); - const personalFilesPage = new BrowsingPage(APP_ROUTES.PERSONAL_FILES); - const dataTable = personalFilesPage.dataTable; + const personalFilesPage = new BrowsingPage(); + const { dataTable } = personalFilesPage; const adminFolder = `admin-folder-${Utils.random()}`; @@ -44,7 +43,7 @@ describe('Personal Files', () => { beforeAll(done => { Promise .all([ - apis.admin.people.createUser(username, password), + apis.admin.people.createUser(username), apis.admin.nodes.createFolders([ adminFolder ]) ]) .then(() => apis.user.nodes.createFolders([ userFolder ])) @@ -71,14 +70,13 @@ describe('Personal Files', () => { }); beforeEach(done => { - personalFilesPage.load() + personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) .then(() => dataTable.waitForHeader()) .then(done); }); afterAll(done => { - logoutPage.load() - .then(done); + logoutPage.load().then(done); }); it('has "Data Dictionary" folder', () => { @@ -93,19 +91,18 @@ describe('Personal Files', () => { describe(`Regular user's personal files`, () => { beforeAll(done => { loginPage.load() - .then(() => loginPage.loginWith(username, password)) + .then(() => loginPage.loginWith(username)) .then(done); }); beforeEach(done => { - personalFilesPage.load() + personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES) .then(() => dataTable.waitForHeader()) .then(done); }); afterAll(done => { - logoutPage.load() - .then(done); + logoutPage.load().then(done); }); it('has the correct columns', () => { @@ -150,24 +147,5 @@ describe('Personal Files', () => { .toBe(true, 'user file is missing'); }); }); - - // Some tests regarding selection, breadcrumb and toolbar - // probably they can be move to a different suite - describe('Item selection', () => { - it('has toolbar when selected', done => { - const { actions } = personalFilesPage.toolbar; - - dataTable - .clickOnItemName(userFolder) - .then(() => { - expect(actions.isEmpty()).toBe(false, 'Toolbar to be present'); - }) - .then(() => actions.openMoreMenu()) - .then(menu => { - expect(menu.items.count()).toBeGreaterThan(0, 'More actions has items'); - }) - .then(done); - }); - }); }); }); diff --git a/e2e/suites/list-views/recent-files.test.ts b/e2e/suites/list-views/recent-files.test.ts new file mode 100644 index 000000000..27b43f7ff --- /dev/null +++ b/e2e/suites/list-views/recent-files.test.ts @@ -0,0 +1,141 @@ +/*! + * @license + * Copyright 2017 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 } from 'protractor'; + +import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; +import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; +import { Utils } from '../../utilities/utils'; +import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; + +describe('Recent Files', () => { + const username = `user-${Utils.random()}`; + const password = username; + + const folderName = `folder-${Utils.random()}`; + let folderId; + const fileName1 = `file-${Utils.random()}.txt`; + + const fileName2 = `file-${Utils.random()}.txt`; + let file2Id; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, password) + }; + + const loginPage = new LoginPage(); + const logoutPage = new LogoutPage(); + const recentFilesPage = new BrowsingPage(); + const { dataTable } = recentFilesPage; + const { breadcrumb } = recentFilesPage.toolbar; + + beforeAll(done => { + apis.admin.people.createUser(username) + .then(() => apis.user.nodes.createFolders([ folderName ])) + .then(resp => folderId = resp.data.entry.id) + .then(() => apis.user.nodes.createFiles([ fileName1 ], folderName)) + + .then(() => apis.user.nodes.createFiles([ fileName2 ])) + .then(resp => file2Id = resp.data.entry.id) + + .then(() => loginPage.load()) + .then(() => loginPage.loginWith(username)) + .then(done); + }); + + beforeEach(done => { + recentFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES) + .then(() => dataTable.isEmptyList()) + .then(empty => { + if (empty) { + browser.sleep(3000); + recentFilesPage.refresh(); + } + }) + .then(() => dataTable.waitForHeader()) + .then(done); + }); + + afterAll(done => { + Promise.all([ + apis.user.nodes.deleteNodesById([ folderId, file2Id ]), + logoutPage.load() + ]) + .then(done); + }); + + it('has the correct columns', () => { + const labels = [ 'Name', 'Location', 'Size', 'Modified' ]; + const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); + + expect(dataTable.getColumnHeaders().count()).toBe(4 + 1, 'Incorrect number of columns'); + + elements.forEach((element, index) => { + expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); + }); + }); + + it('displays the files added by the current user in the last 30 days', () => { + expect(dataTable.countRows()).toEqual(2, 'Incorrect number of sites displayed'); + expect(dataTable.getRowByName(fileName1).isPresent()).toBe(true, `${fileName1} not displayed`); + expect(dataTable.getRowByName(fileName2).isPresent()).toBe(true, `${fileName2} not displayed`); + }); + + it('Location column displays the parent folder of the file', () => { + const itemsLocations = { + [fileName2]: 'Personal Files', + [fileName1]: folderName + }; + + dataTable.getRows() + .map((row) => { + return row.all(dataTable.cell).map(cell => cell.getText()); + }) + .then((rowCells) => { + return rowCells.reduce((acc, cell) => { + acc[cell[1]] = cell[2]; + return acc; + }, {}); + }) + .then((recentList) => { + Object.keys(itemsLocations).forEach((item) => { + expect(recentList[item]).toEqual(itemsLocations[item]); + }); + }); + }); + + it('Location column redirect - file in user Home', () => { + dataTable.clickItemLocation(fileName1) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(folderName); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); + + it('Location column redirect - file in folder', () => { + dataTable.clickItemLocation(fileName2) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); +}); diff --git a/e2e/suites/list-views/shared-files.test.ts b/e2e/suites/list-views/shared-files.test.ts new file mode 100644 index 000000000..1eea1c2f6 --- /dev/null +++ b/e2e/suites/list-views/shared-files.test.ts @@ -0,0 +1,147 @@ +/*! + * @license + * Copyright 2017 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 } from 'protractor'; + +import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs'; +import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages'; +import { Utils } from '../../utilities/utils'; +import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client'; + +describe('Shared Files', () => { + const username = `user-${Utils.random()}`; + const password = username; + + const siteName = `site-${Utils.random()}`; + const fileAdmin = `file-${Utils.random()}.txt`; + + const folderUser = `folder-${Utils.random()}`; + const fileUser = `file-${Utils.random()}.txt`; + + const apis = { + admin: new RepoClient(), + user: new RepoClient(username, password) + }; + + const loginPage = new LoginPage(); + const logoutPage = new LogoutPage(); + const sharedFilesPage = new BrowsingPage(); + const { dataTable } = sharedFilesPage; + const { breadcrumb } = sharedFilesPage.toolbar; + + beforeAll(done => { + apis.admin.people.createUser(username) + .then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)) + .then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER)) + .then(() => apis.admin.nodes.createFiles([ fileAdmin ], `Sites/${siteName}/documentLibrary`)) + .then(resp => apis.admin.shared.shareFileById(resp.data.entry.id)) + + .then(() => apis.user.nodes.createFolders([ folderUser ])) + .then(() => apis.user.nodes.createFiles([ fileUser ], folderUser)) + .then(resp => apis.user.shared.shareFileById(resp.data.entry.id)) + + .then(() => loginPage.load()) + .then(() => loginPage.loginWith(username)) + .then(done); + }); + + beforeEach(done => { + sharedFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES) + .then(() => dataTable.isEmptyList()) + .then(empty => { + if (empty) { + browser.sleep(5000); + sharedFilesPage.refresh(); + } + }) + .then(() => dataTable.waitForHeader()) + .then(done); + }); + + afterAll(done => { + Promise.all([ + apis.admin.sites.deleteSite(siteName), + apis.user.nodes.deleteNodes([ folderUser ]), + logoutPage.load() + ]) + .then(done); + }); + + it('has the correct columns', () => { + const labels = [ 'Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by' ]; + const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label)); + + expect(dataTable.getColumnHeaders().count()).toBe(6 + 1, 'Incorrect number of columns'); + + elements.forEach((element, index) => { + expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`); + }); + }); + + it('displays the files shared by everyone', () => { + expect(dataTable.countRows()).toEqual(2, 'Incorrect number of items displayed'); + expect(dataTable.getRowByName(fileAdmin).isPresent()).toBe(true, `${fileAdmin} not displayed`); + expect(dataTable.getRowByName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`); + }); + + it('Location column displays the parent folder of the file', () => { + const itemsLocations = { + [fileAdmin]: siteName, + [fileUser]: folderUser + }; + + dataTable.getRows() + .map((row) => { + return row.all(dataTable.cell).map(cell => cell.getText()); + }) + .then((rowCells) => { + return rowCells.reduce((acc, cell) => { + acc[cell[1]] = cell[2]; + return acc; + }, {}); + }) + .then((recentList) => { + Object.keys(itemsLocations).forEach((item) => { + expect(recentList[item]).toEqual(itemsLocations[item]); + }); + }); + }); + + it('Location column redirect - file in user Home', () => { + dataTable.clickItemLocation(fileUser) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(folderUser); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); + + it('Location column redirect - file in site', () => { + dataTable.clickItemLocation(fileAdmin) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(siteName); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('File Libraries'); + }); + }); +}); diff --git a/e2e/suites/list-views/trash.test.ts b/e2e/suites/list-views/trash.test.ts index 167a194a5..8fb1e2d5e 100644 --- a/e2e/suites/list-views/trash.test.ts +++ b/e2e/suites/list-views/trash.test.ts @@ -48,6 +48,7 @@ describe('Trash', () => { const logoutPage = new LogoutPage(); const trashPage = new BrowsingPage(); const { dataTable } = trashPage; + const { breadcrumb } = trashPage.toolbar; beforeAll(done => { apis.admin.people.createUser(username) @@ -64,11 +65,8 @@ describe('Trash', () => { .then(() => apis.user.nodes.createFolders([ folderUser ]) .then(resp => folderUserId = resp.data.entry.id)) - .then(() => apis.admin.nodes.deleteNodeById(fileAdminId, false)) - .then(() => apis.admin.nodes.deleteNodeById(folderAdminId, false)) - .then(() => apis.user.nodes.deleteNodeById(fileSiteId, false)) - .then(() => apis.user.nodes.deleteNodeById(fileUserId, false)) - .then(() => apis.user.nodes.deleteNodeById(folderUserId, false)) + .then(() => apis.admin.nodes.deleteNodesById([ fileAdminId, folderAdminId ], false)) + .then(() => apis.user.nodes.deleteNodesById([ fileSiteId, fileUserId, folderUserId ], false)) .then(done); }); @@ -76,11 +74,7 @@ describe('Trash', () => { afterAll(done => { Promise.all([ apis.admin.sites.deleteSite(siteName), - apis.admin.trashcan.permanentlyDelete(fileAdminId), - apis.admin.trashcan.permanentlyDelete(folderAdminId), - apis.admin.trashcan.permanentlyDelete(fileSiteId), - apis.user.trashcan.permanentlyDelete(fileUserId), - apis.user.trashcan.permanentlyDelete(folderUserId) + apis.admin.trashcan.emptyTrash() ]) .then(done); }); @@ -91,7 +85,11 @@ describe('Trash', () => { beforeAll(done => { loginPage.load() .then(() => loginPage.loginWithAdmin()) - .then(() => trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)) + .then(done); + }); + + beforeEach(done => { + trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) .then(() => dataTable.waitForHeader()) .then(done); }); @@ -126,7 +124,11 @@ describe('Trash', () => { beforeAll(done => { loginPage.load() .then(() => loginPage.loginWith(username)) - .then(() => trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)) + .then(done); + }); + + beforeEach(done => { + trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH) .then(() => dataTable.waitForHeader()) .then(done); }); @@ -152,6 +154,27 @@ describe('Trash', () => { expect(dataTable.getRowByName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`); expect(dataTable.getRowByName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`); expect(dataTable.getRowByName(folderUser).isPresent()).toBe(true, `${folderUser} not displayed`); + expect(dataTable.getRowByName(fileAdmin).isPresent()).toBe(false, `${fileAdmin} is displayed`); + }); + + it('Location column redirect - file in user Home', () => { + dataTable.clickItemLocation(fileUser) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe('Personal Files'); + }); + }); + + it('Location column redirect - file in site', () => { + dataTable.clickItemLocation(fileSite) + .then(() => breadcrumb.getCurrentItemName()) + .then(name => { + expect(name).toBe(siteName); + }) + .then(() => breadcrumb.getFirstItemName()) + .then(name => { + expect(name).toBe('File Libraries'); + }); }); }); });