Skip to content

refactor(tests): migrate e2e test suite from Cypress to Playwright#2603

Open
miaulalala wants to merge 6 commits into
masterfrom
refactor/cypress-to-playwright
Open

refactor(tests): migrate e2e test suite from Cypress to Playwright#2603
miaulalala wants to merge 6 commits into
masterfrom
refactor/cypress-to-playwright

Conversation

@miaulalala
Copy link
Copy Markdown
Collaborator

@miaulalala miaulalala commented May 19, 2026

Summary

  • Replaces Cypress + @nextcloud/cypress with @playwright/test + @nextcloud/e2e-test-server
  • All 9 original tests pass locally; the comment activity test remains skipped (pre-existing, pending a fix to the comments app)
  • Adds 7 new tests covering the activity stream page and admin settings page
  • Removes ~440 lines of Cypress config/boilerplate, adds ~750 lines of typed Playwright tests

Motivation

Cypress CI has been flaky enough to block dependabot auto-merge. Playwright's architecture (no iframes, direct browser protocol) is more reliable, and @nextcloud/e2e-test-server already ships a Playwright integration that handles Docker container management and user creation.

Key technical decisions

  • start-server.mjs: spins up an isolated Docker container on port 8081; reuseExistingServer lets local runs skip the Docker step if the container is already up
  • baseURL trailing slash: index.php/ (with slash) is required for the login helper's Origin header construction
  • No leading slash for SPA routes: navigating to apps/activity/all (without /) lets Playwright prepend the index.php/ base, which the Vue Router requires to match its routes
  • cssEscape() helper: CSS.escape() is a browser-only API; replaced with a Node-safe equivalent for attribute selector escaping
  • hover() before Actions click: file rows only fully activate the Actions button on hover; without it the dropdown can silently fail to open
  • Disabled checkboxes: email checkboxes are disabled when no SMTP is configured in the test instance; the settings test skips them
  • NcCheckboxRadioSwitch type="switch": wraps the input inside the label with no for attribute; must click the .checkbox-radio-switch wrapper instead of label[for="..."]

Test plan

  • All sidebar activity tests pass (creation, favorite, share, rename, move, tag)
  • All settings persistence tests pass (form, notification frequency, activity summary)
  • Activity stream tests: entry rendering, heading/filter label, navigation filter, RSS feed toggle
  • Admin settings tests: email enable toggle visible, default settings grid visible, toggle persists across reloads
  • CI workflow updated (playwright.yml replaces cypress.yml)
  • Close superseded PR chore(test): Migrate to @nc/e2e-test-server #2590 (artonge's partial Cypress→e2e-test-server migration)

🤖 Generated with Claude Code

@miaulalala miaulalala requested a review from artonge May 19, 2026 12:13
@miaulalala miaulalala self-assigned this May 19, 2026
@miaulalala miaulalala force-pushed the refactor/cypress-to-playwright branch from 4a62607 to f2e1e9a Compare May 19, 2026 12:13
Replaces the Cypress setup with @playwright/test + @nextcloud/e2e-test-server.
All 9 existing tests pass locally. The comment activity test remains skipped
pending a fix to the comments app (pre-existing skip from the Cypress suite).

Key changes:
- Add playwright.config.ts with managed Docker server via start-server.mjs
- Rewrite e2e helpers (filesUtils, sidebarUtils) using Playwright APIs
- Fix: replace CSS.escape() (browser-only API) with a Node-safe cssEscape()
- Fix: hover file row before clicking Actions to ensure dropdown opens
- Fix: skip disabled checkboxes in settings test (email disabled without SMTP)
- Fix: use numeric values for frequency select assertions (Weekly=2, Hourly=0)
- Add GitHub Actions workflow (playwright.yml), remove cypress.yml
- Remove all Cypress dependencies and config files

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Screenshots are being rebuilt centrally in the nextcloud/documentation repo
for the entire NC suite.

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Covers the activity stream page (entry rendering, heading/filter
navigation, RSS feed toggle) and the admin settings page (email
enable toggle visibility, default settings grid, and persistence
across page reloads).

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@miaulalala
Copy link
Copy Markdown
Collaborator Author

Needs an update for the branch protection rules - the cypress summary is still required there and can go immediately after.

@miaulalala miaulalala requested review from skjnldsv and susnux May 19, 2026 13:19
@miaulalala miaulalala added this to the Nextcloud 35 milestone May 19, 2026
Comment thread playwright.config.ts
Comment thread playwright.config.ts Outdated
Comment thread playwright.config.ts
Comment thread playwright.config.ts Outdated
Replaces the `url:` health-check with `wait: { stdout: /Nextcloud ready at/ }`
so Playwright waits for the explicit ready signal from start-server.mjs
rather than polling the HTTP port, which can respond before Nextcloud
finishes booting and cause flaky test starts.

Also adds gracefulShutdown so the start-server process is cleanly
terminated when Playwright exits.

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@miaulalala
Copy link
Copy Markdown
Collaborator Author

Thanks @susnux! Switched to wait: { stdout: /Nextcloud ready at/ } to wait for the explicit ready log line from start-server.mjs instead of polling the URL. Also added gracefulShutdown while I was at it.

Comment thread playwright.config.ts Outdated
Comment thread package.json Outdated
Comment thread playwright/start-server.mjs
Comment thread .github/workflows/playwright.yml
- Bump @playwright/test 1.49 → 1.60
- Enable fullyParallel, reduce CI retries to 1, keep workers: 1 (single
  container SQLite can't safely handle concurrent test sessions)
- Switch CI reporter to blob+dot+github; add merge-reports job so
  failed runs produce a downloadable HTML report
- Add SIGTERM/SIGINT handlers to start-server.mjs to cleanly stop the
  container in CI; locally the container is left running for reuse
- Add Nextcloud log dump step on CI failure

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Disable the app store to prevent external requests during tests
- Enable SQLite WAL mode with busyTimeout(5000) for better concurrency
- Initialize cron upfront so background jobs are seeded before tests run

Workers stays at 1: even with WAL mode, concurrent sessions for the
same admin user cause Nextcloud-level 500s, so parallelism isn't safe
with this container setup.

Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@miaulalala miaulalala requested a review from susnux May 19, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants