Skip to content

Commit

Permalink
test: Fix cypress tests
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <kate@provokateurin.de>
  • Loading branch information
provokateurin committed Nov 11, 2024
1 parent 6089ac4 commit 2d01544
Show file tree
Hide file tree
Showing 10 changed files with 384 additions and 208 deletions.
4 changes: 2 additions & 2 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default defineConfig({
projectId: 'xcmgay',

// 16/9 screen ratio
viewportWidth: 1280,
viewportHeight: 720,
viewportWidth: 1920,
viewportHeight: 1080,

// Tries again 2 more times on failure
retries: {
Expand Down
13 changes: 9 additions & 4 deletions cypress/e2e/encryption.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,20 @@ import {
PERMISSION_WRITE,
} from './groupfoldersUtils'

import {
assertFileContent,
moveFile,
} from './files/filesUtils'
import { getRowForFile, moveFile, triggerActionForFile } from './files/filesUtils'

import { randHash } from '../utils'

import type { User } from '@nextcloud/cypress'

export const assertFileContent = (fileName: string, expectedContent: string) => {
cy.intercept({ method: 'GET', times: 1, url: 'remote.php/**' }).as('downloadFile')
getRowForFile(fileName).should('be.visible')
triggerActionForFile(fileName, 'download')
cy.wait('@downloadFile')
.then(({ response }) => expect(response?.body).to.equal(expectedContent))
}

describe('Groupfolders encryption behavior', () => {
let user1: User
let groupFolderId: string
Expand Down
110 changes: 96 additions & 14 deletions cypress/e2e/files/filesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,61 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

export const getRowForFileId = (fileid: number) => cy.get(`[data-cy-files-list-row-fileid="${fileid}"]`)
export const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`)

export const getActionsForFileId = (fileid: number) => getRowForFileId(fileid).find('[data-cy-files-list-row-actions]')
export const getActionsForFile = (filename: string) => getRowForFile(filename).find('[data-cy-files-list-row-actions]')

export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).find('button[aria-label="Actions"]')
export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' })
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' })

export const triggerActionForFileId = (fileid: number, actionId: string) => {
getActionButtonForFileId(fileid).click()
// Getting the last button to avoid the one from popup fading out
cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).last()
.should('exist').click()
}
export const triggerActionForFile = (filename: string, actionId: string) => {
getActionButtonForFile(filename).click()
cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).should('exist').click()
// Getting the last button to avoid the one from popup fading out
cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).last()
.should('exist').click()
}

export const triggerInlineActionForFileId = (fileid: number, actionId: string) => {
getActionsForFileId(fileid).find(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`).should('exist').click()
}
export const triggerInlineActionForFile = (filename: string, actionId: string) => {
getActionsForFile(filename).get(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`).should('exist').click()
}

export const selectAllFiles = () => {
cy.get('[data-cy-files-list-selection-checkbox]')
.findByRole('checkbox', { checked: false })
.click({ force: true })
}
export const deselectAllFiles = () => {
cy.get('[data-cy-files-list-selection-checkbox]')
.findByRole('checkbox', { checked: true })
.click({ force: true })
}

export const selectRowForFile = (filename: string, options: Partial<Cypress.ClickOptions> = {}) => {
getRowForFile(filename)
.find('[data-cy-files-list-row-checkbox]')
.findByRole('checkbox')
// don't use click to avoid triggering side effects events
.trigger('change', { ...options, force: true })
.should('be.checked')
cy.get('[data-cy-files-list-selection-checkbox]').findByRole('checkbox').should('satisfy', (elements) => {
return elements.length === 1 && (elements[0].checked === true || elements[0].indeterminate === true)
})

}

export const triggerSelectionAction = (actionId: string) => {
cy.get(`button[data-cy-files-list-selection-action="${CSS.escape(actionId)}"]`).should('exist').click()
}

export const moveFile = (fileName: string, dirPath: string) => {
Expand All @@ -20,7 +66,7 @@ export const moveFile = (fileName: string, dirPath: string) => {

cy.get('.file-picker').within(() => {
// intercept the copy so we can wait for it
cy.intercept({ method: 'MOVE', times: 1, url: /\/remote.php\/dav\/files\// }).as('moveFile')
cy.intercept('MOVE', /\/(remote|public)\.php\/dav\/files\//).as('moveFile')

if (dirPath === '/') {
// select home folder
Expand Down Expand Up @@ -51,7 +97,7 @@ export const copyFile = (fileName: string, dirPath: string) => {

cy.get('.file-picker').within(() => {
// intercept the copy so we can wait for it
cy.intercept({ method: 'COPY', times: 1, url: /\/remote.php\/dav\/files\// }).as('copyFile')
cy.intercept('COPY', /\/(remote|public)\.php\/dav\/files\//).as('copyFile')

if (dirPath === '/') {
// select home folder
Expand All @@ -65,7 +111,7 @@ export const copyFile = (fileName: string, dirPath: string) => {
const directories = dirPath.split('/')
directories.forEach((directory) => {
// select the folder
cy.get(`[data-filename="${directory}"]`).should('be.visible').click()
cy.get(`[data-filename="${CSS.escape(directory)}"]`).should('be.visible').click()
})

// click copy
Expand All @@ -76,10 +122,23 @@ export const copyFile = (fileName: string, dirPath: string) => {
})
}

export const renameFile = (fileName: string, newFileName: string) => {
getRowForFile(fileName)
triggerActionForFile(fileName, 'rename')

// intercept the move so we can wait for it
cy.intercept('MOVE', /\/(remote|public)\.php\/dav\/files\//).as('moveFile')

getRowForFile(fileName).find('[data-cy-files-list-row-name] input').clear()
getRowForFile(fileName).find('[data-cy-files-list-row-name] input').type(`${newFileName}{enter}`)

cy.wait('@moveFile')
}

export const navigateToFolder = (dirPath: string) => {
const directories = dirPath.split('/')
directories.forEach((directory) => {
getRowForFile(directory).should('be.visible').find('[data-cy-files-list-row-name-link]').click()
getRowForFile(directory).should('be.visible').find('[data-cy-files-list-row-name-link]').click({ force: true})
})

}
Expand All @@ -89,16 +148,39 @@ export const closeSidebar = () => {
cy.get('[data-cy-sidebar] .app-sidebar__close').click({ force: true })
}

export const clickOnBreadcumbs = (label: string) => {
cy.intercept({ method: 'PROPFIND', url: /\/remote.php\/dav\// }).as('propfind')
export const clickOnBreadcrumbs = (label: string) => {
cy.intercept('PROPFIND', /\/remote.php\/dav\//).as('propfind')
cy.get('[data-cy-files-content-breadcrumbs]').contains(label).click()
cy.wait('@propfind')
}

export const assertFileContent = (fileName: string, expectedContent: string) => {
cy.intercept({ method: 'GET', times: 1, url: 'remote.php/**' }).as('downloadFile')
getRowForFile(fileName).should('be.visible')
triggerActionForFile(fileName, 'download')
cy.wait('@downloadFile')
.then(({ response }) => expect(response?.body).to.equal(expectedContent))
export const createFolder = (folderName: string) => {
cy.intercept('MKCOL', /\/remote.php\/dav\/files\//).as('createFolder')

// TODO: replace by proper data-cy selectors
cy.get('[data-cy-upload-picker] .action-item__menutoggle').first().click()
cy.contains('.upload-picker__menu-entry button', 'New folder').click()
cy.get('[data-cy-files-new-node-dialog]').should('be.visible')
cy.get('[data-cy-files-new-node-dialog-input]').type(`{selectall}${folderName}`)
cy.get('[data-cy-files-new-node-dialog-submit]').click()

cy.wait('@createFolder')

getRowForFile(folderName).should('be.visible')
}

/**
* Check validity of an input element
* @param validity The expected validity message (empty string means it is valid)
* @example
* ```js
* cy.findByRole('textbox')
* .should(haveValidity(/must not be empty/i))
* ```
*/
export const haveValidity = (validity: string | RegExp) => {
if (typeof validity === 'string') {
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.equal(validity)
}
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.match(validity)
}
8 changes: 7 additions & 1 deletion cypress/e2e/files_versions/version_cross_storage_move.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import type { User } from '@nextcloud/cypress'

import { PERMISSION_DELETE, PERMISSION_READ, PERMISSION_WRITE, addUserToGroup, createGroup, createGroupFolder } from '../groupfoldersUtils'
import { assertVersionContent, nameVersion, openVersionsPanel, uploadThreeVersions } from './filesVersionsUtils'
import { clickOnBreadcumbs, closeSidebar, copyFile, moveFile, navigateToFolder } from '../files/filesUtils'
import { closeSidebar, copyFile, moveFile, navigateToFolder } from '../files/filesUtils'

export const clickOnBreadcumbs = (label: string) => {
cy.intercept({ method: 'PROPFIND', url: /\/remote.php\/dav\// }).as('propfind')
cy.get('[data-cy-files-content-breadcrumbs]').contains(label).click()
cy.wait('@propfind')
}

/**
*
Expand Down
23 changes: 10 additions & 13 deletions cypress/e2e/groupfolders.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import { randHash } from '../utils'

import type { User } from '@nextcloud/cypress'
import { triggerActionForFile } from './files/filesUtils'

describe('Groupfolders ACLs and trashbin behavior', () => {
let user1: User
Expand Down Expand Up @@ -66,7 +67,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
.then(_groupFolderId => {
groupFolderId = _groupFolderId
enableACLPermissions(groupFolderId)
addACLManagerUser(groupFolderId,managerUser.userId)
addACLManagerUser(groupFolderId, managerUser.userId)
})
})
})
Expand All @@ -81,7 +82,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/subfolder2/file2.txt`)

// Set ACL permissions
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId)

// User1 has access
Expand Down Expand Up @@ -165,7 +166,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/file1.txt`)

// Set ACL permissions on subfolder
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId)

// Delete subfolder
Expand Down Expand Up @@ -204,10 +205,8 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
// Rename subfolder1
cy.visit('/apps/files')
enterFolder(groupFolderName)
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [data-cy-files-list-row-actions]`).click()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).scrollIntoView()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).click()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]`).type('subfolder1renamed{enter}')
triggerActionForFile('subfolder1', 'rename')
cy.get('[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]').type('subfolder1renamed{enter}')
fileOrFolderExists('subfolder1renamed')

// Restore from trash
Expand All @@ -231,7 +230,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/file1.txt`)

// Set ACL permissions
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId)

// Delete file
Expand All @@ -245,10 +244,8 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
// Rename subfolder1
cy.visit('/apps/files')
enterFolder(groupFolderName)
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [data-cy-files-list-row-actions]`).click()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).scrollIntoView()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).click()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]`).type('subfolder1renamed{enter}')
triggerActionForFile('subfolder1', 'rename')
cy.get('[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]').type('subfolder1renamed{enter}')
fileOrFolderExists('subfolder1renamed')

// User1 sees it in trash
Expand All @@ -271,7 +268,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => {
cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/subfolder2/file2.txt`)

// Set ACL permissions
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId)
setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId)

// Delete files
Expand Down
Loading

0 comments on commit 2d01544

Please sign in to comment.