When modifying loader/action patterns:
- Ensure loaders use
LoaderFunction<RouterContextProvider> - Ensure actions use
ActionFunction<RouterContextProvider> - Always get the client from context in loaders/actions
- Run
yarn run tsc --noEmitto check for TypeScript errors - Test actual navigation flows to ensure data loading works
The project includes Playwright test infrastructure for browser-based end-to-end tests. The helpers are located in playwright-tests/ and handle authentication, user creation, and permissions.
import { test, expect } from '@playwright/test';
import { setupAndLogin } from './helpers/login';
test('can access admin page', async ({ page }) => {
const conventionDomain = 'myconvention.intercode.test';
await page.goto(`https://${conventionDomain}:5050/admin`);
// Creates test user with admin permissions and logs in
await setupAndLogin(page, conventionDomain, ['update_convention']);
await expect(page.locator('h1')).toBeVisible();
});setupAndLogin(page, conventionDomain, permissions?)
- Creates a test user in the database
- Grants specified permissions (default: none)
- Logs in via the UI
- Reloads the page to ensure auth state is picked up
ensureTestUser(conventionDomain, permissions?)
- Creates/updates a test user via Rails
- Grants permissions via staff positions
- Returns credentials for manual login
login(page, credentials)
- Handles the UI login flow only
- Waits for login modal, fills credentials, submits
Tests must explicitly request permissions. Common permissions:
update_convention- Admin access to convention settingsread_schedule- View schedulesupdate_events- Manage eventsmanage_signups- Manage user signupsread_reports- View reports
See config/permission_names.json for all available permissions.
// Regular user (no special permissions)
await setupAndLogin(page, 'mycon.test');
// Admin user
await setupAndLogin(page, 'mycon.test', ['update_convention']);
// Multiple permissions
await setupAndLogin(page, 'mycon.test', ['update_events', 'read_schedule', 'manage_signups']);TEST_EMAIL- Email for test user (default:playwright-test@example.com)TEST_PASSWORD- Password (default:TestPassword123!)RAILS_ENV- Rails environment (default:development)
# Run all tests
yarn playwright test
# Run specific test file
yarn playwright test my-test.spec.ts
# Run with visible browser
yarn playwright test --headed
# Debug mode
yarn playwright test --debug- Always specify convention domain - No hardcoded defaults
- Request minimum permissions - Only grant what the test needs
- Test users are persistent - Created once and reused across runs
- Use the UI for login - Tests use actual login flow, not session manipulation
See playwright-tests/README.md for comprehensive documentation.