diff options
-rw-r--r-- | cypress/e2e/files/FilesUtils.ts | 83 | ||||
-rw-r--r-- | cypress/e2e/files/files-actions.cy.ts | 18 | ||||
-rw-r--r-- | cypress/e2e/files/files-renaming.cy.ts | 9 | ||||
-rw-r--r-- | cypress/e2e/files_external/files-user-credentials.cy.ts | 11 | ||||
-rw-r--r-- | cypress/e2e/files_sharing/FilesSharingUtils.ts | 4 | ||||
-rw-r--r-- | cypress/e2e/files_sharing/files-download.cy.ts | 27 | ||||
-rw-r--r-- | cypress/e2e/files_sharing/note-to-recipient.cy.ts | 2 | ||||
-rw-r--r-- | cypress/e2e/files_sharing/share-status-action.cy.ts | 15 |
8 files changed, 96 insertions, 73 deletions
diff --git a/cypress/e2e/files/FilesUtils.ts b/cypress/e2e/files/FilesUtils.ts index b138d161600..71ea341a7bf 100644 --- a/cypress/e2e/files/FilesUtils.ts +++ b/cypress/e2e/files/FilesUtils.ts @@ -15,65 +15,63 @@ export const getActionsForFile = (filename: string) => getRowForFile(filename).f export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: '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.$()) - } +export const getActionEntryForFileId = (fileid: number, actionId: string) => { + return getActionButtonForFileId(fileid) + .should('have.attr', 'aria-controls') + .then((menuId) => cy.get(`#${menuId}`).find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)) +} - // 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 = (file: string, actionId: string) => { + return getActionButtonForFile(file) + .should('have.attr', 'aria-controls') + .then((menuId) => cy.get(`#${menuId}`).find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)) } -export const getActionEntryForFileId = (fileid: number, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => { - // If we cannot find the action in the row, it might be in the action menu - return getRowForFileId(fileid).should('be.visible') - .then((row) => searchForActionInRow(row, actionId)) +export const getInlineActionEntryForFileId = (fileid: number, actionId: string) => { + return getActionsForFileId(fileid) + .find(`[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 getInlineActionEntryForFile = (file: string, actionId: string) => { + return getActionsForFile(file) + .find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`) } export const triggerActionForFileId = (fileid: number, actionId: string) => { - // Even if it's inline, we open the action menu to get all actions visible - getActionButtonForFileId(fileid).click({ force: true }) - // wait for the actions menu to be visible - cy.findByRole('menu').findAllByRole('menuitem').first().should('be.visible') - getActionEntryForFileId(fileid, actionId) - .find('button').last().as('actionButton') + getActionButtonForFileId(fileid) + .as('actionButton') .scrollIntoView() cy.get('@actionButton') + .click({ force: true }) // force to avoid issues with overlaying file list header + getActionEntryForFileId(fileid, actionId) + .find('button') .should('be.visible') - .click({ force: true }) + .click() } + 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 }) - // wait for the actions menu to be visible - cy.findByRole('menu').findAllByRole('menuitem').first().should('be.visible') - getActionEntryForFile(filename, actionId) - .find('button').last().as('actionButton') + getActionButtonForFile(filename) + .as('actionButton') .scrollIntoView() cy.get('@actionButton') + .click({ force: true }) // force to avoid issues with overlaying file list header + getActionEntryForFile(filename, actionId) + .find('button') .should('be.visible') - .click({ force: true }) + .click() } export const triggerInlineActionForFileId = (fileid: number, actionId: string) => { - getActionsForFileId(fileid).find(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`).should('exist').click() + 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).find(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`).should('exist').click() + getActionsForFile(filename) + .find(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`) + .should('exist') + .click() } export const selectAllFiles = () => { @@ -176,12 +174,17 @@ export const copyFile = (fileName: string, dirPath: string) => { export const renameFile = (fileName: string, newFileName: string) => { getRowForFile(fileName) + .should('exist') + .scrollIntoView() + 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').type(`{selectAll}${newFileName}{enter}`) + getRowForFile(fileName) + .find('[data-cy-files-list-row-name] input') + .type(`{selectAll}${newFileName}{enter}`) cy.wait('@moveFile') } diff --git a/cypress/e2e/files/files-actions.cy.ts b/cypress/e2e/files/files-actions.cy.ts index a7febbda45a..dbcf810e2a2 100644 --- a/cypress/e2e/files/files-actions.cy.ts +++ b/cypress/e2e/files/files-actions.cy.ts @@ -10,7 +10,6 @@ import { getActionButtonForFileId, getActionEntryForFileId, getRowForFile, getSe 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 { @@ -24,7 +23,6 @@ const expectedDefaultActionsIDs = [ ACTION_COPY_MOVE, ACTION_DELETE, ACTION_DETAILS, - ACTION_SHARING_STATUS, ] const expectedDefaultSelectionActionsIDs = [ ACTION_COPY_MOVE, @@ -90,11 +88,13 @@ describe('Files: Actions', { testIsolation: true }, () => { win._nc_fileactions.push(parent) win._nc_fileactions.push(child1) win._nc_fileactions.push(child2) - } + }, }) // Open the menu - getActionButtonForFileId(fileId).click({ force: true }) + getActionButtonForFileId(fileId) + .scrollIntoView() + .click({ force: true }) // Check we have the parent action but not the children getActionEntryForFileId(fileId, 'nested-action').should('be.visible') @@ -104,8 +104,8 @@ describe('Files: Actions', { testIsolation: true }, () => { // Click on the parent action getActionEntryForFileId(fileId, 'nested-action') - .find('button').last() - .should('exist').click({ force: true }) + .should('be.visible') + .click() // Check we have the children and the back button but not the parent getActionEntryForFileId(fileId, 'nested-action').should('not.exist') @@ -115,8 +115,8 @@ describe('Files: Actions', { testIsolation: true }, () => { // Click on the back button getActionEntryForFileId(fileId, 'menu-back') - .find('button').last() - .should('exist').click({ force: true }) + .should('be.visible') + .click() // Check we have the parent action but not the children getActionEntryForFileId(fileId, 'nested-action').should('be.visible') @@ -177,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-renaming.cy.ts b/cypress/e2e/files/files-renaming.cy.ts index d377417de7b..ac1edb1e104 100644 --- a/cypress/e2e/files/files-renaming.cy.ts +++ b/cypress/e2e/files/files-renaming.cy.ts @@ -181,13 +181,16 @@ describe('files: Rename nodes', { testIsolation: true }, () => { cy.visit('/apps/files') - getRowForFile('file.txt').should('be.visible') + getRowForFile('file.txt') + .should('be.visible') // Z so it is shown last renameFile('file.txt', 'zzz.txt') // not visible any longer - getRowForFile('zzz.txt').should('not.exist') + getRowForFile('zzz.txt') + .should('not.exist') // scroll file list to bottom - cy.get('[data-cy-files-list]').scrollTo('bottom') + cy.get('[data-cy-files-list]') + .scrollTo('bottom') cy.screenshot() // The file is no longer in rename state getRowForFile('zzz.txt') diff --git a/cypress/e2e/files_external/files-user-credentials.cy.ts b/cypress/e2e/files_external/files-user-credentials.cy.ts index a0cd805312c..b20b06b69ba 100644 --- a/cypress/e2e/files_external/files-user-credentials.cy.ts +++ b/cypress/e2e/files_external/files-user-credentials.cy.ts @@ -5,7 +5,7 @@ import { User } from '@nextcloud/cypress' import { AuthBackend, createStorageWithConfig, StorageBackend } from './StorageUtils' -import { getActionEntryForFile, getRowForFile, navigateToFolder, triggerInlineActionForFile } from '../files/FilesUtils' +import { getInlineActionEntryForFile, getRowForFile, navigateToFolder, triggerInlineActionForFile } from '../files/FilesUtils' import { ACTION_CREDENTIALS_EXTERNAL_STORAGE } from '../../../apps/files_external/src/actions/enterCredentialsAction' import { handlePasswordConfirmation } from '../settings/usersUtils' @@ -72,7 +72,8 @@ describe('Files user credentials', { testIsolation: true }, () => { // Auth dialog should be closed and the set credentials button should be gone cy.get('@authDialog').should('not.exist', { timeout: 2000 }) - getActionEntryForFile(storageUser.userId, ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') + getInlineActionEntryForFile(storageUser.userId, ACTION_CREDENTIALS_EXTERNAL_STORAGE) + .should('not.exist') // Finally, the storage should be accessible cy.visit('/apps/files') @@ -112,7 +113,7 @@ describe('Files user credentials', { testIsolation: true }, () => { // Auth dialog should be closed and the set credentials button should be gone cy.get('@authDialog').should('not.exist', { timeout: 2000 }) - getActionEntryForFile('storage1', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') + getInlineActionEntryForFile('storage1', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') // Finally, the storage should be accessible cy.visit('/apps/files') @@ -131,8 +132,8 @@ describe('Files user credentials', { testIsolation: true }, () => { getRowForFile('storage2').should('be.visible') // Since we already have set the credentials, the action should not be present - getActionEntryForFile('storage1', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') - getActionEntryForFile('storage2', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') + getInlineActionEntryForFile('storage1', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') + getInlineActionEntryForFile('storage2', ACTION_CREDENTIALS_EXTERNAL_STORAGE).should('not.exist') // Finally, the storage should be accessible cy.visit('/apps/files') diff --git a/cypress/e2e/files_sharing/FilesSharingUtils.ts b/cypress/e2e/files_sharing/FilesSharingUtils.ts index d63e46914c7..c9b30bd576c 100644 --- a/cypress/e2e/files_sharing/FilesSharingUtils.ts +++ b/cypress/e2e/files_sharing/FilesSharingUtils.ts @@ -125,8 +125,8 @@ export function updateShare(fileName: string, index: number, shareSettings: Part export function openSharingPanel(fileName: string) { triggerActionForFile(fileName, 'details') - cy.get('#app-sidebar-vue') - .get('[aria-controls="tab-sharing"]') + cy.get('[data-cy-sidebar]') + .find('[aria-controls="tab-sharing"]') .click() } diff --git a/cypress/e2e/files_sharing/files-download.cy.ts b/cypress/e2e/files_sharing/files-download.cy.ts index ce310933ff7..97ea91b7647 100644 --- a/cypress/e2e/files_sharing/files-download.cy.ts +++ b/cypress/e2e/files_sharing/files-download.cy.ts @@ -5,6 +5,7 @@ import type { User } from '@nextcloud/cypress' import { createShare } from './FilesSharingUtils.ts' import { + getActionButtonForFile, getActionEntryForFile, getRowForFile, } from '../files/FilesUtils.ts' @@ -41,8 +42,13 @@ describe('files_sharing: Download forbidden', { testIsolation: true }, () => { // visit shared files view cy.visit('/apps/files') // see the shared folder - getRowForFile('folder').should('be.visible') - getActionEntryForFile('folder', 'download').should('not.exist') + getActionButtonForFile('folder') + .should('be.visible') + // open the action menu + .click({ force: true }) + // see no download action + getActionEntryForFile('folder', 'download') + .should('not.exist') // Disable view without download option cy.runOccCommand('config:app:set --value no core shareapi_allow_view_without_download') @@ -51,6 +57,10 @@ describe('files_sharing: Download forbidden', { testIsolation: true }, () => { cy.visit('/apps/files') // see the shared folder getRowForFile('folder').should('be.visible') + getActionButtonForFile('folder') + .should('be.visible') + // open the action menu + .click({ force: true }) getActionEntryForFile('folder', 'download').should('not.exist') }) @@ -68,8 +78,13 @@ describe('files_sharing: Download forbidden', { testIsolation: true }, () => { // visit shared files view cy.visit('/apps/files') // see the shared folder - getRowForFile('file.txt').should('be.visible') - getActionEntryForFile('file.txt', 'download').should('not.exist') + getActionButtonForFile('file.txt') + .should('be.visible') + // open the action menu + .click({ force: true }) + // see no download action + getActionEntryForFile('file.txt', 'download') + .should('not.exist') // Disable view without download option cy.runOccCommand('config:app:set --value no core shareapi_allow_view_without_download') @@ -78,6 +93,10 @@ describe('files_sharing: Download forbidden', { testIsolation: true }, () => { cy.visit('/apps/files') // see the shared folder getRowForFile('file.txt').should('be.visible') + getActionButtonForFile('file.txt') + .should('be.visible') + // open the action menu + .click({ force: true }) getActionEntryForFile('file.txt', 'download').should('not.exist') }) }) diff --git a/cypress/e2e/files_sharing/note-to-recipient.cy.ts b/cypress/e2e/files_sharing/note-to-recipient.cy.ts index 8bca696e95c..08fee587d9a 100644 --- a/cypress/e2e/files_sharing/note-to-recipient.cy.ts +++ b/cypress/e2e/files_sharing/note-to-recipient.cy.ts @@ -72,7 +72,7 @@ describe('files_sharing: Note to recipient', { testIsolation: true }, () => { createShare('folder', sharee.userId, { read: true, download: true, note: 'Hello, this is the note.' }) // reload just to be sure - cy.reload() + cy.visit('/apps/files') // open the sharing tab openSharingPanel('folder') diff --git a/cypress/e2e/files_sharing/share-status-action.cy.ts b/cypress/e2e/files_sharing/share-status-action.cy.ts index 1b88810047a..c88f117ddc8 100644 --- a/cypress/e2e/files_sharing/share-status-action.cy.ts +++ b/cypress/e2e/files_sharing/share-status-action.cy.ts @@ -4,7 +4,7 @@ */ import type { User } from '@nextcloud/cypress' import { createShare } from './FilesSharingUtils.ts' -import { closeSidebar, enableGridMode, getActionButtonForFile, getRowForFile } from '../files/FilesUtils.ts' +import { closeSidebar, enableGridMode, getActionButtonForFile, getInlineActionEntryForFile, getRowForFile } from '../files/FilesUtils.ts' describe('files_sharing: Sharing status action', { testIsolation: true }, () => { /** @@ -78,10 +78,9 @@ describe('files_sharing: Sharing status action', { testIsolation: true }, () => cy.login(user) cy.visit('/apps/files') - getRowForFile('folder') - .should('be.visible') - .find('[data-cy-files-list-row-actions]') - .findByRole('button', { name: /^Shared with/i }) + getInlineActionEntryForFile('folder', 'sharing-status') + .should('have.attr', 'aria-label', `Shared with ${sharee.userId}`) + .should('have.attr', 'title', `Shared with ${sharee.userId}`) .should('be.visible') }) @@ -103,10 +102,8 @@ describe('files_sharing: Sharing status action', { testIsolation: true }, () => cy.login(sharee) cy.visit('/apps/files') - getRowForFile('folder') - .should('be.visible') - .find('[data-cy-files-list-row-actions]') - .findByRole('button', { name: `Shared by ${user.userId}` }) + getInlineActionEntryForFile('folder', 'sharing-status') + .should('have.attr', 'aria-label', `Shared by ${user.userId}`) .should('be.visible') }) |