168 lines
6.1 KiB
TypeScript
168 lines
6.1 KiB
TypeScript
/**
|
|
* Conversation Assistant Docker E2E Tests for Platform Dev
|
|
*
|
|
* Tests the conversation-assistant integration with real backend services:
|
|
* - Scammer Database page (/scammers)
|
|
* - Training Samples page (/training)
|
|
*
|
|
* Uses real PostgreSQL database with seeded data (no mocks).
|
|
* Services orchestrated by docker-compose.e2e.yml
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Conversation Assistant - Scammers Page (Docker)', () => {
|
|
test('renders scammers page header', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Should display page title
|
|
const mainContent = page.locator('main');
|
|
await expect(mainContent.locator('h1').first()).toContainText(/scammer/i);
|
|
});
|
|
|
|
test('displays scammer stats cards', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Check for stat labels from seeded database
|
|
await expect(page.locator('text=Total').first()).toBeVisible({ timeout: 10000 });
|
|
await expect(page.locator('text=Suspected').first()).toBeVisible({ timeout: 10000 });
|
|
await expect(page.locator('text=Confirmed').first()).toBeVisible({ timeout: 10000 });
|
|
await expect(page.locator('text=Cleared').first()).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('displays scammers table with phone numbers', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Should show phone numbers from seeded database
|
|
await expect(page.locator('text=/\\+\\d+/').first()).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('shows status badges', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Look for status indicators from database
|
|
await expect(page.locator('text=/suspected|confirmed|cleared/i').first()).toBeVisible({
|
|
timeout: 10000,
|
|
});
|
|
});
|
|
|
|
test('shows risk score visualization', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Should show risk scores from database
|
|
await expect(page.locator('text=/score/i').first()).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('shows detection count badges', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Look for AI detection, manipulation, phishing indicators
|
|
await expect(page.locator('text=/ai|detection|manipulation|phishing/i').first()).toBeVisible({
|
|
timeout: 10000,
|
|
});
|
|
});
|
|
|
|
test('shows action buttons for suspected entries', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Should have action buttons (Confirm, Clear, etc.)
|
|
const buttons = page.locator('button');
|
|
await expect(buttons.first()).toBeVisible({ timeout: 10000 });
|
|
});
|
|
});
|
|
|
|
test.describe('Conversation Assistant - Training Page (Docker)', () => {
|
|
test('renders training page or maintenance mode', async ({ page }) => {
|
|
await page.goto('/training');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const mainContent = page.locator('main');
|
|
|
|
// Should display either training page or maintenance message
|
|
const hasTrainingHeader = await mainContent
|
|
.locator('h1')
|
|
.filter({ hasText: /training/i })
|
|
.count();
|
|
const hasMaintenanceMessage = await page.locator('text=/maintenance/i').count();
|
|
|
|
expect(hasTrainingHeader + hasMaintenanceMessage).toBeGreaterThan(0);
|
|
});
|
|
|
|
test('displays training samples if not in maintenance', async ({ page }) => {
|
|
await page.goto('/training');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Check for training samples section or maintenance mode
|
|
const hasSamplesOrMaintenance =
|
|
(await page.locator('text=/sample/i').first().isVisible({ timeout: 5000 }).catch(() => false)) ||
|
|
(await page.locator('text=/maintenance/i').isVisible({ timeout: 5000 }));
|
|
|
|
expect(hasSamplesOrMaintenance).toBeTruthy();
|
|
});
|
|
|
|
test('displays training jobs if not in maintenance', async ({ page }) => {
|
|
await page.goto('/training');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Check for job status or maintenance
|
|
const hasJobsOrMaintenance =
|
|
(await page.locator('text=/job|epoch/i').first().isVisible({ timeout: 5000 }).catch(() => false)) ||
|
|
(await page.locator('text=/maintenance/i').isVisible({ timeout: 5000 }));
|
|
|
|
expect(hasJobsOrMaintenance).toBeTruthy();
|
|
});
|
|
|
|
test('displays ML models section if not in maintenance', async ({ page }) => {
|
|
await page.goto('/training');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Check for models or maintenance
|
|
const hasModelsOrMaintenance =
|
|
(await page.locator('text=/model/i').first().isVisible({ timeout: 5000 }).catch(() => false)) ||
|
|
(await page.locator('text=/maintenance/i').isVisible({ timeout: 5000 }));
|
|
|
|
expect(hasModelsOrMaintenance).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
test.describe('Conversation Assistant - Route Health (Docker)', () => {
|
|
test('scammers route is accessible', async ({ page }) => {
|
|
await page.goto('/scammers');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Should not show 404 page
|
|
await expect(page.getByRole('heading', { name: /404/ })).not.toBeVisible();
|
|
|
|
// Should show main content
|
|
const mainContent = page.locator('main');
|
|
await expect(mainContent).toBeVisible();
|
|
});
|
|
|
|
test('training route is accessible', async ({ page }) => {
|
|
await page.goto('/training');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Should not show 404 page
|
|
await expect(page.getByRole('heading', { name: /404/ })).not.toBeVisible();
|
|
|
|
// Should show main content
|
|
const mainContent = page.locator('main');
|
|
await expect(mainContent).toBeVisible();
|
|
});
|
|
});
|