# Towerops E2E Tests End-to-end tests using Playwright for testing the Towerops application against local development or staging environments. ## Setup ### 1. Install Dependencies ```bash cd e2e npm install npx playwright install ``` ### 2. Create Test User You need a test user with TOTP enabled. **Quick Setup (Recommended):** ```bash # 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](TOTP_SETUP.md)** ### 3. Configure Environment ```bash cp .env.example .env ``` Edit `.env` and set: - `TEST_USER_EMAIL` - Your test user email - `TEST_USER_PASSWORD` - Your test user password - `TEST_USER_TOTP_SECRET` - TOTP secret from step 2 ## Running Tests ### Local Development Make sure Phoenix is running first: ```bash cd .. mix phx.server ``` Then run tests: ```bash cd e2e npm test ``` ### Against Staging ```bash npm run test:staging ``` ### Other Commands ```bash # 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 switching - `devices.spec.ts` - Device listing, details, search/filter - `alerts.spec.ts` - Alert viewing, filtering, resolution ### Adding New Tests 1. Create a new `.spec.ts` file in `tests/` 2. Import test utilities: ```typescript import { test, expect } from '@playwright/test'; ``` 3. Write tests using Playwright's API Example: ```typescript 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 email - `TEST_USER_PASSWORD` - Test user password - `TEST_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: ```heex

<%= @device.name %>

``` Then in tests: ```typescript await page.locator('[data-test="device-card"]').first().click(); ``` ### 2. Wait for Network Idle For LiveView pages with dynamic content: ```typescript await page.waitForLoadState('networkidle'); ``` ### 3. Use Semantic Selectors Prefer role-based selectors when possible: ```typescript await page.getByRole('button', { name: 'Submit' }).click(); await page.getByRole('heading', { name: 'Devices' }).toBeVisible(); ``` ### 4. Handle Optional Elements Check if elements exist before interacting: ```typescript if (await page.getByText('No results').count() > 0) { // Handle empty state } ``` ### 5. Avoid Hard Timeouts Use `waitFor` methods instead of `waitForTimeout`: ```typescript // Good await page.getByText('Success').waitFor(); // Bad await page.waitForTimeout(3000); ``` ## CI/CD Integration ### GitHub Actions / GitLab CI ```yaml 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 ```bash # 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 ```bash # 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 `) ### Console Logs Add console logging in tests: ```typescript 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-test` attributes to elements - Use `page.waitForLoadState('networkidle')` before assertions - Check if LiveView is fully mounted before interacting ### Browser not launching ```bash # Reinstall browsers npx playwright install --with-deps ``` ## Resources - [Playwright Documentation](https://playwright.dev/) - [Playwright Test API](https://playwright.dev/docs/api/class-test) - [Best Practices](https://playwright.dev/docs/best-practices) - [Debugging Guide](https://playwright.dev/docs/debug)