-
Notifications
You must be signed in to change notification settings - Fork 149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ACS-6456] Migrated Share File e2es to Playwright #3565
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
65b7111
[AACS-6456] migrated share-file e2es to playwright
e000249
[ACS-6456] fixed code smells and removed duplication
22eb795
[ACS-6456] cleanup, addressed review comments
98ead2d
[ACS-6456] addressed review comments
8b6f822
[ACS-6456] added return types, fixed typos
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
246 changes: 246 additions & 0 deletions
246
e2e/playwright/actions/src/tests/share/share-file.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
/*! | ||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. | ||
* | ||
* Alfresco Example Content Application | ||
* | ||
* This file is part of the Alfresco Example Content Application. | ||
* If the software was purchased under a paid Alfresco license, the terms of | ||
* the paid license agreement will prevail. Otherwise, the software is | ||
* provided under the following open source license terms: | ||
* | ||
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* The Alfresco Example Content Application is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
import { ApiClientFactory, NodesApi, test, timeouts, Utils, SharedLinksApi } from '@alfresco/playwright-shared'; | ||
import { expect } from '@playwright/test'; | ||
|
||
test.describe('Share a file', () => { | ||
const random = Utils.random(); | ||
|
||
const username = `user-${random}`; | ||
const parent = `parent-${random}`; | ||
let parentId: string; | ||
|
||
const file3 = `file3-${random}.txt`; | ||
const file4 = `file4-${random}.txt`; | ||
const file5 = `file5-${random}.txt`; | ||
const file6 = `file6-${random}.txt`; | ||
const file7 = `file7-${random}.txt`; | ||
const file8 = `file8-${random}.txt`; | ||
const file9 = `file9-${random}.txt`; | ||
|
||
const shareLinkPreUrl = `/#/preview/s/`; | ||
|
||
const apiClientFactory = new ApiClientFactory(); | ||
|
||
test.beforeAll(async () => { | ||
await apiClientFactory.setUpAcaBackend('admin'); | ||
await apiClientFactory.createUser({ username }); | ||
const nodesApi = await NodesApi.initialize(username, username); | ||
|
||
parentId = (await nodesApi.createFolder(parent)).entry.id; | ||
}); | ||
|
||
test.afterAll(async () => { | ||
await apiClientFactory.nodes.deleteNodes([parentId]); | ||
}); | ||
|
||
test.describe('when logged out', () => { | ||
let file6SharedLink: string; | ||
let file6Id: string; | ||
|
||
test.beforeAll(async () => { | ||
const nodesApi = await NodesApi.initialize(username, username); | ||
const shareApi = await SharedLinksApi.initialize(username, username); | ||
|
||
file6Id = (await nodesApi.createFile(file6, parentId))?.entry.id; | ||
|
||
const sharedId = (await shareApi.shareFileById(file6Id)).entry.id; | ||
file6SharedLink = `${shareLinkPreUrl}${sharedId}`; | ||
await shareApi.waitForFilesToBeShared([file6Id]); | ||
}); | ||
|
||
test.afterAll(async () => { | ||
await apiClientFactory.nodes.deleteNodes([file6Id]); | ||
}); | ||
|
||
test('[C286326] A non-logged user can download the shared file from the viewer', async ({ personalFiles, page }) => { | ||
await page.goto(file6SharedLink); | ||
await personalFiles.viewer.waitForViewerToOpen(); | ||
|
||
const downloadPromise = personalFiles.page.waitForEvent('download'); | ||
await personalFiles.viewer.toolbar.sharedDownloadButton.click(); | ||
const download = await downloadPromise; | ||
expect(download.suggestedFilename()).toBe(file6); | ||
}); | ||
}); | ||
|
||
test.describe('when logged in', () => { | ||
const expiryDateObj = new Date(); | ||
expiryDateObj.setFullYear(expiryDateObj.getFullYear() + 1); | ||
const expiryDate: any = expiryDateObj.toISOString().replace('Z', '+0000'); | ||
|
||
test.describe('from Personal Files', () => { | ||
let file3Id: string; | ||
let file4Id: string; | ||
let file5Id: string; | ||
let file6Id: string; | ||
let file7Id: string; | ||
let file8Id: string; | ||
let file9Id: string; | ||
|
||
test.beforeAll(async () => { | ||
test.setTimeout(timeouts.extendedTest); | ||
const nodesApi = await NodesApi.initialize(username, username); | ||
const shareApi = await SharedLinksApi.initialize(username, username); | ||
|
||
file3Id = (await nodesApi.createFile(file3, parentId))?.entry.id; | ||
file4Id = (await nodesApi.createFile(file4, parentId))?.entry.id; | ||
file5Id = (await nodesApi.createFile(file5, parentId))?.entry.id; | ||
file6Id = (await nodesApi.createFile(file6, parentId))?.entry.id; | ||
file7Id = (await nodesApi.createFile(file7, parentId))?.entry.id; | ||
file8Id = (await nodesApi.createFile(file8, parentId))?.entry.id; | ||
file9Id = (await nodesApi.createFile(file9, parentId))?.entry.id; | ||
|
||
await shareApi.shareFilesByIds([file6Id, file7Id], expiryDate); | ||
await shareApi.waitForFilesToBeShared([file6Id, file7Id]); | ||
}); | ||
|
||
test.beforeEach(async ({ loginPage, personalFiles, page }) => { | ||
await loginPage.navigate(); | ||
await loginPage.loginUser({ username: username, password: username }); | ||
|
||
await personalFiles.waitForPageLoad(); | ||
await personalFiles.dataTable.getCellByColumnNameAndRowItem(parent, 'Size').dblclick(); | ||
await page.waitForTimeout(timeouts.tiny); | ||
}); | ||
|
||
test.afterAll(async () => { | ||
const nodesApi = await NodesApi.initialize(username, username); | ||
await nodesApi.deleteNodes([file3Id, file4Id, file5Id, file6Id, file7Id, file8Id, file9Id]); | ||
}); | ||
|
||
test('[C286327] Share dialog default values', async ({ personalFiles }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file3, 'Share')); | ||
const labels = await personalFiles.shareDialog.getLabels(); | ||
expect(await personalFiles.shareDialog.getDialogTitle()).toEqual(`Share ${file3}`); | ||
expect(labels[0].trim()).toBe(`Share ${file3}`); | ||
expect(await personalFiles.shareDialog.getInfoText()).toEqual('Share Link'); | ||
expect(await personalFiles.shareDialog.getLinkUrl()).toContain(shareLinkPreUrl); | ||
expect(await personalFiles.shareDialog.isUrlReadOnly()).toBe(true); | ||
expect(await personalFiles.shareDialog.isShareToggleChecked()).toBe(true); | ||
expect(labels[1].trim()).toBe('Link Expiry Date'); | ||
expect(await personalFiles.shareDialog.isExpireToggleEnabled()).toBe(false); | ||
expect(await personalFiles.shareDialog.isCloseEnabled()).toBe(true); | ||
}); | ||
|
||
test('[C286329] Share a file', async ({ personalFiles, nodesApiAction }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file3, 'Share')); | ||
|
||
const url = await personalFiles.shareDialog.getLinkUrl(); | ||
await personalFiles.shareDialog.clickClose(); | ||
|
||
const sharedId = await nodesApiAction.getSharedId(file3Id); | ||
expect(url).toContain(sharedId); | ||
}); | ||
|
||
test('[C286330] Copy shared file URL', async ({ personalFiles, page }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file4, 'Share')); | ||
|
||
const url = await personalFiles.shareDialog.getLinkUrl(); | ||
expect(url).toContain(shareLinkPreUrl); | ||
|
||
await personalFiles.shareDialog.urlAction.click(); | ||
|
||
const shareSnackBar = personalFiles.snackBar; | ||
await expect(shareSnackBar.getByMessageLocator('Link copied to the clipboard')).toBeVisible(); | ||
|
||
await page.goto(url); | ||
akashrathod28 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
await personalFiles.viewer.waitForViewerToOpen(); | ||
|
||
const downloadPromise = personalFiles.page.waitForEvent('download'); | ||
await personalFiles.viewer.toolbar.sharedDownloadButton.click(); | ||
|
||
const download = await downloadPromise; | ||
expect(download.suggestedFilename()).toBe(file4); | ||
}); | ||
|
||
test('[C286332] Share a file with expiration date', async ({ personalFiles, nodesApiAction, page }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file5, 'Share')); | ||
|
||
await personalFiles.shareDialog.expireToggle.click(); | ||
expect(await personalFiles.shareDialog.isExpireToggleEnabled()).toBe(true); | ||
|
||
await personalFiles.shareDialog.datetimePickerButton.click(); | ||
expect(await personalFiles.shareDialog.dateTimePicker.isCalendarOpen()).toBe(true); | ||
|
||
await personalFiles.shareDialog.dateTimePicker.pickDateTime(); | ||
|
||
const inputDate = await personalFiles.shareDialog.getExpireDate(); | ||
|
||
await page.waitForTimeout(timeouts.normal); | ||
akashrathod28 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const expireDateProperty = await nodesApiAction.getSharedExpiryDate(file5Id); | ||
|
||
expect(Utils.formatDate(expireDateProperty)).toEqual(Utils.formatDate(inputDate)); | ||
}); | ||
|
||
test('[C286337] Expire date is displayed correctly', async ({ personalFiles, nodesApiAction }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file6, 'Share')); | ||
const expireProperty = await nodesApiAction.getSharedExpiryDate(file6Id); | ||
|
||
expect(expireProperty).toEqual(expiryDate); | ||
expect(await personalFiles.shareDialog.isExpireToggleEnabled()).toBe(true); | ||
expect(Utils.formatDate(await personalFiles.shareDialog.getExpireDate())).toEqual(Utils.formatDate(expiryDate)); | ||
}); | ||
|
||
test('[C286333] Disable the share link expiration', async ({ personalFiles, nodesApiAction, page }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file7, 'Share')); | ||
|
||
expect(await personalFiles.shareDialog.isExpireToggleEnabled()).toBe(true); | ||
expect(await personalFiles.shareDialog.getExpireDate()).not.toBe(''); | ||
|
||
await personalFiles.shareDialog.expireToggle.click(); | ||
expect(await personalFiles.shareDialog.isExpireToggleEnabled()).toBe(false); | ||
|
||
await page.waitForTimeout(timeouts.tiny); | ||
await personalFiles.shareDialog.clickClose(); | ||
expect(await nodesApiAction.getSharedExpiryDate(file7Id)).toBe(''); | ||
}); | ||
|
||
test('[C286335] Shared file URL is not changed when Share dialog is closed and opened again', async ({ personalFiles }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file8, 'Share')); | ||
|
||
const url1 = await personalFiles.shareDialog.getLinkUrl(); | ||
await personalFiles.shareDialog.clickClose(); | ||
|
||
await personalFiles.dataTable.selectItem(file8); | ||
await personalFiles.acaHeader.shareButton.click(); | ||
const url2 = await personalFiles.shareDialog.getLinkUrl(); | ||
|
||
expect(url1).toEqual(url2); | ||
}); | ||
|
||
test('[C286345] Share a file from the context menu', async ({ personalFiles, nodesApiAction }) => { | ||
expect(await personalFiles.dataTable.performActionFromExpandableMenu(file9, 'Share')); | ||
|
||
const url = await personalFiles.shareDialog.getLinkUrl(); | ||
await personalFiles.shareDialog.clickClose(); | ||
|
||
const sharedId = await nodesApiAction.getSharedId(file9Id); | ||
expect(await nodesApiAction.isFileShared(file9Id)).toBe(true); | ||
expect(url).toContain(sharedId); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use
any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing 'any' here is giving a red line error on expiryDate here
await shareApi.shareFilesByIds([file6Id, file7Id], expiryDate);
because shareFileByIds() and other nested methods expect expireDate to be of type 'Date'. But strangely, the shareFilesByIds() method works only if the expireDate is of type 'string', otherwise the tests don't work as expected.
Due to this strange behavior, having 'any' helps but if I remove 'any', I will have to modify the data type of expireDate from 'Date' to 'string' at multiple places and in JS-API which will need upstream.
I have tried multiple ways to make expiryDate an object of type 'Date' so that no changes are required on the API level but that does not seem to work
What do you suggest here? Should we go ahead with 'any'? or can we use some other approach here? @MichalKinas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need to pass a
Date
there you can useexpiryDateObj
object,expiryDate
should be a string and usingany
here is incorrectThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tried using expiryDateObj but this does not help as 'shareFilesByIds()' is working properly only with expiryDate as string.
If we remove any, we get an error because 'shareFilesByIds()' expects a Date but is somehow working only with string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can try creating new date from
expiryDate
but if it won't work it means that your code is not correct somewhere,any
is anti-pattern and it should be used only in specific cases and this is not one of them.any
shouldn't be used to fix an error or not working codeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I understand what you are saying but the problem I am facing in doing so is that
the API actually expects 'expiryDate' to be of type string. (see sharedLinkBodyCreate https://api-explorer.alfresco.com/api-explorer/?urls.primaryName=Core%20API#/shared-links/createSharedLink)
But, in the code, the expected type of 'expiryDate' is set to Date in JS API and all related methods like 'shareNodes()' or 'shareFileByIds()'
So even if I create new date from 'expiryDate' , the API will still not run as expected.
So far, this approach (using 'any') was being used in Protractor e2es so if we remove 'any', we either get some red line errors but the tests run fine
OR
we might need to make changes in JS API which I am not sure is feasible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case you still don't have to use
any
, you can declareexpiryDate
aslet expiryDate: Date | string = ...
and then pass it to the correct function likeexpiryDate as Date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing expiryDate as Date does not help because
this.apiService.share.createSharedLink(data);
fails if expiry is of type 'Date' and gives status code 400.It gives 200 only with type string (as per swagger https://api-explorer.alfresco.com/api-explorer/?urls.primaryName=Core%20API#/shared-links/createSharedLink)
and I am blocked because I cannot set the type of expiryDate to string.
@DenysVuika, Michal suggested double-checking with you if we should make changes for this in JS-API for e2es.
Can you please suggest what would be the feasible solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MichalKinas, as per my discussion with @DenysVuika, we can use 'any' for now and have a separate ticket to fix typings in JS-API.
I have created this JIRA https://alfresco.atlassian.net/browse/ACS-6533 for the same.