Add Prettier for TypeScript formatting

- Install prettier
- Configure .prettierrc.json and .prettierignore
- Add npm scripts: format, format:check
- Add Makefile target: format-frontend
- Format all frontend files
This commit is contained in:
counterweight 2025-12-21 21:59:26 +01:00
parent 4b394b0698
commit 37de6f70e0
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
44 changed files with 906 additions and 856 deletions

View file

@ -2,7 +2,7 @@ import { test, expect, Page } from "@playwright/test";
/**
* Permission-based E2E tests
*
*
* These tests verify that:
* 1. Regular users can only access Counter and Sum pages
* 2. Admin users can only access the Audit page
@ -18,7 +18,9 @@ const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
function getRequiredEnv(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error(`Required environment variable ${name} is not set. Run 'source .env' or set it in your environment.`);
throw new Error(
`Required environment variable ${name} is not set. Run 'source .env' or set it in your environment.`
);
}
return value;
}
@ -64,10 +66,10 @@ test.describe("Regular User Access", () => {
test("can access counter page", async ({ page }) => {
await page.goto("/");
// Should stay on counter page
await expect(page).toHaveURL("/");
// Should see counter UI
await expect(page.getByText("Current Count")).toBeVisible();
await expect(page.getByRole("button", { name: /increment/i })).toBeVisible();
@ -75,28 +77,28 @@ test.describe("Regular User Access", () => {
test("can access sum page", async ({ page }) => {
await page.goto("/sum");
// Should stay on sum page
await expect(page).toHaveURL("/sum");
// Should see sum UI
await expect(page.getByText("Sum Calculator")).toBeVisible();
});
test("cannot access audit page - redirected to counter", async ({ page }) => {
await page.goto("/audit");
// Should be redirected to counter page (home)
await expect(page).toHaveURL("/");
});
test("navigation only shows Counter and Sum", async ({ page }) => {
await page.goto("/");
// Should see Counter and Sum in nav
await expect(page.getByText("Counter")).toBeVisible();
await expect(page.getByText("Sum")).toBeVisible();
// Should NOT see Audit in nav (for regular users)
const auditLinks = page.locator('a[href="/audit"]');
await expect(auditLinks).toHaveCount(0);
@ -104,11 +106,11 @@ test.describe("Regular User Access", () => {
test("can navigate between Counter and Sum", async ({ page }) => {
await page.goto("/");
// Go to Sum
await page.click('a[href="/sum"]');
await expect(page).toHaveURL("/sum");
// Go back to Counter
await page.click('a[href="/"]');
await expect(page).toHaveURL("/");
@ -116,31 +118,31 @@ test.describe("Regular User Access", () => {
test("can use counter functionality", async ({ page }) => {
await page.goto("/");
// Get initial count (might be any number)
const countElement = page.locator("h1").first();
await expect(countElement).toBeVisible();
// Click increment
await page.click('button:has-text("Increment")');
// Wait for update
await page.waitForTimeout(500);
// Counter should have updated (we just verify no error occurred)
await expect(countElement).toBeVisible();
});
test("can use sum functionality", async ({ page }) => {
await page.goto("/sum");
// Fill in numbers
await page.fill('input[aria-label="First number"]', "5");
await page.fill('input[aria-label="Second number"]', "3");
// Calculate
await page.click('button:has-text("Calculate")');
// Should show result
await expect(page.getByText("8")).toBeVisible();
});
@ -154,24 +156,24 @@ test.describe("Admin User Access", () => {
test("redirected from counter page to audit", async ({ page }) => {
await page.goto("/");
// Should be redirected to audit page
await expect(page).toHaveURL("/audit");
});
test("redirected from sum page to audit", async ({ page }) => {
await page.goto("/sum");
// Should be redirected to audit page
await expect(page).toHaveURL("/audit");
});
test("can access audit page", async ({ page }) => {
await page.goto("/audit");
// Should stay on audit page
await expect(page).toHaveURL("/audit");
// Should see audit tables
await expect(page.getByText("Counter Activity")).toBeVisible();
await expect(page.getByText("Sum Activity")).toBeVisible();
@ -179,10 +181,10 @@ test.describe("Admin User Access", () => {
test("navigation only shows Audit", async ({ page }) => {
await page.goto("/audit");
// Should see Audit as current
await expect(page.getByText("Audit")).toBeVisible();
// Should NOT see Counter or Sum links (for admin users)
const counterLinks = page.locator('a[href="/"]');
const sumLinks = page.locator('a[href="/sum"]');
@ -192,10 +194,10 @@ test.describe("Admin User Access", () => {
test("audit page shows records", async ({ page }) => {
await page.goto("/audit");
// Should see the tables
await expect(page.getByRole("table")).toHaveCount(2);
// Should see column headers (use first() since there are two tables with same headers)
await expect(page.getByRole("columnheader", { name: "User" }).first()).toBeVisible();
await expect(page.getByRole("columnheader", { name: "Date" }).first()).toBeVisible();
@ -228,11 +230,11 @@ test.describe("Permission Boundary via API", () => {
// Login as regular user
await clearAuth(page);
await loginUser(page, REGULAR_USER.email, REGULAR_USER.password);
// Get cookies
const cookies = await page.context().cookies();
const authCookie = cookies.find(c => c.name === "auth_token");
const authCookie = cookies.find((c) => c.name === "auth_token");
if (authCookie) {
// Try to call audit API directly
const response = await request.get(`${API_URL}/api/audit/counter`, {
@ -240,7 +242,7 @@ test.describe("Permission Boundary via API", () => {
Cookie: `auth_token=${authCookie.value}`,
},
});
expect(response.status()).toBe(403);
}
});
@ -249,11 +251,11 @@ test.describe("Permission Boundary via API", () => {
// Login as admin
await clearAuth(page);
await loginUser(page, ADMIN_USER.email, ADMIN_USER.password);
// Get cookies
const cookies = await page.context().cookies();
const authCookie = cookies.find(c => c.name === "auth_token");
const authCookie = cookies.find((c) => c.name === "auth_token");
if (authCookie) {
// Try to call counter API directly
const response = await request.get(`${API_URL}/api/counter`, {
@ -261,7 +263,7 @@ test.describe("Permission Boundary via API", () => {
Cookie: `auth_token=${authCookie.value}`,
},
});
expect(response.status()).toBe(403);
}
});
@ -273,11 +275,11 @@ test.describe("Session and Logout", () => {
await clearAuth(page);
await loginUser(page, REGULAR_USER.email, REGULAR_USER.password);
await expect(page).toHaveURL("/");
// Logout
await page.click("text=Sign out");
await expect(page).toHaveURL("/login");
// Try to access counter
await page.goto("/");
await expect(page).toHaveURL("/login");
@ -293,12 +295,11 @@ test.describe("Session and Logout", () => {
path: "/",
},
]);
// Try to access protected page
await page.goto("/");
// Should be redirected to login
await expect(page).toHaveURL("/login");
});
});