Phase 6: E2E Test

- Update scripts/e2e.sh to start worker alongside backend
- Create frontend/e2e/random-jobs.spec.ts with 3 tests:
  - Counter increment creates random job outcome visible to admin
  - Admin can view empty random jobs list
  - Regular user cannot access random jobs page
This commit is contained in:
counterweight 2025-12-21 23:00:54 +01:00
parent b8470b77a7
commit 7ec987c78d
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
2 changed files with 91 additions and 2 deletions

View file

@ -0,0 +1,84 @@
import { test, expect } from "@playwright/test";
import { clearAuth, loginUser, REGULAR_USER, ADMIN_USER } from "./helpers/auth";
test.describe("Random Jobs - E2E", () => {
test("counter increment creates random job outcome visible to admin", async ({ page }) => {
// Step 1: Login as regular user
await clearAuth(page);
await loginUser(page, REGULAR_USER.email, REGULAR_USER.password);
// Wait for counter page to load
await expect(page.locator("h1")).toBeVisible();
await expect(page.locator("h1")).not.toHaveText("...");
// Step 2: Click increment button
await page.click("text=Increment");
// Wait for the counter to update (value changes)
const counterValue = await page.locator("h1").textContent();
expect(counterValue).toMatch(/^\d+$/);
// Give the worker a moment to process the job
await page.waitForTimeout(1000);
// Step 3: Logout
await page.click("text=Sign out");
await expect(page).toHaveURL("/login");
// Step 4: Login as admin
await loginUser(page, ADMIN_USER.email, ADMIN_USER.password);
// Admin should be on audit page by default
await expect(page).toHaveURL("/audit");
// Step 5: Navigate to Random Jobs page
await page.click('a[href="/admin/random-jobs"]');
await expect(page).toHaveURL("/admin/random-jobs");
// Step 6: Verify the table contains at least one row
// Wait for table to load and have data
await expect(page.locator("table tbody tr")).toHaveCount(1, { timeout: 10000 });
// Verify the row has the regular user's email
const tableContent = await page.locator("table tbody").textContent();
expect(tableContent).toContain(REGULAR_USER.email);
// Verify the outcome has expected fields
// Value should be a number 0-100
const valueCell = page.locator("table tbody tr td").nth(3);
const valueText = await valueCell.textContent();
const value = Number(valueText);
expect(value).toBeGreaterThanOrEqual(0);
expect(value).toBeLessThanOrEqual(100);
// Status should be "completed"
await expect(page.locator("table tbody")).toContainText("completed");
});
test("admin can view empty random jobs list", async ({ page }) => {
// This test just verifies the page loads correctly
// In a fresh DB there might be no outcomes yet
await clearAuth(page);
await loginUser(page, ADMIN_USER.email, ADMIN_USER.password);
await page.goto("/admin/random-jobs");
await expect(page).toHaveURL("/admin/random-jobs");
// Page title should be visible
await expect(page.locator("h2")).toContainText("Random Number Job Outcomes");
// Table should exist
await expect(page.locator("table")).toBeVisible();
});
test("regular user cannot access random jobs page", async ({ page }) => {
await clearAuth(page);
await loginUser(page, REGULAR_USER.email, REGULAR_USER.password);
// Try to navigate directly to the admin page
await page.goto("/admin/random-jobs");
// Should be redirected away (to "/" since fallbackRedirect is "/")
await expect(page).toHaveURL("/");
});
});

View file

@ -23,7 +23,11 @@ cd ..
# Start backend (SECRET_KEY should be set via .envrc or environment) # Start backend (SECRET_KEY should be set via .envrc or environment)
cd backend cd backend
uv run uvicorn main:app --port 8000 --log-level warning & uv run uvicorn main:app --port 8000 --log-level warning &
PID=$! BACKEND_PID=$!
# Start worker for job processing
uv run python worker.py &
WORKER_PID=$!
cd .. cd ..
# Wait for backend # Wait for backend
@ -46,7 +50,8 @@ fi
EXIT_CODE=$? EXIT_CODE=$?
# Cleanup # Cleanup
kill $PID 2>/dev/null || true kill $BACKEND_PID 2>/dev/null || true
kill $WORKER_PID 2>/dev/null || true
exit $EXIT_CODE exit $EXIT_CODE