Files
rxminder/tests/e2e/helpers.ts
William Valentin b4a9318324 test: enhance E2E and integration testing infrastructure
- Add comprehensive TypeScript types to E2E test helpers
- Improve medication, auth, modal, and wait helper classes with proper typing
- Enhance test data with readonly type assertions for better immutability
- Update integration tests with better error handling and assertions
- Improve Playwright type definitions for better IDE support
- Add environment variable support to manual test scripts
2025-09-07 15:22:33 -07:00

159 lines
4.4 KiB
TypeScript

// E2E Test Utilities and Helpers
import { Page } from '@playwright/test';
// Type definitions for better type safety
interface MedicationData {
name: string;
dosage: string;
frequency: string;
times: string;
}
interface UserData {
email: string;
username: string;
password: string;
}
interface ReminderData {
title: string;
icon: string;
frequency: number;
}
export class MedicationHelpers {
constructor(private page: Page) {}
async addMedication(
name: string,
dosage: string,
frequency: string = 'daily',
times: string = '1'
): Promise<void> {
await this.page.click('button:has-text("Add Medication")');
await this.page.fill('input[name="name"]', name);
await this.page.fill('input[name="dosage"]', dosage);
await this.page.selectOption('select[name="frequency"]', frequency);
if (times !== '1') {
await this.page.fill('input[name="times"]', times);
}
await this.page.click('button[type="submit"]');
// Wait for medication to appear
await this.page.waitForSelector(`text=${name}`);
}
async deleteMedication(name: string): Promise<void> {
await this.page.click('button:has-text("Manage")');
// Find the medication row and click delete
await this.page
.locator(`tr:has-text("${name}") [data-testid="delete-medication"]`)
.click();
await this.page.click('button:has-text("Delete")');
// Close manage modal
await this.page.click('button:has-text("Close")');
}
async takeDose(medicationName: string): Promise<void> {
await this.page
.locator(
`.dose-card:has-text("${medicationName}") button:has-text("Take")`
)
.click();
}
}
export class AuthHelpers {
constructor(private page: Page) {}
async loginAsAdmin(): Promise<void> {
await this.page.goto('/');
await this.page.fill('input[type="email"]', 'admin@localhost');
await this.page.fill('input[type="password"]', 'admin123!');
await this.page.click('button[type="submit"]');
await this.page.waitForSelector('h1:has-text("Medication Reminder")');
}
async registerUser(
email: string,
username: string,
password: string
): Promise<void> {
await this.page.goto('/');
await this.page.click('text=Register');
await this.page.fill('input[type="email"]', email);
await this.page.fill('input[name="username"]', username);
await this.page.fill('input[type="password"]', password);
await this.page.click('button[type="submit"]');
}
async logout(): Promise<void> {
await this.page.click('[data-testid="avatar-dropdown"]');
await this.page.click('button:has-text("Logout")');
await this.page.waitForSelector('h2:has-text("Sign In")');
}
}
export class ModalHelpers {
constructor(private page: Page) {}
async openModal(buttonText: string): Promise<void> {
await this.page.click(`button:has-text("${buttonText}")`);
}
async closeModal(): Promise<void> {
await this.page.click('button:has-text("Close")');
}
async confirmAction(): Promise<void> {
await this.page.click('button:has-text("Confirm")');
}
}
export class WaitHelpers {
constructor(private page: Page) {}
async waitForAppLoad(): Promise<void> {
await this.page.waitForSelector('h1:has-text("Medication Reminder")');
}
async waitForModal(title: string): Promise<void> {
await this.page.waitForSelector(`text=${title}`);
}
async waitForNotification(message: string): Promise<void> {
await this.page.waitForSelector(`text=${message}`);
}
}
// Data generators for testing
export const TestData = {
medications: [
{ name: 'Aspirin', dosage: '100mg', frequency: 'daily', times: '1' },
{ name: 'Vitamin D', dosage: '1000 IU', frequency: 'daily', times: '1' },
{ name: 'Omega-3', dosage: '500mg', frequency: 'daily', times: '2' },
{ name: 'Calcium', dosage: '600mg', frequency: 'twice_daily', times: '1' },
] as const satisfies readonly MedicationData[],
users: [
{
email: 'test1@example.com',
username: 'testuser1',
password: 'TestPass123!',
},
{
email: 'test2@example.com',
username: 'testuser2',
password: 'TestPass456!',
},
] as const satisfies readonly UserData[],
reminders: [
{ title: 'Drink Water', icon: 'bell', frequency: 60 },
{ title: 'Exercise', icon: 'heart', frequency: 1440 }, // Daily
{ title: 'Check Blood Pressure', icon: 'chart', frequency: 10080 }, // Weekly
] as const satisfies readonly ReminderData[],
} as const;