Skip to content
Open
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
12 changes: 0 additions & 12 deletions .eslintrc.json

This file was deleted.

142 changes: 69 additions & 73 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -1,106 +1,102 @@
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT

name: Playwright

on: pull_request

concurrency:
group: playwright-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read

env:
APP_NAME: ${{ github.event.repository.name }}
BRANCH: ${{ github.base_ref || github.ref_name }}
name: Playwright Tests
on:
pull_request:
branches: [master]

jobs:
playwright:
playwright-tests:
timeout-minutes: 60
runs-on: ubuntu-latest

name: Playwright E2E tests

strategy:
fail-fast: false
matrix:
shardIndex: [1, 2]
shardTotal: [2]
steps:
- name: Disabled on forks
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
run: |
echo 'Can not run Playwright on forks'
exit 1

- name: Checkout app
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Check composer.json
id: check_composer
uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
with:
files: 'composer.json'

- name: Install composer dependencies
if: steps.check_composer.outputs.files_exists == 'true'
run: composer install --no-dev

- name: Read package.json node and npm engines version
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
- name: Read package.json
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
with:
fallbackNode: '^24'
fallbackNpm: '^11'

- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- name: Set up node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}
node-version: ${{ steps.versions.outputs.node-version }}

- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
- name: Set up npm
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'

- name: Install dependencies & build app
- name: Install node dependencies & build app
run: |
npm ci
TESTING=true npm run build --if-present
npm run build --if-present

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

- name: Run Playwright tests
run: npx playwright test
env:
BRANCH: ${{ env.BRANCH }}
CI: true
run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

- name: Show Nextcloud logs on failure
if: failure()
run: |
docker exec nextcloud-e2e-test-server_${{ env.APP_NAME }} cat data/nextcloud.log || true

- name: Upload Playwright report
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 7
if-no-files-found: ignore

- name: Upload Playwright traces
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: failure()
with:
name: playwright-traces
path: test-results/
retention-days: 7
if-no-files-found: ignore
name: blob-report-${{ matrix.shardIndex }}
path: blob-report
retention-days: 1

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

summary:
runs-on: ubuntu-latest-low
needs: playwright
if: always()
name: playwright-summary
steps:
- name: Summary status
run: if ${{ needs.playwright.result != 'success' && needs.playwright.result != 'skipped' }}; then exit 1; fi
- name: Checkout app
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Read package.json
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions

- name: Set up node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: ${{ steps.versions.outputs.node-version }}

- name: Set up npm
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'

- name: Install dependencies
run: npm ci

- name: Download blob reports from GitHub Actions Artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true

- name: Merge into HTML Report
run: npx playwright merge-reports --config playwright/merge.config.ts ./all-blob-reports

- name: Upload HTML report
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: html-report--attempt-${{ github.run_attempt }}
path: playwright-report
retention-days: 14
44 changes: 44 additions & 0 deletions .github/workflows/vitest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT

name: Vitest

on:
pull_request:
branches: [master]

permissions:
contents: read

concurrency:
group: vitest-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
vitest:
runs-on: ubuntu-latest
name: Unit & component tests

steps:
- name: Checkout app
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Read package.json
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions

- name: Set up node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: ${{ steps.versions.outputs.node-version }}

- name: Set up npm
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'

- name: Install dependencies
run: npm ci

- name: Run vitest
run: npm run test:coverage
19 changes: 9 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ vendor
.php_cs.cache
.php-cs-fixer.cache

build/
coverage/
*.orig

# We do not ship the Roboto font files (only needed for Playwright) - but we need to ship the other font files
css/fonts/roboto-*
js/*roboto*

# Playwright files
playwright-report/
test-results/
blob-report/
playwright/.cache/
/playwright-report/
/test-results/
/blob-report/
/playwright/.cache/

# RelativeCI webpack bundle stats
webpack-stats.json
*.orig
.php-cs-fixer.cache

# Test coverage
/coverage/
15 changes: 3 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,10 @@ Show your latest holiday photos and videos like in the movies. Show a glimpse of
### 🧙 Advanced development stuff
To build the Javascript whenever you make changes, you can also run `npm run dev` for development builds.

### 📷 Running Playwright tests
The end-to-end tests use [Playwright](https://playwright.dev/) and a disposable Nextcloud Docker container.
### 🧪 Running tests
Unit and component tests run with [Vitest](https://vitest.dev): execute `npm run test`.

Build the app once, then run the tests:

```sh
npm ci
npx playwright install chromium
TESTING=true npm run build
npm run test:e2e
```

`npm run test:e2e:ui` opens the interactive UI. The Nextcloud container is started automatically by `playwright/start-server.mjs` (port 8081) and reused between local runs; set `PLAYWRIGHT_BASE_URL` to target an existing instance instead.
End-to-end tests run with [Playwright](https://playwright.dev) and require Docker to spin up a Nextcloud instance. Start the test server with `npm run playwright:start-nextcloud`, then run the tests with `npm run playwright`.

## API

Expand Down
16 changes: 2 additions & 14 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ SPDX-FileCopyrightText = "2023 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"

[[annotations]]
path = [".eslintrc.json"]
path = ["eslint.config.js", "stylelint.config.cjs", "rector.php"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"
Expand Down Expand Up @@ -83,12 +83,6 @@ precedence = "aggregate"
SPDX-FileCopyrightText = "2012 AnRo0002 <https://commons.wikimedia.org/wiki/User:AnRo0002>"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = ["playwright/fixtures/test-card.mp4", "playwright/fixtures/test-card.png"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2023 Bulgarian National Television <https://commons.wikimedia.org/wiki/File:Bulgarian_colour_testcard.png>"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = ["playwright/fixtures/audio.mp3", "playwright/fixtures/audio.ogg"]
precedence = "aggregate"
Expand All @@ -102,17 +96,11 @@ SPDX-FileCopyrightText = "2013 Wilfredor <https://commons.wikimedia.org/wiki/Use
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = ["playwright/fixtures/image.bmp", "playwright/fixtures/image.png", "playwright/fixtures/image.webp"]
path = ["playwright/fixtures/image.png", "playwright/fixtures/image.webp"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 Master Unknown <https://unsplash.com/@exp00>"
SPDX-License-Identifier = "LicenseRef-Unsplash"

[[annotations]]
path = ["playwright/fixtures/image.heic"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 HEIC Digital <https://heic.digital/download-sample/soundboard.heic>"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = ["img/app.svg"]
precedence = "aggregate"
Expand Down
12 changes: 12 additions & 0 deletions __mocks__/@nextcloud/event-bus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*!
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { vi } from 'vitest'

// Shared manual mock for the Nextcloud event bus. Enable per spec with
// `vi.mock('@nextcloud/event-bus')`, then import the spies to assert on them.
// Call history is reset between tests by the global setup (vi.clearAllMocks()).
export const emit = vi.fn()
export const subscribe = vi.fn()
export const unsubscribe = vi.fn()
Loading