From f32c2b878689dbe80c9199daa5432dd9422731c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6?= Date: Fri, 11 Nov 2022 08:49:19 +0100 Subject: [PATCH] Migrate to @nextcloud/cypress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ --- cypress.config.ts | 5 +- cypress/dockerNode.ts | 2 +- cypress/e2e/actions/delete.cy.js | 16 ++-- cypress/e2e/actions/download.cy.js | 15 ++-- cypress/e2e/actions/sidebar.cy.js | 24 +++--- cypress/e2e/audios/audios.cy.js | 26 +++--- cypress/e2e/files.cy.js | 9 +- .../images/images-custom-list-loadmore.cy.js | 24 +++--- cypress/e2e/images/images-custom-list.cy.js | 24 +++--- cypress/e2e/images/images.cy.js | 24 +++--- cypress/e2e/mixins/audio.js | 22 ++--- cypress/e2e/mixins/image.js | 16 ++-- cypress/e2e/mixins/oddname.js | 23 ++---- cypress/e2e/mixins/video.js | 22 ++--- cypress/e2e/non-dav-files.cy.js | 15 ++-- .../e2e/sharing/download-share-disabled.cy.js | 20 ++--- cypress/e2e/sharing/download-share.cy.js | 21 +++-- cypress/e2e/sharing/files-shares.cy.js | 32 ++++---- cypress/e2e/sharing/single-file-share.cy.js | 27 +++--- cypress/e2e/videos/videos.cy.js | 26 +++--- cypress/e2e/visual-regression.cy.js | 24 +++--- cypress/support/commands.js | 82 +++---------------- cypress/utils/index.js | 33 -------- package-lock.json | 35 ++++++-- package.json | 3 +- 25 files changed, 248 insertions(+), 322 deletions(-) delete mode 100644 cypress/utils/index.js diff --git a/cypress.config.ts b/cypress.config.ts index de85f24d7..4fd7a320a 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -34,12 +34,15 @@ export default defineConfig({ trashAssetsBeforeRuns: true, e2e: { + // Enable session management and disable isolation + experimentalSessionAndOrigin: true, + testIsolation: 'off', + // 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', browserify()) - // on('file:preprocessor', webpackPreprocessor({ webpackOptions })) getCompareSnapshotsPlugin(on, config) // Disable spell checking to prevent rendering differences diff --git a/cypress/dockerNode.ts b/cypress/dockerNode.ts index 0c4066f9c..ae0b17bce 100644 --- a/cypress/dockerNode.ts +++ b/cypress/dockerNode.ts @@ -25,12 +25,12 @@ import waitOn from 'wait-on' import path from 'path' export const docker = new Docker() -const CONTAINER_NAME = 'nextcloud-cypress-tests' const pkg = require('../package.json'); const APP_PATH = path.resolve(__dirname, '../') const APP_NAME = pkg.name +const CONTAINER_NAME = 'nextcloud-cypress-tests-' + APP_NAME const SERVER_IMAGE = 'ghcr.io/nextcloud/continuous-integration-shallow-server' /** diff --git a/cypress/e2e/actions/delete.cy.js b/cypress/e2e/actions/delete.cy.js index 34ba15837..a530b97b5 100644 --- a/cypress/e2e/actions/delete.cy.js +++ b/cypress/e2e/actions/delete.cy.js @@ -20,25 +20,23 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Delete image.png in viewer', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image.png', 'image/png') - // Upload test files - cy.uploadFile(randUser, 'image.png', 'image/png') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See image.png in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="image.png"]', { timeout: 10000 }) .should('contain', 'image.png') }) diff --git a/cypress/e2e/actions/download.cy.js b/cypress/e2e/actions/download.cy.js index c72529acc..b16e91308 100644 --- a/cypress/e2e/actions/download.cy.js +++ b/cypress/e2e/actions/download.cy.js @@ -20,19 +20,21 @@ * */ -import { randHash } from '../../utils' import * as path from 'path' -const randUser = randHash() const fileName = 'image.png' describe(`Download ${fileName} in viewer`, function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, fileName, 'image/png') - // Upload test files - cy.uploadFile(randUser, fileName, 'image/png') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { @@ -40,9 +42,6 @@ describe(`Download ${fileName} in viewer`, function() { }) it(`See "${fileName}" in the list`, function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get(`.files-fileList tr[data-file="${fileName}"]`, { timeout: 10000 }) .should('contain', fileName) }) diff --git a/cypress/e2e/actions/sidebar.cy.js b/cypress/e2e/actions/sidebar.cy.js index 7bef449f1..9e3f7ec0a 100644 --- a/cypress/e2e/actions/sidebar.cy.js +++ b/cypress/e2e/actions/sidebar.cy.js @@ -21,28 +21,26 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open the sidebar from the viewer and open viewer with sidebar already opened', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image3.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image4.jpg', 'image/jpeg') + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image1.jpg', 'image/jpeg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg') + cy.uploadFile(user, 'image3.jpg', 'image/jpeg') + cy.uploadFile(user, 'image4.jpg', 'image/jpeg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See images in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="image1.jpg"]', { timeout: 10000 }) .should('contain', 'image1.jpg') cy.get('.files-fileList tr[data-file="image2.jpg"]', { timeout: 10000 }) diff --git a/cypress/e2e/audios/audios.cy.js b/cypress/e2e/audios/audios.cy.js index d51e9a2e6..ddca48fac 100644 --- a/cypress/e2e/audios/audios.cy.js +++ b/cypress/e2e/audios/audios.cy.js @@ -20,26 +20,28 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open mp3 and ogg audio in viewer', function() { + let randUser + before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + randUser = user - // Upload test file - cy.uploadFile(randUser, 'audio.mp3', 'audio/mpeg') - cy.uploadFile(randUser, 'audio.ogg', 'audio/ogg') + // Upload test files + cy.uploadFile(user, 'audio.mp3', 'audio/mpeg') + cy.uploadFile(user, 'audio.ogg', 'audio/ogg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See audios in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="audio.mp3"]', { timeout: 10000 }) .should('contain', 'audio.mp3') cy.get('.files-fileList tr[data-file="audio.ogg"]', { timeout: 10000 }) @@ -66,7 +68,7 @@ describe('Open mp3 and ogg audio in viewer', function() { it('The audio source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active audio') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/audio.mp3`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/audio.mp3`) }) it('Does not see a loading animation', function() { @@ -86,7 +88,7 @@ describe('Open mp3 and ogg audio in viewer', function() { it('The audio source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active audio') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/audio.ogg`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/audio.ogg`) }) it('Does not see a loading animation', function() { diff --git a/cypress/e2e/files.cy.js b/cypress/e2e/files.cy.js index f2879302e..5026f439e 100644 --- a/cypress/e2e/files.cy.js +++ b/cypress/e2e/files.cy.js @@ -20,18 +20,21 @@ * */ +import { User } from '@nextcloud/cypress' + describe('Files default view', function() { + const user = new User('admin', 'admin') + before(function() { - cy.login('admin', 'admin') + cy.login(user) }) + after(function() { cy.logout() }) it('See the default files list', function() { - cy.login('admin', 'admin') cy.visit('/apps/files') - cy.get('.files-fileList tr').should('contain', 'welcome.txt') }) diff --git a/cypress/e2e/images/images-custom-list-loadmore.cy.js b/cypress/e2e/images/images-custom-list-loadmore.cy.js index 293cefebf..40b787cf1 100644 --- a/cypress/e2e/images/images-custom-list-loadmore.cy.js +++ b/cypress/e2e/images/images-custom-list-loadmore.cy.js @@ -20,28 +20,26 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open custom list of images in viewer with pagination', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image3.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image4.jpg', 'image/jpeg') + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image1.jpg', 'image/jpeg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg') + cy.uploadFile(user, 'image3.jpg', 'image/jpeg') + cy.uploadFile(user, 'image4.jpg', 'image/jpeg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See images in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="image1.jpg"]', { timeout: 10000 }) .should('contain', 'image1.jpg') cy.get('.files-fileList tr[data-file="image2.jpg"]', { timeout: 10000 }) diff --git a/cypress/e2e/images/images-custom-list.cy.js b/cypress/e2e/images/images-custom-list.cy.js index 2a0ed140e..4e03b198e 100644 --- a/cypress/e2e/images/images-custom-list.cy.js +++ b/cypress/e2e/images/images-custom-list.cy.js @@ -20,28 +20,26 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open custom images list in viewer', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image3.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image4.jpg', 'image/jpeg') + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image1.jpg', 'image/jpeg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg') + cy.uploadFile(user, 'image3.jpg', 'image/jpeg') + cy.uploadFile(user, 'image4.jpg', 'image/jpeg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See images in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="image1.jpg"]', { timeout: 10000 }) .should('contain', 'image1.jpg') cy.get('.files-fileList tr[data-file="image2.jpg"]', { timeout: 10000 }) diff --git a/cypress/e2e/images/images.cy.js b/cypress/e2e/images/images.cy.js index 0c7c2e4a5..7d8deae20 100644 --- a/cypress/e2e/images/images.cy.js +++ b/cypress/e2e/images/images.cy.js @@ -20,28 +20,26 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open images in viewer', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image3.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'image4.jpg', 'image/jpeg') + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image1.jpg', 'image/jpeg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg') + cy.uploadFile(user, 'image3.jpg', 'image/jpeg') + cy.uploadFile(user, 'image4.jpg', 'image/jpeg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See images in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="image1.jpg"]', { timeout: 10000 }) .should('contain', 'image1.jpg') cy.get('.files-fileList tr[data-file="image2.jpg"]', { timeout: 10000 }) diff --git a/cypress/e2e/mixins/audio.js b/cypress/e2e/mixins/audio.js index a674a6230..d9c5c7886 100644 --- a/cypress/e2e/mixins/audio.js +++ b/cypress/e2e/mixins/audio.js @@ -20,9 +20,6 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - /** * Generate an audio cypress test * @@ -30,21 +27,26 @@ const randUser = randHash() * @param {string} mimeType the audio mime type */ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') { + let randUser + before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + randUser = user - // Upload test files - cy.uploadFile(randUser, fileName, mimeType) + // Upload test files + cy.uploadFile(user, fileName, mimeType) + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it(`See ${fileName} in the list`, function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get(`.files-fileList tr[data-file="${fileName}"]`, { timeout: 10000 }) .should('contain', fileName) }) @@ -75,6 +77,6 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') { it('The audio source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active audio') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/${fileName}`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/${fileName}`) }) } diff --git a/cypress/e2e/mixins/image.js b/cypress/e2e/mixins/image.js index 1ad75bd81..0e7ed73fb 100644 --- a/cypress/e2e/mixins/image.js +++ b/cypress/e2e/mixins/image.js @@ -20,9 +20,6 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - /** * Generate an image cypress test * @@ -33,19 +30,20 @@ const randUser = randHash() export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg', source = null) { before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, fileName, mimeType) - // Upload test files - cy.uploadFile(randUser, fileName, mimeType) + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it(`See ${fileName} in the list`, function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get(`.files-fileList tr[data-file="${fileName}"]`, { timeout: 10000 }) .should('contain', fileName) }) diff --git a/cypress/e2e/mixins/oddname.js b/cypress/e2e/mixins/oddname.js index 29bea1171..4107105fe 100644 --- a/cypress/e2e/mixins/oddname.js +++ b/cypress/e2e/mixins/oddname.js @@ -21,8 +21,6 @@ * */ -import { randHash } from '../../utils/' - /** * Make a name aimed to break the viewer in case of escaping errors * @@ -56,9 +54,6 @@ export default function(file, type) { // We'll escape all the characters in the name to match it with css const placedNameCss = CSS.escape(placedName) - // fresh user for each file - const randUser = randHash() + '@-' + randHash() // @ is allowed, so use it - const folderName = 'Nextcloud "%27%22%60%25%21%23" >`⛰️<' + file + "><` e*'rocks!#?#%~" @@ -70,15 +65,15 @@ export default function(file, type) { } // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.createFolder(randUser, `/${folderName}`) - cy.uploadFile(randUser, file, type, `/${folderName}/${placedName}`) - - // Visit nextcloud - cy.login(randUser) - cy.visit('/apps/files') + cy.createRandomUser().then(user => { + // Upload test files + cy.createFolder(user, `/${folderName}`) + cy.uploadFile(user, file, type, `/${folderName}/${placedName}`) + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) // wait a bit for things to be settled cy.openFile(folderName) diff --git a/cypress/e2e/mixins/video.js b/cypress/e2e/mixins/video.js index b7dc65cfc..c626ad6ce 100644 --- a/cypress/e2e/mixins/video.js +++ b/cypress/e2e/mixins/video.js @@ -20,9 +20,6 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - /** * Generate a video cypress test * @@ -30,21 +27,26 @@ const randUser = randHash() * @param {string} mimeType the video mime type */ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') { + let randUser + before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + randUser = user - // Upload test files - cy.uploadFile(randUser, fileName, mimeType) + // Upload test files + cy.uploadFile(user, fileName, mimeType) + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it(`See ${fileName} in the list`, function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get(`.files-fileList tr[data-file="${fileName}"]`, { timeout: 10000 }) .should('contain', fileName) }) @@ -75,6 +77,6 @@ export default function(fileName = 'image1.jpg', mimeType = 'image/jpeg') { it('The video source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active video') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/${fileName}`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/${fileName}`) }) } diff --git a/cypress/e2e/non-dav-files.cy.js b/cypress/e2e/non-dav-files.cy.js index 6e9fd7be8..94a9c91d0 100644 --- a/cypress/e2e/non-dav-files.cy.js +++ b/cypress/e2e/non-dav-files.cy.js @@ -20,28 +20,27 @@ */ import { basename as pathBasename } from '@nextcloud/paths' -import { randHash } from '../utils' -const randUser = randHash() const source = '/apps/theming/img/background/anatoly-mikhaltsov-butterfly-wing-scale.jpg' const basename = pathBasename(source) describe('Open non-dav files in viewer', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'test-card.mp4', 'video/mp4') - // Upload test file - cy.uploadFile(randUser, 'test-card.mp4', 'video/mp4') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('Open background', function() { - cy.login(randUser) - cy.visit('/apps/files') - const fileInfo = { filename: source, basename, diff --git a/cypress/e2e/sharing/download-share-disabled.cy.js b/cypress/e2e/sharing/download-share-disabled.cy.js index 7a42ae65e..3c4541efa 100644 --- a/cypress/e2e/sharing/download-share-disabled.cy.js +++ b/cypress/e2e/sharing/download-share-disabled.cy.js @@ -20,20 +20,21 @@ * */ -import { randHash } from '../../utils' - -const randUser = randHash() const fileName = 'image1.jpg' describe(`Download ${fileName} in viewer`, function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + // Upload test files + cy.createFolder(user, '/Photos') + cy.uploadFile(user, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') - // Upload test files - cy.createFolder(randUser, '/Photos') - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { // already logged out after visiting share link @@ -41,9 +42,6 @@ describe(`Download ${fileName} in viewer`, function() { }) it('See the default files list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr').should('contain', 'welcome.txt') cy.get('.files-fileList tr').should('contain', 'Photos') }) diff --git a/cypress/e2e/sharing/download-share.cy.js b/cypress/e2e/sharing/download-share.cy.js index 38364c9af..6bd9433c7 100644 --- a/cypress/e2e/sharing/download-share.cy.js +++ b/cypress/e2e/sharing/download-share.cy.js @@ -20,10 +20,8 @@ * */ -import { randHash } from '../../utils' import * as path from 'path' -const randUser = randHash() const fileName = 'image1.jpg' describe(`Download ${fileName} from viewer in link share`, function() { @@ -31,12 +29,16 @@ describe(`Download ${fileName} from viewer in link share`, function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.createFolder(randUser, '/Photos') - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') + cy.createRandomUser().then(user => { + // Upload test files + cy.createFolder(user, '/Photos') + cy.uploadFile(user, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { // already logged out after visiting share link @@ -44,9 +46,6 @@ describe(`Download ${fileName} from viewer in link share`, function() { }) it('See the default files list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr').should('contain', 'welcome.txt') cy.get('.files-fileList tr').should('contain', 'Photos') }) diff --git a/cypress/e2e/sharing/files-shares.cy.js b/cypress/e2e/sharing/files-shares.cy.js index b2413c0a7..b0cad3348 100644 --- a/cypress/e2e/sharing/files-shares.cy.js +++ b/cypress/e2e/sharing/files-shares.cy.js @@ -20,27 +20,29 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('See shared folder with link share', function() { before(function() { // Init user - cy.nextcloudCreateUser(randUser) - - // Upload test files - cy.createFolder(randUser, '/Photos') - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') - cy.uploadFile(randUser, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') - cy.uploadFile(randUser, 'image3.jpg', 'image/jpeg', '/Photos/image3.jpg') - cy.uploadFile(randUser, 'image4.jpg', 'image/jpeg', '/Photos/image4.jpg') - cy.uploadFile(randUser, 'video1.mp4', 'video/mp4', '/Photos/video1.mp4') + cy.createRandomUser().then(user => { + // Upload test files + cy.createFolder(user, '/Photos') + cy.uploadFile(user, 'image1.jpg', 'image/jpeg', '/Photos/image1.jpg') + cy.uploadFile(user, 'image2.jpg', 'image/jpeg', '/Photos/image2.jpg') + cy.uploadFile(user, 'image3.jpg', 'image/jpeg', '/Photos/image3.jpg') + cy.uploadFile(user, 'image4.jpg', 'image/jpeg', '/Photos/image4.jpg') + cy.uploadFile(user, 'video1.mp4', 'video/mp4', '/Photos/video1.mp4') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) + }) + after(function() { + // already logged out after visiting share link + // cy.logout() }) it('See the default files list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr').should('contain', 'welcome.txt') cy.get('.files-fileList tr').should('contain', 'Photos') }) diff --git a/cypress/e2e/sharing/single-file-share.cy.js b/cypress/e2e/sharing/single-file-share.cy.js index dbf98173a..d2a9870d3 100644 --- a/cypress/e2e/sharing/single-file-share.cy.js +++ b/cypress/e2e/sharing/single-file-share.cy.js @@ -20,27 +20,28 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('See shared folder with link share', function() { let imageToken let videoToken before(function() { - cy.nextcloudCreateUser(randUser) - - cy.uploadFile(randUser, 'image1.jpg', 'image/jpeg') - cy.uploadFile(randUser, 'video1.mp4', 'video/mp4') + // Init user + cy.createRandomUser().then(user => { + // Upload test files + cy.uploadFile(user, 'image1.jpg', 'image/jpeg') + cy.uploadFile(user, 'video1.mp4', 'video/mp4') - // Visit nextcloud - cy.login(randUser) - cy.visit('/apps/files') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') - cy.createLinkShare('/image1.jpg').then(token => { imageToken = token }) - cy.createLinkShare('/video1.mp4').then(token => { videoToken = token }) + // Create shares + cy.createLinkShare('/image1.jpg').then(token => { imageToken = token }) + cy.createLinkShare('/video1.mp4').then(token => { videoToken = token }) - cy.logout() + // Done + cy.logout() + }) }) it('Opens the shared image in the viewer', function() { diff --git a/cypress/e2e/videos/videos.cy.js b/cypress/e2e/videos/videos.cy.js index 83252b916..3348b129f 100644 --- a/cypress/e2e/videos/videos.cy.js +++ b/cypress/e2e/videos/videos.cy.js @@ -20,26 +20,28 @@ * */ -import { randHash } from '../../utils' -const randUser = randHash() - describe('Open mp4 videos in viewer', function() { + let randUser + before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + randUser = user - // Upload test file - cy.uploadFile(randUser, 'video1.mp4', 'video/mp4') - cy.uploadFile(randUser, 'video2.mp4', 'video/mp4') + // Upload test files + cy.uploadFile(user, 'video1.mp4', 'video/mp4') + cy.uploadFile(user, 'video2.mp4', 'video/mp4') + + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See videos in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="video1.mp4"]', { timeout: 10000 }) .should('contain', 'video1.mp4') cy.get('.files-fileList tr[data-file="video2.mp4"]', { timeout: 10000 }) @@ -66,7 +68,7 @@ describe('Open mp4 videos in viewer', function() { it('The video source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active video') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/video1.mp4`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/video1.mp4`) }) it('Does not see a loading animation', function() { @@ -86,7 +88,7 @@ describe('Open mp4 videos in viewer', function() { it('The video source is the remote url', function() { cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active video') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/video2.mp4`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/video2.mp4`) }) it('Does not see a loading animation', function() { diff --git a/cypress/e2e/visual-regression.cy.js b/cypress/e2e/visual-regression.cy.js index f62f82ecc..2b3716851 100644 --- a/cypress/e2e/visual-regression.cy.js +++ b/cypress/e2e/visual-regression.cy.js @@ -20,26 +20,28 @@ * */ -import { randHash } from '../utils' -const randUser = randHash() - describe('Visual regression tests ', function() { + let randUser + before(function() { // Init user - cy.nextcloudCreateUser(randUser) + cy.createRandomUser().then(user => { + randUser = user + + // Upload test files + cy.uploadFile(user, 'test-card.mp4', 'video/mp4') + cy.uploadFile(user, 'test-card.png', 'image/png') - // Upload test file - cy.uploadFile(randUser, 'test-card.mp4', 'video/mp4') - cy.uploadFile(randUser, 'test-card.png', 'image/png') + // Visit nextcloud + cy.login(user) + cy.visit('/apps/files') + }) }) after(function() { cy.logout() }) it('See files in the list', function() { - cy.login(randUser) - cy.visit('/apps/files') - cy.get('.files-fileList tr[data-file="test-card.mp4"]', { timeout: 10000 }) .should('contain', 'test-card.mp4') cy.get('.files-fileList tr[data-file="test-card.png"]', { timeout: 10000 }) @@ -61,7 +63,7 @@ describe('Visual regression tests ', function() { cy.get('body > .viewer .modal-container video').should('have.length', 1) cy.get('body > .viewer .modal-container .viewer__file.viewer__file--active video') .should('have.attr', 'src') - .and('contain', `/remote.php/dav/files/${randUser}/test-card.mp4`) + .and('contain', `/remote.php/dav/files/${randUser.userId}/test-card.mp4`) cy.get('body > .viewer button.prev').should('be.visible') cy.get('body > .viewer button.next').should('be.visible') }) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index b10a2a85c..ae3cfd567 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -20,81 +20,21 @@ * */ -// eslint-disable-next-line node/no-unpublished-import -import compareSnapshotCommand from 'cypress-visual-regression/dist/command' -import axios from '@nextcloud/axios' +import { addCommands, User } from '@nextcloud/cypress' import { basename } from 'path' +import axios from '@nextcloud/axios' +import compareSnapshotCommand from 'cypress-visual-regression/dist/command' +addCommands() compareSnapshotCommand() const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '') Cypress.env('baseUrl', url) -/** - * You should always upload files and/or create users - * before login, so that the cookies are NOT YET defined. - */ -Cypress.Commands.add('login', (user, password = user) => { - cy.clearCookies() - - // Keep sessions active between tests until - // we use the new cypress session API - Cypress.Cookies.defaults({ - preserve: /^(oc|nc)/, - }) - - cy.request('/csrftoken').then(({ body }) => { - const requesttoken = body.token - cy.request({ - method: 'POST', - url: '/login', - body: { user, password, requesttoken }, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - followRedirect: false, - }) - }) -}) - -Cypress.Commands.add('logout', () => { - cy.request('/csrftoken').then(({ body }) => { - const requestToken = body.token - cy.visit(`/logout?requesttoken=${encodeURIComponent(requestToken)}`) - }) - cy.clearCookies() -}) - -Cypress.Commands.add('nextcloudCreateUser', (user, password = user) => { - cy.clearCookies() - cy.request({ - method: 'POST', - url: `${Cypress.env('baseUrl')}/ocs/v1.php/cloud/users?format=json`, - form: true, - body: { - userid: user, - password, - }, - auth: { user: 'admin', pass: 'admin' }, - headers: { - 'OCS-ApiRequest': 'true', - 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Basic ${btoa('admin:admin')}`, - }, - }).then(response => { - if (response.body.ocs.meta.status.toLowerCase() === 'ok') { - cy.log(`Created user ${user}`, response.status) - } else { - cy.log(response) - throw new Error(`Unable to create user ${user}`) - } - }) -}) - /** * cy.uploadedFile - uploads a file from the fixtures folder * - * @param {string} user the owner of the file, e.g. admin + * @param {User} user the owner of the file, e.g. admin * @param {string} fixture the fixture file name, e.g. image1.jpg * @param {string} mimeType e.g. image/png * @param {string} [target] the target of the file relative to the user root @@ -109,7 +49,7 @@ Cypress.Commands.add('uploadFile', (user, fixture, mimeType, target = `/${fixtur const blob = Cypress.Blob.base64StringToBlob(file, mimeType) // Process paths - const rootPath = `${Cypress.env('baseUrl')}/remote.php/dav/files/${encodeURIComponent(user)}` + const rootPath = `${Cypress.env('baseUrl')}/remote.php/dav/files/${encodeURIComponent(user.userId)}` const filePath = target.split('/').map(encodeURIComponent).join('/') try { const file = new File([blob], fileName, { type: mimeType }) @@ -121,8 +61,8 @@ Cypress.Commands.add('uploadFile', (user, fixture, mimeType, target = `/${fixtur 'Content-Type': mimeType, }, auth: { - username: user, - password: user, + username: user.userId, + password: user.password, }, }).then(response => { cy.log(`Uploaded ${fixture} as ${fileName}`, response) @@ -139,15 +79,15 @@ Cypress.Commands.add('createFolder', (user, target) => { cy.clearCookies() const dirName = basename(target) - const rootPath = `${Cypress.env('baseUrl')}/remote.php/dav/files/${encodeURIComponent(user)}` + const rootPath = `${Cypress.env('baseUrl')}/remote.php/dav/files/${encodeURIComponent(user.userId)}` const dirPath = target.split('/').map(encodeURIComponent).join('/') cy.request({ url: `${rootPath}${dirPath}`, method: 'MKCOL', auth: { - username: user, - password: user, + username: user.userId, + password: user.password, }, }).then(response => { cy.log(`Created folder ${dirName}`, response) diff --git a/cypress/utils/index.js b/cypress/utils/index.js deleted file mode 100644 index 06a9f05ab..000000000 --- a/cypress/utils/index.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @copyright Copyright (c) 2019 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 . - * - */ - -export const getSearchParams = url => { - return url - .split(/[?&]/) - .reduce((acc, cur) => { - const parts = cur.split('=') - parts[1] && (acc[parts[0]] = parts[1]) - return acc - }, {}) -} - -export const randHash = () => Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 10) diff --git a/package-lock.json b/package-lock.json index c72bea74c..50927a13e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,13 +36,14 @@ "@cypress/browserify-preprocessor": "^3.0.2", "@nextcloud/babel-config": "^1.0.0", "@nextcloud/browserslist-config": "^2.3.0", + "@nextcloud/cypress": "^1.0.0-beta.1", "@nextcloud/eslint-config": "^8.0.0", "@nextcloud/stylelint-config": "^2.3.0", "@nextcloud/webpack-vue-config": "^5.4.0", "@types/dockerode": "^3.3.12", "@vue/tsconfig": "^0.1.3", "babel-loader-exclude-node-modules-except": "^1.2.1", - "cypress": "^10.11.0", + "cypress": "^11.0.1", "cypress-visual-regression": "^1.7.0", "dockerode": "^3.3.4", "eslint-plugin-cypress": "^2.12.1", @@ -3074,6 +3075,19 @@ "core-js": "^3.6.4" } }, + "node_modules/@nextcloud/cypress": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.1.tgz", + "integrity": "sha512-2tO8lGaeMLfyNDhqSXN8FVUXV6E6MPJSBdJs7y2jMg2lljtqJFo4ofgPi4bFksAVJK0qiqZInGn3UIzqMycyqQ==", + "dev": true, + "engines": { + "node": "^16.0.0", + "npm": "^7.0.0 || ^8.0.0" + }, + "peerDependencies": { + "cypress": "^11.0.1" + } + }, "node_modules/@nextcloud/dialogs": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz", @@ -6401,9 +6415,9 @@ "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==" }, "node_modules/cypress": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz", - "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-11.0.1.tgz", + "integrity": "sha512-NuEfd0Vim492RJ3m/+bbTZ3OZrqXgfAfuLaZfIQ9D5lKocS3EDr2tyAarZdAhKwLyoh7OJ33jwMeMFIDbzYqog==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -20594,6 +20608,13 @@ } } }, + "@nextcloud/cypress": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/@nextcloud/cypress/-/cypress-1.0.0-beta.1.tgz", + "integrity": "sha512-2tO8lGaeMLfyNDhqSXN8FVUXV6E6MPJSBdJs7y2jMg2lljtqJFo4ofgPi4bFksAVJK0qiqZInGn3UIzqMycyqQ==", + "dev": true, + "requires": {} + }, "@nextcloud/dialogs": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.2.0.tgz", @@ -23352,9 +23373,9 @@ "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==" }, "cypress": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz", - "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-11.0.1.tgz", + "integrity": "sha512-NuEfd0Vim492RJ3m/+bbTZ3OZrqXgfAfuLaZfIQ9D5lKocS3EDr2tyAarZdAhKwLyoh7OJ33jwMeMFIDbzYqog==", "dev": true, "requires": { "@cypress/request": "^2.88.10", diff --git a/package.json b/package.json index f6ba10c27..7d826c30c 100644 --- a/package.json +++ b/package.json @@ -72,13 +72,14 @@ "@cypress/browserify-preprocessor": "^3.0.2", "@nextcloud/babel-config": "^1.0.0", "@nextcloud/browserslist-config": "^2.3.0", + "@nextcloud/cypress": "^1.0.0-beta.1", "@nextcloud/eslint-config": "^8.0.0", "@nextcloud/stylelint-config": "^2.3.0", "@nextcloud/webpack-vue-config": "^5.4.0", "@types/dockerode": "^3.3.12", "@vue/tsconfig": "^0.1.3", "babel-loader-exclude-node-modules-except": "^1.2.1", - "cypress": "^10.11.0", + "cypress": "^11.0.1", "cypress-visual-regression": "^1.7.0", "dockerode": "^3.3.4", "eslint-plugin-cypress": "^2.12.1",