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
119 changes: 99 additions & 20 deletions cypress/e2e/filesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,120 @@
*
*/

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)
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="${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)
cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="move-copy"]`).click()
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')
})
}

export function toggleMenuAction(fileName: string) {
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${fileName}"] [data-cy-files-list-row-actions] .action-item__menutoggle`).click()
cy.get('[data-cy-files-list-row-action]').should('be.visible')
cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${CSS.escape(fileName)}"] [data-cy-files-list-row-actions]`)
.should('be.visible')
.findByRole('button', { name: 'Actions' })
.should('be.visible')
.click()
cy.get('[data-cy-files-list-row-action]')
.should('be.visible')
}
9 changes: 4 additions & 5 deletions cypress/e2e/sidebar.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
*/

import { createFolder, goToDir, moveFile, renameFile } from './filesUtils'
import { createFolder, moveFile, navigateToFolder, renameFile } from './filesUtils'
import { addComment, addTag, addToFavorites, createPublicShare, removeFromFavorites, showActivityTab } from './sidebarUtils'

describe('Check activity listing in the sidebar', { testIsolation: true }, () => {
Expand Down Expand Up @@ -56,8 +56,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 @@ -66,8 +66,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
48 changes: 38 additions & 10 deletions cypress/e2e/sidebarUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,31 @@ import { toggleMenuAction } from './filesUtils'
function showSidebarForFile(fileName: string) {
closeSidebar()
toggleMenuAction(fileName)
cy.get('[data-cy-files-list-row-action="details"] button').click()
cy.get('[data-cy-files-list-row-action="details"]')
.should('be.visible')
.findByRole('menuitem')
.click()
cy.get('#app-sidebar-vue').should('be.visible')
}

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').contains('Activity').click()

cy.wait('@getActivities')
}

export function addToFavorites(fileName: string) {
Expand All @@ -62,30 +70,50 @@ export function removeFromFavorites(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').contains('Sharing').click()

cy.get('#app-sidebar-vue #tab-sharing').should('be.visible')
cy.get('#app-sidebar-vue button.new-share-link').click({ force: true })
cy.get('#app-sidebar-vue .sharing-entry__copy').should('be.visible')
closeSidebar()

cy.wait('@createPublicShare')
}

export function addTag(fileName: string, tag: string) {
showSidebarForFile(fileName)

cy.get('.app-sidebar-header__menu button').click()
cy.get('.action-button__icon.icon-tag').click()
cy.get('.system-tags input').type(`${tag}{enter}{esc}`)
cy.get('#app-sidebar-vue .app-sidebar-header')
.should('be.visible')
.findByRole('button', { name: 'Actions' })
.click()

cy.findByRole('menuitem', { name: 'Tags' })
.should('be.visible')
.click()

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

cy.findByLabelText('Search or create collaborative tags')
.type(`${tag}{enter}{esc}`)

cy.wait('@tag')
}

export function addComment(fileName: string, comment: string) {
showSidebarForFile(fileName)
cy.get('#app-sidebar-vue').contains('Activity').click()
cy.get('.comment__editor .rich-contenteditable__input').type(comment)
cy.get('.comment__submit button').click()
cy.get('#app-sidebar-vue')
.findByRole('tab', { name: 'Activity' })
.click()

cy.intercept('POST', '**/remote.php/dav/comments/files/*').as('comment')
cy.get('#app-sidebar-vue')
.findByRole('textbox', { name: 'New comment' })
.should('be.visible')
.type(`{selectAll}${comment}{enter}`)

cy.wait(500)
cy.wait('@comment')
}
2 changes: 2 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
/* eslint-disable n/no-unpublished-import */
import { addCommands } from '@nextcloud/cypress'

import '@testing-library/cypress/add-commands'

// Add custom commands
import 'cypress-wait-until'
addCommands()
4 changes: 3 additions & 1 deletion cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"include": ["./**/*.ts"],
"compilerOptions": {
"types": [
"@testing-library/cypress",
"cypress",
"dockerode",
"node"
"node",
"@testing-library/cypress"
]
}
}
Loading
Loading