- Removed brittle 1-second waitForTimeout - Use toPass() with polling to wait for job outcome - Check for specific user's email instead of exact row count - More robust under slow worker conditions or CI load
80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
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+$/);
|
|
|
|
// 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: Poll for job outcome to appear (worker may take time to process)
|
|
// Keep refreshing until we see the regular user's email in the table
|
|
await expect(async () => {
|
|
await page.reload();
|
|
await expect(page.locator("table tbody")).toContainText(REGULAR_USER.email);
|
|
}).toPass({ timeout: 15000, intervals: [500, 1000, 2000] });
|
|
|
|
// 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("/");
|
|
});
|
|
});
|