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:
parent
b8470b77a7
commit
7ec987c78d
2 changed files with 91 additions and 2 deletions
84
frontend/e2e/random-jobs.spec.ts
Normal file
84
frontend/e2e/random-jobs.spec.ts
Normal 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("/");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue