diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2025-05-09 15:05:14 +0200 |
---|---|---|
committer | backportbot[bot] <backportbot[bot]@users.noreply.github.com> | 2025-05-12 09:13:50 +0000 |
commit | 61e399f20d36c02dbc9ee048d850ea8e86c91834 (patch) | |
tree | 3449c90d47bd3dd427f0f818252efe37bd23a096 | |
parent | e5a1b48f8a144342817ef79282127ead6cea57ad (diff) | |
download | nextcloud-server-backport/52755/stable29.tar.gz nextcloud-server-backport/52755/stable29.zip |
chore(cypress): add setup testsbackport/52755/stable29
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
[skip ci]
[skip ci]
-rw-r--r-- | .github/workflows/cypress.yml | 46 | ||||
-rw-r--r-- | core/src/components/setup/RecommendedApps.vue | 5 | ||||
-rw-r--r-- | cypress.config.ts | 19 | ||||
-rw-r--r-- | cypress/dockerNode.ts | 18 | ||||
-rw-r--r-- | cypress/e2e/core/setup.ts | 114 |
5 files changed, 198 insertions, 4 deletions
diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index fe5aaba375e..c7c437cf4f8 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -82,6 +82,51 @@ jobs: # Always aling this number with the total of e2e runners (max. index + 1) total-containers: [6] + services: + mysql: + # Only start mysql if we are running the setup tests + image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-mysql-8.4:latest' || ''}} + ports: + - '3306/tcp' + env: + MYSQL_ROOT_PASSWORD: rootpassword + MYSQL_USER: oc_autotest + MYSQL_PASSWORD: nextcloud + MYSQL_DATABASE: oc_autotest + options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10 + + mariadb: + # Only start mariadb if we are running the setup tests + image: ${{matrix.containers == 'setup' && 'mariadb:11.4' || ''}} + ports: + - '3306/tcp' + env: + MYSQL_ROOT_PASSWORD: rootpassword + MYSQL_USER: oc_autotest + MYSQL_PASSWORD: nextcloud + MYSQL_DATABASE: oc_autotest + options: --health-cmd="mariadb-admin ping" --health-interval 5s --health-timeout 2s --health-retries 5 + + postgres: + # Only start postgres if we are running the setup tests + image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-postgres-17:latest' || ''}} + ports: + - '5432/tcp' + env: + POSTGRES_USER: root + POSTGRES_PASSWORD: rootpassword + POSTGRES_DB: nextcloud + options: --mount type=tmpfs,destination=/var/lib/postgresql/data --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5 + + oracle: + # Only start oracle if we are running the setup tests + image: ${{matrix.containers == 'setup' && 'ghcr.io/gvenzl/oracle-free:23' || ''}} + ports: + - '1521' + env: + ORACLE_PASSWORD: oracle + options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10 + name: runner ${{ matrix.containers }} steps: @@ -119,6 +164,7 @@ jobs: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} SPLIT: ${{ matrix.total-containers }} SPLIT_INDEX: ${{ matrix.containers == 'component' && 0 || matrix.containers }} + SETUP_TESTING: ${{ matrix.containers == 'setup' && 'true' || '' }} - name: Upload snapshots uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 diff --git a/core/src/components/setup/RecommendedApps.vue b/core/src/components/setup/RecommendedApps.vue index 472c011c762..4aaf6d2b34a 100644 --- a/core/src/components/setup/RecommendedApps.vue +++ b/core/src/components/setup/RecommendedApps.vue @@ -20,7 +20,7 @@ --> <template> - <div class="guest-box"> + <div class="guest-box" data-cy-setup-recommended-apps> <h2>{{ t('core', 'Recommended apps') }}</h2> <p v-if="loadingApps" class="loading text-center"> {{ t('core', 'Loading apps …') }} @@ -59,7 +59,8 @@ <NcButton v-if="showInstallButton" type="tertiary" role="link" - :href="defaultPageUrl"> + :href="defaultPageUrl" + data-cy-setup-recommended-apps-skip> {{ t('core', 'Skip') }} </NcButton> diff --git a/cypress.config.ts b/cypress.config.ts index 4b96e052df9..9f4ad8e9dc8 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -3,6 +3,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import type { Configuration } from 'webpack' +import { defineConfig } from 'cypress' +import { join } from 'path' +import { removeDirectory } from 'cypress-delete-downloads-folder' + +import cypressSplit from 'cypress-split' +import webpackPreprocessor from '@cypress/webpack-preprocessor' + import { applyChangesToNextcloud, configureNextcloud, @@ -62,8 +69,6 @@ export default defineConfig({ // We've imported your old cypress plugins here. // You may want to clean this up later by importing these. async setupNodeEvents(on, config) { - cypressSplit(on, config) - on('file:preprocessor', webpackPreprocessor({ webpackOptions: webpackConfig as Configuration })) on('task', { removeDirectory }) @@ -106,6 +111,16 @@ export default defineConfig({ } }) + // Check if we are running the setup checks + if (process.env.SETUP_TESTING === 'true') { + console.log('Adding setup tests to specPattern 🧮') + config.specPattern = [join(__dirname, 'cypress/e2e/core/setup.ts')] + console.log('└─ Done') + } else { + // If we are not running the setup tests, we need to remove the setup tests from the specPattern + cypressSplit(on, config) + } + // Before the browser launches // starting Nextcloud testing container const ip = await startNextcloud(process.env.BRANCH) diff --git a/cypress/dockerNode.ts b/cypress/dockerNode.ts index 03c53c00c12..ba6a002c55b 100644 --- a/cypress/dockerNode.ts +++ b/cypress/dockerNode.ts @@ -290,3 +290,21 @@ const sleep = function(milliseconds: number) { const getCurrentGitBranch = function() { return execSync('git rev-parse --abbrev-ref HEAD').toString().trim() || 'master' } + +/** + * Get the network name of the github actions network + * This is used to connect to the database services + * started by github actions + */ +const getGithubNetwork = async function(): Promise<string|undefined> { + console.log('├─ Looking for github actions network... 🔍') + const networks = await docker.listNetworks() + const network = networks.find((network) => network.Name.startsWith('github_network')) + if (network) { + console.log('│ └─ Found github actions network: ' + network.Name) + return network.Name + } + + console.log('│ └─ No github actions network found') + return undefined +} diff --git a/cypress/e2e/core/setup.ts b/cypress/e2e/core/setup.ts new file mode 100644 index 00000000000..01606a75617 --- /dev/null +++ b/cypress/e2e/core/setup.ts @@ -0,0 +1,114 @@ +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +/** + * DO NOT RENAME THIS FILE to .cy.ts ⚠️ + * This is not following the pattern of the other files in this folder + * because it is manually added to the tests by the cypress config. + */ +describe('Can install Nextcloud', { testIsolation: true, retries: 0 }, () => { + beforeEach(() => { + // Move the config file and data folder + cy.runCommand('rm /var/www/html/config/config.php', { failOnNonZeroExit: false }) + cy.runCommand('rm /var/www/html/data/owncloud.db', { failOnNonZeroExit: false }) + }) + + it('Sqlite', () => { + cy.visit('/') + cy.get('[data-cy-setup-form]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible') + cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data') + + // Select the SQLite database + cy.get('[data-cy-setup-form-field="dbtype-sqlite"] input').check({ force: true }) + + sharedSetup() + }) + + it('MySQL', () => { + cy.visit('/') + cy.get('[data-cy-setup-form]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible') + cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data') + + // Select the SQLite database + cy.get('[data-cy-setup-form-field="dbtype-mysql"] input').check({ force: true }) + + // Fill in the DB form + cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}oc_autotest') + cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}nextcloud') + cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}oc_autotest') + cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}mysql:3306') + + sharedSetup() + }) + + it('MariaDB', () => { + cy.visit('/') + cy.get('[data-cy-setup-form]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible') + cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data') + + // Select the SQLite database + cy.get('[data-cy-setup-form-field="dbtype-mysql"] input').check({ force: true }) + + // Fill in the DB form + cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}oc_autotest') + cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}nextcloud') + cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}oc_autotest') + cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}mariadb:3306') + + sharedSetup() + }) + + it('PostgreSQL', () => { + cy.visit('/') + cy.get('[data-cy-setup-form]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible') + cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible') + cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data') + + // Select the SQLite database + cy.get('[data-cy-setup-form-field="dbtype-pgsql"] input').check({ force: true }) + + // Fill in the DB form + cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}root') + cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}rootpassword') + cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}nextcloud') + cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}postgres:5432') + + sharedSetup() + }) + +}) + +/** + * Shared admin setup function for the Nextcloud setup + */ +function sharedSetup() { + const randAdmin = 'admin-' + Math.random().toString(36).substring(2, 15) + + // Fill in the form + cy.get('[data-cy-setup-form-field="adminlogin"]').type(randAdmin) + cy.get('[data-cy-setup-form-field="adminpass"]').type(randAdmin) + + // Nothing more to do on sqlite, let's continue + cy.get('[data-cy-setup-form-submit]').click() + + // Wait for the setup to finish + cy.location('pathname', { timeout: 10000 }) + .should('include', '/core/apps/recommended') + + // Skip the setup apps + cy.get('[data-cy-setup-recommended-apps]').should('be.visible') + cy.get('[data-cy-setup-recommended-apps-skip]').click() + + // Go to files + cy.visit('/apps/files/') + cy.get('[data-cy-files-content]').should('be.visible') +} |