// 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 }); }); });