diff --git a/e2e/content-services/share-file/share_file.e2e.ts b/e2e/content-services/share-file/share_file.e2e.ts new file mode 100644 index 0000000000..e185bc4853 --- /dev/null +++ b/e2e/content-services/share-file/share_file.e2e.ts @@ -0,0 +1,169 @@ +/*! + * @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 { ContentServicesPage } from '../../pages/adf/contentServicesPage'; +import ContentListPage = require('../../pages/adf/dialog/contentList'); +import NavigationBarPage = require('../../pages/adf/navigationBarPage'); +import { ViewerPage } from '../../pages/adf/viewerPage'; +import { ShareDialog } from '../../pages/adf/dialog/shareDialog'; + +import AcsUserModel = require('../../models/ACS/acsUserModel'); +import FileModel = require('../../models/ACS/fileModel'); + +import TestConfig = require('../../test.config'); +import resources = require('../../util/resources'); + +import AlfrescoApi = require('alfresco-js-api-node'); +import { UploadActions } from '../../actions/ACS/upload.actions'; +import { browser } from 'protractor'; + +describe('Share file', () => { + + const loginPage = new LoginPage(); + const contentServicesPage = new ContentServicesPage(); + const contentListPage = new ContentListPage(); + const shareDialog = new ShareDialog(); + const navigationBarPage = new NavigationBarPage(); + const viewerPage = new ViewerPage(); + + let acsUser = new AcsUserModel(); + let uploadActions = new UploadActions(); + + let pngFileModel = new FileModel({ + 'name': resources.Files.ADF_DOCUMENTS.PNG.file_name, + 'location': resources.Files.ADF_DOCUMENTS.PNG.file_location + }); + + let nodeId; + + 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); + + let pngUploadedFile = await uploadActions.uploadFile(this.alfrescoJsApi, pngFileModel.location, pngFileModel.name, '-my-'); + + nodeId = pngUploadedFile.entry.id; + + loginPage.loginToContentServicesUsingUserModel(acsUser); + + contentServicesPage.navigateToDocumentList(); + + done(); + }); + + afterAll(async (done) => { + await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); + await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, nodeId); + done(); + }); + + describe('Shared link dialog', () => { + afterEach(async (done) => { + await browser.refresh(); + done(); + }); + + it('[C286549] Share toggle button is checked automatically', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.shareToggleButtonIsChecked(); + }); + + it('[C286544] Copy shared link button action shows notification', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickShareLinkButton(); + shareDialog.checkNotificationWithMessage('Link copied to the clipboard'); + }); + + it('[C286328] User can close the Share dialog', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.checkShareLinkIsDisplayed(); + shareDialog.clickCloseButton(); + shareDialog.dialogIsClosed(); + }); + + it('[C286578] Expiration day calendar should have today day option disabled', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickDateTimePickerButton(); + shareDialog.calendarTodayDayIsDisabled(); + }); + + it('[C286548] User can set when the shared file link expires', async () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickDateTimePickerButton(); + shareDialog.setDefaultDay(); + shareDialog.setDefaultHour(); + shareDialog.setDefaultMinutes(); + shareDialog.dateTimePickerDialogIsClosed(); + const value = await shareDialog.getExpirationDate(); + shareDialog.clickCloseButton(); + shareDialog.dialogIsClosed(); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.expirationDateInputHasValue(value); + }); + }); + + describe('Shared link preview', () => { + afterEach(async (done) => { + await loginPage.loginToContentServicesUsingUserModel(acsUser); + await contentServicesPage.navigateToDocumentList(); + done(); + }); + + it('[C286565] Logged user can open shared link', async () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickShareLinkButton(); + shareDialog.checkNotificationWithMessage('Link copied to the clipboard'); + const sharedLink = await shareDialog.getShareLink(); + browser.get(sharedLink); + viewerPage.checkFileNameIsDisplayed(pngFileModel.name); + }); + + it('[C286539] A non-logged user should see the shared file in the viewer', async () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.checkShareLinkIsDisplayed(); + const sharedLink = await shareDialog.getShareLink(); + shareDialog.clickCloseButton(); + navigationBarPage.clickLogoutButton(); + browser.get(sharedLink); + viewerPage.checkFileNameIsDisplayed(pngFileModel.name); + }); + }); +}); diff --git a/e2e/content-services/share-file/unshare_file.e2e.ts b/e2e/content-services/share-file/unshare_file.e2e.ts new file mode 100644 index 0000000000..38999604e6 --- /dev/null +++ b/e2e/content-services/share-file/unshare_file.e2e.ts @@ -0,0 +1,181 @@ +/*! + * @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 CONSTANTS = require('../../util/constants'); +import Util = require('../../util/util'); +import NavigationBarPage = require('../../pages/adf/navigationBarPage'); +import { LoginPage } from '../../pages/adf/loginPage'; +import { ContentServicesPage } from '../../pages/adf/contentServicesPage'; +import ContentListPage = require('../../pages/adf/dialog/contentList'); +import ErrorPage = require('../../pages/adf/errorPage'); +import { ShareDialog } from '../../pages/adf/dialog/shareDialog'; +import AcsUserModel = require('../../models/ACS/acsUserModel'); +import FileModel = require('../../models/ACS/fileModel'); +import TestConfig = require('../../test.config'); +import resources = require('../../util/resources'); +import AlfrescoApi = require('alfresco-js-api-node'); +import { UploadActions } from '../../actions/ACS/upload.actions'; +import { browser } from 'protractor'; + +describe('Unshare file', () => { + + const loginPage = new LoginPage(); + const contentServicesPage = new ContentServicesPage(); + const contentListPage = new ContentListPage(); + let navBar = new NavigationBarPage(); + const errorPage = new ErrorPage(); + const shareDialog = new ShareDialog(); + const siteName = `PRIVATE-TEST-SITE-${Util.generateRandomString(5)}`; + + let acsUser = new AcsUserModel(); + let uploadActions = new UploadActions(); + let nodeBody; + let nodeId; + let testSite; + let pngFileModel = new FileModel({ + 'name': resources.Files.ADF_DOCUMENTS.PNG.file_name, + 'location': resources.Files.ADF_DOCUMENTS.PNG.file_location + }); + + beforeAll(async(done) => { + const site = { + title: siteName, + visibility: 'PRIVATE', + id: siteName + }; + + const memberBody = { + id: acsUser.id, + role: CONSTANTS.CS_USER_ROLES.CONSUMER + }; + + nodeBody = { + name: Util.generateRandomString(5), + nodeType: 'cm:content', + properties: { + 'cm:title': Util.generateRandomString(5) + } + }; + + 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); + testSite = await this.alfrescoJsApi.core.sitesApi.createSite(site); + + const docLibId = (await this.alfrescoJsApi.core.sitesApi.getSiteContainers(siteName)).list.entries[0].entry.id; + const testFile1Id = (await this.alfrescoJsApi.core.nodesApi.addNode(docLibId, nodeBody)).entry.id; + await this.alfrescoJsApi.core.sitesApi.addSiteMember(siteName, memberBody); + + await this.alfrescoJsApi.core.nodesApi.updateNode(testFile1Id, { + permissions: { + isInheritanceEnabled: false, + locallySet: [ + { + authorityId: acsUser.id, + name: CONSTANTS.CS_USER_ROLES.CONSUMER + } + ] + } + }); + await this.alfrescoJsApi.core.sharedlinksApi.addSharedLink({ nodeId: testFile1Id }); + await this.alfrescoJsApi.login(acsUser.id, acsUser.password); + + let pngUploadedFile = await uploadActions.uploadFile(this.alfrescoJsApi, pngFileModel.location, pngFileModel.name, '-my-'); + nodeId = pngUploadedFile.entry.id; + + loginPage.loginToContentServicesUsingUserModel(acsUser); + contentServicesPage.navigateToDocumentList(); + done(); + }); + + afterEach(async (done) => { + await browser.refresh(); + done(); + }); + + describe('with permission', () => { + afterAll(async done => { + await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, nodeId); + done(); + }); + + it('[C286550] Unshare action opens confirmation dialog', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickUnShareFile(); + shareDialog.confirmationDialogIsDisplayed(); + }); + + it('[C286551] Cancel unshare file action', () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickUnShareFile(); + shareDialog.confirmationDialogIsDisplayed(); + shareDialog.clickConfirmationDialogCancelButton(); + shareDialog.shareToggleButtonIsChecked(); + }); + + it('[C286552] Confirm unshare file action', async () => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.clickUnShareFile(); + shareDialog.confirmationDialogIsDisplayed(); + shareDialog.clickConfirmationDialogRemoveButton(); + shareDialog.shareToggleButtonIsChecked(); + }); + + it('[C280556] Unshared file should show 404 page', async() => { + contentListPage.clickRowToSelect(pngFileModel.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + let sharedLink = await shareDialog.getShareLink(); + shareDialog.clickUnShareFile(); + shareDialog.confirmationDialogIsDisplayed(); + shareDialog.clickConfirmationDialogRemoveButton(); + shareDialog.dialogIsClosed(); + browser.get(sharedLink); + errorPage.checkErrorCode(); + }); + }); + + describe('without permission', () => { + afterAll(async done => { + await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword); + await this.alfrescoJsApi.core.sitesApi.deleteSite(siteName, { permanent: true }); + done(); + }); + + it('[C286555] User without permission cannot remove shared file', () => { + navBar.goToSite(testSite); + contentListPage.navigateToFolder('documentLibrary'); + contentListPage.clickRowToSelect(nodeBody.name); + contentServicesPage.clickShareButton(); + shareDialog.checkDialogIsDisplayed(); + shareDialog.shareToggleButtonIsChecked(); + shareDialog.shareToggleButtonIsDisabled(); + shareDialog.clickUnShareFile(); + shareDialog.confirmationDialogIsNotDisplayed(); + }); + }); +}); diff --git a/e2e/content-services/unshare_file.e2e.ts b/e2e/content-services/unshare_file.e2e.ts deleted file mode 100644 index 330f683162..0000000000 --- a/e2e/content-services/unshare_file.e2e.ts +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * @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 { ContentServicesPage } from '../pages/adf/contentServicesPage'; -import ContentListPage = require('../pages/adf/dialog/contentList'); -import ErrorPage = require('../pages/adf/errorPage'); -import { ShareDialog } from '../pages/adf/dialog/shareDialog'; - -import AcsUserModel = require('../models/ACS/acsUserModel'); -import FileModel = require('../models/ACS/fileModel'); - -import TestConfig = require('../test.config'); -import resources = require('../util/resources'); - -import AlfrescoApi = require('alfresco-js-api-node'); -import { UploadActions } from '../actions/ACS/upload.actions'; -import { browser } from 'protractor'; - -describe('Unshare file', () => { - - const loginPage = new LoginPage(); - const contentServicesPage = new ContentServicesPage(); - const contentListPage = new ContentListPage(); - const errorPage = new ErrorPage(); - const shareDialog = new ShareDialog(); - - let acsUser = new AcsUserModel(); - let uploadActions = new UploadActions(); - - let pngFileModel = new FileModel({ - 'name': resources.Files.ADF_DOCUMENTS.PNG.file_name, - 'location': resources.Files.ADF_DOCUMENTS.PNG.file_location - }); - - let nodeId; - - 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); - - let pngUploadedFile = await uploadActions.uploadFile(this.alfrescoJsApi, pngFileModel.location, pngFileModel.name, '-my-'); - - nodeId = pngUploadedFile.entry.id; - - loginPage.loginToContentServicesUsingUserModel(acsUser); - - contentServicesPage.navigateToDocumentList(); - - done(); - }); - - afterAll(async(done) => { - await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, nodeId); - - done(); - }); - - xit('[C280556] Unshared file should show 404 page', async() => { - contentListPage.clickRowToSelect(pngFileModel.name); - - contentServicesPage.clickShareButton(); - - shareDialog.checkDialogIsDisplayed(); - shareDialog.checkShareLinkIsDisplayed(); - - let sharedLink = await shareDialog.getShareLink(); - - shareDialog.clickShareToggle(); - shareDialog.clickCloseButton(); - - browser.get(sharedLink); - browser.sleep(300); - - errorPage.checkErrorCode(); - }); -}); diff --git a/e2e/pages/adf/dialog/shareDialog.ts b/e2e/pages/adf/dialog/shareDialog.ts index e143219a8a..9f3f9c4da0 100644 --- a/e2e/pages/adf/dialog/shareDialog.ts +++ b/e2e/pages/adf/dialog/shareDialog.ts @@ -17,23 +17,47 @@ import { element, by } from 'protractor'; import Util = require('../../../util/util'); +import { FormControllersPage } from '../material/formControllersPage'; export class ShareDialog { + formControllersPage = new FormControllersPage(); + shareDialog = element(by.css('adf-share-dialog')); dialogTitle = element(by.css('[data-automation-id="adf-share-dialog-title"]')); - shareToggle = element(by.id('adf-share-toggle')); - shareLink = element(by.css('[data-automation-id="adf-share-link"')); - closeButton = element(by.css('button[class="mat-button mat-primary"]')); + shareToggle = element(by.css('[data-automation-id="adf-share-toggle"] label')); + shareToggleChecked = element(by.css('mat-dialog-container mat-slide-toggle.mat-checked')); + shareToggleUnchecked = element(by.css('mat-dialog-container mat-slide-toggle:not(.mat-checked)')); + shareToggleDisabled = element(by.css('mat-dialog-container mat-slide-toggle.mat-disabled')); + shareLink = element(by.css('[data-automation-id="adf-share-link"]')); + closeButton = element(by.css('button[data-automation-id="adf-share-dialog-close"]')); + snackBar = element(by.css('simple-snack-bar')); + copySharedLinkButton = element(by.css('.input-action')); + timeDatePickerButton = element(by.css('mat-datetimepicker-toggle button')); + dayPicker = element(by.css('mat-datetimepicker-month-view')); + clockPicker = element(by.css('mat-datetimepicker-clock')); + hoursPicker = element(by.css('.mat-datetimepicker-clock-hours')); + minutePicker = element(by.css('.mat-datetimepicker-clock-minutes')); + expirationDateInput = element(by.css('input[formcontrolname="time"]')); + confirmationDialog = element(by.css('adf-confirm-dialog')); + confirmationCancelButton = element(by.id('adf-confirm-cancel')); + confirmationRemoveButton = element(by.id('adf-confirm-accept')); checkDialogIsDisplayed() { return Util.waitUntilElementIsVisible(this.dialogTitle); } - clickShareToggle() { - Util.waitUntilElementIsVisible(this.shareToggle); - Util.waitUntilElementIsClickable(this.shareToggle); - return this.shareToggle.click(); + clickUnShareFile() { + this.formControllersPage.enableToggle(this.shareToggle); + } + clickConfirmationDialogCancelButton() { + Util.waitUntilElementIsVisible(this.confirmationCancelButton); + this.confirmationCancelButton.click(); + } + + clickConfirmationDialogRemoveButton() { + Util.waitUntilElementIsVisible(this.confirmationRemoveButton); + this.confirmationRemoveButton.click(); } checkShareLinkIsDisplayed() { @@ -49,4 +73,85 @@ export class ShareDialog { Util.waitUntilElementIsVisible(this.closeButton); return this.closeButton.click(); } + + clickShareLinkButton() { + Util.waitUntilElementIsVisible(this.copySharedLinkButton); + return this.copySharedLinkButton.click(); + } + + shareToggleButtonIsChecked() { + Util.waitUntilElementIsPresent(this.shareToggleChecked); + } + + shareToggleButtonIsDisabled() { + Util.waitUntilElementIsPresent(this.shareToggleDisabled); + } + + shareToggleButtonIsUnchecked() { + Util.waitUntilElementIsVisible(this.shareToggleUnchecked); + } + + checkNotificationWithMessage(message) { + Util.waitUntilElementIsVisible( + element(by.cssContainingText('simple-snack-bar', message)) + ); + } + + waitForNotificationToClose() { + Util.waitUntilElementIsStale(element(by.css('simple-snack-bar'))); + } + + dialogIsClosed() { + Util.waitUntilElementIsStale(this.shareDialog); + } + + clickDateTimePickerButton() { + Util.waitUntilElementIsVisible(this.timeDatePickerButton); + this.timeDatePickerButton.click(); + } + + async calendarTodayDayIsDisabled() { + const today = await this.dayPicker.element(by.css('.mat-datetimepicker-calendar-body-today')).getText(); + Util.waitUntilElementIsPresent(element(by.cssContainingText('.mat-datetimepicker-calendar-body-disabled', today))); + } + + async setDefaultDay() { + const selector = '.mat-datetimepicker-calendar-body-active .mat-datetimepicker-calendar-body-cell-content'; + Util.waitUntilElementIsVisible(this.dayPicker); + const today = await this.dayPicker.element(by.css('.mat-datetimepicker-calendar-body-today')).getText(); + const tomorrow = (parseInt(today, 10) + 1).toString(); + this.dayPicker.element(by.cssContainingText(selector, tomorrow )).click(); + } + + setDefaultHour() { + const selector = '.mat-datetimepicker-clock-cell:not(.mat-datetimepicker-clock-cell-disabled)'; + Util.waitUntilElementIsVisible(this.clockPicker); + this.hoursPicker.all(by.css(selector)).first().click(); + } + + setDefaultMinutes() { + const selector = '.mat-datetimepicker-clock-cell:not(.mat-datetimepicker-clock-cell-disabled)'; + Util.waitUntilElementIsVisible(this.minutePicker); + this.minutePicker.all(by.css(selector)).first().click(); + } + + dateTimePickerDialogIsClosed() { + Util.waitUntilElementIsStale(element(by.css('mat-datetimepicker-content'))); + } + + getExpirationDate() { + return this.expirationDateInput.getAttribute('value'); + } + + expirationDateInputHasValue(value) { + Util.waitUntilElementHasValue(this.expirationDateInput, value); + } + + confirmationDialogIsDisplayed() { + return Util.waitUntilElementIsVisible(this.confirmationDialog); + } + + confirmationDialogIsNotDisplayed() { + return Util.waitUntilElementIsNotVisible(this.confirmationDialog); + } }