Skip to content

Commit a0e05f1

Browse files
committed
test(cypress): harden assertions
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent d63e24a commit a0e05f1

8 files changed

Lines changed: 141 additions & 298 deletions

File tree

cypress/e2e/files/FilesUtils.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ export function getActionEntryForFileId(fileid: number, actionId: string) {
3434
*/
3535
export function getActionEntryForFile(file: string, actionId: string) {
3636
getActionButtonForFile(file)
37-
.should('have.attr', 'aria-controls')
37+
.if('not.have.attr', 'aria-expanded', 'true')
38+
.click({ force: true })
39+
3840
return cy.findByRole('menu')
3941
.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
4042
}
@@ -83,10 +85,8 @@ export function triggerActionForFileId(fileid: number, actionId: string) {
8385
*/
8486
export function triggerActionForFile(filename: string, actionId: string) {
8587
getActionButtonForFile(filename)
86-
.as('actionButton')
87-
.scrollIntoView()
88-
cy.get('@actionButton')
89-
.click({ force: true }) // force to avoid issues with overlaying file list header
88+
.should('have.attr', 'aria-expanded', 'false')
89+
.click({ force: true, scrollBehavior: 'nearest' }) // force to avoid issues with overlaying file list header
9090
getActionEntryForFile(filename, actionId)
9191
.find('button')
9292
.should('be.visible')
@@ -287,7 +287,10 @@ export function navigateToFolder(dirPath: string) {
287287
export function closeSidebar() {
288288
// {force: true} as it might be hidden behind toasts
289289
cy.get('[data-cy-sidebar] .app-sidebar__close').click({ force: true })
290-
cy.get('[data-cy-sidebar]').should('not.be.visible')
290+
cy.get('[data-cy-sidebar]')
291+
.should('not.be.visible')
292+
// eslint-disable-next-line cypress/no-unnecessary-waiting -- wait for the animation to finish
293+
cy.wait(300)
291294
}
292295

293296
/**

cypress/e2e/files_sharing/FilesSharingUtils.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { triggerActionForFile } from '../files/FilesUtils.ts'
6+
import { closeSidebar, triggerActionForFile } from '../files/FilesUtils.ts'
77

88
export interface ShareSetting {
99
read: boolean
@@ -18,6 +18,7 @@ export interface ShareSetting {
1818

1919
export function createShare(fileName: string, username: string, shareSettings: Partial<ShareSetting> = {}) {
2020
openSharingPanel(fileName)
21+
cy.intercept('POST', '**/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createShare')
2122

2223
cy.get('#app-sidebar-vue').within(() => {
2324
cy.intercept({ times: 1, method: 'GET', url: '**/apps/files_sharing/api/v1/sharees?*' }).as('userSearch')
@@ -30,6 +31,12 @@ export function createShare(fileName: string, username: string, shareSettings: P
3031

3132
// HACK: Save the share and then update it, as permissions changes are currently not saved for new share.
3233
cy.get('[data-cy-files-sharing-share-editor-action="save"]').click({ scrollBehavior: 'nearest' })
34+
cy.wait('@createShare')
35+
cy.get('.toast-success')
36+
.findAllByRole('button')
37+
.click({ force: true, multiple: true })
38+
39+
closeSidebar()
3340
updateShare(fileName, 0, shareSettings)
3441
}
3542

@@ -55,10 +62,16 @@ export function updateShare(fileName: string, index: number, shareSettings: Part
5562
cy.get('[data-cy-files-sharing-share-permissions-checkbox="download"]').find('input').as('downloadCheckbox')
5663
if (shareSettings.download) {
5764
// Force:true because the checkbox is hidden by the pretty UI.
58-
cy.get('@downloadCheckbox').check({ force: true, scrollBehavior: 'nearest' })
65+
cy.get('@downloadCheckbox')
66+
.check({ force: true, scrollBehavior: 'nearest' })
67+
cy.get('@downloadCheckbox')
68+
.should('be.checked')
5969
} else {
6070
// Force:true because the checkbox is hidden by the pretty UI.
61-
cy.get('@downloadCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
71+
cy.get('@downloadCheckbox')
72+
.uncheck({ force: true, scrollBehavior: 'nearest' })
73+
cy.get('@downloadCheckbox')
74+
.should('not.be.checked')
6275
}
6376
}
6477

@@ -123,7 +136,9 @@ export function updateShare(fileName: string, index: number, shareSettings: Part
123136
cy.wait('@updateShare')
124137
})
125138
// close all toasts
126-
cy.get('.toast-success').findAllByRole('button').click({ force: true, multiple: true })
139+
cy.get('.toast-success')
140+
.findAllByRole('button')
141+
.click({ force: true, multiple: true })
127142
}
128143

129144
export function openSharingPanel(fileName: string) {

cypress/e2e/files_sharing/limit_to_same_group.cy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ describe('Limit to sharing to people in the same group', () => {
2929
cy.createRandomUser()
3030
.then((user) => {
3131
alice = user
32-
cy.createRandomUser()
3332
})
33+
cy.createRandomUser()
3434
.then((user) => {
3535
bob = user
3636

@@ -49,9 +49,12 @@ describe('Limit to sharing to people in the same group', () => {
4949
cy.login(alice)
5050
cy.visit('/apps/files')
5151
createShare(randomFileName1, bob.userId)
52+
cy.logout()
53+
5254
cy.login(bob)
5355
cy.visit('/apps/files')
5456
createShare(randomFileName2, alice.userId)
57+
cy.logout()
5558
})
5659
})
5760

cypress/e2e/files_versions/filesVersionsUtils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ export function setupTestSharedFileFromUser(owner: User, randomFileName: string,
8686
cy.login(owner)
8787
cy.visit('/apps/files')
8888
createShare(randomFileName, recipient.userId, shareOptions)
89-
cy.logout()
9089

9190
cy.login(recipient)
9291
cy.visit('/apps/files')

cypress/e2e/files_versions/version_deletion.cy.ts

Lines changed: 27 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,95 +6,56 @@
66
import type { User } from '@nextcloud/e2e-test-server/cypress'
77

88
import { randomString } from '../../support/utils/randomString.ts'
9-
import { getRowForFile, navigateToFolder } from '../files/FilesUtils.ts'
9+
import { navigateToFolder } from '../files/FilesUtils.ts'
1010
import { deleteVersion, doesNotHaveAction, openVersionsPanel, setupTestSharedFileFromUser, uploadThreeVersions } from './filesVersionsUtils.ts'
1111

12-
describe('Versions restoration', () => {
12+
describe('Versions deletion', () => {
1313
const folderName = 'shared_folder'
1414
const randomFileName = randomString(10) + '.txt'
1515
const randomFilePath = `/${folderName}/${randomFileName}`
1616
let user: User
1717
let versionCount = 0
1818

19-
before(() => {
19+
beforeEach(() => {
2020
cy.createRandomUser()
2121
.then((_user) => {
2222
user = _user
2323
cy.mkdir(user, `/${folderName}`)
2424
uploadThreeVersions(user, randomFilePath)
25-
uploadThreeVersions(user, randomFilePath)
26-
versionCount = 6
25+
versionCount = 3
2726
cy.login(user)
2827
cy.visit('/apps/files')
29-
navigateToFolder(folderName)
30-
openVersionsPanel(randomFilePath)
3128
})
3229
})
3330

3431
it('Delete initial version', () => {
35-
cy.get('[data-files-versions-version]').should('have.length', versionCount)
36-
deleteVersion(2)
37-
versionCount--
38-
cy.get('[data-files-versions-version]').should('have.length', versionCount)
32+
navigateToFolder(folderName)
33+
openVersionsPanel(randomFilePath)
34+
35+
cy.get('[data-files-versions-version]')
36+
.should('have.length', versionCount)
37+
deleteVersion(--versionCount)
38+
cy.get('[data-files-versions-version]')
39+
.should('have.length', versionCount)
3940
})
4041

41-
context('Delete versions of shared file', () => {
42-
it('Works with delete permission', () => {
43-
setupTestSharedFileFromUser(user, folderName, { delete: true })
44-
navigateToFolder(folderName)
45-
openVersionsPanel(randomFilePath)
46-
47-
cy.get('[data-files-versions-version]').should('have.length', versionCount)
48-
deleteVersion(2)
49-
versionCount--
50-
cy.get('[data-files-versions-version]').should('have.length', versionCount)
51-
})
52-
53-
it('Does not work without delete permission', () => {
54-
setupTestSharedFileFromUser(user, folderName, { delete: false })
55-
navigateToFolder(folderName)
56-
openVersionsPanel(randomFilePath)
57-
58-
doesNotHaveAction(0, 'delete')
59-
doesNotHaveAction(1, 'delete')
60-
doesNotHaveAction(2, 'delete')
61-
})
42+
it('Delete versions of shared file with delete permission', () => {
43+
setupTestSharedFileFromUser(user, folderName, { delete: true })
44+
navigateToFolder(folderName)
45+
openVersionsPanel(randomFilePath)
6246

63-
it('Does not work without delete permission through direct API access', () => {
64-
let fileId: string | undefined
65-
let versionId: string | undefined
66-
67-
setupTestSharedFileFromUser(user, folderName, { delete: false })
68-
.then((recipient) => {
69-
navigateToFolder(folderName)
70-
openVersionsPanel(randomFilePath)
71-
72-
getRowForFile(randomFileName)
73-
.should('be.visible')
74-
.invoke('attr', 'data-cy-files-list-row-fileid')
75-
.then(($fileId) => { fileId = $fileId })
47+
cy.get('[data-files-versions-version]').should('have.length', versionCount)
48+
deleteVersion(--versionCount)
49+
cy.get('[data-files-versions-version]').should('have.length', versionCount)
50+
})
7651

77-
cy.get('[data-files-versions-version]')
78-
.eq(1)
79-
.invoke('attr', 'data-files-versions-version')
80-
.then(($versionId) => { versionId = $versionId })
52+
it('Delete versions of shared file without delete permission', () => {
53+
setupTestSharedFileFromUser(user, folderName, { delete: false })
54+
navigateToFolder(folderName)
55+
openVersionsPanel(randomFilePath)
8156

82-
cy.logout()
83-
cy.then(() => {
84-
const base = Cypress.config('baseUrl')!.replace(/\/index\.php\/?$/, '')
85-
return cy.request({
86-
method: 'DELETE',
87-
url: `${base}/remote.php/dav/versions/${recipient.userId}/versions/${fileId}/${versionId}`,
88-
auth: { user: recipient.userId, pass: recipient.password },
89-
headers: {
90-
cookie: '',
91-
},
92-
failOnStatusCode: false,
93-
})
94-
}).then(({ status }) => {
95-
expect(status).to.equal(403)
96-
})
97-
})
98-
})
57+
doesNotHaveAction(0, 'delete')
58+
doesNotHaveAction(1, 'delete')
59+
doesNotHaveAction(2, 'delete')
9960
})
10061
})

cypress/e2e/files_versions/version_download.cy.ts

Lines changed: 24 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,54 @@
66
import type { User } from '@nextcloud/e2e-test-server/cypress'
77

88
import { randomString } from '../../support/utils/randomString.ts'
9-
import { getRowForFile } from '../files/FilesUtils.ts'
109
import { assertVersionContent, doesNotHaveAction, openVersionsPanel, setupTestSharedFileFromUser, uploadThreeVersions } from './filesVersionsUtils.ts'
1110

1211
describe('Versions download', () => {
1312
let randomFileName = ''
1413
let user: User
1514

16-
before(() => {
15+
before(() => cy.runOccCommand('config:app:set --value no core shareapi_allow_view_without_download'))
16+
after(() => {
17+
cy.runOccCommand('config:app:delete core shareapi_allow_view_without_download')
18+
})
19+
20+
beforeEach(() => {
1721
randomFileName = randomString(10) + '.txt'
1822

19-
cy.runOccCommand('config:app:set --value no core shareapi_allow_view_without_download')
2023
cy.createRandomUser()
2124
.then((_user) => {
2225
user = _user
2326
uploadThreeVersions(user, randomFileName)
24-
cy.login(user)
25-
cy.visit('/apps/files')
26-
openVersionsPanel(randomFileName)
2727
})
2828
})
2929

30-
after(() => {
31-
cy.runOccCommand('config:app:delete core shareapi_allow_view_without_download')
32-
})
33-
3430
it('Download versions and assert their content', () => {
31+
cy.login(user)
32+
cy.visit('/apps/files')
33+
openVersionsPanel(randomFileName)
34+
3535
assertVersionContent(0, 'v3')
3636
assertVersionContent(1, 'v2')
3737
assertVersionContent(2, 'v1')
3838
})
3939

40-
context('Download versions of shared file', () => {
41-
it('Works with download permission', () => {
42-
setupTestSharedFileFromUser(user, randomFileName, { download: true })
43-
openVersionsPanel(randomFileName)
40+
it('Download versions of shared file with download permission', () => {
41+
setupTestSharedFileFromUser(user, randomFileName, { download: true })
42+
openVersionsPanel(randomFileName)
4443

45-
assertVersionContent(0, 'v3')
46-
assertVersionContent(1, 'v2')
47-
assertVersionContent(2, 'v1')
48-
})
49-
50-
it('Does not show action without download permission', () => {
51-
setupTestSharedFileFromUser(user, randomFileName, { download: false })
52-
openVersionsPanel(randomFileName)
53-
54-
cy.get('[data-files-versions-version]').eq(0).find('.action-item__menutoggle').should('not.exist')
55-
cy.get('[data-files-versions-version]').eq(0).get('[data-cy-version-action="download"]').should('not.exist')
56-
57-
doesNotHaveAction(1, 'download')
58-
doesNotHaveAction(2, 'download')
59-
})
60-
61-
it('Does not work without download permission through direct API access', () => {
62-
let fileId: string | undefined
63-
let versionId: string | undefined
64-
65-
setupTestSharedFileFromUser(user, randomFileName, { download: false })
66-
.then((recipient) => {
67-
openVersionsPanel(randomFileName)
44+
assertVersionContent(0, 'v3')
45+
assertVersionContent(1, 'v2')
46+
assertVersionContent(2, 'v1')
47+
})
6848

69-
getRowForFile(randomFileName)
70-
.should('be.visible')
71-
.invoke('attr', 'data-cy-files-list-row-fileid')
72-
.then(($fileId) => { fileId = $fileId })
49+
it('Does not show action without download permission', () => {
50+
setupTestSharedFileFromUser(user, randomFileName, { download: false })
51+
openVersionsPanel(randomFileName)
7352

74-
cy.get('[data-files-versions-version]')
75-
.eq(1)
76-
.invoke('attr', 'data-files-versions-version')
77-
.then(($versionId) => { versionId = $versionId })
53+
cy.get('[data-files-versions-version]').eq(0).find('.action-item__menutoggle').should('not.exist')
54+
cy.get('[data-files-versions-version]').eq(0).get('[data-cy-version-action="download"]').should('not.exist')
7855

79-
cy.logout()
80-
cy.then(() => {
81-
const base = Cypress.config('baseUrl')!.replace(/\/index\.php\/?$/, '')
82-
return cy.request({
83-
url: `${base}/remote.php/dav/versions/${recipient.userId}/versions/${fileId}/${versionId}`,
84-
auth: { user: recipient.userId, pass: recipient.password },
85-
headers: {
86-
cookie: '',
87-
},
88-
failOnStatusCode: false,
89-
})
90-
}).then(({ status }) => {
91-
expect(status).to.equal(403)
92-
})
93-
})
94-
})
56+
doesNotHaveAction(1, 'download')
57+
doesNotHaveAction(2, 'download')
9558
})
9659
})

0 commit comments

Comments
 (0)