aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2025-03-03 17:16:57 +0100
committerFerdinand Thiessen <opensource@fthiessen.de>2025-03-05 08:24:54 +0100
commit571124bc3c8b4770001e22d2169d7060b4f49d6c (patch)
tree331ba1cf91940e526a3079a33dae14ca53a67f61
parentea24143154791d435ad4cb63d7f36f1bef50b558 (diff)
downloadnextcloud-server-571124bc3c8b4770001e22d2169d7060b4f49d6c.tar.gz
nextcloud-server-571124bc3c8b4770001e22d2169d7060b4f49d6c.zip
test(e2e): adjust trashbin tests to be less flakybackport/51211/stable31
1. Move general files delete action (thats not trashbin app!) to files tests. 2. Delete files (move to trashbin) before loading the page so previews are not generated so they cannot lock the file. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r--cypress/e2e/files/FilesUtils.ts8
-rw-r--r--cypress/e2e/files/files-actions.cy.ts12
-rw-r--r--cypress/e2e/files/files-delete.cy.ts74
-rw-r--r--cypress/e2e/files_trashbin/files-trash-action.cy.ts44
4 files changed, 94 insertions, 44 deletions
diff --git a/cypress/e2e/files/FilesUtils.ts b/cypress/e2e/files/FilesUtils.ts
index 1b2cced53be..f207403e1ee 100644
--- a/cypress/e2e/files/FilesUtils.ts
+++ b/cypress/e2e/files/FilesUtils.ts
@@ -170,9 +170,13 @@ export const renameFile = (fileName: string, newFileName: string) => {
export const navigateToFolder = (dirPath: string) => {
const directories = dirPath.split('/')
- directories.forEach((directory) => {
+ for (const directory of directories) {
+ if (directory === '') {
+ continue
+ }
+
getRowForFile(directory).should('be.visible').find('[data-cy-files-list-row-name-link]').click()
- })
+ }
}
diff --git a/cypress/e2e/files/files-actions.cy.ts b/cypress/e2e/files/files-actions.cy.ts
index 8b0057e3042..e44ca74ecec 100644
--- a/cypress/e2e/files/files-actions.cy.ts
+++ b/cypress/e2e/files/files-actions.cy.ts
@@ -6,14 +6,14 @@
import type { User } from '@nextcloud/cypress'
import { FileAction } from '@nextcloud/files'
-import { getActionButtonForFileId, getActionEntryForFileId, getRowForFile, getSelectionActionButton, getSelectionActionEntry, selectRowForFile, triggerActionForFile, triggerActionForFileId } from './FilesUtils'
+import { getActionButtonForFileId, getActionEntryForFileId, getRowForFile, getSelectionActionButton, getSelectionActionEntry, selectRowForFile } from './FilesUtils'
import { ACTION_COPY_MOVE } from '../../../apps/files/src/actions/moveOrCopyAction'
import { ACTION_DELETE } from '../../../apps/files/src/actions/deleteAction'
import { ACTION_DETAILS } from '../../../apps/files/src/actions/sidebarAction'
import { ACTION_SHARING_STATUS } from '../../../apps/files_sharing/src/files_actions/sharingStatusAction'
declare global {
- interface Window {
+ interface Window {
_nc_fileactions: FileAction[]
}
}
@@ -53,6 +53,8 @@ describe('Files: Actions', { testIsolation: true }, () => {
getActionButtonForFileId(fileId).click({ force: true })
// Check the action is visible
getActionEntryForFileId(fileId, actionId).should('be.visible')
+ // Close the menu
+ cy.get('body').click({ force: true })
})
})
@@ -60,7 +62,7 @@ describe('Files: Actions', { testIsolation: true }, () => {
const parent = new FileAction({
id: 'nested-action',
displayName: () => 'Nested Action',
- exec: cy.spy(),
+ exec: cy.spy(),
iconSvgInline: () => '<svg></svg>',
})
@@ -88,7 +90,7 @@ describe('Files: Actions', { testIsolation: true }, () => {
win._nc_fileactions.push(parent)
win._nc_fileactions.push(child1)
win._nc_fileactions.push(child2)
- }
+ },
})
// Open the menu
@@ -175,7 +177,7 @@ describe('Files: Actions', { testIsolation: true }, () => {
win._nc_fileactions.push(parent)
win._nc_fileactions.push(child1)
win._nc_fileactions.push(child2)
- }
+ },
})
selectRowForFile('image.jpg')
diff --git a/cypress/e2e/files/files-delete.cy.ts b/cypress/e2e/files/files-delete.cy.ts
new file mode 100644
index 00000000000..edb88519c59
--- /dev/null
+++ b/cypress/e2e/files/files-delete.cy.ts
@@ -0,0 +1,74 @@
+/*!
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import type { User } from '@nextcloud/cypress'
+import { getRowForFile, navigateToFolder, selectAllFiles, triggerActionForFile } from './FilesUtils.ts'
+
+describe('files: Delete files using file actions', { testIsolation: true }, () => {
+ let user: User
+
+ beforeEach(() => {
+ cy.createRandomUser().then(($user) => {
+ user = $user
+ })
+ })
+
+ it('can delete file', () => {
+ cy.uploadContent(user, new Blob([]), 'text/plain', '/file.txt')
+ cy.login(user)
+ cy.visit('/apps/files')
+
+ // The file must exist and the preview loaded as it locks the file
+ getRowForFile('file.txt')
+ .should('be.visible')
+ .find('.files-list__row-icon-preview--loaded')
+ .should('exist')
+
+ cy.intercept('DELETE', '**/remote.php/dav/files/**').as('deleteFile')
+
+ triggerActionForFile('file.txt', 'delete')
+ cy.wait('@deleteFile').its('response.statusCode').should('eq', 204)
+ })
+
+ it('can delete multiple files', () => {
+ cy.mkdir(user, '/root')
+ for (let i = 0; i < 5; i++) {
+ cy.uploadContent(user, new Blob([]), 'text/plain', `/root/file${i}.txt`)
+ }
+ cy.login(user)
+ cy.visit('/apps/files')
+ navigateToFolder('/root')
+
+ // The file must exist and the preview loaded as it locks the file
+ cy.get('.files-list__row-icon-preview--loaded')
+ .should('have.length', 5)
+
+ cy.intercept('DELETE', '**/remote.php/dav/files/**').as('deleteFile')
+
+ // select all
+ selectAllFiles()
+ cy.get('[data-cy-files-list-selection-actions]')
+ .findByRole('button', { name: 'Actions' })
+ .click()
+ cy.get('[data-cy-files-list-selection-action="delete"]')
+ .findByRole('menuitem', { name: /^Delete files/ })
+ .click()
+
+ // see dialog for confirmation
+ cy.findByRole('dialog', { name: 'Confirm deletion' })
+ .findByRole('button', { name: 'Delete files' })
+ .click()
+
+ cy.wait('@deleteFile')
+ cy.get('@deleteFile.all')
+ .should('have.length', 5)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ .should((all: any) => {
+ for (const call of all) {
+ expect(call.response.statusCode).to.equal(204)
+ }
+ })
+ })
+})
diff --git a/cypress/e2e/files_trashbin/files-trash-action.cy.ts b/cypress/e2e/files_trashbin/files-trash-action.cy.ts
index ee06f6c3158..090a7ed8d5d 100644
--- a/cypress/e2e/files_trashbin/files-trash-action.cy.ts
+++ b/cypress/e2e/files_trashbin/files-trash-action.cy.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { User } from '@nextcloud/cypress'
-import { deleteFileWithRequest, getRowForFile, triggerActionForFile, triggerFileListAction } from '../files/FilesUtils.ts'
+import { deleteFileWithRequest, triggerFileListAction } from '../files/FilesUtils.ts'
const FILE_COUNT = 5
describe('files_trashbin: Empty trashbin action', { testIsolation: true }, () => {
@@ -12,44 +12,19 @@ describe('files_trashbin: Empty trashbin action', { testIsolation: true }, () =>
beforeEach(() => {
cy.createRandomUser().then(($user) => {
user = $user
- // create 10 fake files
- new Array(FILE_COUNT).fill(0).forEach((_, index) => {
+ // create 5 fake files and move them to trash
+ for (let index = 0; index < FILE_COUNT; index++) {
cy.uploadContent(user, new Blob(['<content>']), 'text/plain', `/file${index}.txt`)
- })
-
+ deleteFileWithRequest(user, `/file${index}.txt`)
+ }
+ // login
cy.login(user)
- cy.visit('/apps/files')
})
})
- it('Can delete files', () => {
- for (let i = 0; i < FILE_COUNT; i++) {
- getRowForFile(`file${i}.txt`).should('be.visible')
- }
-
- cy.intercept('DELETE', '**/remote.php/dav/files/**').as('deleteFile')
-
- // Delete all files one by one
- for (let i = 0; i < FILE_COUNT; i++) {
- triggerActionForFile(`file${i}.txt`, 'delete')
- cy.wait('@deleteFile').its('response.statusCode').should('eq', 204)
- }
-
- cy.get('@deleteFile.all').should('have.length', FILE_COUNT)
-
- for (let i = 0; i < FILE_COUNT; i++) {
- getRowForFile(`file${i}.txt`).should('not.exist')
- }
- })
-
it('Can empty trashbin', () => {
- // Delete files from home
- new Array(FILE_COUNT).fill(0).forEach((_, index) => {
- deleteFileWithRequest(user, `/file${index}.txt`)
- })
-
- // Home have no files (or the default welcome file)
cy.visit('/apps/files')
+ // Home have no files (or the default welcome file)
cy.get('[data-cy-files-list-row-fileid]').should('have.length', 1)
cy.get('[data-cy-files-list-action="empty-trash"]').should('not.exist')
@@ -74,11 +49,6 @@ describe('files_trashbin: Empty trashbin action', { testIsolation: true }, () =>
})
it('Cancelling empty trashbin action does not delete anything', () => {
- // Delete files from home
- new Array(FILE_COUNT).fill(0).forEach((_, index) => {
- deleteFileWithRequest(user, `/file${index}.txt`)
- })
-
// Go to trashbin, and see our deleted files
cy.visit('/apps/files/trashbin')
cy.get('[data-cy-files-list-row-fileid]').should('have.length', FILE_COUNT)