Update frontend e2e tests for current UI

This commit is contained in:
MOHAN 2026-07-16 23:07:32 +05:30
parent b3b3fa3392
commit 1649fb8e77
3 changed files with 80 additions and 31 deletions

View File

@ -4,12 +4,12 @@ export default defineConfig({
testDir: "./tests",
timeout: 30_000,
use: {
baseURL: "http://localhost:3001",
baseURL: "http://localhost:3052",
trace: "on-first-retry"
},
webServer: {
command: "npm run dev",
url: "http://localhost:3001",
url: "http://localhost:3052",
reuseExistingServer: !process.env.CI
}
});

View File

@ -6,9 +6,21 @@ const apiOk = (data: unknown) => ({
error: null
});
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
localStorage.setItem("ledgerone_user_id", "test_user");
test.beforeEach(async ({ context, page }) => {
await context.addCookies([
{ name: "ledgerone_auth", value: "1", domain: "localhost", path: "/" },
]);
await page.route("**/api/auth/me", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ user: { id: "user_1", email: "test@example.com", name: "Test User" } })),
});
});
await page.route("**/api/billing/subscription", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ plan: "pro", status: "active" })),
});
});
});
@ -41,16 +53,27 @@ test("dashboard renders summary, cashflow, and merchants", async ({ page }) => {
)
});
});
await page.route("**/api/accounts**", async (route) => {
await page.route("**/api/view/accounts**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk([{ id: "acct_1" }, { id: "acct_2" }]))
body: JSON.stringify(apiOk({ accounts: [{ viewRef: "acct_1" }, { viewRef: "acct_2" }], total: 2 }))
});
});
await page.route("**/api/view/transactions**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({
transactions: [
{ viewRef: "tx_1", date: "2025-09-10", description: "Acme Corp", category: "Office", amount: "-25.00" }
],
total: 1
}))
});
});
await page.goto("/app");
await expect(page.getByText("Income (30d)")).toBeVisible();
await expect(page.getByText("Top Merchants")).toBeVisible();
await expect(page.getByText("Acme Corp")).toBeVisible();
await expect(page.getByText("2025-09")).toBeVisible();
await expect(page.getByText("Acme Corp").first()).toBeVisible();
await expect(page.getByText("Sep 2025")).toBeVisible();
});

View File

@ -6,25 +6,42 @@ const apiOk = (data: unknown) => ({
error: null
});
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
localStorage.setItem("ledgerone_user_id", "test_user");
test.beforeEach(async ({ context, page }) => {
await context.addCookies([
{ name: "ledgerone_auth", value: "1", domain: "localhost", path: "/" },
]);
await page.route("**/api/auth/me", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ user: { id: "user_1", email: "test@example.com", name: "Test User" } })),
});
});
await page.route("**/api/billing/subscription", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ plan: "pro", status: "active" })),
});
});
});
test("transactions page supports filters, manual add, and edit", async ({ page }) => {
let listResponse = apiOk([
let listResponse = apiOk({
transactions: [
{
id: "tx_1",
name: "Coffee Bar",
viewRef: "tx_1",
description: "Coffee Bar",
amount: "12.50",
category: "Dining",
note: "",
attribution: "mine",
split: { mode: "none", minePercent: 50, yoursPercent: 50, mineAmount: 0, yoursAmount: 0 },
status: "raw",
hidden: false,
date: "2025-01-10"
}
]);
],
total: 1
});
await page.route("**/api/transactions/summary**", async (route) => {
await route.fulfill({
@ -81,44 +98,53 @@ test("transactions page supports filters, manual add, and edit", async ({ page }
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(
apiOk([
{ id: "acct_1", institutionName: "Chase", accountType: "checking", mask: "1234" }
])
apiOk({
accounts: [
{ viewRef: "acct_1", institutionName: "Chase", accountType: "checking", mask: "1234" }
],
total: 1
})
)
});
});
await page.goto("/transactions");
await expect(page.getByText("Sync transactions")).toBeVisible();
await expect(page.getByText("Export CSV")).toBeVisible();
await expect(page.getByRole("button", { name: "Sync" })).toBeVisible();
await expect(page.getByRole("link", { name: "Export", exact: true })).toBeVisible();
await page.getByRole("button", { name: "Show filters" }).click();
await expect(page.getByPlaceholder("Search description")).toBeVisible();
await page.getByRole("button", { name: "Filters" }).click();
await expect(page.getByPlaceholder("Description...")).toBeVisible();
await page.getByRole("button", { name: "Add manual" }).click();
await expect(page.getByText("Manual transaction")).toBeVisible();
await page.getByPlaceholder("Description").fill("Manual payment");
await page.getByPlaceholder("0.00").fill("40.25");
await page.getByRole("button", { name: "Save manual transaction" }).click();
const manualForm = page.locator("form").first();
await manualForm.getByText("Description").locator("..").getByRole("textbox").fill("Manual payment");
await manualForm.getByPlaceholder("-42.50").fill("40.25");
await manualForm.getByRole("button", { name: "Save" }).click();
await expect(page.getByText("Manual transaction saved.")).toBeVisible();
await page.getByRole("button", { name: "Edit" }).click();
await page.getByPlaceholder("Category").fill("Coffee");
await page.getByPlaceholder("Note").fill("Edited note");
listResponse = apiOk([
listResponse = apiOk({
transactions: [
{
id: "tx_1",
name: "Coffee Bar",
viewRef: "tx_1",
description: "Coffee Bar",
amount: "12.50",
category: "Coffee",
note: "Edited note",
attribution: "mine",
split: { mode: "none", minePercent: 50, yoursPercent: 50, mineAmount: 0, yoursAmount: 0 },
status: "user",
hidden: false,
date: "2025-01-10"
}
]);
await page.getByRole("button", { name: "Save edits" }).click();
],
total: 1
});
await page.getByRole("button", { name: "Save" }).click();
await expect(page.getByText("Transaction updated.")).toBeVisible();
});