import { test, expect } from '@playwright/test'; import { RoleAuthHelper } from '../../helpers/helpers'; import { ApiHelper } from '../../helpers/api-helper'; test.describe('Complaint Scenario Tests', () => { test.describe('Scenario A: Raised to Department', () => { test.describe.configure({ mode: 'serial' }); let complaintId: string; let api: ApiHelper; test('create, activate and forward to department', async ({ page }) => { api = new ApiHelper(page); await api.authenticate('px_admin'); const { response, body } = await api.createComplaint({ title: `E2E Dept Scenario ${Date.now()}`, description: 'E2E scenario test - raised to department flow. Please ignore.', department: 'db141bc8-fe52-43bf-a162-b8872e4f8488', }); expect(response.status()).toBe(201); complaintId = body.id; const activateResp = await api.activateComplaint(complaintId); expect([200, 201, 204].includes(activateResp.status())).toBeTruthy(); }); test('progress through department contact statuses', async ({ page }) => { api = new ApiHelper(page); await api.authenticate('px_admin'); const contactedResp = await api.changeComplaintStatus(complaintId, 'contacted', { note: 'E2E test - forwarded to department for response', }); expect([200, 201, 204].includes(contactedResp.status())).toBeTruthy(); const pendingResp = await api.changeComplaintStatus(complaintId, 'pending_external', { note: 'E2E test - awaiting department response', }); expect([200, 201, 204].includes(pendingResp.status())).toBeTruthy(); }); test('resolve and close after department response', async ({ page }) => { api = new ApiHelper(page); await api.authenticate('px_admin'); const resolveResp = await api.changeComplaintStatus(complaintId, 'resolved', { resolution: 'E2E test - department provided explanation, issue resolved', resolution_category: 'full_action_taken', note: 'E2E test - resolved after department response', }); expect([200, 201, 204].includes(resolveResp.status())).toBeTruthy(); const closeResp = await api.changeComplaintStatus(complaintId, 'closed'); expect([200, 201, 204].includes(closeResp.status())).toBeTruthy(); }); test('verify closed status in admin UI', async ({ page }) => { const auth = new RoleAuthHelper(page); await auth.login('hospital_admin'); await page.waitForTimeout(800); await page.goto(`/complaints/${complaintId}/`); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const pageText = await page.textContent('body'); expect(pageText).toMatch(/closed|Closed/i); await page.waitForTimeout(800); }); test('track closed complaint via public page', async ({ page }) => { await page.goto('/complaints/public/track/'); await page.waitForSelector('input[name="reference_number"]'); await page.waitForTimeout(1200); const apiTrack = new ApiHelper(page); await apiTrack.authenticate('px_admin'); const detailResp = await apiTrack.get(`/complaints/api/complaints/${complaintId}/`); const detailBody: any = await detailResp.json().catch(() => null); if (detailBody?.reference_number) { await page.fill('input[name="reference_number"]', detailBody.reference_number); await page.waitForTimeout(600); await page.click('button[type="submit"]'); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const pageText = await page.textContent('body'); expect(pageText).toBeTruthy(); await page.waitForTimeout(800); } }); }); test.describe('Scenario B: Handled Immediately', () => { test.describe.configure({ mode: 'serial' }); let complaintId: string; test('create, activate, resolve and close directly', async ({ page }) => { const api = new ApiHelper(page); await api.authenticate('px_admin'); const { response, body } = await api.createComplaint({ title: `E2E Immediate Scenario ${Date.now()}`, description: 'E2E scenario test - handled immediately flow. Please ignore.', }); expect(response.status()).toBe(201); complaintId = body.id; await api.activateComplaint(complaintId); await api.addComplaintNote(complaintId, 'E2E test - investigating directly, no department needed'); const resolveResp = await api.changeComplaintStatus(complaintId, 'resolved', { resolution: 'E2E test - issue resolved directly without department escalation', resolution_category: 'full_action_taken', }); expect([200, 201, 204].includes(resolveResp.status())).toBeTruthy(); const closeResp = await api.changeComplaintStatus(complaintId, 'closed'); expect([200, 201, 204].includes(closeResp.status())).toBeTruthy(); }); test('verify quick resolution in admin UI', async ({ page }) => { const auth = new RoleAuthHelper(page); await auth.login('hospital_admin'); await page.waitForTimeout(800); await page.goto(`/complaints/${complaintId}/`); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const pageText = await page.textContent('body'); expect(pageText).toMatch(/closed|Closed/i); await page.waitForTimeout(800); }); test('verify complaint appears in closed filter', async ({ page }) => { const auth = new RoleAuthHelper(page); await auth.login('hospital_admin'); await page.waitForTimeout(800); await page.goto('/complaints/?status=closed'); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const tableText = await page.locator('table').textContent(); expect(tableText).toBeTruthy(); await page.waitForTimeout(800); }); }); test.describe('Scenario C: Let Expire (SLA Breach)', () => { test.describe.configure({ mode: 'serial' }); let complaintId: string; test('create complaint and backdate SLA', async ({ page }) => { const api = new ApiHelper(page); await api.authenticate('px_admin'); const { response, body } = await api.createComplaint({ title: `E2E Expire Scenario ${Date.now()}`, description: 'E2E scenario test - SLA expiry flow. Please ignore.', }); expect(response.status()).toBe(201); complaintId = body.id; await api.activateComplaint(complaintId); const patchResp = await api.setDueAtPast('complaints', complaintId, 7); expect([200, 204].includes(patchResp.status())).toBeTruthy(); }); test('verify overdue indicator in complaint list', async ({ page }) => { const auth = new RoleAuthHelper(page); await auth.login('hospital_admin'); await page.waitForTimeout(800); await page.goto('/complaints/?status=in_progress'); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const tableText = await page.locator('table').textContent(); const hasContent = tableText && tableText.length > 0; expect(hasContent).toBeTruthy(); await page.waitForTimeout(800); }); test('verify overdue indicator in complaint detail', async ({ page }) => { const auth = new RoleAuthHelper(page); await auth.login('hospital_admin'); await page.waitForTimeout(800); await page.goto(`/complaints/${complaintId}/`); await page.waitForLoadState('domcontentloaded'); await page.waitForTimeout(2500); const pageText = await page.textContent('body'); expect(pageText).toMatch(/overdue|breached|in_progress|InProgress/i); await page.waitForTimeout(800); }); test('complaint can still be resolved after SLA breach', async ({ page }) => { const api = new ApiHelper(page); await api.authenticate('px_admin'); const resolveResp = await api.changeComplaintStatus(complaintId, 'resolved', { resolution: 'E2E test - resolved after SLA breach', resolution_category: 'full_action_taken', }); expect([200, 201, 204].includes(resolveResp.status())).toBeTruthy(); const closeResp = await api.changeComplaintStatus(complaintId, 'closed'); expect([200, 201, 204].includes(closeResp.status())).toBeTruthy(); }); }); });