import { test, expect } from '@playwright/test'; async function openEditModal(page: any) { await page.goto('/transaction2'); await page.waitForSelector('table tbody tr'); const editButton = page.locator('button[hx-get*="/transaction2/"][hx-get*="/edit"]').first(); await editButton.click(); await page.waitForSelector('#modal-holder[x-show="open"]', { state: 'visible' }); await page.waitForSelector('#wizardmodal'); await page.click('button:has-text("Transaction Actions")'); await page.waitForSelector('text=Transaction Actions', { state: 'visible' }); await page.click('button:has-text("Manual")'); await page.waitForSelector('#account-grid-body'); } async function addNewAccount(page: any) { await page.click('text=New account'); await page.waitForTimeout(500); } async function selectAccountFromTypeahead(page: any, rowIndex: number, accountName: string) { const allRows = page.locator('#account-grid-body tbody tr'); const rowCount = await allRows.count(); let accountRow = null; let accountRowIndex = 0; for (let i = 0; i < rowCount; i++) { const row = allRows.nth(i); const hasAccountInput = await row.locator('input[name*="transaction-account/account"]').count() > 0; if (hasAccountInput) { if (accountRowIndex === rowIndex) { accountRow = row; break; } accountRowIndex++; } } if (!accountRow) { throw new Error(`Could not find account row at index ${rowIndex}`); } const hiddenInput = accountRow.locator('input[type="hidden"][name*="transaction-account/account"]').first(); // Get account ID from test-info const testInfoResponse = await page.request.get('/test-info'); const testInfo = await testInfoResponse.json(); const accountKey = accountName === 'Test' ? 'test-account' : 'second-account'; const accountId = testInfo.accounts[accountKey]; await hiddenInput.evaluate((el: HTMLInputElement, value: string) => { el.value = value; const alpineEl = el.closest('[x-data]'); if (alpineEl && (alpineEl as any).__x) { (alpineEl as any).__x.$data.value.value = parseInt(value); (alpineEl as any).__x.$data.value.label = 'Selected Account'; } const rowEl = el.closest('tr[x-data]'); if (rowEl && (rowEl as any).__x) { (rowEl as any).__x.$data.accountId = parseInt(value); } el.dispatchEvent(new Event('change', { bubbles: true })); }, accountId.toString()); await page.waitForTimeout(300); } async function setAccountAmount(page: any, rowIndex: number, amount: string) { const allRows = page.locator('#account-grid-body tbody tr'); const rowCount = await allRows.count(); let accountRowIndex = 0; for (let i = 0; i < rowCount; i++) { const row = allRows.nth(i); const hasAccountInput = await row.locator('input[name*="transaction-account/account"]').count() > 0; if (hasAccountInput) { if (accountRowIndex === rowIndex) { const amountInput = row.locator('input[name*="transaction-account/amount"]').first(); await amountInput.fill(amount); await amountInput.dispatchEvent('change'); await page.waitForTimeout(300); return; } accountRowIndex++; } } throw new Error(`Could not find account row at index ${rowIndex}`); } test('debug save with percentage', async ({ page }) => { await openEditModal(page); // Switch to percentage mode await page.locator('input[name="step-params[amount-mode]"][value="%"]').click(); await page.waitForResponse(response => response.url().includes('/toggle-amount-mode') && response.status() === 200 ); await page.waitForTimeout(200); await addNewAccount(page); await selectAccountFromTypeahead(page, 0, 'Test'); await setAccountAmount(page, 0, '100'); // Intercept the form submission to see what happens let responseStatus = 0; let responseBody = ''; page.on('request', (request: any) => { if (request.url().includes('/edit-submit')) { console.log('Request URL:', request.url()); console.log('Request method:', request.method()); } }); page.on('response', async (response: any) => { if (response.url().includes('/edit-submit')) { responseStatus = response.status(); try { responseBody = await response.text(); } catch (e) { responseBody = 'Could not read body'; } console.log('Response status:', responseStatus); console.log('Response body:', responseBody.substring(0, 500)); } }); // Click Done await page.click('button:has-text("Done")'); // Wait a bit await page.waitForTimeout(2000); console.log('Final status:', responseStatus); console.log('Response body length:', responseBody.length); // Check for error messages in the response if (responseBody.includes('error') || responseBody.includes('Error') || responseBody.includes('has-error')) { console.log('Response contains errors!'); // Extract error messages const errorMatches = responseBody.match(/text-red-600[^>]*>([^<]+)/g); if (errorMatches) { errorMatches.forEach((match: string) => console.log('Error:', match)); } } // Check if modal is open const modalVisible = await page.locator('#modal-holder[x-show="open"]').isVisible(); console.log('Modal visible:', modalVisible); });