- Add comprehensive TOTP_SETUP.md with multiple setup options - Create scripts/create_test_user.exs for automated test user creation - Update .gitignore to exclude Playwright browser binaries and artifacts - Update README to reference TOTP setup guide
6 KiB
Towerops E2E Tests
End-to-end tests using Playwright for testing the Towerops application against local development or staging environments.
Setup
1. Install Dependencies
cd e2e
npm install
npx playwright install
2. Create Test User
You need a test user with TOTP enabled.
Quick Setup (Recommended):
# From the Phoenix app directory
cd ..
mix run e2e/scripts/create_test_user.exs
This creates a test user with known credentials and outputs the configuration for your .env file.
For detailed TOTP setup instructions, see TOTP_SETUP.md
3. Configure Environment
cp .env.example .env
Edit .env and set:
TEST_USER_EMAIL- Your test user emailTEST_USER_PASSWORD- Your test user passwordTEST_USER_TOTP_SECRET- TOTP secret from step 2
Running Tests
Local Development
Make sure Phoenix is running first:
cd ..
mix phx.server
Then run tests:
cd e2e
npm test
Against Staging
npm run test:staging
Other Commands
# Run tests with UI (interactive mode)
npm run test:ui
# Run tests with browser visible
npm run test:headed
# Debug a specific test
npm run test:debug -- tests/devices.spec.ts
# Generate tests by recording actions
npm run codegen
# View last test report
npm run report
Test Organization
tests/auth.setup.ts
Authentication setup that runs before all other tests. Logs in once and saves the session state so other tests don't need to authenticate.
Test Files
organizations.spec.ts- Organization listing and switchingdevices.spec.ts- Device listing, details, search/filteralerts.spec.ts- Alert viewing, filtering, resolution
Adding New Tests
- Create a new
.spec.tsfile intests/ - Import test utilities:
import { test, expect } from '@playwright/test'; - Write tests using Playwright's API
Example:
import { test, expect } from '@playwright/test';
test.describe('My Feature', () => {
test('can do something', async ({ page }) => {
await page.goto('/my-page');
await expect(page.getByRole('heading')).toBeVisible();
});
});
Configuration
Environment Variables
BASE_URL- Base URL of the application (default: http://localhost:4000)TEST_USER_EMAIL- Test user emailTEST_USER_PASSWORD- Test user passwordTEST_USER_TOTP_SECRET- TOTP secret for test user
Playwright Config
Edit playwright.config.ts to:
- Add/remove browsers
- Change timeout settings
- Configure reporters
- Add mobile viewports
- Enable video recording
Best Practices
1. Use Data Test Attributes
Add data-test attributes to important elements in your templates:
<div data-test="device-card">
<h3 data-test="device-name"><%= @device.name %></h3>
</div>
Then in tests:
await page.locator('[data-test="device-card"]').first().click();
2. Wait for Network Idle
For LiveView pages with dynamic content:
await page.waitForLoadState('networkidle');
3. Use Semantic Selectors
Prefer role-based selectors when possible:
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('heading', { name: 'Devices' }).toBeVisible();
4. Handle Optional Elements
Check if elements exist before interacting:
if (await page.getByText('No results').count() > 0) {
// Handle empty state
}
5. Avoid Hard Timeouts
Use waitFor methods instead of waitForTimeout:
// Good
await page.getByText('Success').waitFor();
// Bad
await page.waitForTimeout(3000);
CI/CD Integration
GitHub Actions / GitLab CI
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: |
cd e2e
npm ci
npx playwright install --with-deps
- name: Run tests
run: |
cd e2e
BASE_URL=${{ secrets.STAGING_URL }} npm test
env:
TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }}
TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
TEST_USER_TOTP_SECRET: ${{ secrets.TEST_USER_TOTP_SECRET }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: e2e/playwright-report/
Debugging
Visual Debugging
# Open test in UI mode
npm run test:ui
# Run specific test with browser visible
npm run test:headed -- tests/devices.spec.ts
Debug Mode
# Opens Playwright Inspector
npm run test:debug -- tests/devices.spec.ts
Screenshots and Videos
Failed tests automatically capture:
- Screenshots (in
test-results/) - Videos (in
test-results/) - Traces (view with
npx playwright show-trace <trace-file>)
Console Logs
Add console logging in tests:
test('debug test', async ({ page }) => {
page.on('console', msg => console.log('Browser:', msg.text()));
await page.goto('/devices');
});
Troubleshooting
"Authentication failed" or TOTP errors
- Verify TOTP secret is correct in
.env - Check test user exists and has TOTP enabled
- Ensure test user has access to at least one organization
Tests timing out
- Increase timeout in
playwright.config.ts - Check Phoenix server is running
- Verify BASE_URL is correct
- Check network connectivity to staging
"Element not found" errors
- Add
data-testattributes to elements - Use
page.waitForLoadState('networkidle')before assertions - Check if LiveView is fully mounted before interacting
Browser not launching
# Reinstall browsers
npx playwright install --with-deps