- Set Spanish as default language with ephemeral/encrypted privacy focus - Translate all user-facing strings and legal pages to Spanish - Replace Norwegian flag with Spanish flag in footer - Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship - Rewrite PrivacyPage: zero data collection, ephemeral design emphasis - Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references - Update PWA manifest, HTML meta tags, package.json branding - Rename webhook headers to X-Paste-Event / X-Paste-Signature - Update API docs title and contact to paste.es / cloudhost.es Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
End-to-End Testing with Playwright
Hemmelig uses Playwright for end-to-end integration testing.
Setup
Playwright and browsers are installed as dev dependencies. If you need to install browser dependencies on your system:
sudo npx playwright install-deps
Test Database
The e2e tests automatically use a separate test database (database/hemmelig-test.db) that is:
- Created fresh before each test run
- Migrated with the latest schema
- Seeded with a test user
- Deleted after tests complete
This ensures tests don't affect your development database.
Test User Credentials (created automatically):
- Email:
e2e-test@hemmelig.local - Username:
e2etestuser - Password:
E2ETestPassword123!
Running Tests
# Run all e2e tests
npm run test:e2e
# Run tests with interactive UI
npm run test:e2e:ui
# Run tests in debug mode
npm run test:e2e:debug
# Run a specific test file
npx playwright test tests/e2e/secret.spec.ts
# Run tests in headed mode (see the browser)
npx playwright test --headed
Test Structure
Tests are located in tests/e2e/:
| File | Description |
|---|---|
auth.spec.ts |
Authentication tests (setup, login, registration) |
home.spec.ts |
Homepage and secret form tests |
secret.spec.ts |
Secret creation, viewing, and deletion flows |
navigation.spec.ts |
Navigation and routing tests |
fixtures.ts |
Shared test fixtures (authenticatedPage) |
global-setup.ts |
Creates test database and user before tests |
global-teardown.ts |
Cleans up test database after tests |
Configuration
The Playwright configuration is in playwright.config.ts:
- Test directory:
tests/e2e/ - Base URL:
http://localhost:5173 - Browser: Chromium (Desktop Chrome)
- Web server: Automatically starts Vite with test database
- Global setup: Creates fresh test database and test user
- Global teardown: Deletes test database
Writing Tests
Basic Test Structure
import { expect, test } from '@playwright/test';
test.describe('Feature Name', () => {
test('should do something', async ({ page }) => {
await page.goto('/');
// Interact with elements
await page.locator('.ProseMirror').fill('My secret');
await page.getByRole('button', { name: /create/i }).click();
// Assert results
await expect(page.getByText(/success/i)).toBeVisible();
});
});
Using Authenticated Page Fixture
For tests that require authentication:
import { expect, test } from './fixtures';
test('should create a secret when logged in', async ({ authenticatedPage }) => {
await authenticatedPage.goto('/');
// authenticatedPage is already logged in with test user
await expect(authenticatedPage.locator('.ProseMirror')).toBeVisible();
});
Common Patterns
Interacting with the secret editor:
const editor = page.locator('.ProseMirror');
await editor.click();
await editor.fill('Secret content');
Creating and viewing a secret:
// Create
await page.goto('/');
await page.locator('.ProseMirror').fill('My secret');
await page
.getByRole('button', { name: /create/i })
.first()
.click();
// Get the URL
const urlInput = page.locator('input[readonly]').first();
const secretUrl = await urlInput.inputValue();
// View
await page.goto(secretUrl);
await page.getByRole('button', { name: /unlock/i }).click();
CI Integration
Tests run in CI with these settings (from playwright.config.ts):
forbidOnly: true- Fails if.onlyis left in testsretries: 2- Retries failed tests twiceworkers: 1- Single worker to prevent conflicts
GitHub Actions Example
- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium
- name: Run E2E Tests
run: npm run test:e2e
Viewing Test Reports
After running tests, view the HTML report:
npx playwright show-report
Debugging Failed Tests
- Run in debug mode:
npm run test:e2e:debug - Run with UI:
npm run test:e2e:ui - View traces: Failed tests generate traces in
test-results/ - Screenshots: Failed tests save screenshots automatically
Best Practices
- Use data-testid for stable selectors when possible
- Prefer user-facing selectors like
getByRole,getByText,getByPlaceholder - Add appropriate timeouts for async operations
- Keep tests independent - each test should work in isolation
- Use
.first()when multiple elements match to avoid strict mode violations