Skip to content

Commit

Permalink
chore(tests): Add missing files for cypress tests
Browse files Browse the repository at this point in the history
Pulled master version of cypress/e2e/files/FilesUtils.ts and cypress/e2e/files_sharing/FilesSharingUtils.ts
 dependencies of the test

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
  • Loading branch information
come-nc committed Aug 19, 2024
1 parent 571b955 commit e82ccee
Show file tree
Hide file tree
Showing 3 changed files with 322 additions and 1 deletion.
138 changes: 138 additions & 0 deletions cypress/e2e/files/FilesUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* 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 getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).find('button[aria-label="Actions"]')
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).find('button[aria-label="Actions"]')

export const triggerActionForFileId = (fileid: number, actionId: string) => {
getActionButtonForFileId(fileid).click()
cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).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()
}

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 moveFile = (fileName: string, dirPath: string) => {
getRowForFile(fileName).should('be.visible')
triggerActionForFile(fileName, 'move-copy')

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

if (dirPath === '/') {
// select home folder
cy.get('button[title="Home"]').should('be.visible').click()
// click move
cy.contains('button', 'Move').should('be.visible').click()
} else if (dirPath === '.') {
// click move
cy.contains('button', 'Copy').should('be.visible').click()
} else {
const directories = dirPath.split('/')
directories.forEach((directory) => {
// select the folder
cy.get(`[data-filename="${directory}"]`).should('be.visible').click()
})

// click move
cy.contains('button', `Move to ${directories.at(-1)}`).should('be.visible').click()
}

cy.wait('@moveFile')
})
}

export const copyFile = (fileName: string, dirPath: string) => {
getRowForFile(fileName).should('be.visible')
triggerActionForFile(fileName, 'move-copy')

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

if (dirPath === '/') {
// select home folder
cy.get('button[title="Home"]').should('be.visible').click()
// click copy
cy.contains('button', 'Copy').should('be.visible').click()
} else if (dirPath === '.') {
// click copy
cy.contains('button', 'Copy').should('be.visible').click()
} else {
const directories = dirPath.split('/')
directories.forEach((directory) => {
// select the folder
cy.get(`[data-filename="${CSS.escape(directory)}"]`).should('be.visible').click()
})

// click copy
cy.contains('button', `Copy to ${directories.at(-1)}`).should('be.visible').click()
}

cy.wait('@copyFile')
})
}

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.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()
})

}

export const closeSidebar = () => {
// {force: true} as it might be hidden behind toasts
cy.get('[data-cy-sidebar] .app-sidebar__close').click({ force: true })
}

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 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')
}
183 changes: 183 additions & 0 deletions cypress/e2e/files_sharing/FilesSharingUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/* eslint-disable jsdoc/require-jsdoc */
import { triggerActionForFile } from '../files/FilesUtils'

export interface ShareSetting {
read: boolean
update: boolean
delete: boolean
share: boolean
download: boolean
note: string
}

export function createShare(fileName: string, username: string, shareSettings: Partial<ShareSetting> = {}) {
openSharingPanel(fileName)

cy.get('#app-sidebar-vue').within(() => {
cy.get('#sharing-search-input').clear()
cy.intercept({ times: 1, method: 'GET', url: '**/apps/files_sharing/api/v1/sharees?*' }).as('userSearch')
cy.get('#sharing-search-input').type(username)
cy.wait('@userSearch')
})

cy.get(`[user="${username}"]`).click()

// HACK: Save the share and then update it, as permissions changes are currently not saved for new share.
cy.get('[data-cy-files-sharing-share-editor-action="save"]').click({ scrollBehavior: 'nearest' })
updateShare(fileName, 0, shareSettings)
}

export function updateShare(fileName: string, index: number, shareSettings: Partial<ShareSetting> = {}) {
openSharingPanel(fileName)

cy.intercept({ times: 1, method: 'PUT', url: '**/apps/files_sharing/api/v1/shares/*' }).as('updateShare')

cy.get('#app-sidebar-vue').within(() => {
cy.get('[data-cy-files-sharing-share-actions]').eq(index).click()
cy.get('[data-cy-files-sharing-share-permissions-bundle="custom"]').click()

if (shareSettings.download !== undefined) {
cy.get('[data-cy-files-sharing-share-permissions-checkbox="download"]').find('input').as('downloadCheckbox')
if (shareSettings.download) {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@downloadCheckbox').check({ force: true, scrollBehavior: 'nearest' })
} else {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@downloadCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
}
}

if (shareSettings.read !== undefined) {
cy.get('[data-cy-files-sharing-share-permissions-checkbox="read"]').find('input').as('readCheckbox')
if (shareSettings.read) {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@readCheckbox').check({ force: true, scrollBehavior: 'nearest' })
} else {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@readCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
}
}

if (shareSettings.update !== undefined) {
cy.get('[data-cy-files-sharing-share-permissions-checkbox="update"]').find('input').as('updateCheckbox')
if (shareSettings.update) {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@updateCheckbox').check({ force: true, scrollBehavior: 'nearest' })
} else {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@updateCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
}
}

if (shareSettings.delete !== undefined) {
cy.get('[data-cy-files-sharing-share-permissions-checkbox="delete"]').find('input').as('deleteCheckbox')
if (shareSettings.delete) {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@deleteCheckbox').check({ force: true, scrollBehavior: 'nearest' })
} else {
// Force:true because the checkbox is hidden by the pretty UI.
cy.get('@deleteCheckbox').uncheck({ force: true, scrollBehavior: 'nearest' })
}
}

if (shareSettings.note !== undefined) {
cy.findByRole('checkbox', { name: /note to recipient/i }).check({ force: true, scrollBehavior: 'nearest' })
cy.findByRole('textbox', { name: /note to recipient/i }).type(shareSettings.note)
}

cy.get('[data-cy-files-sharing-share-editor-action="save"]').click({ scrollBehavior: 'nearest' })

cy.wait('@updateShare')
})
}

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

cy.get('#app-sidebar-vue')
.get('[aria-controls="tab-sharing"]')
.click()
}

type FileRequestOptions = {
label?: string
note?: string
password?: string
/* YYYY-MM-DD format */
expiration?: string
}

/**
* Create a file request for a folder
* @param path The path of the folder, leading slash is required
* @param options The options for the file request
*/
export const createFileRequest = (path: string, options: FileRequestOptions = {}) => {
if (!path.startsWith('/')) {
throw new Error('Path must start with a slash')
}

// Navigate to the folder
cy.visit('/apps/files/files?dir=' + path)

// Open the file request dialog
cy.get('[data-cy-upload-picker] .action-item__menutoggle').first().click()
cy.contains('.upload-picker__menu-entry button', 'Create file request').click()
cy.get('[data-cy-file-request-dialog]').should('be.visible')

// Check and fill the first page options
cy.get('[data-cy-file-request-dialog-fieldset="label"]').should('be.visible')
cy.get('[data-cy-file-request-dialog-fieldset="destination"]').should('be.visible')
cy.get('[data-cy-file-request-dialog-fieldset="note"]').should('be.visible')

cy.get('[data-cy-file-request-dialog-fieldset="destination"] input').should('contain.value', path)
if (options.label) {
cy.get('[data-cy-file-request-dialog-fieldset="label"] input').type(`{selectall}${options.label}`)
}
if (options.note) {
cy.get('[data-cy-file-request-dialog-fieldset="note"] textarea').type(`{selectall}${options.note}`)
}

// Go to the next page
cy.get('[data-cy-file-request-dialog-controls="next"]').click()
cy.get('[data-cy-file-request-dialog-fieldset="expiration"] input[type="checkbox"]').should('exist')
cy.get('[data-cy-file-request-dialog-fieldset="expiration"] input[type="date"]').should('not.exist')
cy.get('[data-cy-file-request-dialog-fieldset="password"] input[type="checkbox"]').should('exist')
cy.get('[data-cy-file-request-dialog-fieldset="password"] input[type="password"]').should('not.exist')
if (options.expiration) {
cy.get('[data-cy-file-request-dialog-fieldset="expiration"] input[type="checkbox"]').check({ force: true })
cy.get('[data-cy-file-request-dialog-fieldset="expiration"] input[type="date"]').type(`{selectall}${options.expiration}`)
}
if (options.password) {
cy.get('[data-cy-file-request-dialog-fieldset="password"] input[type="checkbox"]').check({ force: true })
cy.get('[data-cy-file-request-dialog-fieldset="password"] input[type="password"]').type(`{selectall}${options.password}`)
}

// Create the file request
cy.get('[data-cy-file-request-dialog-controls="next"]').click()

// Get the file request URL
cy.get('[data-cy-file-request-dialog-fieldset="link"]').then(($link) => {
const url = $link.val()
cy.log(`File request URL: ${url}`)
cy.wrap(url).as('fileRequestUrl')
})

// Close
cy.get('[data-cy-file-request-dialog-controls="finish"]').click()
}

export const enterGuestName = (name: string) => {
cy.get('[data-cy-public-auth-prompt-dialog]').should('be.visible')
cy.get('[data-cy-public-auth-prompt-dialog-name]').should('be.visible')
cy.get('[data-cy-public-auth-prompt-dialog-submit]').should('be.visible')

cy.get('[data-cy-public-auth-prompt-dialog-name]').type(`{selectall}${name}`)
cy.get('[data-cy-public-auth-prompt-dialog-submit]').click()

cy.get('[data-cy-public-auth-prompt-dialog]').should('not.exist')
}
2 changes: 1 addition & 1 deletion cypress/e2e/files_sharing/limit_to_same_group.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { User } from "@nextcloud/cypress"
import { createShare } from "./filesSharingUtils"
import { createShare } from "./FilesSharingUtils"

describe('Limit to sharing to people in the same group', () => {
let alice: User
Expand Down

0 comments on commit e82ccee

Please sign in to comment.