import { test, expect } from '@playwright/test'; import { login, BASE_URL } from '../../helpers/auth'; import { markManual, markPartial } from '../../helpers/manual'; test.describe('pbx-regression', () => { test('pbx-regression-check-core_call_features_after_any_code_change', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'partial' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markPartial('Admin portal CRUD and configuration regression can be automated; actual call-flow regression (inbound/outbound/hold/transfer) requires active SIP endpoints outside Playwright scope'); testInfo.annotations.push({ type: 'description', description: 'Run regression checks on core call features after any code change to detect regressions' }); await test.step('Login and verify portal is accessible', async () => { await login(page); await expect(page.locator('body')).toBeVisible(); }); await test.step('Verify Extension CRUD functions are intact', async () => { await page.goto(`${BASE_URL}/admin/extensions`); await expect(page.locator('body')).not.toContainText(/500|unexpected error/i); await expect(page.locator('table, .extension-list, .no-extensions').first()).toBeVisible(); }); await test.step('Verify Trunk list loads correctly', async () => { await page.goto(`${BASE_URL}/admin/trunks`); await expect(page.locator('body')).not.toContainText(/500/i); }); await test.step('Verify Dial Plan section is intact', async () => { await page.goto(`${BASE_URL}/admin/dialplans`); await expect(page.locator('body')).not.toContainText(/500/i); }); await test.step('Verify Voicemail settings load correctly', async () => { await page.goto(`${BASE_URL}/admin/voicemail`); await expect(page.locator('body')).not.toContainText(/500/i); }); await test.step('Verify IVR / Auto-Attendant section loads', async () => { await page.goto(`${BASE_URL}/admin/ivr`); await expect(page.locator('body')).not.toContainText(/500/i); }); // TODO_MANUAL: After each code merge, run SIP regression suite: // - Internal call test (ext→ext) // - Inbound DID test // - Outbound call test // - Hold/Resume, Transfer, Voicemail deposit/retrieval }); test('pbx-regression-check-previously_fixed_bugs_and_edge_cases_reverification', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'partial' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markPartial('UI-level bug fixes can be regression-tested via Playwright; telephony-layer or server-side bug fixes require SIP clients or SSH-based verification'); testInfo.annotations.push({ type: 'description', description: 'Verify all previously fixed bugs and known edge cases have not regressed in this release' }); const knownBugRoutes = [ // Add routes that previously had UI bugs — update this list per release { name: 'Extension edit page', path: '/admin/extensions' }, { name: 'Trunk status display', path: '/admin/trunks' }, { name: 'CDR export', path: '/admin/logs/cdr' }, { name: 'User roles', path: '/admin/users/roles' }, ]; await test.step('Login', async () => { await login(page); }); for (const route of knownBugRoutes) { await test.step(`Verify "${route.name}" loads without regression`, async () => { const response = await page.goto(`${BASE_URL}${route.path}`); expect(response?.status()).toBeLessThan(500); await expect(page.locator('body')).not.toContainText(/unexpected error|traceback|exception/i); }); } // TODO_MANUAL: For each closed bug ticket, execute the reproduction steps from the ticket // and verify the bug is not reproducible on this release. }); test('pbx-regression-check-performance_baselines_comparison_against_previous_version', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Requires SIPp load tests producing comparable metrics against the previous version baseline; statistical comparison and pass/fail determination require human or scripted analysis outside the browser'); testInfo.annotations.push({ type: 'description', description: 'Compare key performance metrics (concurrent calls, call setup time, resource usage) against the previous version baseline' }); // Manual steps: // 1. Run the standard SIPp performance benchmark on the PREVIOUS version. Record: max CPS, P95 setup time, peak CPU. // 2. Install NEW version. Run the identical SIPp benchmark. // 3. Compare: max CPS diff must be ≤ 5% degradation; setup time P95 diff ≤ 10%. // 4. If any metric degrades > threshold, file a performance regression bug. // 5. Attach benchmark results (CSV + charts) to this test report. }); test('pbx-regression-check-security_hardening_and_vulnerability_scan_baseline', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'partial' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markPartial('Security configuration checks (HTTPS, RBAC, encryption enabled) can be automated via admin portal; full vulnerability scan baseline requires external tools (OpenVAS, Nessus, Trivy) integrated into the CI pipeline'); testInfo.annotations.push({ type: 'description', description: 'Verify security hardening settings are intact and vulnerability scan result is no worse than the previous version baseline' }); await test.step('Login and navigate to security overview', async () => { await login(page); await page.goto(`${BASE_URL}/admin/security`); }); await test.step('Verify HTTPS enforcement is active', async () => { expect(page.url()).toMatch(/^https:\/\//); }); await test.step('Verify RBAC settings page loads', async () => { await page.goto(`${BASE_URL}/admin/users/roles`); await expect(page.locator('body')).not.toContainText(/500/i); }); await test.step('Verify media encryption is still enabled after code change', async () => { await page.goto(`${BASE_URL}/admin/security/media-encryption`); const pageText = await page.locator('body').textContent() ?? ''; expect(pageText).toMatch(/srtp|tls/i); }); await test.step('Verify audit logging is still active', async () => { await page.goto(`${BASE_URL}/admin/security/audit`); await expect(page.locator('body')).not.toContainText(/500/i); }); // TODO_MANUAL / TODO_CI: Run `trivy image ` and compare CVE count // against the previous version scan. New Critical/High CVEs = regression. }); });