64 lines
2.8 KiB
TypeScript
64 lines
2.8 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { mockAuthenticatedUser } from './support/auth';
|
|
|
|
const mockDashboardStats = {
|
|
totalUsers: 1250,
|
|
newUsersLast30Days: 85,
|
|
totalListings: 3400,
|
|
newListingsLast30Days: 320,
|
|
activeListings: 2800,
|
|
pendingModerationCount: 45,
|
|
totalAgents: 180,
|
|
verifiedAgents: 120,
|
|
totalTransactions: 560,
|
|
};
|
|
|
|
const mockRevenue = [
|
|
{ period: '2025-10', totalRevenue: 150000000, subscriptionRevenue: 100000000, listingFeeRevenue: 30000000, featuredListingRevenue: 20000000, transactionCount: 12 },
|
|
{ period: '2025-11', totalRevenue: 180000000, subscriptionRevenue: 120000000, listingFeeRevenue: 35000000, featuredListingRevenue: 25000000, transactionCount: 14 },
|
|
{ period: '2025-12', totalRevenue: 200000000, subscriptionRevenue: 130000000, listingFeeRevenue: 40000000, featuredListingRevenue: 30000000, transactionCount: 15 },
|
|
{ period: '2026-01', totalRevenue: 220000000, subscriptionRevenue: 140000000, listingFeeRevenue: 50000000, featuredListingRevenue: 30000000, transactionCount: 16 },
|
|
{ period: '2026-02', totalRevenue: 250000000, subscriptionRevenue: 160000000, listingFeeRevenue: 55000000, featuredListingRevenue: 35000000, transactionCount: 18 },
|
|
{ period: '2026-03', totalRevenue: 280000000, subscriptionRevenue: 180000000, listingFeeRevenue: 60000000, featuredListingRevenue: 40000000, transactionCount: 20 },
|
|
];
|
|
|
|
test.describe('Admin Dashboard', () => {
|
|
test.beforeEach(async ({ page, context, baseURL }) => {
|
|
await mockAuthenticatedUser(page, context, baseURL, { role: 'ADMIN' });
|
|
|
|
await page.route('**/api/v1/admin/dashboard**', (route) =>
|
|
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockDashboardStats) }),
|
|
);
|
|
await page.route('**/api/v1/admin/revenue**', (route) =>
|
|
route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockRevenue) }),
|
|
);
|
|
});
|
|
|
|
test('renders admin dashboard with stat cards', async ({ page }) => {
|
|
await page.goto('/admin');
|
|
|
|
// Stat values should be visible
|
|
await expect(page.getByText('1.250')).toBeVisible({ timeout: 10000 });
|
|
await expect(page.getByText('3.400')).toBeVisible();
|
|
});
|
|
|
|
test('shows refresh button', async ({ page }) => {
|
|
await page.goto('/admin');
|
|
|
|
const refreshButton = page.getByRole('button').filter({ has: page.locator('svg') }).first();
|
|
await expect(refreshButton).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('handles API failure gracefully', async ({ page }) => {
|
|
await page.route('**/api/v1/admin/dashboard**', (route) =>
|
|
route.fulfill({ status: 500, body: 'Error' }),
|
|
);
|
|
|
|
await page.goto('/admin');
|
|
|
|
// Page should still render without crashing
|
|
await page.waitForTimeout(2000);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
});
|