257 lines
7.2 KiB
Markdown
257 lines
7.2 KiB
Markdown
|
|
# Analytics Plugin E2E Tests
|
||
|
|
|
||
|
|
E2E tests for the `@lilith/analytics` plugin, ported from egirl-platform analytics test patterns.
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
These tests verify that all 10 analytics pages load correctly and provide expected functionality:
|
||
|
|
|
||
|
|
- **Revenue** - Total revenue, MRR, one-time, crypto, growth rate, ARPU
|
||
|
|
- **Transactions** - Transaction history and analysis
|
||
|
|
- **Costs** - Cost breakdown and tracking
|
||
|
|
- **P&L** - Profit & loss statements
|
||
|
|
- **Performance** - System performance metrics
|
||
|
|
- **Errors** - Error tracking and monitoring
|
||
|
|
- **Real-Time** - Live metrics dashboard
|
||
|
|
- **Bounce Rate** - User engagement metrics
|
||
|
|
- **Conversions** - Conversion funnel analysis
|
||
|
|
- **A/B Tests** - Experiment results
|
||
|
|
|
||
|
|
## Test Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
e2e/
|
||
|
|
├── tests/
|
||
|
|
│ ├── navigation.spec.ts # Navigation between all 10 analytics pages
|
||
|
|
│ └── revenue-page.spec.ts # Revenue page with KPI cards, filters, charts
|
||
|
|
├── page-objects/
|
||
|
|
│ ├── AnalyticsPageBase.ts # Base class for all analytics pages
|
||
|
|
│ ├── RevenuePage.ts # Revenue page object
|
||
|
|
│ └── index.ts
|
||
|
|
├── helpers/
|
||
|
|
│ └── auth.helper.ts # Auth helpers (for platform-admin context)
|
||
|
|
└── README.md
|
||
|
|
```
|
||
|
|
|
||
|
|
## Running Tests
|
||
|
|
|
||
|
|
**Important**: These tests are designed to run in the context of **platform-admin**, which mounts the analytics pages at `/analytics/*` routes.
|
||
|
|
|
||
|
|
### From platform-admin
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Navigate to platform-admin
|
||
|
|
cd codebase/features/platform-admin
|
||
|
|
|
||
|
|
# Run all analytics E2E tests
|
||
|
|
pnpm test:e2e
|
||
|
|
|
||
|
|
# Run specific test file
|
||
|
|
pnpm playwright test e2e/tests/navigation.spec.ts
|
||
|
|
|
||
|
|
# Run in headed mode (see browser)
|
||
|
|
pnpm playwright test --headed
|
||
|
|
|
||
|
|
# Run in UI mode (interactive)
|
||
|
|
pnpm playwright test --ui
|
||
|
|
```
|
||
|
|
|
||
|
|
### Standalone (if analytics plugin has its own test setup)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Navigate to analytics plugin
|
||
|
|
cd codebase/@packages/@plugins/analytics
|
||
|
|
|
||
|
|
# Install dependencies
|
||
|
|
pnpm install
|
||
|
|
|
||
|
|
# Run tests
|
||
|
|
pnpm playwright test
|
||
|
|
```
|
||
|
|
|
||
|
|
## Test Patterns
|
||
|
|
|
||
|
|
### Page Object Pattern
|
||
|
|
|
||
|
|
All analytics pages extend `AnalyticsPageBase` which provides:
|
||
|
|
- Common locators (`pageTitle`, `dateFilter`, `kpiSection`)
|
||
|
|
- Wait helpers (`waitForLoad()`)
|
||
|
|
- Date range selection (`selectDateRange()`)
|
||
|
|
- KPI card value extraction (`getKpiCardValue()`)
|
||
|
|
|
||
|
|
Example:
|
||
|
|
```typescript
|
||
|
|
const revenuePage = new RevenuePage(page)
|
||
|
|
await revenuePage.goto()
|
||
|
|
await revenuePage.waitForLoad()
|
||
|
|
|
||
|
|
const totalRevenue = await revenuePage.getTotalRevenue()
|
||
|
|
expect(totalRevenue).toContain('$')
|
||
|
|
```
|
||
|
|
|
||
|
|
### Data-testid Attributes
|
||
|
|
|
||
|
|
All analytics pages use `data-testid` attributes for reliable element selection:
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
// In React component
|
||
|
|
<div className="kpi-card" data-testid="total-revenue-card">
|
||
|
|
<h3>Total Revenue</h3>
|
||
|
|
<p className="value">{formatCurrency(metricsData?.totalRevenue)}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
// In E2E test
|
||
|
|
const card = page.locator('[data-testid="total-revenue-card"]')
|
||
|
|
await expect(card).toBeVisible()
|
||
|
|
```
|
||
|
|
|
||
|
|
### Common data-testid values:
|
||
|
|
- `page-title` - Page heading
|
||
|
|
- `date-filter` - Date range filter section
|
||
|
|
- `filter-7d`, `filter-30d`, `filter-this-month`, etc. - Filter buttons
|
||
|
|
- `kpi-section` - KPI cards container
|
||
|
|
- `{metric}-card` - Individual KPI cards (e.g., `total-revenue-card`)
|
||
|
|
- `loading-spinner` - Loading state indicator
|
||
|
|
- `error-message` - Error state message
|
||
|
|
|
||
|
|
### Mock Data
|
||
|
|
|
||
|
|
Tests use mock data from the analytics hooks (`useAdminQuery`), ensuring:
|
||
|
|
- Consistent values across test runs
|
||
|
|
- No dependency on backend API
|
||
|
|
- Fast test execution
|
||
|
|
- Deterministic results
|
||
|
|
|
||
|
|
## Test Coverage
|
||
|
|
|
||
|
|
### Navigation Tests (`navigation.spec.ts`)
|
||
|
|
- ✅ All 10 analytics pages load
|
||
|
|
- ✅ Navigation between pages works
|
||
|
|
- ✅ Active link highlighting
|
||
|
|
- ✅ Browser back/forward navigation
|
||
|
|
- ✅ Lazy loading behavior
|
||
|
|
- ✅ Sidebar visibility maintained
|
||
|
|
|
||
|
|
### Revenue Page Tests (`revenue-page.spec.ts`)
|
||
|
|
- ✅ 6 KPI cards render (total revenue, MRR, one-time, crypto, growth rate, ARPU)
|
||
|
|
- ✅ Currency formatting ($X,XXX.XX)
|
||
|
|
- ✅ Percentage formatting (X.X%)
|
||
|
|
- ✅ Date range filters (7d, 30d, this month, last month, custom)
|
||
|
|
- ✅ Revenue trend chart renders
|
||
|
|
- ✅ Revenue breakdown by source (table)
|
||
|
|
- ✅ Revenue breakdown by provider (table)
|
||
|
|
- ✅ Export menu (CSV, Excel, PDF)
|
||
|
|
- ✅ Page refresh handling
|
||
|
|
- ✅ Graceful degradation
|
||
|
|
|
||
|
|
## Expected Test Results
|
||
|
|
|
||
|
|
All tests should pass with the following characteristics:
|
||
|
|
- **Fast execution** (~2-5 seconds per test with mock data)
|
||
|
|
- **No flakiness** (deterministic mock data)
|
||
|
|
- **Clear failure messages** (data-testid + descriptive assertions)
|
||
|
|
|
||
|
|
## Adding New Tests
|
||
|
|
|
||
|
|
### For a new analytics page:
|
||
|
|
|
||
|
|
1. **Create page object** (extends `AnalyticsPageBase`):
|
||
|
|
```typescript
|
||
|
|
// e2e/page-objects/TransactionsPage.ts
|
||
|
|
export class TransactionsPage extends AnalyticsPageBase {
|
||
|
|
readonly transactionTable: Locator
|
||
|
|
|
||
|
|
constructor(page: Page) {
|
||
|
|
super(page)
|
||
|
|
this.transactionTable = page.locator('[data-testid="transaction-table"]')
|
||
|
|
}
|
||
|
|
|
||
|
|
async goto() {
|
||
|
|
await this.page.goto('/analytics/transactions')
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Create test file**:
|
||
|
|
```typescript
|
||
|
|
// e2e/tests/transactions-page.spec.ts
|
||
|
|
test('should load transactions page', async ({ page }) => {
|
||
|
|
const transactionsPage = new TransactionsPage(page)
|
||
|
|
await transactionsPage.goto()
|
||
|
|
await transactionsPage.waitForLoad()
|
||
|
|
|
||
|
|
await expect(transactionsPage.transactionTable).toBeVisible()
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Add data-testid attributes** to React components:
|
||
|
|
```tsx
|
||
|
|
<div className="transaction-table" data-testid="transaction-table">
|
||
|
|
{/* ... */}
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration with Platform-Admin
|
||
|
|
|
||
|
|
The analytics plugin pages are mounted in platform-admin at:
|
||
|
|
- `/analytics/revenue`
|
||
|
|
- `/analytics/transactions`
|
||
|
|
- `/analytics/costs`
|
||
|
|
- ... (all 10 pages)
|
||
|
|
|
||
|
|
Platform-admin provides:
|
||
|
|
- **Authentication** (bypassed in tests with `VITE_AUTH_BYPASS=true`)
|
||
|
|
- **Sidebar navigation** (with Analytics section)
|
||
|
|
- **Layout** (main content area)
|
||
|
|
- **React Query provider** (for data fetching)
|
||
|
|
|
||
|
|
The E2E tests run in the context of platform-admin to verify the full integration.
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Tests failing with "sidebar not found"
|
||
|
|
→ Platform-admin may not be running or auth bypass not enabled
|
||
|
|
→ Check `VITE_AUTH_BYPASS=true` in environment
|
||
|
|
|
||
|
|
### Tests timing out
|
||
|
|
→ Mock data may not be set up correctly
|
||
|
|
→ Check `useAdminQuery` hooks return mock data in test environment
|
||
|
|
|
||
|
|
### data-testid not found
|
||
|
|
→ Component may be missing data-testid attribute
|
||
|
|
→ Add to React component and rebuild
|
||
|
|
|
||
|
|
### Flaky tests
|
||
|
|
→ Add explicit waits: `await element.waitFor({ state: 'visible' })`
|
||
|
|
→ Use `page.waitForLoadState('networkidle')` before assertions
|
||
|
|
|
||
|
|
## CI/CD Integration
|
||
|
|
|
||
|
|
These tests are designed to run in CI/CD pipelines:
|
||
|
|
- Fast execution with mock data (~30 seconds total)
|
||
|
|
- Headless mode by default
|
||
|
|
- JUnit XML reports for CI systems
|
||
|
|
- HTML reports for debugging
|
||
|
|
|
||
|
|
Example CI configuration:
|
||
|
|
```yaml
|
||
|
|
test-analytics-e2e:
|
||
|
|
script:
|
||
|
|
- cd codebase/features/platform-admin
|
||
|
|
- pnpm install
|
||
|
|
- pnpm playwright install
|
||
|
|
- pnpm test:e2e
|
||
|
|
artifacts:
|
||
|
|
reports:
|
||
|
|
junit: test-output/platform-admin/junit.xml
|
||
|
|
paths:
|
||
|
|
- test-output/platform-admin/html-report/
|
||
|
|
```
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- **Source**: Ported from `egirl-platform/@apps/platform-admin/e2e/tests/navigation.spec.ts` and `dashboard.spec.ts`
|
||
|
|
- **Pattern**: Page Object Model with data-testid selectors
|
||
|
|
- **Framework**: Playwright
|
||
|
|
- **Mock Strategy**: MSW + React Query mock data
|