/** * Agents Page E2E Tests * * Tests the agent profile page at /agents/[id]. * The app does not have a public agent listing page, only individual agent profiles. * Tests use route mocking to avoid API dependency. */ import { test, expect } from '@playwright/test'; import { mockAuthenticatedUser } from './support/auth'; const seededAgentId = 'seed-agentprofile-001'; const seededAgentName = 'Nguyễn Văn An'; const seededAgentAgency = 'GoodGo Premium Realty'; test.describe('Agent Profile Page', () => { test.beforeEach(async ({ page, context, baseURL }) => { await mockAuthenticatedUser(page, context, baseURL, { role: 'AGENT' }); }); test('renders agent name and verified badge', async ({ page }) => { await page.goto(`/agents/${seededAgentId}`); await expect(page.getByRole('heading', { name: seededAgentName })).toBeVisible({ timeout: 10_000, }); await expect(page.getByText('KYC xác minh')).toBeVisible(); }); test('shows agent agency and contact info', async ({ page }) => { await page.goto(`/agents/${seededAgentId}`); await expect(page.getByRole('heading', { name: seededAgentName })).toBeVisible({ timeout: 10_000, }); await expect(page.getByText(seededAgentAgency)).toBeVisible(); await expect(page.getByText('+84900000002').first()).toBeVisible(); }); test('shows listings and reviews sections', async ({ page }) => { await page.goto(`/agents/${seededAgentId}`); await expect(page.getByRole('heading', { name: seededAgentName })).toBeVisible({ timeout: 10_000, }); await expect(page.getByText('Danh mục bất động sản')).toBeVisible(); await expect(page.getByRole('heading', { name: /Đánh giá/ })).toBeVisible(); }); test('has breadcrumb back to homepage', async ({ page }) => { await page.goto(`/agents/${seededAgentId}`); await expect(page.getByRole('heading', { name: seededAgentName })).toBeVisible({ timeout: 10_000, }); await expect( page.locator('#main-content').getByRole('link', { name: /Trang chủ/i }), ).toBeVisible(); }); test('renders without critical console errors', async ({ page }) => { const criticalErrors: string[] = []; page.on('console', (msg) => { if (msg.type() === 'error') { const text = msg.text(); if ( text.includes('mapbox') || text.includes('NEXT_PUBLIC') || text.includes('net::ERR') || text.includes('Failed to load resource') ) { return; } criticalErrors.push(text); } }); await page.goto(`/agents/${seededAgentId}`); await page.waitForLoadState('networkidle', { timeout: 15_000 }).catch(() => {}); expect(criticalErrors).toHaveLength(0); }); test('handles 404 for unknown agent gracefully', async ({ page }) => { const res = await page.goto('/agents/nonexistent-agent-id'); const status = res?.status(); if (status && status >= 500) { throw new Error(`Agent page returned ${status} for unknown ID (expected 404 or redirect)`); } }); }); test.describe('Agent Profile — Responsive', () => { const viewports = [ { label: '375px (mobile)', width: 375, height: 667 }, { label: '768px (tablet)', width: 768, height: 1024 }, { label: '1280px (laptop)', width: 1280, height: 800 }, { label: '1920px (desktop)', width: 1920, height: 1080 }, ]; for (const vp of viewports) { test(`renders at ${vp.label}`, async ({ page, context, baseURL }) => { await mockAuthenticatedUser(page, context, baseURL, { role: 'AGENT' }); await page.setViewportSize({ width: vp.width, height: vp.height }); await page.goto(`/agents/${seededAgentId}`); await expect(page.getByRole('heading', { name: seededAgentName })).toBeVisible({ timeout: 10_000, }); // No horizontal overflow (layout break indicator) const bodyWidth = await page.evaluate(() => document.body.scrollWidth); const viewportWidth = await page.evaluate(() => window.innerWidth); expect(bodyWidth).toBeLessThanOrEqual(viewportWidth + 2); // 2px tolerance }); } });