platform-codebase/@packages/@plugins/analytics/e2e/tests/revenue-page.spec.ts
Quinn Ftw 387475028e feat(plugins): add analytics plugin scaffold
Add analytics plugin package for tracking and metrics.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 16:08:06 -08:00

334 lines
11 KiB
TypeScript

import { test, expect } from '@playwright/test'
import { RevenuePage } from '../page-objects/RevenuePage'
import { loginAsAdmin } from '../helpers/auth.helper'
/**
* E2E Tests: Revenue Analytics Page
*
* Tests revenue page functionality:
* - KPI cards render with data-testid attributes
* - Date range filters work correctly
* - Charts and tables display data
* - Export functionality
*
* These tests use mock data from the analytics hooks,
* so values are consistent across test runs.
*/
test.describe('Revenue Analytics Page', () => {
test.beforeEach(async ({ page }) => {
await loginAsAdmin(page)
})
test('should load revenue page and display key metrics', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify page loaded
await expect(page).toHaveURL('/analytics/revenue')
await expect(revenuePage.pageTitle).toBeVisible()
await expect(revenuePage.pageTitle).toHaveText('Revenue Analytics')
// Verify KPI section visible
await expect(revenuePage.kpiSection).toBeVisible()
})
test('should display all 6 KPI cards', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify all 6 KPI cards are present
const allCardsPresent = await revenuePage.verifyAllKpiCardsPresent()
expect(allCardsPresent).toBe(true)
// Verify each card individually
await expect(revenuePage.totalRevenueCard).toBeVisible()
await expect(revenuePage.mrrCard).toBeVisible()
await expect(revenuePage.oneTimeRevenueCard).toBeVisible()
await expect(revenuePage.cryptoRevenueCard).toBeVisible()
await expect(revenuePage.growthRateCard).toBeVisible()
await expect(revenuePage.arpuCard).toBeVisible()
})
test('should display total revenue with currency format', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Get total revenue value
const totalRevenue = await revenuePage.getTotalRevenue()
expect(totalRevenue).toBeTruthy()
// Verify has currency format ($ prefix)
expect(totalRevenue).toContain('$')
})
test('should display monthly recurring revenue', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Get MRR value
const mrr = await revenuePage.getMonthlyRecurring()
expect(mrr).toBeTruthy()
// Verify has currency format
expect(mrr).toContain('$')
})
test('should display growth rate with percentage', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Get growth rate value
const growthRate = await revenuePage.getKpiCardValue('growth-rate-card')
expect(growthRate).toBeTruthy()
// Verify has percentage format (% suffix)
expect(growthRate).toContain('%')
})
test('should render revenue trend chart', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify chart section visible
await expect(revenuePage.revenueTrendChart).toBeVisible()
// Verify chart has title
const chartTitle = revenuePage.revenueTrendChart.locator('h2')
await expect(chartTitle).toHaveText('Revenue Trend')
})
test('should render revenue breakdown by source', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify breakdown table renders
const tableRendered = await revenuePage.verifyRevenueBreakdownTableRendered()
expect(tableRendered).toBe(true)
// Verify table headers
const table = page.locator('[data-testid="breakdown-table"]')
await expect(table.locator('th:has-text("Source")')).toBeVisible()
await expect(table.locator('th:has-text("Amount")')).toBeVisible()
await expect(table.locator('th:has-text("Percentage")')).toBeVisible()
})
test('should render revenue breakdown by provider', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify provider breakdown table renders
const tableRendered = await revenuePage.verifyProviderBreakdownTableRendered()
expect(tableRendered).toBe(true)
// Verify table headers
const table = page.locator('[data-testid="provider-table"]')
await expect(table.locator('th:has-text("Provider")')).toBeVisible()
await expect(table.locator('th:has-text("Amount")')).toBeVisible()
await expect(table.locator('th:has-text("Percentage")')).toBeVisible()
})
test.describe('Date Range Filters', () => {
test('should have date range filter section', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify filter section visible
await expect(revenuePage.dateFilter).toBeVisible()
// Verify filter buttons present
await expect(page.locator('[data-testid="filter-7d"]')).toBeVisible()
await expect(page.locator('[data-testid="filter-30d"]')).toBeVisible()
await expect(page.locator('[data-testid="filter-this-month"]')).toBeVisible()
await expect(page.locator('[data-testid="filter-last-month"]')).toBeVisible()
await expect(page.locator('[data-testid="filter-custom"]')).toBeVisible()
})
test('should select 7 days filter', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Click 7 days filter
await revenuePage.selectDateRange('7d')
// Verify button is active
const button = page.locator('[data-testid="filter-7d"]')
await expect(button).toHaveClass(/active/)
})
test('should select 30 days filter', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Click 30 days filter
await revenuePage.selectDateRange('30d')
// Verify button is active (default state)
const button = page.locator('[data-testid="filter-30d"]')
await expect(button).toHaveClass(/active/)
})
test('should select this month filter', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Click this month filter
await revenuePage.selectDateRange('this-month')
// Verify button is active
const button = page.locator('[data-testid="filter-this-month"]')
await expect(button).toHaveClass(/active/)
})
test('should switch between date ranges', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Select 7 days
await revenuePage.selectDateRange('7d')
let activeButton = page.locator('[data-testid="filter-7d"]')
await expect(activeButton).toHaveClass(/active/)
// Switch to this month
await revenuePage.selectDateRange('this-month')
activeButton = page.locator('[data-testid="filter-this-month"]')
await expect(activeButton).toHaveClass(/active/)
// Switch back to 30 days
await revenuePage.selectDateRange('30d')
activeButton = page.locator('[data-testid="filter-30d"]')
await expect(activeButton).toHaveClass(/active/)
})
})
test.describe('Export Functionality', () => {
test('should have export section', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Verify export section visible
await expect(revenuePage.exportSection).toBeVisible()
})
test('should open export menu', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Open export menu
await revenuePage.openExportMenu()
// Verify export options visible
await expect(revenuePage.exportCsvButton).toBeVisible()
await expect(revenuePage.exportExcelButton).toBeVisible()
await expect(revenuePage.exportPdfButton).toBeVisible()
})
test('should have CSV export option', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Open export menu
await revenuePage.openExportMenu()
// Verify CSV button
await expect(revenuePage.exportCsvButton).toBeVisible()
await expect(revenuePage.exportCsvButton).toHaveText('CSV')
})
test('should have Excel export option', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Open export menu
await revenuePage.openExportMenu()
// Verify Excel button
await expect(revenuePage.exportExcelButton).toBeVisible()
await expect(revenuePage.exportExcelButton).toHaveText('Excel')
})
test('should have PDF export option', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Open export menu
await revenuePage.openExportMenu()
// Verify PDF button
await expect(revenuePage.exportPdfButton).toBeVisible()
await expect(revenuePage.exportPdfButton).toHaveText('PDF')
})
})
test('should handle page refresh', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Get initial title
const initialTitle = await revenuePage.pageTitle.textContent()
// Refresh page
await page.reload()
await page.waitForLoadState('networkidle')
await revenuePage.waitForLoad()
// Verify page still loads with same title
const updatedTitle = await revenuePage.pageTitle.textContent()
expect(updatedTitle).toBe(initialTitle)
// Verify KPI cards still visible
const allCardsPresent = await revenuePage.verifyAllKpiCardsPresent()
expect(allCardsPresent).toBe(true)
})
test('should handle graceful degradation when data is missing', async ({ page }) => {
const revenuePage = new RevenuePage(page)
await revenuePage.goto()
await revenuePage.waitForLoad()
// Page should always show KPI section (even with mock data or errors)
await expect(revenuePage.kpiSection).toBeVisible()
// Should have at least one KPI card visible
const cardCount = await revenuePage.verifyKpiCardsRendered()
expect(cardCount).toBeGreaterThan(0)
})
})