106 lines
4.6 KiB
JavaScript
106 lines
4.6 KiB
JavaScript
// @ts-check
|
|
const { test, expect } = require('@playwright/test');
|
|
|
|
/**
|
|
* E2E tests run against the full Docker stack (frontend on port 52867,
|
|
* backend on port 3001). To run locally:
|
|
* docker-compose up -d
|
|
* npx playwright test
|
|
*/
|
|
|
|
const BASE_URL = process.env.E2E_BASE_URL || 'http://localhost:52867';
|
|
|
|
test.describe('UI Flow — create experiment → add animal → log status', () => {
|
|
test('full happy path', async ({ page }) => {
|
|
await page.goto(BASE_URL);
|
|
|
|
// ── Create experiment ────────────────────────────────────────
|
|
await page.click('button:has-text("New Experiment")');
|
|
await expect(page.getByRole('dialog')).toBeVisible();
|
|
|
|
await page.getByLabel(/experiment title/i).fill('E2E Test Study');
|
|
await page.click('button:has-text("Create Experiment")');
|
|
|
|
// Modal closes and new experiment appears in the list
|
|
await expect(page.getByRole('dialog')).not.toBeVisible();
|
|
await expect(page.getByText('E2E Test Study')).toBeVisible();
|
|
|
|
// ── Navigate into experiment ──────────────────────────────────
|
|
await page.click('text=E2E Test Study');
|
|
await expect(page.url()).toContain('/experiments/');
|
|
|
|
// ── Add animal ────────────────────────────────────────────────
|
|
await page.click('button:has-text("Add Animal")');
|
|
await expect(page.getByRole('dialog')).toBeVisible();
|
|
|
|
await page.getByLabel(/animal id/i).fill('M-E2E-001');
|
|
await page.getByLabel(/animal name/i).fill('TestMouse');
|
|
await page.click('button:has-text("Add Animal")');
|
|
|
|
await expect(page.getByRole('dialog')).not.toBeVisible();
|
|
await expect(page.getByText('TestMouse')).toBeVisible();
|
|
|
|
// ── Navigate into animal ──────────────────────────────────────
|
|
await page.click('text=TestMouse');
|
|
await expect(page.url()).toContain('/animals/');
|
|
|
|
// ── Log daily status ──────────────────────────────────────────
|
|
await page.click('button:has-text("Log Daily Status")');
|
|
await expect(page.getByRole('dialog')).toBeVisible();
|
|
|
|
// Date is pre-filled with today; add vitals
|
|
await page.getByLabel(/vitals/i).fill('HR 70, Temp 37.0');
|
|
await page.getByLabel(/treatment/i).fill('Control');
|
|
await page.click('button:has-text("Log Status")');
|
|
|
|
await expect(page.getByRole('dialog')).not.toBeVisible();
|
|
await expect(page.getByText('HR 70, Temp 37.0')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('UX Flow — validation error states', () => {
|
|
test('empty experiment title shows error', async ({ page }) => {
|
|
await page.goto(BASE_URL);
|
|
await page.click('button:has-text("New Experiment")');
|
|
await page.click('button:has-text("Create Experiment")');
|
|
await expect(page.getByRole('alert')).toContainText(/title is required/i);
|
|
});
|
|
|
|
test('empty animal fields show errors', async ({ page }) => {
|
|
await page.goto(BASE_URL);
|
|
|
|
// Need an experiment to navigate into — create one first
|
|
await page.click('button:has-text("New Experiment")');
|
|
await page.getByLabel(/experiment title/i).fill('UX Test Study');
|
|
await page.click('button:has-text("Create Experiment")');
|
|
await page.click('text=UX Test Study');
|
|
|
|
await page.click('button:has-text("Add Animal")');
|
|
await page.click('button:has-text("Add Animal")'); // submit without filling
|
|
const alerts = page.getByRole('alert');
|
|
await expect(alerts).toHaveCount(2); // ID + Name errors
|
|
});
|
|
|
|
test('missing date on daily status shows error', async ({ page }) => {
|
|
await page.goto(BASE_URL);
|
|
|
|
// Create experiment + animal to get to daily status form
|
|
await page.click('button:has-text("New Experiment")');
|
|
await page.getByLabel(/experiment title/i).fill('Date Test Study');
|
|
await page.click('button:has-text("Create Experiment")');
|
|
await page.click('text=Date Test Study');
|
|
|
|
await page.click('button:has-text("Add Animal")');
|
|
await page.getByLabel(/animal id/i).fill('M-DT-001');
|
|
await page.getByLabel(/animal name/i).fill('DateTestMouse');
|
|
await page.click('button:has-text("Add Animal")');
|
|
await page.click('text=DateTestMouse');
|
|
|
|
await page.click('button:has-text("Log Daily Status")');
|
|
// Clear the date field
|
|
await page.getByLabel(/date/i).fill('');
|
|
await page.click('button:has-text("Log Status")');
|
|
await expect(page.getByRole('alert')).toContainText(/date is required/i);
|
|
});
|
|
});
|