Update frontend e2e tests for current UI
This commit is contained in:
parent
b3b3fa3392
commit
1649fb8e77
@ -4,12 +4,12 @@ export default defineConfig({
|
|||||||
testDir: "./tests",
|
testDir: "./tests",
|
||||||
timeout: 30_000,
|
timeout: 30_000,
|
||||||
use: {
|
use: {
|
||||||
baseURL: "http://localhost:3001",
|
baseURL: "http://localhost:3052",
|
||||||
trace: "on-first-retry"
|
trace: "on-first-retry"
|
||||||
},
|
},
|
||||||
webServer: {
|
webServer: {
|
||||||
command: "npm run dev",
|
command: "npm run dev",
|
||||||
url: "http://localhost:3001",
|
url: "http://localhost:3052",
|
||||||
reuseExistingServer: !process.env.CI
|
reuseExistingServer: !process.env.CI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,9 +6,21 @@ const apiOk = (data: unknown) => ({
|
|||||||
error: null
|
error: null
|
||||||
});
|
});
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ context, page }) => {
|
||||||
await page.addInitScript(() => {
|
await context.addCookies([
|
||||||
localStorage.setItem("ledgerone_user_id", "test_user");
|
{ 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({
|
await route.fulfill({
|
||||||
contentType: "application/json",
|
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 page.goto("/app");
|
||||||
await expect(page.getByText("Income (30d)")).toBeVisible();
|
await expect(page.getByText("Income (30d)")).toBeVisible();
|
||||||
await expect(page.getByText("Top Merchants")).toBeVisible();
|
await expect(page.getByText("Top Merchants")).toBeVisible();
|
||||||
await expect(page.getByText("Acme Corp")).toBeVisible();
|
await expect(page.getByText("Acme Corp").first()).toBeVisible();
|
||||||
await expect(page.getByText("2025-09")).toBeVisible();
|
await expect(page.getByText("Sep 2025")).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,25 +6,42 @@ const apiOk = (data: unknown) => ({
|
|||||||
error: null
|
error: null
|
||||||
});
|
});
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ context, page }) => {
|
||||||
await page.addInitScript(() => {
|
await context.addCookies([
|
||||||
localStorage.setItem("ledgerone_user_id", "test_user");
|
{ 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 }) => {
|
test("transactions page supports filters, manual add, and edit", async ({ page }) => {
|
||||||
let listResponse = apiOk([
|
let listResponse = apiOk({
|
||||||
|
transactions: [
|
||||||
{
|
{
|
||||||
id: "tx_1",
|
viewRef: "tx_1",
|
||||||
name: "Coffee Bar",
|
description: "Coffee Bar",
|
||||||
amount: "12.50",
|
amount: "12.50",
|
||||||
category: "Dining",
|
category: "Dining",
|
||||||
note: "",
|
note: "",
|
||||||
|
attribution: "mine",
|
||||||
|
split: { mode: "none", minePercent: 50, yoursPercent: 50, mineAmount: 0, yoursAmount: 0 },
|
||||||
status: "raw",
|
status: "raw",
|
||||||
hidden: false,
|
hidden: false,
|
||||||
date: "2025-01-10"
|
date: "2025-01-10"
|
||||||
}
|
}
|
||||||
]);
|
],
|
||||||
|
total: 1
|
||||||
|
});
|
||||||
|
|
||||||
await page.route("**/api/transactions/summary**", async (route) => {
|
await page.route("**/api/transactions/summary**", async (route) => {
|
||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
@ -81,44 +98,53 @@ test("transactions page supports filters, manual add, and edit", async ({ page }
|
|||||||
await route.fulfill({
|
await route.fulfill({
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
body: JSON.stringify(
|
body: JSON.stringify(
|
||||||
apiOk([
|
apiOk({
|
||||||
{ id: "acct_1", institutionName: "Chase", accountType: "checking", mask: "1234" }
|
accounts: [
|
||||||
])
|
{ viewRef: "acct_1", institutionName: "Chase", accountType: "checking", mask: "1234" }
|
||||||
|
],
|
||||||
|
total: 1
|
||||||
|
})
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.goto("/transactions");
|
await page.goto("/transactions");
|
||||||
|
|
||||||
await expect(page.getByText("Sync transactions")).toBeVisible();
|
await expect(page.getByRole("button", { name: "Sync" })).toBeVisible();
|
||||||
await expect(page.getByText("Export CSV")).toBeVisible();
|
await expect(page.getByRole("link", { name: "Export", exact: true })).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Show filters" }).click();
|
await page.getByRole("button", { name: "Filters" }).click();
|
||||||
await expect(page.getByPlaceholder("Search description")).toBeVisible();
|
await expect(page.getByPlaceholder("Description...")).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Add manual" }).click();
|
await page.getByRole("button", { name: "Add manual" }).click();
|
||||||
await expect(page.getByText("Manual transaction")).toBeVisible();
|
await expect(page.getByText("Manual transaction")).toBeVisible();
|
||||||
|
|
||||||
await page.getByPlaceholder("Description").fill("Manual payment");
|
const manualForm = page.locator("form").first();
|
||||||
await page.getByPlaceholder("0.00").fill("40.25");
|
await manualForm.getByText("Description").locator("..").getByRole("textbox").fill("Manual payment");
|
||||||
await page.getByRole("button", { name: "Save manual transaction" }).click();
|
await manualForm.getByPlaceholder("-42.50").fill("40.25");
|
||||||
|
await manualForm.getByRole("button", { name: "Save" }).click();
|
||||||
await expect(page.getByText("Manual transaction saved.")).toBeVisible();
|
await expect(page.getByText("Manual transaction saved.")).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Edit" }).click();
|
await page.getByRole("button", { name: "Edit" }).click();
|
||||||
await page.getByPlaceholder("Category").fill("Coffee");
|
await page.getByPlaceholder("Category").fill("Coffee");
|
||||||
await page.getByPlaceholder("Note").fill("Edited note");
|
await page.getByPlaceholder("Note").fill("Edited note");
|
||||||
listResponse = apiOk([
|
listResponse = apiOk({
|
||||||
|
transactions: [
|
||||||
{
|
{
|
||||||
id: "tx_1",
|
viewRef: "tx_1",
|
||||||
name: "Coffee Bar",
|
description: "Coffee Bar",
|
||||||
amount: "12.50",
|
amount: "12.50",
|
||||||
category: "Coffee",
|
category: "Coffee",
|
||||||
note: "Edited note",
|
note: "Edited note",
|
||||||
|
attribution: "mine",
|
||||||
|
split: { mode: "none", minePercent: 50, yoursPercent: 50, mineAmount: 0, yoursAmount: 0 },
|
||||||
status: "user",
|
status: "user",
|
||||||
hidden: false,
|
hidden: false,
|
||||||
date: "2025-01-10"
|
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();
|
await expect(page.getByText("Transaction updated.")).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user