improvements

This commit is contained in:
2026-05-26 11:18:52 -07:00
parent f239b114c3
commit ae0788e6dd
6 changed files with 299 additions and 147 deletions

View File

@@ -103,27 +103,19 @@ async function selectAccountFromTypeahead(page: any, rowIndex: number, accountNa
}
async function findAccountRow(page: any, rowIndex: number) {
const allRows = page.locator('#account-grid-body tbody tr');
const rowCount = await allRows.count();
const accountRows = page.locator('#account-grid-body tbody tr.account-row');
const rowCount = await accountRows.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) {
return row;
}
accountRowIndex++;
}
if (rowIndex >= rowCount) {
throw new Error(`Could not find account row at index ${rowIndex}. Only ${rowCount} account rows found.`);
}
throw new Error(`Could not find account row at index ${rowIndex}`);
return accountRows.nth(rowIndex);
}
async function setAccountAmount(page: any, rowIndex: number, amount: string) {
const row = await findAccountRow(page, rowIndex);
const amountInput = row.locator('input[name*="transaction-account/amount"]').first();
const amountInput = row.locator('.account-amount-field');
await amountInput.fill(amount);
await amountInput.dispatchEvent('change');
await page.waitForTimeout(300);
@@ -164,34 +156,24 @@ async function getAccountLocation(page: any, rowIndex: number): Promise<string>
}
async function removeAllAccounts(page: any) {
const allRows = page.locator('#account-grid-body tbody tr');
const rowCount = await allRows.count();
const accountRows = page.locator('#account-grid-body tbody tr.account-row');
const rowCount = await accountRows.count();
for (let i = rowCount - 1; i >= 0; i--) {
const row = allRows.nth(i);
const hasAccountInput = await row.locator('input[name*="transaction-account/account"]').count() > 0;
if (hasAccountInput) {
// Click the X button to remove (it's an <a> tag, not a <button>)
const removeButton = row.locator('a').first();
await removeButton.click();
// Wait for the Alpine.js removal animation (500ms + buffer)
await page.waitForTimeout(700);
}
const row = accountRows.nth(i);
const removeButton = row.locator('.account-remove-action');
await removeButton.click();
// Wait for the Alpine.js removal animation (500ms + buffer)
await page.waitForTimeout(700);
}
}
async function saveTransaction(page: any) {
// Submit the form directly instead of clicking the button
// The Done button might not have type="submit"
await page.evaluate(() => {
const form = document.querySelector('#wizard-form') as HTMLFormElement;
if (form) {
form.dispatchEvent(new Event('submit', { bubbles: true }));
}
});
// Click the save button to submit the form via HTMX
await page.locator('.wizard-save-action').click();
// Wait for the modal to close
await page.waitForSelector('#modal-holder[x-show="open"]', { state: 'hidden', timeout: 10000 });
// Wait for the modal to close (longer timeout for parallel test load)
await page.waitForSelector('#modal-holder[x-show="open"]', { state: 'hidden', timeout: 20000 });
}
async function toggleToPercentMode(page: any) {
@@ -226,6 +208,9 @@ test.describe('Transaction Edit Shared Location', () => {
// Step 1: Open edit modal and add an account with Shared location
await openEditModal(page, transactionIndex);
// Remove any existing accounts from previous tests
await removeAllAccounts(page);
// Add a new account row
await addNewAccount(page);
@@ -261,11 +246,17 @@ test.describe('Transaction Edit Full Workflow', () => {
// Step 1: Open edit modal and code with 100% to one account
await openEditModal(page);
// Switch to percentage mode
// Switch to percentage mode first (this re-renders the grid from server state)
await toggleToPercentMode(page);
// Add a new account row
await addNewAccount(page);
// Check if there's already an account from previous tests
const allRows = page.locator('#account-grid-body tbody tr');
const hasExistingAccount = await allRows.locator('input[name*="transaction-account/account"]').count() > 0;
if (!hasExistingAccount) {
// Add a new account row if none exist
await addNewAccount(page);
}
// Select the account
await selectAccountFromTypeahead(page, 0, 'Test');
@@ -289,6 +280,7 @@ test.describe('Transaction Edit Full Workflow', () => {
// Add a second account at 50%
await addNewAccount(page);
await page.waitForTimeout(1000);
await selectAccountFromTypeahead(page, 1, 'Second');
await setAccountAmount(page, 1, '50');
@@ -310,8 +302,8 @@ test.describe('Transaction Edit Full Workflow', () => {
const row0 = await findAccountRow(page, 0);
const row1 = await findAccountRow(page, 1);
const amount0 = row0.locator('input[name*="transaction-account/amount"]').first();
const amount1 = row1.locator('input[name*="transaction-account/amount"]').first();
const amount0 = row0.locator('.account-amount-field');
const amount1 = row1.locator('.account-amount-field');
// Each should be $50.00 (or close to it)
const val0 = await amount0.inputValue();
@@ -331,6 +323,9 @@ test.describe('Transaction Edit Validation', () => {
await openEditModal(page, 2);
// Stay in dollar mode (default)
// Remove any existing accounts from previous tests
await removeAllAccounts(page);
await page.waitForTimeout(2000);
// Add an account
await addNewAccount(page);
await selectAccountFromTypeahead(page, 0, 'Test');
@@ -338,17 +333,12 @@ test.describe('Transaction Edit Validation', () => {
// Set amount to $50 (which doesn't match the $300 transaction)
await setAccountAmount(page, 0, '50');
// Try to save - this should fail because $50 != $100
// We submit the form and expect the modal to stay open
await page.evaluate(() => {
const form = document.querySelector('#wizard-form') as HTMLFormElement;
if (form) {
form.dispatchEvent(new Event('submit', { bubbles: true }));
}
});
// Try to save - this should fail because $50 != $300
// Click the save button to submit the form via HTMX
await page.locator('.wizard-save-action').click();
// Wait a bit for the response
await page.waitForTimeout(1000);
// Wait for the response (longer timeout for parallel test load)
await page.waitForTimeout(3000);
// Modal should still be open (save failed)
await expect(page.locator('#modal-holder[x-show="open"]')).toBeVisible();
@@ -358,7 +348,7 @@ test.describe('Transaction Edit Validation', () => {
await expect(form).toBeVisible();
// Verify the account row is still there with our $50 value
const amountInput = page.locator('input[name*="transaction-account/amount"]').first();
const amountInput = page.locator('.account-amount-field').first();
const value = await amountInput.inputValue();
expect(parseFloat(value)).toBeCloseTo(50.0, 1);