npx skills add ...
npx skills add umbraco/umbraco-cms-backoffice-skills --skill umbraco-e2e-testing
E2E testing for Umbraco backoffice extensions using Playwright and @umbraco-cms/acceptance-test-helpers
npx skills add umbraco/umbraco-cms-backoffice-skills --skill umbraco-e2e-testing
End-to-end testing for Umbraco backoffice extensions using Playwright and @umbraco-cms/acceptance-test-helpers. This approach tests against a real running Umbraco instance, validating complete user workflows.
Use @umbraco-cms/acceptance-test-helpers for core Umbraco operations:
| Package | Purpose | Why Required |
|---|---|---|
@umbraco-cms/acceptance-test-helpers | UI and API helpers | Handles auth, navigation, core entity CRUD |
@umbraco/json-models-builders | Test data builders | Creates valid Umbraco entities with correct structure |
Why use testhelpers for core Umbraco?
data-mark instead of data-testid - testhelpers handle thisSTORAGE_STAGE_PATHFor custom extensions, use umbracoUi.page (raw Playwright) because testhelpers don't know about your custom elements:
| Use Testhelpers For | Use umbracoUi.page For |
|---|---|
| Login/logout | Custom tree items |
| Navigate to ANY section (including custom) | Custom workspace elements |
| Create/edit documents via API | Custom entity actions |
| Built-in UI interactions | Custom UI components |
Umbraco-CMS/tests/Umbraco.Tests.AcceptanceTestAdd to package.json:
Then run:
Version Compatibility: Match testhelpers to your Umbraco version:
| Umbraco | Testhelpers |
|---|---|
| 18.x | ^18.0.0 |
| 17.x | ^17.0.15 |
| 14.x | ^14.x |
Create playwright.config.ts:
| Setting | Value | Why Required |
|---|---|---|
testIdAttribute | 'data-mark' | Umbraco uses data-mark, not data-testid |
STORAGE_STAGE_PATH | Path to user.json | Testhelpers read auth tokens from this file |
ignoreHTTPSErrors | true | For local dev with self-signed certs |
Without testIdAttribute: 'data-mark', all getByTestId() calls will fail.
Create tests/e2e/auth.setup.ts:
Create .env (add to .gitignore):
| Variable | Required | Purpose |
|---|---|---|
UMBRACO_URL | Yes | Backoffice URL |
UMBRACO_USER_LOGIN | Yes | Admin email |
UMBRACO_USER_PASSWORD | Yes | Admin password |
UMBRACO_DATA_PATH | No | App_Data path for test data reset (see "Testing with Persistent Data") |
Document Types:
Documents:
Data Types:
For complex test data, use @umbraco/json-models-builders:
Why use builders?
Navigation:
When testing custom tree extensions (e.g., in Settings), use this pattern to handle async loading and scrolling:
Why this pattern?
getByRole('link', { name: '...' }) is more reliable than generic umb-tree-item selectorsumb-tree-item, causing selector conflictsContent Actions:
Constants:
The tree-example demonstrates E2E testing for a custom tree extension:
Location: umbraco-backoffice/examples/tree-example/Client/
Key files:
tests/playwright.e2e.config.ts - E2E configuration with auth setuptests/auth.setup.ts - Authentication using testhelperstests/tree-e2e.spec.ts - Tests for custom tree in Settings sidebarThe notes-wiki demonstrates E2E testing with persistent data and CRUD operations:
Location: umbraco-backoffice/examples/notes-wiki/Client/
Key files:
tests/playwright.e2e.config.ts - Config with globalSetup for data resettests/global-setup.ts - Resets data to seed state before teststests/test-seed-data.json - Known test data (notes, folders)tests/notes-wiki-e2e.spec.ts - CRUD and navigation testsWhat it demonstrates:
goToSection('notes')When your extension persists data (JSON files, database, etc.), tests need predictable starting state.
Add globalSetup to reset data before tests:
playwright.e2e.config.ts:
global-setup.ts:
test-seed-data.json:
Add UMBRACO_DATA_PATH to locate your Umbraco's App_Data folder:
Custom sections work with testhelpers' goToSection() method - pass the section pathname:
Testing entity actions on tree items. Uses umbracoUi.page since testhelpers don't cover custom entity actions.
Important: Entity actions in Umbraco are rendered as buttons inside the dropdown menu, not as menuitem roles directly. The most reliable approach is to use the "View actions" button rather than right-click:
Right-click also works but the actions button approach is more reliable:
For custom extensions, use umbracoUi.page for UI interactions. For core Umbraco content, prefer umbracoApi helpers for setup/teardown.
When multiple tree items exist with similar elements, scope selectors to avoid ambiguity:
Ensure testIdAttribute: 'data-mark' is set in playwright.config.ts.
.env credentials are correctSTORAGE_STAGE_PATH is setnpx playwright install chromiumFor faster testing without a real Umbraco backend, use the mocked backoffice approach.
Invoke: skill: umbraco-mocked-backoffice
| Aspect | Real Backend (this skill) | MSW Mode |
|---|---|---|
| Setup | Running Umbraco instance | Clone Umbraco-CMS, npm install |
| Auth | Required | Not required |
| Speed | Slower | Faster |
| Use case | Integration/acceptance | UI/component testing |