Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 92 additions & 17 deletions cypress/e2e/filesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,110 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

export const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`)
export const getActionsForFile = (filename: string) => getRowForFile(filename).find('[data-cy-files-list-row-actions]')
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' })

const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
if (action.length > 0) {
cy.log('Found action in row')
return cy.wrap(action)
}

// Else look in the action menu
const menuButtonId = row.find('button[aria-controls]').attr('aria-controls')
if (menuButtonId === undefined) {
return cy.wrap(Cypress.$())
}

// eslint-disable-next-line no-unused-expressions
expect(menuButtonId).not.to.be.undefined
return cy.get(`#${menuButtonId} [data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
}

export const getActionEntryForFile = (filename: string, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
// If we cannot find the action in the row, it might be in the action menu
return getRowForFile(filename).should('be.visible')
.then(row => searchForActionInRow(row, actionId))
}

export const triggerActionForFile = (filename: string, actionId: string) => {
// Even if it's inline, we open the action menu to get all actions visible
getActionButtonForFile(filename).click({ force: true })
getActionEntryForFile(filename, actionId)
.find('button').last()
.should('exist').click({ force: true })
}

export function renameFile(fileName: string, newName: string) {
toggleMenuAction(fileName, 'rename')
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${fileName}"] .files-list__row-rename input`).clear()
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${fileName}"] .files-list__row-rename input`).type(`${newName}.txt`)
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${fileName}"] .files-list__row-rename`).submit()
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(`${newName}{enter}`)
cy.get('.toast-close').click()
cy.wait(500)
cy.wait('@moveFile')
}

export function goToDir(dirName: string) {
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${dirName}"]`).click()
cy.wait(500)
export function navigateToFolder(dirPath: string) {
cy.intercept('PROPFIND', /\/remote.php\/dav\/files\//).as('navigateFolder')

const directories = dirPath.split('/')
for (const directory of directories) {
if (directory === '') {
continue
}

getRowForFile(directory).should('be.visible').find('[data-cy-files-list-row-name-link]').click()
cy.wait('@navigateFolder')
}
}

export function createFolder (dirName: string) {
cy.get('.files-list__header .breadcrumb__actions button.action-item__menutoggle').click()
cy.get('.v-popper__popper').contains('New folder').click()
cy.contains('Folder name').siblings('input').clear()
cy.contains('Folder name').siblings('input').type(`${dirName}{enter}`)
cy.log('Created folder', dirName)
cy.wait(500)
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.get('[data-cy-upload-picker-menu-entry="newFolder"] button').click()
cy.get('[data-cy-files-new-node-dialog]').should('be.visible')
cy.get('[data-cy-files-new-node-dialog-input]').type(`{selectall}${dirName}`)
cy.get('[data-cy-files-new-node-dialog-submit]').click()

cy.wait('@createFolder')

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

export function moveFile (fileName: string, dirName: string) {
toggleMenuAction(fileName, 'move-copy')
cy.get('.file-picker').within(() => {
cy.get(`[data-filename="${dirName}"]`).click()
cy.contains(`Move to ${dirName}`).click()
cy.wait(500)
// intercept the copy so we can wait for it
cy.intercept('MOVE', /\/(remote|public)\.php\/dav\/files\//).as('moveFile')

if (dirName === '/') {
// select home folder
cy.get('button[title="Home"]').should('be.visible').click()
// click move
cy.contains('button', 'Move').should('be.visible').click()
} else if (dirName === '.') {
// click move
cy.contains('button', 'Copy').should('be.visible').click()
} else {
const directories = dirName.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')
})
}

Expand Down
11 changes: 5 additions & 6 deletions cypress/e2e/sidebar.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { createFolder, getFileListRow, goToDir, moveFile, renameFile } from './filesUtils'
import { addComment, addTag, createPublicShare, toggleFavorite, showActivityTab, closeSidebar } from './sidebarUtils'
import { createFolder, getFileListRow, navigateToFolder, moveFile, renameFile } from './filesUtils'
import { addComment, addTag, createPublicShare, toggleFavorite, showActivityTab } from './sidebarUtils'

describe('Check activity listing in the sidebar', { testIsolation: true }, () => {
beforeEach(function() {
Expand Down Expand Up @@ -45,8 +45,8 @@ describe('Check activity listing in the sidebar', { testIsolation: true }, () =>
})

it('Has rename activity', () => {
renameFile('welcome.txt', 'new name')
renameFile('new name.txt', 'welcome')
renameFile('welcome.txt', 'new name.txt')
renameFile('new name.txt', 'welcome.txt')

showActivityTab('welcome.txt')
cy.get('.activity-entry').first().should('contains.text', 'You renamed')
Expand All @@ -55,8 +55,7 @@ describe('Check activity listing in the sidebar', { testIsolation: true }, () =>
it('Has move activity', () => {
createFolder('Test folder')
moveFile('welcome.txt', 'Test folder')
cy.get('.toast-close').click({ multiple: true })
goToDir('Test folder')
navigateToFolder('Test folder')

showActivityTab('welcome.txt')
cy.get('.activity-entry').first().should('contains.text', 'You moved')
Expand Down
15 changes: 12 additions & 3 deletions cypress/e2e/sidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ export function closeSidebar() {
cy.get('body')
.then(($body) => {
if ($body.find('.app-sidebar__close').length !== 0) {
cy.get('.app-sidebar__close').click({ force: true })
// {force: true} as it might be hidden behind toasts
cy.get('[data-cy-sidebar] .app-sidebar__close').click({ force: true })
}
})
cy.get('#app-sidebar-vue').should('not.exist')
}

export function showActivityTab(fileName: string) {
cy.intercept('GET', '/ocs/v2.php/apps/activity/api/v2/activity/filter**').as('getActivities')

showSidebarForFile(fileName)
cy.get('#app-sidebar-vue')
.findByRole('tab', { name: 'Activity' })
Expand All @@ -30,6 +33,8 @@ export function showActivityTab(fileName: string) {
cy.get('#app-sidebar-vue')
.findByRole('tabpanel', { name: 'Activity' })
.should('be.visible')

cy.wait('@getActivities')
}

export function toggleFavorite(fileName: string) {
Expand All @@ -47,6 +52,8 @@ export function toggleFavorite(fileName: string) {
* @param fileName Name of the file to share
*/
export function createPublicShare(fileName: string) {
cy.intercept('POST', '/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createPublicShare')

showSidebarForFile(fileName)
cy.get('#app-sidebar-vue')
.findByRole('tab', { name: 'Sharing' })
Expand All @@ -59,9 +66,11 @@ export function createPublicShare(fileName: string) {
.should('be.visible')
.findByRole('button', { name: "Create a new share link" })
.click({ force: true })

cy.wait('@createShare')
closeSidebar()

cy.wait('@createPublicShare')
}

export function addTag(fileName: string, tag: string) {
Expand All @@ -76,7 +85,7 @@ export function addTag(fileName: string, tag: string) {
.should('be.visible')
.click()

cy.intercept('PUT', '**/remote.php/dav/systemtags-relations/files/**').as('tag')
cy.intercept('POST', '/remote.php/dav/systemtags').as('tag')

cy.findByLabelText('Search or create collaborative tags')
.type(`${tag}{enter}{esc}`)
Expand Down
3 changes: 2 additions & 1 deletion cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"types": [
"cypress",
"dockerode",
"node"
"node",
"@testing-library/cypress"
]
}
}
Loading