From 6e4dcc6ce041dfb8d55d4c63e5c4597d5be160b4 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 22 Jan 2026 12:21:42 +0100 Subject: [PATCH] test: adjust Cypress tests for refactored files app UI Signed-off-by: Ferdinand Thiessen --- cypress/e2e/files/FilesUtils.ts | 20 ++- cypress/e2e/files/drag-n-drop.cy.ts | 8 ++ cypress/e2e/files/files-filtering.cy.ts | 118 +++++++++--------- cypress/e2e/files/files-settings.cy.ts | 18 ++- cypress/e2e/files/live_photos.cy.ts | 20 +-- cypress/e2e/files/search.cy.ts | 12 +- .../e2e/systemtags/files-bulk-action.cy.ts | 96 +++++++------- cypress/pages/FilesFilters.ts | 58 ++++++++- 8 files changed, 209 insertions(+), 141 deletions(-) diff --git a/cypress/e2e/files/FilesUtils.ts b/cypress/e2e/files/FilesUtils.ts index 6e3fdc5d055..9ae1ee31f35 100644 --- a/cypress/e2e/files/FilesUtils.ts +++ b/cypress/e2e/files/FilesUtils.ts @@ -162,7 +162,7 @@ export function triggerSelectionAction(actionId: string) { getSelectionActionButton().click({ force: true }) // the entry might already be a button or a button might its child getSelectionActionEntry(actionId) - .then(($el) => $el.is('button') ? cy.wrap($el) : cy.wrap($el).findByRole('button').last()) + .then(($el) => $el.is('button') ? cy.wrap($el) : cy.wrap($el).findByRole('menuitem').last()) .should('exist') .click() } @@ -384,12 +384,24 @@ export function triggerFileListAction(actionId: string) { } /** + * Reloads the current folder * + * @param intercept if true this will wait for the PROPFIND to complete before it resolves */ -export function reloadCurrentFolder() { +export function reloadCurrentFolder(intercept = true) { cy.intercept('PROPFIND', /\/remote.php\/dav\//).as('propfind') - cy.get('[data-cy-files-content-breadcrumbs]').findByRole('button', { description: 'Reload current directory' }).click() - cy.wait('@propfind') + cy.findByRole('navigation', { name: 'Current directory path' }) + .findAllByRole('button') + .filter('[aria-haspopup="menu"]') + .click() + cy.findByRole('menu') + .should('be.visible') + .findByRole('menuitem', { name: 'Reload content' }) + .click() + + if (intercept) { + cy.wait('@propfind') + } } /** diff --git a/cypress/e2e/files/drag-n-drop.cy.ts b/cypress/e2e/files/drag-n-drop.cy.ts index d8df1938694..b57390edb34 100644 --- a/cypress/e2e/files/drag-n-drop.cy.ts +++ b/cypress/e2e/files/drag-n-drop.cy.ts @@ -132,6 +132,14 @@ describe('files: Drag and Drop', { testIsolation: true }, () => { cy.get('[data-cy-upload-picker] progress').should('not.be.visible') cy.get('@uploadFile.all').should('have.length', 2) + // see the warning + cy.get('.toast-warning').should('exist') + + // close all toasts + cy.get('.toastify') + .findAllByRole('button', { name: 'Close' }) + .click({ multiple: true }) + getRowForFile('first.txt').should('be.visible') getRowForFile('second.txt').should('be.visible') getRowForFile('Foo').should('not.exist') diff --git a/cypress/e2e/files/files-filtering.cy.ts b/cypress/e2e/files/files-filtering.cy.ts index 5c6ff159347..0b6397a2b73 100644 --- a/cypress/e2e/files/files-filtering.cy.ts +++ b/cypress/e2e/files/files-filtering.cy.ts @@ -69,17 +69,17 @@ describe('files: Filter in files list', { testIsolation: true }, () => { getRowForFile('file.txt').should('be.visible') getRowForFile('spreadsheet.csv').should('be.visible') - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .should('be.visible') - .click() - cy.findByRole('menuitemcheckbox', { name: 'Spreadsheets' }) - .should('be.visible') - .click() - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Spreadsheets' }) .should('be.visible') + .and('have.attr', 'aria-pressed', 'false') + .as('spreadsheetsFilterButton') .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() // See that only the spreadsheet is visible getRowForFile('spreadsheet.csv').should('be.visible') @@ -91,33 +91,32 @@ describe('files: Filter in files list', { testIsolation: true }, () => { // All are visible by default getRowForFile('folder').should('be.visible') - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .should('be.visible') - .click() - cy.findByRole('menuitemcheckbox', { name: 'Spreadsheets' }) - .should('be.visible') - .click() - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Spreadsheets' }) .should('be.visible') + .as('spreadsheetsFilterButton') .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() // See folder is not visible getRowForFile('folder').should('not.exist') // clear filter - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .should('be.visible') - .click() - cy.findByRole('menuitem', { name: /clear filter/i }) - .should('be.visible') - .click() - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Spreadsheets' }) .should('be.visible') + .and('have.attr', 'aria-pressed', 'true') + .as('spreadsheetsFilterButton') .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'false') + + filesFilters.closeFilterMenu() // See folder is visible again getRowForFile('folder').should('be.visible') @@ -127,17 +126,16 @@ describe('files: Filter in files list', { testIsolation: true }, () => { // All are visible by default getRowForFile('folder').should('be.visible') - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .should('be.visible') - .click() - cy.findByRole('menuitemcheckbox', { name: 'Spreadsheets' }) - .should('be.visible') - .click() - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Spreadsheets' }) .should('be.visible') + .as('spreadsheetsFilterButton') .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() // See folder is not visible getRowForFile('folder').should('not.exist') @@ -154,16 +152,16 @@ describe('files: Filter in files list', { testIsolation: true }, () => { getRowForFile('folder').should('be.visible') getRowForFile('file.txt').should('be.visible') - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Folders' }) .should('be.visible') + .as('spreadsheetsFilterButton') .click() - cy.findByRole('menuitemcheckbox', { name: 'Folders' }) - .should('be.visible') - .click() - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() // See that only the folder is visible getRowForFile('folder').should('be.visible') @@ -189,20 +187,16 @@ describe('files: Filter in files list', { testIsolation: true }, () => { getRowForFile('file.txt').should('be.visible') // enable type filter for folders - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Folders' }) .should('be.visible') + .as('spreadsheetsFilterButton') .click() - cy.findByRole('menuitemcheckbox', { name: 'Folders' }) - .should('be.visible') - .click() - // assert the button is checked - cy.findByRole('menuitemcheckbox', { name: 'Folders' }) - .should('have.attr', 'aria-checked', 'true') - // close the menu - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) - .click() + cy.get('@spreadsheetsFilterButton') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() // See the chips are active filesFilters.activeFilters() @@ -222,13 +216,13 @@ describe('files: Filter in files list', { testIsolation: true }, () => { .should('have.length', 1) .contains(/Folder/).should('be.visible') // And also the button should be active - filesFilters.filterContainter() - .findByRole('button', { name: 'Type' }) + filesFilters.triggerFilter('Type') + + cy.findByRole('button', { name: 'Folders' }) .should('be.visible') - .click() - cy.findByRole('menuitemcheckbox', { name: 'Folders' }) - .should('be.visible') - .and('have.attr', 'aria-checked', 'true') + .should('have.attr', 'aria-pressed', 'true') + + filesFilters.closeFilterMenu() }) /** Regression test of https://github.com/nextcloud/server/issues/53038 */ diff --git a/cypress/e2e/files/files-settings.cy.ts b/cypress/e2e/files/files-settings.cy.ts index e03283c3f49..299609e9d69 100644 --- a/cypress/e2e/files/files-settings.cy.ts +++ b/cypress/e2e/files/files-settings.cy.ts @@ -19,11 +19,10 @@ describe('files: Set default view', { testIsolation: true }, () => { // See URL and current view cy.url().should('match', /\/apps\/files\/files/) - cy.get('[data-cy-files-content-breadcrumbs]') - .findByRole('button', { - name: 'All files', - description: 'Reload current directory', - }) + cy.findByRole('navigation', { name: 'Current directory path' }) + .findAllByRole('button') + .first() + .should('have.text', 'All files') // See the option is also selected // Open the files settings @@ -54,11 +53,10 @@ describe('files: Set default view', { testIsolation: true }, () => { cy.visit('/apps/files') cy.url().should('match', /\/apps\/files\/personal/) - cy.get('[data-cy-files-content-breadcrumbs]') - .findByRole('button', { - name: 'Personal files', - description: 'Reload current directory', - }) + cy.findByRole('navigation', { name: 'Current directory path' }) + .findAllByRole('button') + .first() + .should('have.text', 'Personal files') }) }) diff --git a/cypress/e2e/files/live_photos.cy.ts b/cypress/e2e/files/live_photos.cy.ts index 2e2d19f9985..b8514de4bc1 100644 --- a/cypress/e2e/files/live_photos.cy.ts +++ b/cypress/e2e/files/live_photos.cy.ts @@ -6,13 +6,13 @@ import type { User } from '@nextcloud/e2e-test-server/cypress' import { - clickOnBreadcrumbs, copyFile, createFolder, getRowForFile, getRowForFileId, moveFile, navigateToFolder, + reloadCurrentFolder, renameFile, triggerActionForFile, triggerInlineActionForFileId, @@ -52,7 +52,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Copies both files when copying the .jpg', () => { copyFile(`${randomFileName}.jpg`, '.') - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFile(`${randomFileName}.jpg`).should('have.length', 1) getRowForFile(`${randomFileName}.mov`).should('have.length', 1) @@ -62,7 +62,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Copies both files when copying the .mov', () => { copyFile(`${randomFileName}.mov`, '.') - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFile(`${randomFileName}.mov`).should('have.length', 1) getRowForFile(`${randomFileName} (copy).jpg`).should('have.length', 1) @@ -100,7 +100,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Moves files when moving the .jpg', () => { renameFile(`${randomFileName}.jpg`, `${randomFileName}_moved.jpg`) - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFileId(jpgFileId).invoke('attr', 'data-cy-files-list-row-name').should('equal', `${randomFileName}_moved.jpg`) getRowForFileId(movFileId).invoke('attr', 'data-cy-files-list-row-name').should('equal', `${randomFileName}_moved.mov`) @@ -108,7 +108,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Moves files when moving the .mov', () => { renameFile(`${randomFileName}.mov`, `${randomFileName}_moved.mov`) - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFileId(jpgFileId).invoke('attr', 'data-cy-files-list-row-name').should('equal', `${randomFileName}_moved.jpg`) getRowForFileId(movFileId).invoke('attr', 'data-cy-files-list-row-name').should('equal', `${randomFileName}_moved.mov`) @@ -116,7 +116,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Deletes files when deleting the .jpg', () => { triggerActionForFile(`${randomFileName}.jpg`, 'delete') - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFile(`${randomFileName}.jpg`).should('have.length', 0) getRowForFile(`${randomFileName}.mov`).should('have.length', 0) @@ -129,7 +129,7 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Block deletion when deleting the .mov', () => { triggerActionForFile(`${randomFileName}.mov`, 'delete') - clickOnBreadcrumbs('All files') + reloadCurrentFolder() getRowForFile(`${randomFileName}.jpg`).should('have.length', 1) getRowForFile(`${randomFileName}.mov`).should('have.length', 1) @@ -143,8 +143,9 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Restores files when restoring the .jpg', () => { triggerActionForFile(`${randomFileName}.jpg`, 'delete') cy.visit('/apps/files/trashbin') + triggerInlineActionForFileId(jpgFileId, 'restore') - clickOnBreadcrumbs('Deleted files') + reloadCurrentFolder() getRowForFile(`${randomFileName}.jpg`).should('have.length', 0) getRowForFile(`${randomFileName}.mov`).should('have.length', 0) @@ -158,8 +159,9 @@ describe('Files: Live photos', { testIsolation: true }, () => { it('Blocks restoration when restoring the .mov', () => { triggerActionForFile(`${randomFileName}.jpg`, 'delete') cy.visit('/apps/files/trashbin') + triggerInlineActionForFileId(movFileId, 'restore') - clickOnBreadcrumbs('Deleted files') + reloadCurrentFolder() getRowForFileId(jpgFileId).should('have.length', 1) getRowForFileId(movFileId).should('have.length', 1) diff --git a/cypress/e2e/files/search.cy.ts b/cypress/e2e/files/search.cy.ts index 96036d16640..2800a71a539 100644 --- a/cypress/e2e/files/search.cy.ts +++ b/cypress/e2e/files/search.cy.ts @@ -6,7 +6,7 @@ import type { User } from '@nextcloud/e2e-test-server/cypress' import { FilesNavigationPage } from '../../pages/FilesNavigation.ts' -import { getRowForFile, navigateToFolder } from './FilesUtils.ts' +import { getRowForFile, navigateToFolder, reloadCurrentFolder } from './FilesUtils.ts' describe('files: search', () => { let user: User @@ -74,7 +74,7 @@ describe('files: search', () => { it('See "search everywhere" button', () => { // Not visible initially - cy.get('[data-cy-files-filters]') + cy.get('.files-list__filters') .findByRole('button', { name: /Search everywhere/i }) .should('not.to.exist') @@ -82,7 +82,7 @@ describe('files: search', () => { navigation.searchInput().type('file') // see its visible - cy.get('[data-cy-files-filters]') + cy.get('.files-list__filters') .findByRole('button', { name: /Search everywhere/i }) .should('be.visible') @@ -90,7 +90,7 @@ describe('files: search', () => { navigation.searchClearButton().click() // see its not visible again - cy.get('[data-cy-files-filters]') + cy.get('.files-list__filters') .findByRole('button', { name: /Search everywhere/i }) .should('not.to.exist') }) @@ -108,7 +108,7 @@ describe('files: search', () => { cy.get('[data-cy-files-list-row-fileid]').should('have.length', 3) // toggle global search - cy.get('[data-cy-files-filters]') + cy.get('.files-list__filters') .findByRole('button', { name: /Search everywhere/i }) .should('be.visible') .click() @@ -206,7 +206,7 @@ describe('files: search', () => { cy.intercept('SEARCH', '**/remote.php/dav/').as('search') // refresh the view - cy.findByRole('button', { description: /reload current directory/i }).click() + reloadCurrentFolder(false) // no PROPFIND intercept here as we want to wait for SEARCH // wait for the request cy.wait('@search') // see that the search view is reloaded diff --git a/cypress/e2e/systemtags/files-bulk-action.cy.ts b/cypress/e2e/systemtags/files-bulk-action.cy.ts index 84119badbc4..491b551a09b 100644 --- a/cypress/e2e/systemtags/files-bulk-action.cy.ts +++ b/cypress/e2e/systemtags/files-bulk-action.cy.ts @@ -18,45 +18,6 @@ const files = [ 'file5.txt', ] -function resetTags() { - tags = {} - for (let i = 0; i < 5; i++) { - tags[randomBytes(8).toString('base64').slice(0, 6)] = 0 - } - - // delete any existing tags - cy.runOccCommand('tag:list --output=json').then((output) => { - Object.keys(JSON.parse(output.stdout)).forEach((id) => { - cy.runOccCommand(`tag:delete ${id}`) - }) - }) - - // create tags - Object.keys(tags).forEach((tag) => { - cy.runOccCommand(`tag:add ${tag} public --output=json`).then((output) => { - tags[tag] = JSON.parse(output.stdout).id as number - }) - }) - cy.log('Using tags', tags) -} - -function expectInlineTagForFile(file: string, tags: string[]) { - getRowForFile(file) - .find('[data-systemtags-fileid]') - .findAllByRole('listitem') - .should('have.length', tags.length) - .each((tag) => { - expect(tag.text()).to.be.oneOf(tags) - }) -} - -function triggerTagManagementDialogAction() { - cy.intercept('PROPFIND', '/remote.php/dav/systemtags/').as('getTagsList') - triggerSelectionAction('systemtags:bulk') - cy.wait('@getTagsList') - cy.get('[data-cy-systemtags-picker]').should('be.visible') -} - describe('Systemtags: Files bulk action', { testIsolation: false }, () => { let user1: User let user2: User @@ -98,7 +59,7 @@ describe('Systemtags: Files bulk action', { testIsolation: false }, () => { cy.intercept('PROPFIND', '/remote.php/dav/systemtags/*/files').as('getTagData') cy.intercept('PROPPATCH', '/remote.php/dav/systemtags/*/files').as('assignTagData') - const tag = Object.keys(tags)[3] + const tag = Object.keys(tags)[3]! cy.get(`[data-cy-systemtags-picker-tag=${tags[tag]}]`).should('be.visible') .findByRole('checkbox').click({ force: true }) cy.get('[data-cy-systemtags-picker-button-submit]').click() @@ -127,9 +88,9 @@ describe('Systemtags: Files bulk action', { testIsolation: false }, () => { cy.intercept('PROPFIND', '/remote.php/dav/systemtags/*/files').as('getTagData') cy.intercept('PROPPATCH', '/remote.php/dav/systemtags/*/files').as('assignTagData') - const prevTag = Object.keys(tags)[3] - const tag1 = Object.keys(tags)[1] - const tag2 = Object.keys(tags)[2] + const prevTag = Object.keys(tags)[3]! + const tag1 = Object.keys(tags)[1]! + const tag2 = Object.keys(tags)[2]! cy.get(`[data-cy-systemtags-picker-tag=${tags[tag1]}]`).should('be.visible') .findByRole('checkbox').click({ force: true }) cy.get(`[data-cy-systemtags-picker-tag=${tags[tag2]}]`).should('be.visible') @@ -166,9 +127,9 @@ describe('Systemtags: Files bulk action', { testIsolation: false }, () => { cy.intercept('PROPFIND', '/remote.php/dav/systemtags/*/files').as('getTagData') cy.intercept('PROPPATCH', '/remote.php/dav/systemtags/*/files').as('assignTagData') - const firstTag = Object.keys(tags)[3] - const tag1 = Object.keys(tags)[1] - const tag2 = Object.keys(tags)[2] + const firstTag = Object.keys(tags)[3]! + const tag1 = Object.keys(tags)[1]! + const tag2 = Object.keys(tags)[2]! cy.get(`[data-cy-systemtags-picker-tag=${tags[tag2]}]`).should('be.visible') .findByRole('checkbox').click({ force: true }) cy.get('[data-cy-systemtags-picker-button-submit]').click() @@ -247,8 +208,8 @@ describe('Systemtags: Files bulk action', { testIsolation: false }, () => { cy.intercept('PROPFIND', '/remote.php/dav/systemtags/*/files').as('getTagData1') cy.intercept('PROPPATCH', '/remote.php/dav/systemtags/*/files').as('assignTagData1') - const tag1 = Object.keys(tags)[0] - const tag2 = Object.keys(tags)[3] + const tag1 = Object.keys(tags)[0]! + const tag2 = Object.keys(tags)[3]! cy.get(`[data-cy-systemtags-picker-tag=${tags[tag1]}]`).should('be.visible') .findByRole('checkbox').click({ force: true }) cy.get(`[data-cy-systemtags-picker-tag=${tags[tag2]}]`).should('be.visible') @@ -466,3 +427,42 @@ describe('Systemtags: Files bulk action', { testIsolation: false }, () => { }) }) }) + +function resetTags() { + tags = {} + for (let i = 0; i < 5; i++) { + tags[randomBytes(8).toString('base64').slice(0, 6)] = 0 + } + + // delete any existing tags + cy.runOccCommand('tag:list --output=json').then((output) => { + Object.keys(JSON.parse(output.stdout)).forEach((id) => { + cy.runOccCommand(`tag:delete ${id}`) + }) + }) + + // create tags + Object.keys(tags).forEach((tag) => { + cy.runOccCommand(`tag:add ${tag} public --output=json`).then((output) => { + tags[tag] = JSON.parse(output.stdout).id as number + }) + }) + cy.log('Using tags', tags) +} + +function expectInlineTagForFile(file: string, tags: string[]) { + getRowForFile(file) + .find('[data-systemtags-fileid]') + .findAllByRole('listitem') + .should('have.length', tags.length) + .each((tag) => { + expect(tag.text()).to.be.oneOf(tags) + }) +} + +function triggerTagManagementDialogAction() { + cy.intercept('PROPFIND', '/remote.php/dav/systemtags/').as('getTagsList') + triggerSelectionAction('systemtags:bulk') + cy.wait('@getTagsList') + cy.get('[data-cy-systemtags-picker]').should('be.visible') +} diff --git a/cypress/pages/FilesFilters.ts b/cypress/pages/FilesFilters.ts index ecefba40fe7..9a10f39a5dc 100644 --- a/cypress/pages/FilesFilters.ts +++ b/cypress/pages/FilesFilters.ts @@ -7,8 +7,62 @@ * Page object model for the files filters */ export class FilesFilterPage { - filterContainter() { - return cy.get('[data-cy-files-filters]') + /** + * Get the filters menu button (only on narrow and medium widths) + */ + getFiltersMenuToggle() { + return cy.get('[data-test-id="files-list-filters"]') + .findByRole('button', { name: 'Filters' }) + } + + /** + * Get and trigger the filter within the menu (only on narrow and medium widths) + * + * @param name - The name of the filter button + */ + triggerFilterMenu(name: string | RegExp) { + cy.get('[data-test-id="files-list-filters"]') + .findByRole('button', { name: 'Filters' }) + .should('be.visible') + .as('filtersMenuToggle') + .click() + + cy.get('@filtersMenuToggle') + .should('have.attr', 'aria-expanded', 'true') + + cy.findByRole('menu') + .should('be.visible') + .findByRole('menuitem', { name }) + .should('be.visible') + .click() + } + + /** + * Get and trigger the filter button if the files list is wide enough to show all filters + * + * @param name - The name of the filter button + */ + triggerFilterButton(name: string | RegExp) { + cy.get('[data-test-id="files-list-filters"]') + .findByRole('button', { name }) + .should('be.visible') + .click() + } + + triggerFilter(name: string | RegExp) { + cy.get('[data-cy-files-list]') + .should('be.visible') + .if(($el) => expect($el.get(0).clientWidth).to.be.gte(1024)) + .then(() => this.triggerFilterButton(name)) + .else() + .then(() => this.triggerFilterMenu(name)) + } + + closeFilterMenu() { + cy.get('[data-test-id="files-list-filters"]') + .findAllByRole('button') + .filter('[aria-expanded="true"]') + .click({ multiple: true }) } activeFiltersList() {