remove: broken Playwright E2E testing infrastructure

- Remove playwright.config.ts (references non-existent docker/docker-compose.yaml)
- Remove tests/e2e/ directory with broken test files
- Remove @playwright/test dependency from package.json
- Update documentation to remove E2E test references:
  - docs/architecture/PROJECT_STRUCTURE.md
  - docs/implementation/IMPLEMENTATION_SUMMARY.md
  - README.md
  - CONTRIBUTING.md
- E2E tests were non-functional due to missing Docker setup
- Focus on working unit and integration tests instead
This commit is contained in:
William Valentin
2025-09-08 22:23:17 -07:00
parent b5b475f21b
commit d693dcf45c
16 changed files with 10 additions and 1092 deletions

View File

@@ -1,319 +0,0 @@
# 🎭 End-to-End Testing with Playwright
## Overview
This directory contains comprehensive end-to-end tests for the Medication Reminder App using Playwright. These tests simulate real user interactions across different browsers and devices.
## Test Structure
```
tests/e2e/
├── README.md # This documentation
├── fixtures.ts # Custom test fixtures and utilities
├── helpers.ts # Test helper functions and data
├── auth.spec.ts # Authentication flow tests
├── medication.spec.ts # Medication management tests
├── admin.spec.ts # Admin interface tests
├── ui-navigation.spec.ts # UI and navigation tests
└── reminders.spec.ts # Reminder system tests
```
## Test Categories
### 🔐 **Authentication Tests** (`auth.spec.ts`)
- User registration and login
- Admin authentication
- OAuth button visibility
- Invalid credential handling
- Session management
### 💊 **Medication Management** (`medication.spec.ts`)
- Adding new medications
- Editing existing medications
- Deleting medications
- Marking doses as taken
- Viewing medication history
### 👑 **Admin Interface** (`admin.spec.ts`)
- User management operations
- Password changes
- User status toggles
- Admin permissions
### 🎨 **UI & Navigation** (`ui-navigation.spec.ts`)
- Theme switching
- Modal interactions
- Responsive design
- Search functionality
- Account management
### ⏰ **Reminder System** (`reminders.spec.ts`)
- Custom reminder creation
- Reminder editing and deletion
- Scheduled dose display
- Missed dose handling
## Setup and Installation
### 1. Install Playwright
```bash
# Install Playwright and browsers
bun add -D @playwright/test
bunx playwright install
```
### 2. Update Package.json
```json
{
"scripts": {
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:debug": "playwright test --debug",
"test:e2e:report": "playwright show-report"
}
}
```
## Running Tests
### Basic Test Execution
```bash
# Run all E2E tests
bun run test:e2e
# Run tests in UI mode (interactive)
bun run test:e2e:ui
# Run specific test file
bunx playwright test auth.spec.ts
# Run tests in debug mode
bun run test:e2e:debug
```
### Browser-Specific Testing
```bash
# Run on specific browser
bunx playwright test --project=chromium
bunx playwright test --project=firefox
bunx playwright test --project=webkit
# Run on mobile browsers
bunx playwright test --project="Mobile Chrome"
bunx playwright test --project="Mobile Safari"
```
### Test Reporting
```bash
# Generate and view HTML report
bun run test:e2e:report
# Run with specific reporter
bunx playwright test --reporter=line
bunx playwright test --reporter=json
```
## Test Configuration
The tests are configured via `playwright.config.ts`:
- **Base URL**: `http://localhost:8080`
- **Auto-start**: Docker Compose before tests
- **Browsers**: Chrome, Firefox, Safari, Mobile Chrome, Mobile Safari
- **Retries**: 2 on CI, 0 locally
- **Screenshots**: On failure
- **Videos**: On failure
- **Traces**: On retry
## Test Data and Fixtures
### Custom Fixtures (`fixtures.ts`)
- `adminPage`: Auto-login as admin user
- `userPage`: Auto-login as regular user
### Helper Functions (`helpers.ts`)
- `MedicationHelpers`: Medication CRUD operations
- `AuthHelpers`: Authentication actions
- `ModalHelpers`: Modal interactions
- `WaitHelpers`: Wait utilities
- `TestData`: Pre-defined test data
### Example Usage
```typescript
import { test } from './fixtures';
import { MedicationHelpers, TestData } from './helpers';
test('should add medication', async ({ adminPage }) => {
const medicationHelper = new MedicationHelpers(adminPage);
const testMed = TestData.medications[0];
await medicationHelper.addMedication(testMed.name, testMed.dosage, testMed.frequency);
});
```
## Best Practices
### ✅ Test Organization
- Group related tests in describe blocks
- Use descriptive test names
- Keep tests independent and isolated
### ✅ Selectors
- Use data-testid attributes for reliable targeting
- Prefer semantic selectors (role, text content)
- Avoid CSS selectors that may change
### ✅ Waiting Strategies
- Use `waitForSelector()` for dynamic content
- Leverage auto-waiting for most actions
- Add explicit waits for complex interactions
### ✅ Test Data
- Use helper functions for common operations
- Keep test data in centralized location
- Clean up test data after tests
## Debugging Tests
### Local Debugging
```bash
# Debug specific test
bunx playwright test auth.spec.ts --debug
# Run with headed browser
bunx playwright test --headed
# Slow down execution
bunx playwright test --slow-mo=1000
```
### CI/CD Integration
```bash
# Run in CI mode
CI=true bunx playwright test
# Generate artifacts for CI
bunx playwright test --reporter=github
```
## Adding New Tests
### 1. Create Test File
```typescript
import { test, expect } from './fixtures';
test.describe('New Feature', () => {
test('should do something', async ({ adminPage }) => {
// Test implementation
});
});
```
### 2. Add Helper Functions
```typescript
// In helpers.ts
export class NewFeatureHelpers {
constructor(private page: any) {}
async performAction() {
// Helper implementation
}
}
```
### 3. Update Documentation
- Add test description to this README
- Update test count in project documentation
## Troubleshooting
### Common Issues
**Tests timeout:**
- Increase timeout in config
- Add explicit waits
- Check application startup time
**Flaky tests:**
- Add proper wait conditions
- Use retry logic
- Check for race conditions
**Browser compatibility:**
- Test across all configured browsers
- Check for browser-specific issues
- Use cross-browser compatible selectors
### Debug Commands
```bash
# Show browser developer tools
bunx playwright test --debug
# Record test execution
bunx playwright codegen localhost:8080
# Trace viewer
bunx playwright show-trace trace.zip
```
## Continuous Integration
Example GitHub Actions workflow:
```yaml
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: bun install
- run: bunx playwright install --with-deps
- run: bun run test:e2e
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
```
## Coverage and Metrics
The E2E tests provide coverage for:
- ✅ User authentication flows
- ✅ Core medication management
- ✅ Admin functionality
- ✅ UI interactions and navigation
- ✅ Responsive design
- ✅ Cross-browser compatibility
For optimal coverage, run tests regularly and add new tests for new features.

View File

@@ -1,63 +0,0 @@
import { test, expect } from '@playwright/test';
test.describe('Admin Interface', () => {
test.beforeEach(async ({ page }) => {
// Login as admin
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
// Wait for main app and open admin interface
await expect(page.locator('h1')).toContainText('Medication Reminder');
await page.click('button:has-text("Admin")');
});
test('should display admin interface', async ({ page }) => {
await expect(page.locator('text=Admin Interface')).toBeVisible();
await expect(page.locator('text=User Management')).toBeVisible();
});
test('should show list of users', async ({ page }) => {
// Should show admin user at minimum
await expect(page.locator('text=admin@localhost')).toBeVisible();
await expect(page.locator('text=Admin')).toBeVisible(); // Role
});
test('should allow changing user password', async ({ page }) => {
// Click on a user's change password button
await page.click('[data-testid="change-password"]');
// Fill new password
await page.fill('input[type="password"]', 'NewPassword123!');
// Submit password change
await page.click('button:has-text("Change Password")');
// Should show success message
await expect(page.locator('text=Password changed')).toBeVisible();
});
test('should allow suspending/activating users', async ({ page }) => {
// Look for user status controls
const statusButton = page
.locator('[data-testid="toggle-user-status"]')
.first();
await expect(statusButton).toBeVisible();
});
test('should refresh user list', async ({ page }) => {
await page.click('button:has-text("Refresh")');
// Should still show users after refresh
await expect(page.locator('text=admin@localhost')).toBeVisible();
});
test('should close admin interface', async ({ page }) => {
await page.click('button[aria-label="Close"]');
// Should return to main app
await expect(page.locator('text=Admin Interface')).not.toBeVisible();
await expect(page.locator('h1')).toContainText('Medication Reminder');
});
});

View File

@@ -1,58 +0,0 @@
import { test, expect } from '@playwright/test';
test.describe('Authentication Flow', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
test('should display login page for unauthenticated users', async ({
page,
}) => {
await expect(page.locator('h2')).toContainText(['Sign In', 'Login']);
await expect(page.locator('input[type="email"]')).toBeVisible();
await expect(page.locator('input[type="password"]')).toBeVisible();
});
test('should allow user registration', async ({ page }) => {
// Click register tab/link
await page.click('text=Register');
// Fill registration form
await page.fill('input[type="email"]', 'test@example.com');
await page.fill('input[name="username"]', 'testuser');
await page.fill('input[type="password"]', 'TestPassword123!');
// Submit registration
await page.click('button[type="submit"]');
// Should show verification message or redirect
await expect(page.locator('text=verification')).toBeVisible();
});
test('should login with admin credentials', async ({ page }) => {
// Fill login form with admin credentials
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
// Submit login
await page.click('button[type="submit"]');
// Should redirect to main app
await expect(page.locator('h1')).toContainText('Medication Reminder');
await expect(page.locator('text=Admin')).toBeVisible();
});
test('should show error for invalid credentials', async ({ page }) => {
await page.fill('input[type="email"]', 'invalid@example.com');
await page.fill('input[type="password"]', 'wrongpassword');
await page.click('button[type="submit"]');
await expect(page.locator('text=Invalid')).toBeVisible();
});
test('should handle OAuth login buttons', async ({ page }) => {
await expect(page.locator('button:has-text("Google")')).toBeVisible();
await expect(page.locator('button:has-text("GitHub")')).toBeVisible();
});
});

View File

@@ -1,54 +0,0 @@
import { test as base, Page } from '@playwright/test';
// Define fixture types
type TestFixtures = {
adminPage: Page;
userPage: Page;
};
// Extend basic test with custom fixtures
export const test = base.extend<TestFixtures>({
// Auto-login fixture for admin user
adminPage: async ({ page }, use) => {
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
// Wait for app to load
await page.waitForSelector('h1:has-text("Medication Reminder")');
await use(page);
},
// Regular user login fixture
userPage: async ({ page }, use) => {
await page.goto('/');
// Register a test user first if needed
await page.click('text=Register');
await page.fill('input[type="email"]', 'testuser@example.com');
await page.fill('input[name="username"]', 'testuser');
await page.fill('input[type="password"]', 'TestPassword123!');
await page.click('button[type="submit"]');
// For mock database, user might be auto-verified
// Wait for either verification message or app load
try {
await page.waitForSelector('h1:has-text("Medication Reminder")', {
timeout: 5000,
});
} catch {
// If not auto-logged in, login manually
await page.goto('/');
await page.fill('input[type="email"]', 'testuser@example.com');
await page.fill('input[type="password"]', 'TestPassword123!');
await page.click('button[type="submit"]');
await page.waitForSelector('h1:has-text("Medication Reminder")');
}
await use(page);
},
});
export { expect } from '@playwright/test';

View File

@@ -1,158 +0,0 @@
// 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;

View File

@@ -1,95 +0,0 @@
import { test, expect } from '@playwright/test';
test.describe('Medication Management', () => {
test.beforeEach(async ({ page }) => {
// Login as admin first
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
// Wait for main app to load
await expect(page.locator('h1')).toContainText('Medication Reminder');
});
test('should add a new medication', async ({ page }) => {
// Click add medication button
await page.click('button:has-text("Add Medication")');
// Fill medication form
await page.fill('input[name="name"]', 'Aspirin');
await page.fill('input[name="dosage"]', '100mg');
await page.selectOption('select[name="frequency"]', 'daily');
await page.fill('input[name="times"]', '2');
// Submit form
await page.click('button[type="submit"]');
// Should see medication in list
await expect(page.locator('text=Aspirin')).toBeVisible();
await expect(page.locator('text=100mg')).toBeVisible();
});
test('should edit existing medication', async ({ page }) => {
// First add a medication
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Vitamin D');
await page.fill('input[name="dosage"]', '1000 IU');
await page.click('button[type="submit"]');
// Click edit button for the medication
await page.click('[data-testid="edit-medication"]');
// Update dosage
await page.fill('input[name="dosage"]', '2000 IU');
await page.click('button[type="submit"]');
// Should see updated dosage
await expect(page.locator('text=2000 IU')).toBeVisible();
});
test('should delete medication', async ({ page }) => {
// Add a medication first
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Test Medicine');
await page.fill('input[name="dosage"]', '50mg');
await page.click('button[type="submit"]');
// Open manage medications modal
await page.click('button:has-text("Manage")');
// Delete the medication
await page.click('[data-testid="delete-medication"]');
await page.click('button:has-text("Delete")'); // Confirm deletion
// Should not see medication anymore
await expect(page.locator('text=Test Medicine')).not.toBeVisible();
});
test('should mark dose as taken', async ({ page }) => {
// Add a medication first
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Daily Vitamin');
await page.fill('input[name="dosage"]', '1 tablet');
await page.selectOption('select[name="frequency"]', 'daily');
await page.click('button[type="submit"]');
// Find and click the "Take" button for upcoming dose
await page.click('button:has-text("Take")');
// Should show as taken
await expect(page.locator('text=Taken')).toBeVisible();
await expect(page.locator('.bg-green-50')).toBeVisible();
});
test('should show medication history', async ({ page }) => {
// Open history modal
await page.click('button:has-text("History")');
// Should show history modal
await expect(page.locator('text=Medication History')).toBeVisible();
// Close modal
await page.click('button:has-text("Close")');
});
});

View File

@@ -1,87 +0,0 @@
import { test, expect } from '@playwright/test';
test.describe('Reminder System', () => {
test.beforeEach(async ({ page }) => {
// Login as admin
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
await expect(page.locator('h1')).toContainText('Medication Reminder');
});
test('should create custom reminder', async ({ page }) => {
// Click manage reminders
await page.click('button:has-text("Reminders")');
// Add new reminder
await page.click('button:has-text("Add Reminder")');
// Fill reminder form
await page.fill('input[name="title"]', 'Drink Water');
await page.selectOption('select[name="icon"]', 'bell');
await page.fill('input[name="frequency"]', '60'); // Every hour
await page.click('button[type="submit"]');
// Should see reminder in list
await expect(page.locator('text=Drink Water')).toBeVisible();
});
test('should edit custom reminder', async ({ page }) => {
// First create a reminder
await page.click('button:has-text("Reminders")');
await page.click('button:has-text("Add Reminder")');
await page.fill('input[name="title"]', 'Exercise');
await page.click('button[type="submit"]');
// Edit the reminder
await page.click('[data-testid="edit-reminder"]');
await page.fill('input[name="title"]', 'Morning Exercise');
await page.click('button[type="submit"]');
await expect(page.locator('text=Morning Exercise')).toBeVisible();
});
test('should delete custom reminder', async ({ page }) => {
// Create and then delete reminder
await page.click('button:has-text("Reminders")');
await page.click('button:has-text("Add Reminder")');
await page.fill('input[name="title"]', 'Temporary Reminder');
await page.click('button[type="submit"]');
// Delete it
await page.click('[data-testid="delete-reminder"]');
await page.click('button:has-text("Delete")'); // Confirm
await expect(page.locator('text=Temporary Reminder')).not.toBeVisible();
});
test('should show scheduled medication doses', async ({ page }) => {
// Add a medication first
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Scheduled Med');
await page.fill('input[name="dosage"]', '5mg');
await page.selectOption('select[name="frequency"]', 'daily');
await page.fill('input[name="times"]', '3'); // 3 times daily
await page.click('button[type="submit"]');
// Should see scheduled doses for today
await expect(page.locator('text=Scheduled Med')).toBeVisible();
await expect(page.locator('button:has-text("Take")')).toHaveCount(3);
});
test('should handle missed doses', async ({ page }) => {
// This would test the logic for marking doses as missed
// when they pass their scheduled time
// Add medication with past schedule
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Past Due Med');
await page.fill('input[name="dosage"]', '10mg');
await page.click('button[type="submit"]');
// Simulate time passing or manually mark as missed
// This would depend on your app's specific implementation
});
});

View File

@@ -1,36 +0,0 @@
// Optimized test utilities to reduce duplication
import { Page } from '@playwright/test';
export class TestUtils {
static async loginAsAdmin(page: Page): Promise<void> {
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
await page.waitForSelector('h1:has-text("Medication Reminder")');
}
static async loginAsUser(
page: Page,
email: string = 'testuser@example.com',
password: string = 'TestPassword123!'
): Promise<void> {
await page.goto('/');
await page.fill('input[type="email"]', email);
await page.fill('input[type="password"]', password);
await page.click('button[type="submit"]');
await page.waitForSelector('h1:has-text("Medication Reminder")');
}
static async waitForApp(page: Page): Promise<void> {
await page.waitForSelector('h1:has-text("Medication Reminder")');
}
static async openModal(page: Page, buttonText: string): Promise<void> {
await page.click(`button:has-text("${buttonText}")`);
}
static async closeModal(page: Page): Promise<void> {
await page.click('button:has-text("Close")');
}
}

View File

@@ -1,100 +0,0 @@
import { test, expect } from '@playwright/test';
test.describe('User Interface and Navigation', () => {
test.beforeEach(async ({ page }) => {
// Login as admin
await page.goto('/');
await page.fill('input[type="email"]', 'admin@localhost');
await page.fill('input[type="password"]', 'admin123!');
await page.click('button[type="submit"]');
await expect(page.locator('h1')).toContainText('Medication Reminder');
});
test('should display main navigation elements', async ({ page }) => {
await expect(
page.locator('button:has-text("Add Medication")')
).toBeVisible();
await expect(page.locator('button:has-text("Manage")')).toBeVisible();
await expect(page.locator('button:has-text("History")')).toBeVisible();
await expect(page.locator('button:has-text("Stats")')).toBeVisible();
});
test('should toggle theme', async ({ page }) => {
// Click theme switcher
await page.click('[data-testid="theme-switcher"]');
// Check if dark mode is applied
await expect(page.locator('html')).toHaveClass(/dark/);
// Toggle back to light mode
await page.click('[data-testid="theme-switcher"]');
await expect(page.locator('html')).not.toHaveClass(/dark/);
});
test('should open and close account modal', async ({ page }) => {
// Click account button
await page.click('button:has-text("Account")');
// Should show account modal
await expect(page.locator('text=Account Settings')).toBeVisible();
// Close modal
await page.click('button:has-text("Close")');
await expect(page.locator('text=Account Settings')).not.toBeVisible();
});
test('should open stats modal', async ({ page }) => {
await page.click('button:has-text("Stats")');
await expect(page.locator('text=Medication Statistics')).toBeVisible();
await expect(page.locator('text=Weekly Adherence')).toBeVisible();
await page.click('button:has-text("Close")');
});
test('should show current time and date', async ({ page }) => {
// Should display current time somewhere on the page
const timeElement = page.locator('[data-testid="current-time"]');
await expect(timeElement).toBeVisible();
});
test('should handle responsive design', async ({ page }) => {
// Test mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
// Should still show main elements
await expect(page.locator('h1')).toBeVisible();
await expect(
page.locator('button:has-text("Add Medication")')
).toBeVisible();
// Reset to desktop
await page.setViewportSize({ width: 1280, height: 720 });
});
test('should search medications', async ({ page }) => {
// Add a test medication first
await page.click('button:has-text("Add Medication")');
await page.fill('input[name="name"]', 'Searchable Medicine');
await page.fill('input[name="dosage"]', '10mg');
await page.click('button[type="submit"]');
// Use search functionality
await page.fill('input[placeholder*="search"]', 'Searchable');
// Should show filtered results
await expect(page.locator('text=Searchable Medicine')).toBeVisible();
// Clear search
await page.fill('input[placeholder*="search"]', '');
});
test('should logout user', async ({ page }) => {
// Click logout (usually in avatar dropdown)
await page.click('[data-testid="avatar-dropdown"]');
await page.click('button:has-text("Logout")');
// Should return to login page
await expect(page.locator('h2')).toContainText(['Sign In', 'Login']);
});
});