Skip to content

Commit d645e91

Browse files
committed
chore: Add budget E2E tests and update package locks
1 parent be4d318 commit d645e91

File tree

3 files changed

+181
-3
lines changed

3 files changed

+181
-3
lines changed

cmd/prism-gui/frontend/node_modules/.package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/prism-gui/frontend/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Budget Workflows', () => {
4+
test.beforeEach(async ({ page, context }) => {
5+
// Set localStorage BEFORE navigating to prevent onboarding modal
6+
await context.addInitScript(() => {
7+
localStorage.setItem('cws_onboarding_complete', 'true');
8+
});
9+
await page.goto('/');
10+
await page.waitForLoadState('domcontentloaded');
11+
});
12+
13+
test('should display budget overview', async ({ page }) => {
14+
// Navigate to budgets
15+
await page.click('text=Budgets');
16+
17+
// Verify budget overview page elements
18+
await expect(page.locator('text=Budget Overview')).toBeVisible();
19+
await expect(page.locator('text=Total Budgets')).toBeVisible();
20+
await expect(page.locator('text=Total Allocated')).toBeVisible();
21+
await expect(page.locator('text=Total Spent')).toBeVisible();
22+
await expect(page.locator('text=Active Alerts')).toBeVisible();
23+
24+
// Verify table is present
25+
await expect(page.locator('[data-testid="budgets-table"]')).toBeVisible();
26+
});
27+
28+
test('should create budget pool', async ({ page }) => {
29+
// Navigate to budgets
30+
await page.click('text=Budgets');
31+
32+
// Wait for page to load
33+
await page.waitForSelector('[data-testid="budgets-table"]');
34+
35+
// Open create budget modal (click the first button, which is in the header)
36+
await page.locator('button:has-text("Create Budget Pool")').first().click();
37+
38+
// Wait for modal to appear - use visible dialog selector
39+
const dialog = page.locator('[role="dialog"]:visible').first();
40+
await dialog.waitFor({ state: 'visible' });
41+
await page.waitForTimeout(500); // Allow modal animation to complete
42+
43+
// Fill in budget details using accessible labels - scope to dialog
44+
const budgetName = `Test Budget Pool ${Date.now()}`;
45+
await dialog.getByLabel('Budget Name').fill(budgetName);
46+
await dialog.getByLabel('Description').fill('Test budget for E2E');
47+
await dialog.getByLabel('Total Amount (USD)').fill('50000');
48+
await dialog.getByLabel('Alert Threshold (%)').fill('80');
49+
50+
// Submit form - scope to dialog
51+
await dialog.getByRole('button', { name: /create budget/i }).click();
52+
53+
// Verify success notification
54+
await expect(page.locator('text=Budget Created')).toBeVisible({ timeout: 10000 });
55+
await expect(page.locator(`text=Budget pool "${budgetName}" created successfully`)).toBeVisible();
56+
});
57+
58+
test('should filter budgets by status', async ({ page }) => {
59+
// Navigate to budgets
60+
await page.click('text=Budgets');
61+
62+
// Verify filter dropdown is visible
63+
const filterSelect = page.locator('[data-testid="budget-filter-select"]');
64+
await expect(filterSelect).toBeVisible();
65+
66+
// Test filtering to Warning
67+
await filterSelect.click();
68+
await page.click('text=Warning (80-95%)');
69+
await expect(page.locator('[data-testid="budgets-table"]')).toBeVisible();
70+
71+
// Test filtering to Critical
72+
await filterSelect.click();
73+
await page.click('text=Critical (≥95%)');
74+
await expect(page.locator('[data-testid="budgets-table"]')).toBeVisible();
75+
76+
// Test filtering back to All
77+
await filterSelect.click();
78+
await page.click('text=All Budgets');
79+
await expect(page.locator('[data-testid="budgets-table"]')).toBeVisible();
80+
});
81+
82+
test('should display budget actions dropdown', async ({ page }) => {
83+
// Navigate to budgets
84+
await page.click('text=Budgets');
85+
86+
// Wait for table to load
87+
await page.waitForSelector('[data-testid="budgets-table"]');
88+
89+
// Look for any budget actions dropdown
90+
const actionsDropdown = page.locator('[data-testid^="budget-actions-"]').first();
91+
92+
// Only test if budgets exist
93+
const count = await actionsDropdown.count();
94+
if (count > 0) {
95+
await actionsDropdown.click();
96+
97+
// Verify action menu items
98+
await expect(page.locator('text=View Summary')).toBeVisible();
99+
await expect(page.locator('text=Manage Allocations')).toBeVisible();
100+
await expect(page.locator('text=Spending Report')).toBeVisible();
101+
await expect(page.locator('text=Edit Budget')).toBeVisible();
102+
await expect(page.locator('text=Delete').last()).toBeVisible();
103+
}
104+
});
105+
106+
test('should show validation error for empty budget name', async ({ page }) => {
107+
// Navigate to budgets
108+
await page.click('text=Budgets');
109+
await page.waitForSelector('[data-testid="budgets-table"]');
110+
111+
// Open create budget modal (click the first button, which is in the header)
112+
await page.locator('button:has-text("Create Budget Pool")').first().click();
113+
const dialog = page.locator('[role="dialog"]:visible').first();
114+
await dialog.waitFor({ state: 'visible' });
115+
await page.waitForTimeout(500); // Allow modal animation to complete
116+
117+
// Try to submit without filling name - scope to dialog
118+
await dialog.getByLabel('Total Amount (USD)').fill('50000');
119+
await dialog.getByRole('button', { name: /create budget/i }).click();
120+
121+
// Verify validation error
122+
await expect(page.locator('text=Budget name is required')).toBeVisible();
123+
});
124+
125+
test('should show validation error for invalid amount', async ({ page }) => {
126+
// Navigate to budgets
127+
await page.click('text=Budgets');
128+
await page.waitForSelector('[data-testid="budgets-table"]');
129+
130+
// Open create budget modal (click the first button, which is in the header)
131+
await page.locator('button:has-text("Create Budget Pool")').first().click();
132+
const dialog = page.locator('[role="dialog"]:visible').first();
133+
await dialog.waitFor({ state: 'visible' });
134+
await page.waitForTimeout(500); // Allow modal animation to complete
135+
136+
// Fill name but invalid amount - scope to dialog
137+
await dialog.getByLabel('Budget Name').fill('Test Budget');
138+
await dialog.getByLabel('Total Amount (USD)').fill('0');
139+
await dialog.getByRole('button', { name: /create budget/i }).click();
140+
141+
// Verify validation error
142+
await expect(page.locator('text=Total amount must be greater than 0')).toBeVisible();
143+
});
144+
145+
test('should cancel budget creation', async ({ page }) => {
146+
// Navigate to budgets
147+
await page.click('text=Budgets');
148+
await page.waitForSelector('[data-testid="budgets-table"]');
149+
150+
// Open create budget modal (click the first button, which is in the header)
151+
await page.locator('button:has-text("Create Budget Pool")').first().click();
152+
const dialog = page.locator('[role="dialog"]:visible').first();
153+
await dialog.waitFor({ state: 'visible' });
154+
await page.waitForTimeout(500); // Allow modal animation to complete
155+
156+
// Fill some data - scope to dialog
157+
await dialog.getByLabel('Budget Name').fill('Test Budget to Cancel');
158+
159+
// Click cancel
160+
await dialog.getByRole('button', { name: /cancel/i }).click();
161+
162+
// Verify modal is closed
163+
await page.waitForTimeout(500);
164+
const visibleDialogs = await page.locator('[role="dialog"]:visible').count();
165+
expect(visibleDialogs).toBe(0);
166+
});
167+
168+
test('should refresh budgets data', async ({ page }) => {
169+
// Navigate to budgets
170+
await page.click('text=Budgets');
171+
172+
// Click refresh button
173+
await page.click('button:has-text("Refresh")');
174+
175+
// Verify table is still visible after refresh
176+
await expect(page.locator('[data-testid="budgets-table"]')).toBeVisible();
177+
});
178+
});

0 commit comments

Comments
 (0)