Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 1 addition & 48 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,56 +141,10 @@ jobs:
matrix:
# Run multiple copies of the current job in parallel
# Please increase the number or runners as your tests suite grows (0 based index for e2e tests)
containers: ['setup', '0', '1', '2', '3']
# Hack as strategy.job-total includes the "setup" and GitHub does not allow math expressions
containers: ['0', '1', '2', '3']
# Always align this number with the total of e2e runners (max. index + 1)
total-containers: [4]

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' || ''}} # zizmor: ignore[unpinned-images]
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' || ''}} # zizmor: ignore[unpinned-images]
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' || ''}} # zizmor: ignore[unpinned-images]
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' || ''}} # zizmor: ignore[unpinned-images]
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:
Expand Down Expand Up @@ -254,7 +208,6 @@ jobs:
SPLIT: ${{ matrix.total-containers }}
SPLIT_INDEX: ${{ matrix.containers == 'component' && 0 || matrix.containers }}
SPLIT_RANDOM_SEED: ${{ github.run_id }}
SETUP_TESTING: ${{ matrix.containers == 'setup' && 'true' || '' }}

- name: Upload snapshots and videos
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down
116 changes: 113 additions & 3 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,120 @@ jobs:
path: blob-report
retention-days: 1

playwright-installer-tests:
needs: [gate, playwright-setup]
timeout-minutes: 30
name: Playwright tests for installer
runs-on: ubuntu-latest

# The installation-wizard tests exercise every supported database backend, so
# they need reachable database service containers. The Nextcloud container is
# joined to the GitHub Actions network at startup so it can resolve these by
# hostname (see tests/playwright/start-nextcloud-server.js).
services:
mysql:
image: mysql:9.7 # zizmor: ignore[unpinned-images]
ports:
- '3306/tcp'
env:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: nextcloud
MYSQL_PASSWORD: nextcloud
MYSQL_DATABASE: nextcloud
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10

mariadb:
image: mariadb:12.3 # zizmor: ignore[unpinned-images]
ports:
- '3306/tcp'
env:
MARIADB_ROOT_PASSWORD: rootpassword
MARIADB_USER: nextcloud
MARIADB_PASSWORD: nextcloud
MARIADB_DATABASE: nextcloud
options: --health-cmd="mariadb-admin ping" --health-interval 5s --health-timeout 2s --health-retries 5

postgres:
image: postgres:18 # zizmor: ignore[unpinned-images]
ports:
- '5432/tcp'
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: rootpassword
POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5

oracle:
image: ghcr.io/gvenzl/oracle-free:23 # zizmor: ignore[unpinned-images]
ports:
- '1521'
env:
ORACLE_PASSWORD: oracle
options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10

steps:
- name: Restore context
id: cache
uses: buildjet/cache/restore@3e70d19e31d6a8030aeddf6ed8dbe601f94d09f4 # v4.0.2
with:
key: playwright-context-${{ github.run_id }}
path: ./

- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
if: steps.cache.outputs.cache-hit != 'true'
with:
persist-credentials: false
submodules: true # for 3rdparty

- name: Read package.json
if: steps.cache.outputs.cache-hit != 'true'
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions

- name: Set up node
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ steps.versions.outputs.node-version }}

- name: Set up npm
if: steps.cache.outputs.cache-hit != 'true'
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'

- name: Install dependencies and build
if: steps.cache.outputs.cache-hit != 'true'
run: |
npm ci
npm run build --if-present

- name: Install Playwright browsers
run: npx playwright install --with-deps

- name: Run Playwright setup tests
run: npm run playwright:setup

- name: Show logs
if: failure()
run: |
for id in $(docker ps -aq); do
docker container inspect "$id" --format '=== Logs for container {{.Name}} ==='
docker logs "$id" >> nextcloud.log
done
echo '=== Nextcloud server logs ==='
docker exec nextcloud-e2e-test-server_server cat data/nextcloud.log || true

- name: Upload blob report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: blob-report-setup
path: blob-report
retention-days: 1

merge-reports:
# Merge reports after playwright-tests, even if some shards have failed
if: ${{ !cancelled() }}
needs: [gate, playwright-tests]
needs: [gate, playwright-tests, playwright-installer-tests]

runs-on: ubuntu-latest-low
steps:
Expand Down Expand Up @@ -206,12 +316,12 @@ jobs:
permissions:
contents: none
runs-on: ubuntu-latest-low
needs: [gate, playwright-tests]
needs: [gate, playwright-tests, playwright-installer-tests]

if: always()

name: playwright-test-summary

steps:
- name: Summary status
run: if ${{ needs.playwright-tests.result != 'success' }}; then exit 1; fi
run: if ${{ needs.playwright-tests.result != 'success' || needs.playwright-installer-tests.result != 'success' }}; then exit 1; fi
39 changes: 3 additions & 36 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { configureNextcloud, docker, getContainer, getContainerName, runExec, runOcc, startNextcloud, stopNextcloud, waitOnNextcloud } from '@nextcloud/e2e-test-server'
import { configureNextcloud, getContainerName, runExec, runOcc, startNextcloud, stopNextcloud, waitOnNextcloud } from '@nextcloud/e2e-test-server'
import { defineConfig } from 'cypress'
import cypressSplit from 'cypress-split'
import vitePreprocessor from 'cypress-vite'
import { existsSync, rmSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

Expand Down Expand Up @@ -116,15 +116,7 @@ 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)
}
cypressSplit(on, config)

const mounts = {
'3rdparty': resolve(__dirname, './3rdparty'),
Expand Down Expand Up @@ -163,8 +155,6 @@ export default defineConfig({
})
// Setting container's IP as base Url
config.baseUrl = `http://localhost:${port}/index.php`
// if needed for the setup tests, connect to the actions network
await connectToActionsNetwork()
// make sure not to write into apps but use a local apps folder
runExec(['mkdir', 'apps-cypress'])
runExec(['cp', 'cypress/fixtures/app.config.php', 'config'])
Expand All @@ -185,26 +175,3 @@ export default defineConfig({
},
},
})

/**
* Connect the running test container to the GitHub Actions network
*/
async function connectToActionsNetwork() {
if (process.env.SETUP_TESTING !== 'true') {
console.log('├─ Not running setup tests, skipping actions network connection 🌐')
return
}

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('│ └─ No actions network found ⚠️')
return
}

console.log('│ |─ Found actions network: ' + network.Name)
await docker.getNetwork(network.Id)
.connect({ Container: getContainer().id })
console.log('│ └─ Connected to actions network 🌐')
}
Loading
Loading