import { test, expect } from '@playwright/test'; import { login, BASE_URL } from '../../helpers/auth'; import { markManual, markPartial } from '../../helpers/manual'; test.describe('core-upgrade', () => { test('core-upgrade-check-in_place_upgrade_from_previous_major_version', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Requires a running instance of the previous major version, access to the new release package, and execution of the upgrade procedure; needs dedicated test environment'); testInfo.annotations.push({ type: 'description', description: 'Verify in-place upgrade from the previous major version completes successfully without data loss' }); // Manual steps: // 1. Take a VM snapshot of the previous-version system as rollback point. // 2. Upload / stage the new release package on the system. // 3. Execute the upgrade command (e.g., `pbx-upgrade --release X.Y.Z`). // 4. Monitor upgrade logs for errors. // 5. Verify the system comes back online at the new version. // 6. Check admin portal version string matches the target release. // 7. Verify a sample set of configuration objects (extensions, trunks) survived the upgrade. }); test('core-upgrade-check-configuration_and_database_migration_validation', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'partial' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markPartial('Post-upgrade UI configuration checks are automated; DB schema integrity validation requires direct DB access (psql/mysql CLI) outside Playwright scope'); testInfo.annotations.push({ type: 'description', description: 'Verify configuration objects and database content migrate correctly after upgrade' }); await test.step('Login to admin portal after upgrade', async () => { await login(page); }); await test.step('Verify extensions list is intact', async () => { await page.goto(`${BASE_URL}/admin/extensions`); await expect(page.locator('table tbody tr, .extension-item').first()).toBeVisible(); }); await test.step('Verify trunk configurations are present', async () => { await page.goto(`${BASE_URL}/admin/trunks`); await expect(page.locator('table tbody tr, .trunk-item').first()).toBeVisible(); }); await test.step('Verify dial plan rules are present', async () => { await page.goto(`${BASE_URL}/admin/dialplans`); await expect(page.locator('body')).not.toContainText(/no.*rule|empty/i); }); // TODO_MANUAL: SSH into the server and run: // psql -U pbx -c '\dt' (or equivalent for your DB) // Verify all expected tables are present and row counts match pre-upgrade counts. }); test('core-upgrade-check-schema_upgrade_and_data_integrity_check', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Requires direct database access (psql/mysql) and schema comparison tooling; DB schema is not exposed via the admin portal'); testInfo.annotations.push({ type: 'description', description: 'Verify the database schema is correctly upgraded and all data maintains integrity after migration' }); // Manual steps: // 1. Before upgrade: dump schema with `pg_dump --schema-only` and row counts. // 2. After upgrade: dump new schema and compare with expected schema for new version. // 3. Verify: no unexpected table drops, all new columns added, indexes intact. // 4. Run data integrity checks: FK constraints, NULL columns for required fields. // 5. Compare row counts for critical tables (extensions, cdr, trunks). // 6. Document any discrepancies as issues. }); test('core-upgrade-check-rollback_procedure_execution_and_verification', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Rollback requires either reverting a VM snapshot or downgrading packages on the OS — both require physical/hypervisor-level access and cannot be driven by Playwright'); testInfo.annotations.push({ type: 'description', description: 'Verify the rollback procedure successfully reverts the system to the previous version' }); // Manual steps: // 1. Use the VM snapshot taken before upgrade OR follow documented package rollback procedure. // 2. Execute rollback (snapshot revert or `pbx-upgrade --rollback`). // 3. Monitor rollback logs for errors. // 4. Verify the system boots at the previous version. // 5. Verify admin portal is accessible and shows the previous version number. // 6. Verify a sample call can be completed (if safe to test in this environment). // 7. Record rollback duration and outcome. }); test('core-upgrade-check-post_upgrade_regression_of_core_features', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'automated' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); testInfo.annotations.push({ type: 'description', description: 'Run automated regression checks on core portal features after upgrade to detect any regressions' }); await test.step('Login and verify portal is accessible', async () => { await login(page); await expect(page.locator('body')).toBeVisible(); }); const sections = [ { name: 'Extensions', path: '/admin/extensions' }, { name: 'Trunks', path: '/admin/trunks' }, { name: 'Dial Plans', path: '/admin/dialplans' }, { name: 'Users', path: '/admin/users' }, { name: 'Security', path: '/admin/security' }, { name: 'Logs', path: '/admin/logs' }, ]; for (const section of sections) { await test.step(`Verify "${section.name}" section loads without HTTP errors`, async () => { const response = await page.goto(`${BASE_URL}${section.path}`); expect(response?.status()).toBeLessThan(500); await expect(page.locator('body')).not.toContainText(/unexpected error|500 internal/i); }); } }); test('core-upgrade-check-zero_downtime_upgrade_where_supported', async ({ page }, testInfo) => { testInfo.annotations.push({ type: 'automationStatus', description: 'manual' }); testInfo.annotations.push({ type: 'testType', description: 'check' }); markManual('Requires active call sessions monitored during the upgrade window and concurrent upgrade execution on the server; calls cannot be established or monitored by Playwright'); testInfo.annotations.push({ type: 'description', description: 'Verify zero-downtime upgrade keeps the service available throughout the upgrade process' }); // Manual steps: // 1. Establish 5+ active SIP calls before starting the upgrade. // 2. Begin the rolling upgrade procedure. // 3. Monitor portal availability with a ping/health-check script every 5 s. // 4. Monitor active calls — none should drop. // 5. Verify: no HTTP 5xx responses during upgrade, all calls survive, upgrade completes. // 6. Record: downtime (should be 0), call drop count, upgrade duration. }); });