Skip to content

Commit 19ed452

Browse files
authored
Merge pull request #61883 from nextcloud/test/setup-pw
test(installer): migrate end-to-end tests to PlayWright
2 parents 900d937 + bd5fd38 commit 19ed452

9 files changed

Lines changed: 488 additions & 309 deletions

File tree

.github/workflows/cypress.yml

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -141,56 +141,10 @@ jobs:
141141
matrix:
142142
# Run multiple copies of the current job in parallel
143143
# Please increase the number or runners as your tests suite grows (0 based index for e2e tests)
144-
containers: ['setup', '0', '1', '2', '3']
145-
# Hack as strategy.job-total includes the "setup" and GitHub does not allow math expressions
144+
containers: ['0', '1', '2', '3']
146145
# Always align this number with the total of e2e runners (max. index + 1)
147146
total-containers: [4]
148147

149-
services:
150-
mysql:
151-
# Only start mysql if we are running the setup tests
152-
image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-mysql-8.4:latest' || ''}} # zizmor: ignore[unpinned-images]
153-
ports:
154-
- '3306/tcp'
155-
env:
156-
MYSQL_ROOT_PASSWORD: rootpassword
157-
MYSQL_USER: oc_autotest
158-
MYSQL_PASSWORD: nextcloud
159-
MYSQL_DATABASE: oc_autotest
160-
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
161-
162-
mariadb:
163-
# Only start mariadb if we are running the setup tests
164-
image: ${{matrix.containers == 'setup' && 'mariadb:11.4' || ''}} # zizmor: ignore[unpinned-images]
165-
ports:
166-
- '3306/tcp'
167-
env:
168-
MYSQL_ROOT_PASSWORD: rootpassword
169-
MYSQL_USER: oc_autotest
170-
MYSQL_PASSWORD: nextcloud
171-
MYSQL_DATABASE: oc_autotest
172-
options: --health-cmd="mariadb-admin ping" --health-interval 5s --health-timeout 2s --health-retries 5
173-
174-
postgres:
175-
# Only start postgres if we are running the setup tests
176-
image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-postgres-17:latest' || ''}} # zizmor: ignore[unpinned-images]
177-
ports:
178-
- '5432/tcp'
179-
env:
180-
POSTGRES_USER: root
181-
POSTGRES_PASSWORD: rootpassword
182-
POSTGRES_DB: nextcloud
183-
options: --mount type=tmpfs,destination=/var/lib/postgresql/data --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
184-
185-
oracle:
186-
# Only start oracle if we are running the setup tests
187-
image: ${{matrix.containers == 'setup' && 'ghcr.io/gvenzl/oracle-free:23' || ''}} # zizmor: ignore[unpinned-images]
188-
ports:
189-
- '1521'
190-
env:
191-
ORACLE_PASSWORD: oracle
192-
options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10
193-
194148
name: runner ${{ matrix.containers }}
195149

196150
steps:
@@ -254,7 +208,6 @@ jobs:
254208
SPLIT: ${{ matrix.total-containers }}
255209
SPLIT_INDEX: ${{ matrix.containers == 'component' && 0 || matrix.containers }}
256210
SPLIT_RANDOM_SEED: ${{ github.run_id }}
257-
SETUP_TESTING: ${{ matrix.containers == 'setup' && 'true' || '' }}
258211

259212
- name: Upload snapshots and videos
260213
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1

.github/workflows/playwright.yml

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,15 @@ jobs:
103103
submodules: true # for 3rdparty
104104

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

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

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

120117
- name: Install dependencies and build
@@ -147,10 +144,119 @@ jobs:
147144
path: blob-report
148145
retention-days: 1
149146

147+
playwright-installer-tests:
148+
needs: [gate, playwright-setup]
149+
timeout-minutes: 30
150+
name: Playwright tests for installer
151+
runs-on: ubuntu-latest
152+
153+
# The installation-wizard tests exercise every supported database backend, so
154+
# they need reachable database service containers. The Nextcloud container is
155+
# joined to the GitHub Actions network at startup so it can resolve these by
156+
# hostname (see tests/playwright/start-nextcloud-server.js).
157+
services:
158+
mysql:
159+
image: mysql:9.7 # zizmor: ignore[unpinned-images]
160+
ports:
161+
- '3306/tcp'
162+
env:
163+
MYSQL_ROOT_PASSWORD: rootpassword
164+
MYSQL_USER: nextcloud
165+
MYSQL_PASSWORD: nextcloud
166+
MYSQL_DATABASE: nextcloud
167+
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
168+
169+
mariadb:
170+
image: mariadb:12.3 # zizmor: ignore[unpinned-images]
171+
ports:
172+
- '3306/tcp'
173+
env:
174+
MARIADB_ROOT_PASSWORD: rootpassword
175+
MARIADB_USER: nextcloud
176+
MARIADB_PASSWORD: nextcloud
177+
MARIADB_DATABASE: nextcloud
178+
options: --health-cmd="mariadb-admin ping" --health-interval 5s --health-timeout 2s --health-retries 5
179+
180+
postgres:
181+
image: postgres:18 # zizmor: ignore[unpinned-images]
182+
ports:
183+
- '5432/tcp'
184+
env:
185+
POSTGRES_USER: root
186+
POSTGRES_PASSWORD: rootpassword
187+
POSTGRES_DB: nextcloud
188+
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
189+
190+
oracle:
191+
image: ghcr.io/gvenzl/oracle-free:23 # zizmor: ignore[unpinned-images]
192+
ports:
193+
- '1521'
194+
env:
195+
ORACLE_PASSWORD: oracle
196+
options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10
197+
198+
steps:
199+
- name: Restore context
200+
id: cache
201+
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
202+
with:
203+
key: playwright-context-${{ github.run_id }}
204+
path: ./
205+
206+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
207+
if: steps.cache.outputs.cache-hit != 'true'
208+
with:
209+
persist-credentials: false
210+
submodules: true # for 3rdparty
211+
212+
- name: Read package.json
213+
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
214+
id: versions
215+
216+
- name: Set up node
217+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
218+
with:
219+
node-version: ${{ steps.versions.outputs.node-version }}
220+
221+
- name: Set up npm
222+
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'
223+
224+
- name: Install dependencies and build
225+
if: steps.cache.outputs.cache-hit != 'true'
226+
run: |
227+
npm ci
228+
npm run build --if-present
229+
230+
- name: Install Playwright browsers
231+
run: npx playwright install --with-deps
232+
233+
- name: Run Playwright setup tests
234+
run: npm run playwright:setup
235+
env:
236+
PLAYWRIGHT_SETUP: 'true'
237+
238+
- name: Show logs
239+
if: failure()
240+
run: |
241+
for id in $(docker ps -aq); do
242+
docker container inspect "$id" --format '=== Logs for container {{.Name}} ==='
243+
docker logs "$id" >> nextcloud.log
244+
done
245+
echo '=== Nextcloud server logs ==='
246+
docker exec nextcloud-e2e-test-server_server cat data/nextcloud.log || true
247+
248+
- name: Upload blob report to GitHub Actions Artifacts
249+
if: ${{ !cancelled() }}
250+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
251+
with:
252+
name: blob-report-setup
253+
path: blob-report
254+
retention-days: 1
255+
150256
merge-reports:
151257
# Merge reports after playwright-tests, even if some shards have failed
152258
if: ${{ !cancelled() }}
153-
needs: [gate, playwright-tests]
259+
needs: [gate, playwright-tests, playwright-installer-tests]
154260

155261
runs-on: ubuntu-latest-low
156262
steps:
@@ -206,12 +312,12 @@ jobs:
206312
permissions:
207313
contents: none
208314
runs-on: ubuntu-latest-low
209-
needs: [gate, playwright-tests]
315+
needs: [gate, playwright-tests, playwright-installer-tests]
210316

211317
if: always()
212318

213319
name: playwright-test-summary
214320

215321
steps:
216322
- name: Summary status
217-
run: if ${{ needs.playwright-tests.result != 'success' }}; then exit 1; fi
323+
run: if ${{ needs.playwright-tests.result != 'success' || needs.playwright-installer-tests.result != 'success' }}; then exit 1; fi

cypress.config.ts

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
* SPDX-License-Identifier: AGPL-3.0-or-later
55
*/
66

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

@@ -116,15 +116,7 @@ export default defineConfig({
116116
}
117117
})
118118

119-
// Check if we are running the setup checks
120-
if (process.env.SETUP_TESTING === 'true') {
121-
console.log('Adding setup tests to specPattern 🧮')
122-
config.specPattern = [join(__dirname, 'cypress/e2e/core/setup.ts')]
123-
console.log('└─ Done')
124-
} else {
125-
// If we are not running the setup tests, we need to remove the setup tests from the specPattern
126-
cypressSplit(on, config)
127-
}
119+
cypressSplit(on, config)
128120

129121
const mounts = {
130122
'3rdparty': resolve(__dirname, './3rdparty'),
@@ -163,8 +155,6 @@ export default defineConfig({
163155
})
164156
// Setting container's IP as base Url
165157
config.baseUrl = `http://localhost:${port}/index.php`
166-
// if needed for the setup tests, connect to the actions network
167-
await connectToActionsNetwork()
168158
// make sure not to write into apps but use a local apps folder
169159
runExec(['mkdir', 'apps-cypress'])
170160
runExec(['cp', 'cypress/fixtures/app.config.php', 'config'])
@@ -185,26 +175,3 @@ export default defineConfig({
185175
},
186176
},
187177
})
188-
189-
/**
190-
* Connect the running test container to the GitHub Actions network
191-
*/
192-
async function connectToActionsNetwork() {
193-
if (process.env.SETUP_TESTING !== 'true') {
194-
console.log('├─ Not running setup tests, skipping actions network connection 🌐')
195-
return
196-
}
197-
198-
console.log('├─ Looking for github actions network... 🔍')
199-
const networks = await docker.listNetworks()
200-
const network = networks.find((network) => network.Name.startsWith('github_network'))
201-
if (!network) {
202-
console.log('│ └─ No actions network found ⚠️')
203-
return
204-
}
205-
206-
console.log('│ |─ Found actions network: ' + network.Name)
207-
await docker.getNetwork(network.Id)
208-
.connect({ Container: getContainer().id })
209-
console.log('│ └─ Connected to actions network 🌐')
210-
}

0 commit comments

Comments
 (0)