mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
feat: add E2E smoke tests, architecture docs, and operations runbook
- 27 Playwright E2E tests covering login (3 roles), CC Agent pages (call desk, call history, patients, appointments, my performance, sidebar, sign-out), and Supervisor pages (all 11 pages + sidebar) - Tests run against live EC2 at ramaiah.engage.healix360.net - Last test completes sign-out to release agent session for next run - Architecture doc with updated Mermaid diagram including telephony dispatcher, service discovery, and multi-tenant topology - Operations runbook with SSH access (VPS + EC2), accounts, container reference, deploy steps, Redis ops, and troubleshooting guide Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
121
e2e/supervisor-smoke.spec.ts
Normal file
121
e2e/supervisor-smoke.spec.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Supervisor / Admin — happy-path smoke tests.
|
||||
*
|
||||
* Role: admin (supervisor@ramaiahcare.com)
|
||||
* Landing: / → Dashboard
|
||||
* Pages: Dashboard, Team Performance, Live Monitor,
|
||||
* Leads, Patients, Appointments, Call Log,
|
||||
* Call Recordings, Missed Calls, Campaigns, Settings
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { loginAs, waitForApp } from './helpers';
|
||||
|
||||
const EMAIL = 'supervisor@ramaiahcare.com';
|
||||
const PASSWORD = 'MrRamaiah@2026';
|
||||
|
||||
test.describe('Supervisor Smoke', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await loginAs(page, EMAIL, PASSWORD);
|
||||
});
|
||||
|
||||
test('lands on Dashboard after login', async ({ page }) => {
|
||||
await expect(page.locator('aside').first()).toBeVisible();
|
||||
// Verify we're authenticated and on the app
|
||||
await expect(page).not.toHaveURL(/\/login/);
|
||||
});
|
||||
|
||||
test('Team Performance loads', async ({ page }) => {
|
||||
await page.goto('/team-performance');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Team|Performance|Agent|No data/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Live Call Monitor loads', async ({ page }) => {
|
||||
await page.goto('/live-monitor');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Live|Monitor|Active|No active/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Leads page loads', async ({ page }) => {
|
||||
await page.goto('/leads');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Lead|No leads/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Patients page loads', async ({ page }) => {
|
||||
await page.goto('/patients');
|
||||
await waitForApp(page);
|
||||
|
||||
const search = page.getByPlaceholder(/search/i).or(page.getByLabel(/search/i));
|
||||
await expect(search.first()).toBeVisible();
|
||||
});
|
||||
|
||||
test('Appointments page loads', async ({ page }) => {
|
||||
await page.goto('/appointments');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Appointment|Schedule|No appointment/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Call Log page loads', async ({ page }) => {
|
||||
await page.goto('/call-history');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(page.locator('text="Call History"').first()).toBeVisible();
|
||||
});
|
||||
|
||||
test('Call Recordings page loads', async ({ page }) => {
|
||||
await page.goto('/call-recordings');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Recording|No recording/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Missed Calls page loads', async ({ page }) => {
|
||||
await page.goto('/missed-calls');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Missed|No missed/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Campaigns page loads', async ({ page }) => {
|
||||
await page.goto('/campaigns');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Campaign|No campaign/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('Settings page loads', async ({ page }) => {
|
||||
await page.goto('/settings');
|
||||
await waitForApp(page);
|
||||
|
||||
await expect(
|
||||
page.locator('text=/Settings|Configuration/i').first(),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
test('sidebar has expected nav items', async ({ page }) => {
|
||||
const sidebar = page.locator('aside').first();
|
||||
// Check key items — exact labels depend on the role the sidecar assigns
|
||||
for (const item of ['Patients', 'Appointments', 'Campaigns']) {
|
||||
await expect(sidebar.locator(`text="${item}"`)).toBeVisible();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user