83 lines
3.1 KiB
JavaScript
83 lines
3.1 KiB
JavaScript
// tests/e2e/45b-financial-profile.spec.mjs
|
|
// @ts-nocheck
|
|
import { test, expect } from '@playwright/test';
|
|
import { loadTestUser } from '../utils/testUser.js';
|
|
|
|
const byName = (page, n) => page.locator(`input[name="${n}"]`).first();
|
|
// Label → first following input (works even without for/id)
|
|
const inputAfterLabel = (page, labelRe) =>
|
|
page.locator('label').filter({ hasText: labelRe }).first()
|
|
.locator('xpath=following::input[1]').first();
|
|
|
|
test.describe('@p1 Profile — Financial editor (45b)', () => {
|
|
test.setTimeout(45000);
|
|
|
|
test('Save financial profile (accept alert) → leaves page', async ({ page }) => {
|
|
const u = loadTestUser();
|
|
|
|
// Premium gate
|
|
await page.route(
|
|
/\/api\/user-profile\?fields=.*(firstname|is_premium|is_pro_premium).*/i,
|
|
r => r.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ firstname: 'Tester', is_premium: 1, is_pro_premium: 0 })
|
|
})
|
|
);
|
|
|
|
// Deterministic GET/POST for the form
|
|
await page.route('**/api/premium/financial-profile', async route => {
|
|
if (route.request().method() === 'GET') {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({
|
|
current_salary: 0,
|
|
additional_income: 0,
|
|
monthly_expenses: 0,
|
|
monthly_debt_payments: 0,
|
|
retirement_savings: 0,
|
|
emergency_fund: 0,
|
|
retirement_contribution: 0,
|
|
emergency_contribution: 0,
|
|
extra_cash_emergency_pct: 50,
|
|
extra_cash_retirement_pct: 50
|
|
})
|
|
});
|
|
} else if (route.request().method() === 'POST') {
|
|
await route.fulfill({ status: 200, body: '{}' });
|
|
} else {
|
|
await route.fallback();
|
|
}
|
|
});
|
|
|
|
// Sign in
|
|
await page.context().clearCookies();
|
|
await page.goto('/signin', { waitUntil: 'domcontentloaded' });
|
|
await page.getByPlaceholder('Username', { exact: true }).fill(u.username);
|
|
await page.getByPlaceholder('Password', { exact: true }).fill(u.password);
|
|
await page.getByRole('button', { name: /^Sign In$/ }).click();
|
|
await page.waitForURL('**/signin-landing**', { timeout: 15_000 });
|
|
|
|
// Go to form
|
|
await page.goto('/financial-profile', { waitUntil: 'domcontentloaded' });
|
|
await expect(page.getByRole('heading', { name: /Edit\s*Your\s*Financial\s*Profile/i }))
|
|
.toBeVisible({ timeout: 15_000 });
|
|
|
|
// Fill minimal fields
|
|
await byName(page, 'currentSalary').fill('55000');
|
|
|
|
// This field has NO name attribute → select by label then first input
|
|
await inputAfterLabel(page, /Monthly\s*Living\s*Expenses/i).fill('1800');
|
|
|
|
await byName(page, 'monthlyDebtPayments').fill('200');
|
|
await byName(page, 'extraCashEmergencyPct').fill('40'); // complements to 60
|
|
|
|
// Accept expected alert then leave page
|
|
page.once('dialog', d => d.accept().catch(() => {}));
|
|
await page.getByRole('button', { name: /^Save$/ }).click();
|
|
|
|
await expect(page).not.toHaveURL(/\/financial-profile$/i, { timeout: 20_000 });
|
|
});
|
|
});
|