Skip to content

Commit fd96a32

Browse files
committed
test: adjust cypress tests
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 3726596 commit fd96a32

10 files changed

Lines changed: 182 additions & 306 deletions

cypress.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export default defineConfig({
2525
viewportWidth: 1280,
2626
viewportHeight: 720,
2727

28-
// Tries again 2 more times on failure
28+
// Tries again when in run mode (cypress run) e.g. on CI
2929
retries: {
30-
runMode: 2,
30+
runMode: 3,
3131
// do not retry in `cypress open`
3232
openMode: 0,
3333
},

cypress/e2e/files/FilesUtils.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ export const getActionButtonForFile = (filename: string) => getActionsForFile(fi
2424
export function getActionEntryForFileId(fileid: number, actionId: string) {
2525
return getActionButtonForFileId(fileid)
2626
.should('have.attr', 'aria-controls')
27-
.then((menuId) => cy.get(`#${menuId}`).find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`))
27+
.then((menuId) => cy.get(`#${menuId}`)
28+
.should('exist')
29+
.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`))
2830
}
2931

3032
/**
@@ -33,10 +35,11 @@ export function getActionEntryForFileId(fileid: number, actionId: string) {
3335
* @param actionId
3436
*/
3537
export function getActionEntryForFile(file: string, actionId: string) {
36-
getActionButtonForFile(file)
38+
return getActionButtonForFile(file)
3739
.should('have.attr', 'aria-controls')
38-
return cy.findByRole('menu')
39-
.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
40+
.then((menuId) => cy.get(`#${menuId}`)
41+
.should('exist')
42+
.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`))
4043
}
4144

4245
/**
@@ -66,9 +69,8 @@ export function getInlineActionEntryForFile(file: string, actionId: string) {
6669
*/
6770
export function triggerActionForFileId(fileid: number, actionId: string) {
6871
getActionButtonForFileId(fileid)
69-
.as('actionButton')
7072
.scrollIntoView()
71-
cy.get('@actionButton')
73+
getActionButtonForFileId(fileid)
7274
.click({ force: true }) // force to avoid issues with overlaying file list header
7375
getActionEntryForFileId(fileid, actionId)
7476
.find('button')
@@ -83,9 +85,8 @@ export function triggerActionForFileId(fileid: number, actionId: string) {
8385
*/
8486
export function triggerActionForFile(filename: string, actionId: string) {
8587
getActionButtonForFile(filename)
86-
.as('actionButton')
8788
.scrollIntoView()
88-
cy.get('@actionButton')
89+
getActionButtonForFile(filename)
8990
.click({ force: true }) // force to avoid issues with overlaying file list header
9091
getActionEntryForFile(filename, actionId)
9192
.find('button')
@@ -286,8 +287,19 @@ export function navigateToFolder(dirPath: string) {
286287
*/
287288
export function closeSidebar() {
288289
// {force: true} as it might be hidden behind toasts
289-
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] .app-sidebar__close')
291+
.click({ force: true })
292+
cy.get('[data-cy-sidebar]')
293+
.should('not.be.visible')
294+
// eslint-disable-next-line cypress/no-unnecessary-waiting -- wait for the animation to finish
295+
cy.wait(500)
296+
cy.url()
297+
.should('not.contain', 'opendetails')
298+
// close all toasts
299+
cy.get('.toast-success')
300+
.if()
301+
.findAllByRole('button')
302+
.click({ force: true, multiple: true })
291303
}
292304

293305
/**

cypress/e2e/files/favorites.cy.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ describe('files: Favorites', { testIsolation: true }, () => {
113113
cy.intercept('POST', '**/apps/files/api/v1/files/new%20folder').as('addToFavorites')
114114
// open sidebar
115115
triggerActionForFile('new folder', 'details')
116+
cy.get('[data-cy-sidebar]')
117+
.should('be.visible')
118+
119+
// open sidebar actions
116120
cy.get('[data-cy-sidebar]')
117121
.findByRole('button', { name: 'Actions' })
118122
.click()
@@ -121,8 +125,9 @@ describe('files: Favorites', { testIsolation: true }, () => {
121125
.findByRole('menuitem', { name: 'Favorite' })
122126
.should('be.visible')
123127
.click()
124-
125128
cy.wait('@addToFavorites')
129+
130+
// close sidebar
126131
closeSidebar()
127132

128133
// See favorites star
@@ -131,9 +136,14 @@ describe('files: Favorites', { testIsolation: true }, () => {
131136
.should('be.visible')
132137

133138
cy.reload()
139+
getRowForFile('new folder')
140+
.should('be.visible')
134141

135142
// can unfavorite
136143
triggerActionForFile('new folder', 'details')
144+
cy.get('[data-cy-sidebar]')
145+
.should('be.visible')
146+
137147
cy.get('[data-cy-sidebar]')
138148
.findByRole('button', { name: 'Actions' })
139149
.click()

cypress/e2e/files_sharing/FilesSharingUtils.ts

Lines changed: 17 additions & 5 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,9 @@ 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+
closeSidebar()
36+
3337
updateShare(fileName, 0, shareSettings)
3438
}
3539

@@ -55,10 +59,16 @@ export function updateShare(fileName: string, index: number, shareSettings: Part
5559
cy.get('[data-cy-files-sharing-share-permissions-checkbox="download"]').find('input').as('downloadCheckbox')
5660
if (shareSettings.download) {
5761
// Force:true because the checkbox is hidden by the pretty UI.
58-
cy.get('@downloadCheckbox').check({ force: true, scrollBehavior: 'nearest' })
62+
cy.get('@downloadCheckbox')
63+
.check({ force: true, scrollBehavior: 'nearest' })
64+
cy.get('@downloadCheckbox')
65+
.should('be.checked')
5966
} else {
6067
// Force:true because the checkbox is hidden by the pretty UI.
61-
cy.get('@downloadCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
68+
cy.get('@downloadCheckbox')
69+
.uncheck({ force: true, scrollBehavior: 'nearest' })
70+
cy.get('@downloadCheckbox')
71+
.should('not.be.checked')
6272
}
6373
}
6474

@@ -122,14 +132,16 @@ export function updateShare(fileName: string, index: number, shareSettings: Part
122132

123133
cy.wait('@updateShare')
124134
})
125-
// close all toasts
126-
cy.get('.toast-success').findAllByRole('button').click({ force: true, multiple: true })
135+
closeSidebar()
127136
}
128137

129138
export function openSharingPanel(fileName: string) {
130139
triggerActionForFile(fileName, 'details')
131140

132141
cy.get('[data-cy-sidebar]')
142+
.as('sidebar')
143+
.should('be.visible')
144+
cy.get('@sidebar')
133145
.find('[aria-controls="tab-sharing"]')
134146
.click()
135147
}

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: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export function openVersionsPanel(fileName: string) {
2828

2929
triggerActionForFile(basename(fileName), 'details')
3030
cy.get('[data-cy-sidebar]')
31+
.as('sidebar')
32+
.should('be.visible')
33+
cy.get('@sidebar')
3134
.find('[aria-controls="tab-files_versions"]')
3235
.click()
3336

@@ -86,7 +89,6 @@ export function setupTestSharedFileFromUser(owner: User, randomFileName: string,
8689
cy.login(owner)
8790
cy.visit('/apps/files')
8891
createShare(randomFileName, recipient.userId, shareOptions)
89-
cy.logout()
9092

9193
cy.login(recipient)
9294
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
})

0 commit comments

Comments
 (0)