diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index a6a741e87..05d99b91c 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -30,7 +30,7 @@ permissions: jobs: init: - runs-on: ubuntu-latest-low + runs-on: ubuntu-latest outputs: nodeVersion: ${{ steps.versions.outputs.nodeVersion }} npmVersion: ${{ steps.versions.outputs.npmVersion }} @@ -116,7 +116,7 @@ jobs: run: npm i -g 'npm@${{ needs.init.outputs.npmVersion }}' - name: Run ${{ matrix.containers == 'component' && 'component' || 'E2E' }} cypress tests - uses: cypress-io/github-action@57b70560982e6a11d23d4b8bec7f8a487cdbb71b # v6.7.8 + uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16 with: record: ${{ secrets.CYPRESS_RECORD_KEY && true }} parallel: ${{ secrets.CYPRESS_RECORD_KEY && true }} @@ -139,18 +139,20 @@ jobs: CYPRESS_GROUP: Run ${{ matrix.containers == 'component' && 'component' || 'E2E' }} - name: Upload snapshots - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 if: always() with: - name: snapshots_${{ matrix.containers }} - path: cypress/snapshots + name: snapshots_videos_${{ matrix.containers }} + path: | + cypress/snapshots + cypress/videos - name: Extract NC logs if: failure() && matrix.containers != 'component' - run: docker logs nextcloud-cypress-tests-${{ env.APP_NAME }} > nextcloud.log + run: docker logs nextcloud-cypress-tests_${{ env.APP_NAME }} > nextcloud.log - name: Upload NC logs - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 if: failure() && matrix.containers != 'component' with: name: nc_logs_${{ matrix.containers }} diff --git a/.github/workflows/lint-php-cs.yml b/.github/workflows/lint-php-cs.yml index 519b345ea..a1a246fd8 100644 --- a/.github/workflows/lint-php-cs.yml +++ b/.github/workflows/lint-php-cs.yml @@ -34,7 +34,7 @@ jobs: uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 - name: Set up php${{ steps.versions.outputs.php-min }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ steps.versions.outputs.php-min }} extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml index adaa50b8a..94de4b5fc 100644 --- a/.github/workflows/lint-php.yml +++ b/.github/workflows/lint-php.yml @@ -48,7 +48,7 @@ jobs: persist-credentials: false - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite diff --git a/.github/workflows/node-test.yml b/.github/workflows/node-test.yml index b0678c2c2..9fda53347 100644 --- a/.github/workflows/node-test.yml +++ b/.github/workflows/node-test.yml @@ -93,7 +93,7 @@ jobs: run: npm run test:coverage --if-present - name: Collect coverage - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0 with: files: ./coverage/lcov.info diff --git a/.github/workflows/npm-audit-fix.yml b/.github/workflows/npm-audit-fix.yml index ee0203b67..6dec3eeb9 100644 --- a/.github/workflows/npm-audit-fix.yml +++ b/.github/workflows/npm-audit-fix.yml @@ -54,7 +54,7 @@ jobs: - name: Fix npm audit id: npm-audit - uses: nextcloud-libraries/npm-audit-action@2a60bd2e79cc77f2cc4d9a3fe40f1a69896f3a87 # v0.1.0 + uses: nextcloud-libraries/npm-audit-action@1b1728b2b4a7a78d69de65608efcf4db0e3e42d0 # v0.2.0 - name: Run npm ci and npm run build if: steps.checkout.outcome == 'success' @@ -66,7 +66,7 @@ jobs: - name: Create Pull Request if: steps.checkout.outcome == 'success' - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ secrets.COMMAND_BOT_PAT }} commit-message: 'fix(deps): Fix npm audit' diff --git a/.github/workflows/phpunit-mariadb.yml b/.github/workflows/phpunit-mariadb.yml index 74dbcbb67..aa12be426 100644 --- a/.github/workflows/phpunit-mariadb.yml +++ b/.github/workflows/phpunit-mariadb.yml @@ -105,7 +105,7 @@ jobs: path: apps/${{ env.APP_NAME }} - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation diff --git a/.github/workflows/phpunit-mysql.yml b/.github/workflows/phpunit-mysql.yml index 1f26d5bc3..305abf83e 100644 --- a/.github/workflows/phpunit-mysql.yml +++ b/.github/workflows/phpunit-mysql.yml @@ -103,7 +103,7 @@ jobs: path: apps/${{ env.APP_NAME }} - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation diff --git a/.github/workflows/phpunit-oci.yml b/.github/workflows/phpunit-oci.yml index 1d9ae9235..4ffadfd6e 100644 --- a/.github/workflows/phpunit-oci.yml +++ b/.github/workflows/phpunit-oci.yml @@ -116,7 +116,7 @@ jobs: path: apps/${{ env.APP_NAME }} - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation diff --git a/.github/workflows/phpunit-pgsql.yml b/.github/workflows/phpunit-pgsql.yml index 284efa294..ef8e6c264 100644 --- a/.github/workflows/phpunit-pgsql.yml +++ b/.github/workflows/phpunit-pgsql.yml @@ -106,7 +106,7 @@ jobs: path: apps/${{ env.APP_NAME }} - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation diff --git a/.github/workflows/phpunit-sqlite.yml b/.github/workflows/phpunit-sqlite.yml index bdbc39bef..129873300 100644 --- a/.github/workflows/phpunit-sqlite.yml +++ b/.github/workflows/phpunit-sqlite.yml @@ -95,7 +95,7 @@ jobs: path: apps/${{ env.APP_NAME }} - name: Set up php ${{ matrix.php-versions }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ matrix.php-versions }} # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 452186eea..facd92b13 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -36,7 +36,7 @@ jobs: run: grep 'phpVersion="${{ steps.versions.outputs.php-min }}' psalm.xml - name: Set up php${{ steps.versions.outputs.php-available }} - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: ${{ steps.versions.outputs.php-available }} extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite diff --git a/.github/workflows/update-nextcloud-ocp.yml b/.github/workflows/update-nextcloud-ocp.yml index 98ec8efaa..865b80818 100644 --- a/.github/workflows/update-nextcloud-ocp.yml +++ b/.github/workflows/update-nextcloud-ocp.yml @@ -38,7 +38,7 @@ jobs: - name: Set up php8.2 if: steps.checkout.outcome == 'success' - uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 with: php-version: 8.2 # https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation @@ -107,7 +107,7 @@ jobs: - name: Create Pull Request if: steps.checkout.outcome == 'success' - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ secrets.COMMAND_BOT_PAT }} commit-message: 'chore(dev-deps): Bump nextcloud/ocp package' diff --git a/cypress.config.ts b/cypress.config.ts index 435882dbc..2d8fe55df 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -11,9 +11,10 @@ export default defineConfig({ viewportWidth: 1280, viewportHeight: 720, - // Tries again 2 more times on failure + requestTimeout: 20000, + retries: { - runMode: 2, + runMode: 0, // do not retry in `cypress open` openMode: 0, }, @@ -21,6 +22,9 @@ export default defineConfig({ // Needed to trigger `after:run` events with cypress open experimentalInteractiveRunEvents: true, + // disabled if running in CI but enabled in debug mode + video: !process.env.CI || !!process.env.RUNNER_DEBUG, + // faster video processing videoCompression: false, @@ -33,14 +37,25 @@ export default defineConfig({ trashAssetsBeforeRuns: true, e2e: { - testIsolation: false, - // We've imported your old cypress plugins here. // You may want to clean this up later by importing these. async setupNodeEvents(on, config) { // Fix browserslist extend https://github.com/cypress-io/cypress/issues/2983#issuecomment-570616682 on('file:preprocessor', vitePreprocessor({ configFile: false })) + // This allows to store global data (e.g. the name of a snapshot) + // because Cypress.env() and other options are local to the current spec file. + const data = {} + on('task', { + setVariable({ key, value }) { + data[key] = value + return null + }, + getVariable({ key }) { + return data[key] ?? null + }, + }) + // Disable spell checking to prevent rendering differences on('before:browser:launch', (browser, launchOptions) => { if (browser.family === 'chromium' && browser.name !== 'electron') { @@ -61,22 +76,19 @@ export default defineConfig({ // Remove container after run on('after:run', () => { - stopNextcloud() + if (!process.env.CI) { + stopNextcloud() + } }) // Before the browser launches // starting Nextcloud testing container - return startNextcloud(process.env.BRANCH) - .then((ip) => { - // Setting container's IP as base Url - config.baseUrl = `http://${ip}/index.php` - return ip - }) - .then(waitOnNextcloud) - .then(() => configureNextcloud(process.env.BRANCH)) - .then(() => { - return config - }) + const ip = await startNextcloud(process.env.BRANCH || 'master', undefined, { exposePort: 8080 }) + // Setting container's IP as base Url + config.baseUrl = `http://${ip}/index.php` + await waitOnNextcloud(ip) + await configureNextcloud(['viewer']) + return config }, }, }) diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml deleted file mode 100644 index 73ae49038..000000000 --- a/cypress/docker-compose.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: '3.7' - -services: - nextcloud: - image: ghcr.io/nextcloud/continuous-integration-shallow-server - - ports: - - 8082:80 - - environment: - CYPRESS_baseUrl: "http://127.0.0.1:8082/index.php" - BRANCH: "${BRANCH:-master}" - - volumes: - # Using fallback to make sure this script doesn't mess - # with the mounting if APP_NAME is not provided. - - ../:/var/www/html/apps/${APP_NAME:-activity} - - ./initserver.sh:/initserver.sh diff --git a/cypress/dockerNode.ts b/cypress/dockerNode.ts deleted file mode 100644 index 62dd7a89f..000000000 --- a/cypress/dockerNode.ts +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @copyright Copyright (c) 2022 John Molakvoæ - * - * @author John Molakvoæ - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ -/* eslint-disable no-console */ -/* eslint-disable n/no-unpublished-import */ -/* eslint-disable n/no-extraneous-import */ - -import Docker from 'dockerode' -import path from 'path' -import waitOn from 'wait-on' - -import { fileURLToPath } from 'url'; -const __dirname = fileURLToPath(new URL('.', import.meta.url)); - -export const docker = new Docker() - -const APP_PATH = path.resolve(__dirname, '../') -const APP_NAME = 'activity' - -const CONTAINER_NAME = 'nextcloud-cypress-tests-' + APP_NAME -const SERVER_IMAGE = 'ghcr.io/nextcloud/continuous-integration-shallow-server' - -/** - * Start the testing container - */ -export const startNextcloud = async function(branch: string = 'master'): Promise { - - try { - // Pulling images - console.log('\nPulling images... ⏳') - await new Promise((resolve, reject): any => docker.pull(SERVER_IMAGE, (err, stream) => { - if (err) { - reject(err) - } - // https://github.com/apocas/dockerode/issues/357 - docker.modem.followProgress(stream, onFinished) - - /** - * - * @param err - */ - function onFinished(err) { - if (!err) { - resolve(true) - return - } - reject(err) - } - })) - console.log('└─ Done') - - // Remove old container if exists - console.log('\nChecking running containers... 🔍') - try { - const oldContainer = docker.getContainer(CONTAINER_NAME) - const oldContainerData = await oldContainer.inspect() - if (oldContainerData) { - console.log('├─ Existing running container found') - console.log('├─ Removing... ⏳') - // Forcing any remnants to be removed just in case - await oldContainer.remove({ force: true }) - console.log('└─ Done') - } - } catch (error) { - console.log('└─ None found!') - } - - // Starting container - console.log('\nStarting Nextcloud container... 🚀') - console.log(`├─ Using branch '${branch}'`) - console.log(`├─ And binding app '${APP_NAME}' from '${APP_PATH}'`) - const container = await docker.createContainer({ - Image: SERVER_IMAGE, - name: CONTAINER_NAME, - HostConfig: { - Binds: [ - // TODO: improve local app directory detection - `${APP_PATH}/:/var/www/html/apps/${APP_NAME}:ro`, - ], - }, - Env: [ - `BRANCH=${branch}`, - ], - }) - await container.start() - - // Get container's IP - const ip = await getContainerIP(container) - - console.log(`├─ Nextcloud container's IP is ${ip} 🌏`) - return ip - } catch (err) { - console.log('└─ Unable to start the container 🛑') - console.log(err) - stopNextcloud() - throw new Error('Unable to start the container') - } -} - -/** - * Configure Nextcloud - */ -export const configureNextcloud = async function(branch: string = 'master') { - console.log('\nConfiguring nextcloud...') - const container = docker.getContainer(CONTAINER_NAME) - await runExec(container, ['php', 'occ', '--version'], true) - - // Clone the viewer app - await runExec(container, ['git', 'clone', '--depth', '1', '--branch', branch, 'https://github.com/nextcloud/viewer.git', '/var/www/html/apps/viewer'], true) - - // Be consistent for screenshots - await runExec(container, ['php', 'occ', 'config:system:set', 'default_language', '--value', 'en'], true) - await runExec(container, ['php', 'occ', 'config:system:set', 'force_language', '--value', 'en'], true) - await runExec(container, ['php', 'occ', 'config:system:set', 'default_locale', '--value', 'en_US'], true) - await runExec(container, ['php', 'occ', 'config:system:set', 'force_locale', '--value', 'en_US'], true) - await runExec(container, ['php', 'occ', 'config:system:set', 'enforce_theme', '--value', 'light'], true) - - console.log('└─ Nextcloud is now ready to use 🎉') -} - -/** - * Force stop the testing container - */ -export const stopNextcloud = async function() { - try { - const container = docker.getContainer(CONTAINER_NAME) - console.log('Stopping Nextcloud container...') - container.remove({ force: true }) - console.log('└─ Nextcloud container removed 🥀') - } catch (err) { - console.log(err) - } -} - -/** - * Get the testing container's IP - */ -export const getContainerIP = async function( - container: Docker.Container = docker.getContainer(CONTAINER_NAME) -): Promise { - let ip = '' - let tries = 0 - while (ip === '' && tries < 10) { - tries++ - - await container.inspect(function(err, data) { - if (err) { - throw err - } - ip = data?.NetworkSettings?.IPAddress || '' - }) - - if (ip !== '') { - break - } - - await sleep(1000 * tries) - } - - return ip -} - -// Would be simpler to start the container from cypress.config.ts, -// but when checking out different branches, it can take a few seconds -// Until we can properly configure the baseUrl retry intervals, -// We need to make sure the server is already running before cypress -// https://github.com/cypress-io/cypress/issues/22676 -export const waitOnNextcloud = async function(ip: string) { - console.log('├─ Waiting for Nextcloud to be ready... ⏳') - await waitOn({ resources: [`http://${ip}/index.php`] }) - console.log('└─ Done') -} - -const runExec = async function( - container: Docker.Container, - command: string[], - verbose = false, - user = 'www-data' -) { - const exec = await container.exec({ - Cmd: command, - AttachStdout: true, - AttachStderr: true, - User: user, - }) - - return new Promise((resolve, reject) => { - exec.start({}, (err, stream) => { - if (err) { - reject(err) - } - if (stream) { - stream.setEncoding('utf-8') - stream.on('data', str => { - if (verbose && str.trim() !== '') { - console.log(`├─ ${str.trim().replace(/\n/gi, '\n├─ ')}`) - } - }) - stream.on('end', resolve) - } - }) - }) -} - -const sleep = function(milliseconds: number) { - return new Promise((resolve) => setTimeout(resolve, milliseconds)) -} diff --git a/cypress/e2e/filesUtils.ts b/cypress/e2e/filesUtils.ts index c624ca271..845ff19d0 100644 --- a/cypress/e2e/filesUtils.ts +++ b/cypress/e2e/filesUtils.ts @@ -20,6 +20,8 @@ * */ +import { closeSidebar } from "./sidebarUtils" + export const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`) export const getActionsForFile = (filename: string) => getRowForFile(filename).find('[data-cy-files-list-row-actions]') export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' }) @@ -57,7 +59,12 @@ export const triggerActionForFile = (filename: string, actionId: string) => { } export function renameFile(fileName: string, newName: string) { + // The file must exist and the preview loaded as it locks the file getRowForFile(fileName) + .should('be.visible') + .find('.files-list__row-icon-preview--loaded') + .should('exist') + triggerActionForFile(fileName, 'rename') // intercept the move so we can wait for it @@ -128,7 +135,17 @@ export function moveFile (fileName: string, dirName: string) { }) } +export function getFileListRow(filename: string) { + return cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${CSS.escape(filename)}"]`) +} + export function toggleMenuAction(fileName: string) { + closeSidebar() + + // Wait for the files actions to be loaded. + cy.get('.files-list__row-mtime') + .should('be.visible') + cy.get(`[data-cy-files-list] [data-cy-files-list-row-name="${CSS.escape(fileName)}"] [data-cy-files-list-row-actions]`) .should('be.visible') .findByRole('button', { name: 'Actions' }) diff --git a/cypress/e2e/settings.cy.ts b/cypress/e2e/settings.cy.ts index 3af74c5a4..952c2d15d 100644 --- a/cypress/e2e/settings.cy.ts +++ b/cypress/e2e/settings.cy.ts @@ -20,13 +20,19 @@ * */ +import type { User } from "@nextcloud/cypress" + describe('Check that user\'s settings survive a reload', () => { + let user: User + before(() => { cy.createRandomUser() - .then((user) => { - cy.login(user) - cy.visit('/settings/user/notifications') - }) + .then(_user => user = _user) + }) + + beforeEach(() => { + cy.login(user) + cy.visit('/settings/user/notifications') }) it('Form survive a reload', () => { diff --git a/cypress/e2e/sidebar.cy.ts b/cypress/e2e/sidebar.cy.ts index c0d124dae..bf33dde9f 100644 --- a/cypress/e2e/sidebar.cy.ts +++ b/cypress/e2e/sidebar.cy.ts @@ -20,8 +20,8 @@ * */ -import { createFolder, moveFile, navigateToFolder, renameFile } from './filesUtils' -import { addComment, addTag, addToFavorites, createPublicShare, removeFromFavorites, showActivityTab } from './sidebarUtils' +import { createFolder, navigateToFolder, moveFile, renameFile, getFileListRow } from './filesUtils' +import { addComment, addTag, addToFavorites, createPublicShare, randHash, removeFromFavorites, showActivityTab } from './sidebarUtils' describe('Check activity listing in the sidebar', { testIsolation: true }, () => { beforeEach(function() { @@ -49,8 +49,9 @@ describe('Check activity listing in the sidebar', { testIsolation: true }, () => it('Has share activity', () => { createPublicShare('welcome.txt') - cy.get('body').contains('Link share created').should('exist') - cy.get('.toast-close').click({ multiple: true }) + cy.visit('/apps/files') + getFileListRow('welcome.txt').should('be.visible') + showActivityTab('welcome.txt') cy.get('.activity-entry').first().should('contains.text', 'Shared as public link') }) @@ -73,7 +74,8 @@ describe('Check activity listing in the sidebar', { testIsolation: true }, () => }) it('Has tag activity', () => { - addTag('welcome.txt', 'my_tag') + addTag('welcome.txt', `my_tag_${randHash()}`) + cy.visit('/apps/files') showActivityTab('welcome.txt') cy.get('.activity-entry').first().should('contains.text', 'Added system tag') diff --git a/cypress/e2e/sidebarUtils.ts b/cypress/e2e/sidebarUtils.ts index 4f15a5a27..540ed7d0d 100644 --- a/cypress/e2e/sidebarUtils.ts +++ b/cypress/e2e/sidebarUtils.ts @@ -32,7 +32,7 @@ function showSidebarForFile(fileName: string) { cy.get('#app-sidebar-vue').should('be.visible') } -function closeSidebar() { +export function closeSidebar() { cy.get('body') .then(($body) => { if ($body.find('.app-sidebar__close').length !== 0) { @@ -47,7 +47,7 @@ export function showActivityTab(fileName: string) { cy.intercept('GET', '/ocs/v2.php/apps/activity/api/v2/activity/filter**').as('getActivities') showSidebarForFile(fileName) - cy.get('#app-sidebar-vue').contains('Activity').click() + cy.get('#app-sidebar-vue').contains('Activity').click({ force: true }) cy.wait('@getActivities') } @@ -117,3 +117,7 @@ export function addComment(fileName: string, comment: string) { cy.wait('@comment') } + +export function randHash() { + return Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 10) +} diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index ad5fa26b9..beee02da8 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,13 +1,16 @@ { "extends": "../tsconfig.json", - "include": ["./**/*.ts"], + "include": [ + "../*.ts", + "." + ], "compilerOptions": { + "rootDir": "..", "types": [ - "@testing-library/cypress", "cypress", "dockerode", "node", "@testing-library/cypress" ] } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index d68c70e25..7bd490cc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,20 +29,20 @@ }, "devDependencies": { "@nextcloud/browserslist-config": "^3.0.0", - "@nextcloud/cypress": "^1.0.0-beta.14", + "@nextcloud/cypress": "^1.0.0-beta.15", "@nextcloud/eslint-config": "^8.3.0", "@nextcloud/stylelint-config": "^2.4.0", "@nextcloud/vite-config": "^1.2.0", "@testing-library/cypress": "^10.0.3", "@testing-library/vue": "^5.9.0", - "@types/dockerode": "^3.3.26", + "@types/dockerode": "^3.3.34", "@vitest/coverage-v8": "^1.4.0", "@vue/test-utils": "^1.3.6", "@vue/tsconfig": "^0.5.1", "cypress": "^13.13.3", - "cypress-vite": "^1.5.0", + "cypress-vite": "^1.6.0", "cypress-wait-until": "^3.0.1", - "dockerode": "^4.0.2", + "dockerode": "^4.0.4", "eslint-plugin-cypress": "^2.15.1", "happy-dom": "^13.2.0", "typescript": "^5.2.2", @@ -2651,13 +2651,13 @@ } }, "node_modules/@nextcloud/cypress": { - "version": "1.0.0-beta.14", - "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.14.tgz", - "integrity": "sha512-qXs+VtdhgK5Mdahyp95FTBmxJfj49IiRkD1YqsyHo4PvexDO3qzbR+aIMESRjfcdz7iMyDkPRzRtsqGI4cQUmA==", + "version": "1.0.0-beta.15", + "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.15.tgz", + "integrity": "sha512-0pTweoFmw9x0J2R1Ou+ycIw8aGuJGTrbudaorl4vFXUEDEIo4GAx136RzH1TzYkRn1zPxDloFi2qmHh54NMdng==", "dev": true, "dependencies": { "dockerode": "^4.0.2", - "fast-xml-parser": "^4.3.6", + "fast-xml-parser": "^5.2.2", "wait-on": "^8.0.0" }, "engines": { @@ -2668,6 +2668,36 @@ "cypress": "^13.9.0" } }, + "node_modules/@nextcloud/cypress/node_modules/fast-xml-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.3.tgz", + "integrity": "sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/@nextcloud/cypress/node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] + }, "node_modules/@nextcloud/cypress/node_modules/wait-on": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", @@ -4453,13 +4483,14 @@ } }, "node_modules/@types/dockerode": { - "version": "3.3.26", - "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.26.tgz", - "integrity": "sha512-/K+I9bGhRO2SvyIHisGeOsy/ypxnWLz8+Rde9S2tNNEKa3r91e0XMYIEq2D+kb7srm7xrmpAR0CDKfXoZOr4OA==", + "version": "3.3.38", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.38.tgz", + "integrity": "sha512-nnrcfUe2iR+RyOuz0B4bZgQwD9djQa9ADEjp7OAgBs10pYT0KSCtplJjcmBDJz0qaReX5T7GbE5i4VplvzUHvA==", "dev": true, "dependencies": { "@types/docker-modem": "*", - "@types/node": "*" + "@types/node": "*", + "@types/ssh2": "*" } }, "node_modules/@types/dompurify": { @@ -7600,16 +7631,16 @@ } }, "node_modules/cypress-vite": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cypress-vite/-/cypress-vite-1.5.0.tgz", - "integrity": "sha512-vvTMqJZgI3sN2ylQTi4OQh8LRRjSrfrIdkQD5fOj+EC/e9oHkxS96lif1SyDF1PwailG1tnpJE+VpN6+AwO/rg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cypress-vite/-/cypress-vite-1.6.0.tgz", + "integrity": "sha512-6oZPDvHgLEZjuFgoejtRuyph369zbVn7fjh4hzhMar3XvKT5YhTEoA+KixksMuxNEaLn9uqA4HJVz6l7BybwBQ==", "dev": true, "dependencies": { "chokidar": "^3.5.3", "debug": "^4.3.4" }, "peerDependencies": { - "vite": "^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + "vite": "^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/cypress-wait-until": { @@ -21762,16 +21793,31 @@ } }, "@nextcloud/cypress": { - "version": "1.0.0-beta.14", - "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.14.tgz", - "integrity": "sha512-qXs+VtdhgK5Mdahyp95FTBmxJfj49IiRkD1YqsyHo4PvexDO3qzbR+aIMESRjfcdz7iMyDkPRzRtsqGI4cQUmA==", + "version": "1.0.0-beta.15", + "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.15.tgz", + "integrity": "sha512-0pTweoFmw9x0J2R1Ou+ycIw8aGuJGTrbudaorl4vFXUEDEIo4GAx136RzH1TzYkRn1zPxDloFi2qmHh54NMdng==", "dev": true, "requires": { "dockerode": "^4.0.2", - "fast-xml-parser": "^4.3.6", + "fast-xml-parser": "^5.2.2", "wait-on": "^8.0.0" }, "dependencies": { + "fast-xml-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.3.tgz", + "integrity": "sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==", + "dev": true, + "requires": { + "strnum": "^2.1.0" + } + }, + "strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "dev": true + }, "wait-on": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", @@ -22972,13 +23018,14 @@ } }, "@types/dockerode": { - "version": "3.3.26", - "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.26.tgz", - "integrity": "sha512-/K+I9bGhRO2SvyIHisGeOsy/ypxnWLz8+Rde9S2tNNEKa3r91e0XMYIEq2D+kb7srm7xrmpAR0CDKfXoZOr4OA==", + "version": "3.3.38", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.38.tgz", + "integrity": "sha512-nnrcfUe2iR+RyOuz0B4bZgQwD9djQa9ADEjp7OAgBs10pYT0KSCtplJjcmBDJz0qaReX5T7GbE5i4VplvzUHvA==", "dev": true, "requires": { "@types/docker-modem": "*", - "@types/node": "*" + "@types/node": "*", + "@types/ssh2": "*" } }, "@types/dompurify": { @@ -25402,9 +25449,9 @@ } }, "cypress-vite": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cypress-vite/-/cypress-vite-1.5.0.tgz", - "integrity": "sha512-vvTMqJZgI3sN2ylQTi4OQh8LRRjSrfrIdkQD5fOj+EC/e9oHkxS96lif1SyDF1PwailG1tnpJE+VpN6+AwO/rg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cypress-vite/-/cypress-vite-1.6.0.tgz", + "integrity": "sha512-6oZPDvHgLEZjuFgoejtRuyph369zbVn7fjh4hzhMar3XvKT5YhTEoA+KixksMuxNEaLn9uqA4HJVz6l7BybwBQ==", "dev": true, "requires": { "chokidar": "^3.5.3", diff --git a/package.json b/package.json index b5f53409a..3326d3a2a 100644 --- a/package.json +++ b/package.json @@ -59,20 +59,20 @@ }, "devDependencies": { "@nextcloud/browserslist-config": "^3.0.0", - "@nextcloud/cypress": "^1.0.0-beta.14", + "@nextcloud/cypress": "^1.0.0-beta.15", "@nextcloud/eslint-config": "^8.3.0", "@nextcloud/stylelint-config": "^2.4.0", "@nextcloud/vite-config": "^1.2.0", "@testing-library/cypress": "^10.0.3", "@testing-library/vue": "^5.9.0", - "@types/dockerode": "^3.3.26", + "@types/dockerode": "^3.3.34", "@vitest/coverage-v8": "^1.4.0", "@vue/test-utils": "^1.3.6", "@vue/tsconfig": "^0.5.1", "cypress": "^13.13.3", - "cypress-vite": "^1.5.0", + "cypress-vite": "^1.6.0", "cypress-wait-until": "^3.0.1", - "dockerode": "^4.0.2", + "dockerode": "^4.0.4", "eslint-plugin-cypress": "^2.15.1", "happy-dom": "^13.2.0", "typescript": "^5.2.2", diff --git a/tsconfig.json b/tsconfig.json index e904f1a59..89bb67031 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,17 @@ { "extends": "@vue/tsconfig/tsconfig.json", - "include": ["./src/**/*.ts", "./src/**/*.vue"], + "include": [ + "./src" + ], "compilerOptions": { - "allowJs": true, - "allowSyntheticDefaultImports": true, - "moduleResolution": "Bundler", + "lib": [ + "DOM", + "ES2015" + ], + "rootDir": "src", "noImplicitAny": false, - "outDir": "./js/", - "strict": true }, "vueCompilerOptions": { "target": 2.7 } -} \ No newline at end of file +}