diff --git a/cypress.config.ts b/cypress.config.ts index 59a3ff301..0705584f5 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -10,8 +10,8 @@ export default defineConfig({ projectId: 'xcmgay', // 16/9 screen ratio - viewportWidth: 1280, - viewportHeight: 720, + viewportWidth: 1920, + viewportHeight: 1080, // Tries again 2 more times on failure retries: { diff --git a/cypress/e2e/encryption.cy.ts b/cypress/e2e/encryption.cy.ts index 478279603..748719dcb 100644 --- a/cypress/e2e/encryption.cy.ts +++ b/cypress/e2e/encryption.cy.ts @@ -22,15 +22,20 @@ import { PERMISSION_WRITE, } from './groupfoldersUtils' -import { - assertFileContent, - moveFile, -} from './files/filesUtils' +import { getRowForFile, moveFile, triggerActionForFile } from './files/filesUtils' import { randHash } from '../utils' import type { User } from '@nextcloud/cypress' +export const assertFileContent = (fileName: string, expectedContent: string) => { + cy.intercept({ method: 'GET', times: 1, url: 'remote.php/**' }).as('downloadFile') + getRowForFile(fileName).should('be.visible') + triggerActionForFile(fileName, 'download') + cy.wait('@downloadFile') + .then(({ response }) => expect(response?.body).to.equal(expectedContent)) +} + describe('Groupfolders encryption behavior', () => { let user1: User let groupFolderId: string diff --git a/cypress/e2e/files/filesUtils.ts b/cypress/e2e/files/filesUtils.ts index 2ea28a8c5..98fc45ee0 100644 --- a/cypress/e2e/files/filesUtils.ts +++ b/cypress/e2e/files/filesUtils.ts @@ -3,15 +3,61 @@ * 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 getActionButtonForFile = (filename: string) => getActionsForFile(filename).find('button[aria-label="Actions"]') +export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' }) +export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' }) +export const triggerActionForFileId = (fileid: number, actionId: string) => { + getActionButtonForFileId(fileid).click() + // Getting the last button to avoid the one from popup fading out + cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).last() + .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() + // Getting the last button to avoid the one from popup fading out + cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"] > button`).last() + .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 selectAllFiles = () => { + cy.get('[data-cy-files-list-selection-checkbox]') + .findByRole('checkbox', { checked: false }) + .click({ force: true }) +} +export const deselectAllFiles = () => { + cy.get('[data-cy-files-list-selection-checkbox]') + .findByRole('checkbox', { checked: true }) + .click({ force: true }) +} + +export const selectRowForFile = (filename: string, options: Partial = {}) => { + getRowForFile(filename) + .find('[data-cy-files-list-row-checkbox]') + .findByRole('checkbox') + // don't use click to avoid triggering side effects events + .trigger('change', { ...options, force: true }) + .should('be.checked') + cy.get('[data-cy-files-list-selection-checkbox]').findByRole('checkbox').should('satisfy', (elements) => { + return elements.length === 1 && (elements[0].checked === true || elements[0].indeterminate === true) + }) + +} + +export const triggerSelectionAction = (actionId: string) => { + cy.get(`button[data-cy-files-list-selection-action="${CSS.escape(actionId)}"]`).should('exist').click() } export const moveFile = (fileName: string, dirPath: string) => { @@ -20,7 +66,7 @@ export const moveFile = (fileName: string, dirPath: string) => { cy.get('.file-picker').within(() => { // intercept the copy so we can wait for it - cy.intercept({ method: 'MOVE', times: 1, url: /\/remote.php\/dav\/files\// }).as('moveFile') + cy.intercept('MOVE', /\/(remote|public)\.php\/dav\/files\//).as('moveFile') if (dirPath === '/') { // select home folder @@ -51,7 +97,7 @@ export const copyFile = (fileName: string, dirPath: string) => { cy.get('.file-picker').within(() => { // intercept the copy so we can wait for it - cy.intercept({ method: 'COPY', times: 1, url: /\/remote.php\/dav\/files\// }).as('copyFile') + cy.intercept('COPY', /\/(remote|public)\.php\/dav\/files\//).as('copyFile') if (dirPath === '/') { // select home folder @@ -65,7 +111,7 @@ export const copyFile = (fileName: string, dirPath: string) => { const directories = dirPath.split('/') directories.forEach((directory) => { // select the folder - cy.get(`[data-filename="${directory}"]`).should('be.visible').click() + cy.get(`[data-filename="${CSS.escape(directory)}"]`).should('be.visible').click() }) // click copy @@ -76,10 +122,23 @@ export const copyFile = (fileName: string, dirPath: string) => { }) } +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|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(`${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() + getRowForFile(directory).should('be.visible').find('[data-cy-files-list-row-name-link]').click({ force: true}) }) } @@ -89,16 +148,39 @@ export const closeSidebar = () => { cy.get('[data-cy-sidebar] .app-sidebar__close').click({ force: true }) } -export const clickOnBreadcumbs = (label: string) => { - cy.intercept({ method: 'PROPFIND', url: /\/remote.php\/dav\// }).as('propfind') +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 assertFileContent = (fileName: string, expectedContent: string) => { - cy.intercept({ method: 'GET', times: 1, url: 'remote.php/**' }).as('downloadFile') - getRowForFile(fileName).should('be.visible') - triggerActionForFile(fileName, 'download') - cy.wait('@downloadFile') - .then(({ response }) => expect(response?.body).to.equal(expectedContent)) +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') +} + +/** + * Check validity of an input element + * @param validity The expected validity message (empty string means it is valid) + * @example + * ```js + * cy.findByRole('textbox') + * .should(haveValidity(/must not be empty/i)) + * ``` + */ +export const haveValidity = (validity: string | RegExp) => { + if (typeof validity === 'string') { + return (el: JQuery) => expect((el.get(0) as HTMLInputElement).validationMessage).to.equal(validity) + } + return (el: JQuery) => expect((el.get(0) as HTMLInputElement).validationMessage).to.match(validity) } diff --git a/cypress/e2e/files_versions/version_cross_storage_move.cy.ts b/cypress/e2e/files_versions/version_cross_storage_move.cy.ts index 0ddc3145d..76b7ed40e 100644 --- a/cypress/e2e/files_versions/version_cross_storage_move.cy.ts +++ b/cypress/e2e/files_versions/version_cross_storage_move.cy.ts @@ -7,7 +7,13 @@ import type { User } from '@nextcloud/cypress' import { PERMISSION_DELETE, PERMISSION_READ, PERMISSION_WRITE, addUserToGroup, createGroup, createGroupFolder } from '../groupfoldersUtils' import { assertVersionContent, nameVersion, openVersionsPanel, uploadThreeVersions } from './filesVersionsUtils' -import { clickOnBreadcumbs, closeSidebar, copyFile, moveFile, navigateToFolder } from '../files/filesUtils' +import { closeSidebar, copyFile, moveFile, navigateToFolder } from '../files/filesUtils' + +export const clickOnBreadcumbs = (label: string) => { + cy.intercept({ method: 'PROPFIND', url: /\/remote.php\/dav\// }).as('propfind') + cy.get('[data-cy-files-content-breadcrumbs]').contains(label).click() + cy.wait('@propfind') +} /** * diff --git a/cypress/e2e/groupfolders.cy.ts b/cypress/e2e/groupfolders.cy.ts index 1304aba08..1bf0ed52f 100644 --- a/cypress/e2e/groupfolders.cy.ts +++ b/cypress/e2e/groupfolders.cy.ts @@ -29,6 +29,7 @@ import { import { randHash } from '../utils' import type { User } from '@nextcloud/cypress' +import { triggerActionForFile } from './files/filesUtils' describe('Groupfolders ACLs and trashbin behavior', () => { let user1: User @@ -66,7 +67,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => { .then(_groupFolderId => { groupFolderId = _groupFolderId enableACLPermissions(groupFolderId) - addACLManagerUser(groupFolderId,managerUser.userId) + addACLManagerUser(groupFolderId, managerUser.userId) }) }) }) @@ -81,7 +82,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => { cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/subfolder2/file2.txt`) // Set ACL permissions - setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId) + setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId) setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId) // User1 has access @@ -165,7 +166,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => { cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/file1.txt`) // Set ACL permissions on subfolder - setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId) + setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId) setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId) // Delete subfolder @@ -204,10 +205,8 @@ describe('Groupfolders ACLs and trashbin behavior', () => { // Rename subfolder1 cy.visit('/apps/files') enterFolder(groupFolderName) - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [data-cy-files-list-row-actions]`).click() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).scrollIntoView() - 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="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]`).type('subfolder1renamed{enter}') + triggerActionForFile('subfolder1', 'rename') + cy.get('[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]').type('subfolder1renamed{enter}') fileOrFolderExists('subfolder1renamed') // Restore from trash @@ -231,7 +230,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => { cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/file1.txt`) // Set ACL permissions - setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId) + setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId) setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId) // Delete file @@ -245,10 +244,8 @@ describe('Groupfolders ACLs and trashbin behavior', () => { // Rename subfolder1 cy.visit('/apps/files') enterFolder(groupFolderName) - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [data-cy-files-list-row-actions]`).click() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="rename"]`).scrollIntoView() - 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="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]`).type('subfolder1renamed{enter}') + triggerActionForFile('subfolder1', 'rename') + cy.get('[data-cy-files-list] [data-cy-files-list-row-name="subfolder1"] [class="files-list__row-rename"] [class="input-field__input"]').type('subfolder1renamed{enter}') fileOrFolderExists('subfolder1renamed') // User1 sees it in trash @@ -271,7 +268,7 @@ describe('Groupfolders ACLs and trashbin behavior', () => { cy.uploadContent(managerUser, new Blob(['Content of the file']), 'text/plain', `/${groupFolderName}/subfolder1/subfolder2/file2.txt`) // Set ACL permissions - setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`,`-${PERMISSION_WRITE}`], undefined, user1.userId) + setACLPermissions(groupFolderId, '/subfolder1', [`+${PERMISSION_READ}`, `-${PERMISSION_WRITE}`], undefined, user1.userId) setACLPermissions(groupFolderId, '/subfolder1', [`-${PERMISSION_READ}`], undefined, user2.userId) // Delete files diff --git a/cypress/e2e/groupfoldersUtils.ts b/cypress/e2e/groupfoldersUtils.ts index 577d4463e..d3291478b 100644 --- a/cypress/e2e/groupfoldersUtils.ts +++ b/cypress/e2e/groupfoldersUtils.ts @@ -4,6 +4,8 @@ */ /* eslint-disable jsdoc/require-jsdoc */ +import {getActionButtonForFile, getRowForFile, triggerActionForFile} from './files/filesUtils' + export const PERMISSION_READ = 'read' export const PERMISSION_WRITE = 'write' export const PERMISSION_SHARE = 'share' @@ -93,89 +95,81 @@ export function disableGroupfoldersEncryption() { export function fileOrFolderExists(name: string) { // Make sure file list is loaded first cy.get('[data-cy-files-list-tfoot],[data-cy-files-content-empty]').should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"]`).should('be.visible') + getRowForFile(name).should('be.visible') } export function fileOrFolderDoesNotExist(name: string) { // Make sure file list is loaded first cy.get('[data-cy-files-list-tfoot],[data-cy-files-content-empty]').should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"]`).should('not.exist') + getRowForFile(name).should('not.exist') } export function fileOrFolderExistsInTrashbin(name: string) { // Make sure file list is loaded first cy.get('[data-cy-files-list-tfoot],[data-cy-files-content-empty]').should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"]`).should('be.visible') + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"]`).should('be.visible') } export function fileOrFolderDoesNotExistInTrashbin(name: string) { // Make sure file list is loaded first cy.get('[data-cy-files-list-tfoot],[data-cy-files-content-empty]').should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"]`).should('not.exist') + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"]`).should('not.exist') } export function enterFolder(name: string) { cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/files/**/${name}` }).as('propFindFolder') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"]`).click() + getRowForFile(name).findByRole('button', { name: `Open folder ${name}` }).click({force: true}) cy.wait('@propFindFolder') } export function enterFolderInTrashbin(name: string) { cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/trashbin/**/${name}.d*` }).as('propFindFolder') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"] [data-cy-files-list-row-name]`).click() + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"]`).findByRole('button', { name: `Open folder ${name}` }).click({ force: true }) cy.wait('@propFindFolder') } export function deleteFolder(name: string) { cy.intercept({ times: 1, method: 'DELETE', url: `**/dav/files/**/${name}` }).as('delete') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"] [data-cy-files-list-row-actions]`).click() - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').should('be.visible') - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').scrollIntoView() - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').click() + triggerActionForFile(name, 'delete') cy.wait('@delete').its('response.statusCode').should('eq', 204) } export function deleteFolderFromTrashbin(name: string) { cy.intercept({ times: 1, method: 'DELETE', url: `**/dav/trashbin/**/${name}.d*` }).as('delete') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"] [data-cy-files-list-row-actions] button:not([data-cy-files-list-row-action])`).click() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).scrollIntoView() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).click() + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"] [data-cy-files-list-row-actions]`).findByRole('button', { name: 'Actions' }).click() + // Getting the last button to avoid the one from popup fading out + cy.get(`[data-cy-files-list-row-action="${CSS.escape('delete')}"] > button`).last().should('exist').click() cy.wait('@delete').its('response.statusCode').should('eq', 204) } export function deleteFile(name: string) { cy.intercept({ times: 1, method: 'DELETE', url: `**/dav/files/**/${name}` }).as('delete') // For files wait for preview to load and release lock - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"] .files-list__row-icon img`) + getRowForFile(name).get('.files-list__row-icon img') .should('be.visible') .and(($img) => { // "naturalWidth" and "naturalHeight" are set when the image loads expect($img[0].naturalWidth, 'image has natural width').to.be.greaterThan(0) }) - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${name}"] [data-cy-files-list-row-actions]`).click() - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').should('be.visible') - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').scrollIntoView() - cy.get('[data-cy-files-list] [data-cy-files-list-row-action="delete"]').click() + triggerActionForFile(name, 'delete') cy.wait('@delete').its('response.statusCode').should('eq', 204) } export function deleteFileFromTrashbin(name: string) { cy.intercept({ times: 1, method: 'DELETE', url: `**/dav/trashbin/**/${name}.d*` }).as('delete') // For files wait for preview to load and release lock - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"] .files-list__row-icon img`) - .should('be.visible') - .and(($img) => { + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"]`).get('.files-list__row-icon img') + .should('be.visible') + .and(($img) => { // "naturalWidth" and "naturalHeight" are set when the image loads - expect($img[0].naturalWidth, 'image has natural width').to.be.greaterThan(0) - }) - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"] [data-cy-files-list-row-actions] button:not([data-cy-files-list-row-action])`).click() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).should('be.visible') - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).scrollIntoView() - cy.get(`[data-cy-files-list] [data-cy-files-list-row-action="delete"]`).click() + expect($img[0].naturalWidth, 'image has natural width').to.be.greaterThan(0) + }) + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"] [data-cy-files-list-row-actions]`).findByRole('button', { name: 'Actions' }).click() + // Getting the last button to avoid the one from popup fading out + cy.get(`[data-cy-files-list-row-action="${CSS.escape('delete')}"] > button`).last().should('exist').click() cy.wait('@delete').its('response.statusCode').should('eq', 204) } export function restoreFile(name: string) { - cy.get(`[data-cy-files-list] [data-cy-files-list-row-name^="${name}.d"] [data-cy-files-list-row-action="restore"]`).click() + cy.get(`[data-cy-files-list-row-name^="${CSS.escape(`${name}.d`)}"] button[data-cy-files-list-row-action="${CSS.escape('restore')}"]`).last().should('exist').click() } diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 6fd8a701b..b2c90eb31 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -6,6 +6,7 @@ import axios from '@nextcloud/axios' import { addCommands, User } from '@nextcloud/cypress' import { basename } from 'path' +import '@testing-library/cypress/add-commands' // Add custom commands import 'cypress-wait-until' diff --git a/package-lock.json b/package-lock.json index 721689ae5..fa7ba27fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "@nextcloud/stylelint-config": "^3.0.1", "@nextcloud/typings": "^1.9.1", "@nextcloud/webpack-vue-config": "^5.5.1", + "@testing-library/cypress": "^10.0.2", "@types/bootstrap": "^5.2.10", "@types/jest": "^29.5.14", "@types/react": "^17.0.43", @@ -51,6 +52,7 @@ "@vue/vue2-jest": "^29.2.6", "babel-loader-exclude-node-modules-except": "^1.2.1", "clean-webpack-plugin": "^4.0.0", + "cypress": "^13.15.1", "cypress-split": "^1.24.4", "cypress-visual-regression": "^5.2.2", "cypress-wait-until": "^3.0.2", @@ -2093,7 +2095,6 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=0.1.90" } @@ -2219,7 +2220,6 @@ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", "dev": true, - "peer": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -2249,7 +2249,6 @@ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.1.0", "lodash.once": "^4.1.1" @@ -2260,7 +2259,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -4742,6 +4740,155 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@testing-library/cypress": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@testing-library/cypress/-/cypress-10.0.2.tgz", + "integrity": "sha512-dKv95Bre5fDmNb9tOIuWedhGUryxGu1GWYWtXDqUsDPcr9Ekld0fiTb+pcBvSsFpYXAZSpmyEjhoXzLbhh06yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.14.6", + "@testing-library/dom": "^10.1.0" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "cypress": "^12.0.0 || ^13.0.0" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -4775,6 +4922,13 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -5168,8 +5322,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/sizzle": { "version": "2.3.8", @@ -5279,7 +5432,6 @@ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -6212,7 +6364,6 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "peer": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -6226,7 +6377,6 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -6303,7 +6453,6 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6394,8 +6543,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/are-docs-informative": { "version": "0.0.2", @@ -6422,6 +6570,16 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -6647,7 +6805,6 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, - "peer": true, "engines": { "node": ">=0.8" } @@ -6666,7 +6823,6 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -6675,8 +6831,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -6688,7 +6843,6 @@ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -6713,7 +6867,6 @@ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -6722,8 +6875,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/axios": { "version": "1.7.7", @@ -7098,8 +7250,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/bluebird": { "version": "3.7.2", @@ -7426,7 +7577,6 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -7542,7 +7692,6 @@ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -7614,8 +7763,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ccount": { "version": "2.0.1", @@ -7699,7 +7847,6 @@ "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -7790,7 +7937,6 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -7815,7 +7961,6 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, - "peer": true, "dependencies": { "restore-cursor": "^3.1.0" }, @@ -7828,7 +7973,6 @@ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0" }, @@ -7844,7 +7988,6 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, - "peer": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -7959,8 +8102,7 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -8013,7 +8155,6 @@ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0.0" } @@ -8236,8 +8377,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cosmiconfig": { "version": "7.1.0", @@ -8668,12 +8808,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", - "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", + "version": "13.15.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.1.tgz", + "integrity": "sha512-DwUFiKXo4lef9kA0M4iEhixFqoqp2hw8igr0lTqafRb9qtU3X0XGxKbkSYsUFdkrAkphc7MPDxoNPhk5pj9PVg==", "dev": true, "hasInstallScript": true, - "peer": true, + "license": "MIT", "dependencies": { "@cypress/request": "^3.0.4", "@cypress/xvfb": "^1.2.4", @@ -8715,6 +8855,7 @@ "semver": "^7.5.3", "supports-color": "^8.1.1", "tmp": "~0.2.3", + "tree-kill": "1.2.2", "untildify": "^4.0.0", "yauzl": "^2.10.0" }, @@ -8858,7 +8999,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -8874,7 +9014,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8891,7 +9030,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8904,7 +9042,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8916,15 +9053,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cypress/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, - "peer": true, "engines": { "node": ">= 6" } @@ -8934,7 +9069,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -8944,7 +9078,6 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -8956,15 +9089,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cypress/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -8980,7 +9111,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8995,15 +9125,13 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -9093,8 +9221,7 @@ "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/de-indent": { "version": "1.0.2", @@ -9740,6 +9867,13 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, "node_modules/dom-event-types": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.1.0.tgz", @@ -9876,7 +10010,6 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, - "peer": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -10073,7 +10206,6 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, - "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -11491,8 +11623,7 @@ "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/eventemitter3": { "version": "4.0.7", @@ -11527,7 +11658,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, - "peer": true, "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -11551,7 +11681,6 @@ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", "dev": true, - "peer": true, "dependencies": { "pify": "^2.2.0" }, @@ -11564,7 +11693,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11677,7 +11805,6 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -11700,8 +11827,7 @@ "dev": true, "engines": [ "node >=0.6.0" - ], - "peer": true + ] }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -11822,7 +11948,6 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, - "peer": true, "dependencies": { "pend": "~1.2.0" } @@ -11854,7 +11979,6 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, - "peer": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -11870,7 +11994,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -12246,7 +12369,6 @@ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true, - "peer": true, "engines": { "node": "*" } @@ -12306,7 +12428,6 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -12449,7 +12570,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -12495,7 +12615,6 @@ "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", "dev": true, - "peer": true, "dependencies": { "async": "^3.2.0" } @@ -12505,7 +12624,6 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -12586,7 +12704,6 @@ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "dev": true, - "peer": true, "dependencies": { "ini": "2.0.0" }, @@ -13236,7 +13353,6 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", "dev": true, - "peer": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^2.0.2", @@ -13272,7 +13388,6 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, - "peer": true, "engines": { "node": ">=8.12.0" } @@ -13424,7 +13539,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -13611,7 +13725,6 @@ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, - "peer": true, "dependencies": { "ci-info": "^3.2.0" }, @@ -13756,7 +13869,6 @@ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, - "peer": true, "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -13881,7 +13993,6 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -14031,15 +14142,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -14153,8 +14262,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -16126,8 +16234,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", @@ -16211,8 +16318,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -16231,8 +16337,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json5": { "version": "2.2.3", @@ -16251,7 +16356,6 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -16267,7 +16371,6 @@ "engines": [ "node >=0.6.0" ], - "peer": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -16350,7 +16453,6 @@ "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", "dev": true, - "peer": true, "engines": { "node": "> 0.8" } @@ -16411,7 +16513,6 @@ "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", "dev": true, - "peer": true, "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -16439,7 +16540,6 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, - "peer": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -16515,8 +16615,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.throttle": { "version": "4.1.1", @@ -16536,7 +16635,6 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "peer": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -16553,7 +16651,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -16569,7 +16666,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -16586,7 +16682,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -16598,15 +16693,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/log-symbols/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -16616,7 +16709,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -16629,7 +16721,6 @@ "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, - "peer": true, "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -16648,7 +16739,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -16664,7 +16754,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -16676,15 +16765,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -16702,7 +16789,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16755,6 +16841,16 @@ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "peer": true }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.30.12", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", @@ -18460,8 +18556,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/p-limit": { "version": "3.1.0", @@ -18738,15 +18833,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/picocolors": { "version": "1.1.1", @@ -19178,7 +19271,6 @@ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true, - "peer": true, "engines": { "node": ">=6" }, @@ -19385,7 +19477,6 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, - "peer": true, "dependencies": { "side-channel": "^1.0.6" }, @@ -20012,7 +20103,6 @@ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", "dev": true, - "peer": true, "dependencies": { "throttleit": "^1.0.0" } @@ -20176,7 +20266,6 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, - "peer": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -20209,8 +20298,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/rimraf": { "version": "2.7.1", @@ -20906,7 +20994,6 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -20921,7 +21008,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -20937,7 +21023,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -20949,8 +21034,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/sockjs": { "version": "0.3.24", @@ -21138,7 +21222,6 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, - "peer": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -22291,7 +22374,6 @@ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -22300,8 +22382,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/thunky": { "version": "1.1.0", @@ -22373,7 +22454,6 @@ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "peer": true, "engines": { "node": ">=14.14" } @@ -22447,6 +22527,16 @@ "node": ">=12" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/tributejs": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", @@ -22780,7 +22870,6 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -23170,7 +23259,6 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "peer": true, "engines": { "node": ">= 10.0.0" } @@ -23190,7 +23278,6 @@ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -23331,7 +23418,6 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "uuid": "dist/bin/uuid" } @@ -23374,7 +23460,6 @@ "engines": [ "node >=0.6.0" ], - "peer": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -24452,7 +24537,6 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, - "peer": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index aa8411070..3820e4ec2 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@nextcloud/stylelint-config": "^3.0.1", "@nextcloud/typings": "^1.9.1", "@nextcloud/webpack-vue-config": "^5.5.1", + "@testing-library/cypress": "^10.0.2", "@types/bootstrap": "^5.2.10", "@types/jest": "^29.5.14", "@types/react": "^17.0.43", @@ -36,6 +37,7 @@ "@vue/vue2-jest": "^29.2.6", "babel-loader-exclude-node-modules-except": "^1.2.1", "clean-webpack-plugin": "^4.0.0", + "cypress": "^13.15.1", "cypress-split": "^1.24.4", "cypress-visual-regression": "^5.2.2", "cypress-wait-until": "^3.0.2", diff --git a/tsconfig.json b/tsconfig.json index 33bd8b3c9..58a73be12 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,11 @@ "sourceMap": true, "jsx": "react", "allowSyntheticDefaultImports": true, - "esModuleInterop": true + "esModuleInterop": true, + "types": [ + "cypress", + "@testing-library/cypress", + "@types/webpack-env" + ] } }