import { test, expect } from '@playwright/test'; import { login } from './helpers/auth'; import { epic, feature, severity, description, tag } from './helpers/allure'; import { navigateToSettings } from './helpers/navigation'; test.describe('Settings Tests', () => { test.setTimeout(90000); test.beforeEach(async ({ page }) => { epic('Settings'); await login(page); await navigateToSettings(page); await page.waitForTimeout(2000); }); test('should display Discount Rate Configuration for the Discounts settings tab', async ({ page }) => { feature('Settings Operations'); tag('functional'); severity('normal'); description('Open the Discount rates settings tab and verify the configuration table renders correctly, whether rates are configured or not'); console.log('Testing Discount rates settings tab...'); await test.step('Open Discount rates tab', async () => { const discountRatesTab = page.getByText('Discount rates', { exact: true }).first(); await expect(discountRatesTab, 'Discount rates tab should be visible').toBeVisible({ timeout: 10000 }); await discountRatesTab.click(); await page.waitForTimeout(1500); console.log('✓ Opened Discount rates'); }); await test.step('Verify the Discount Rate Configuration table', async () => { const ratesTable = page.locator('xpath=//*[contains(text(),"Discount Rate Configuration")]/following::table[1]').first(); await expect(ratesTable, 'Discount Rate Configuration table should be visible').toBeVisible({ timeout: 10000 }); const headers = await ratesTable.locator('thead th').allTextContents(); console.log('Headers:', JSON.stringify(headers)); let cardIdx = -1, mdrIdx = -1, vatIdx = -1, capIdx = -1, feeIdx = -1; for (let i = 0; i < headers.length; i++) { const t = headers[i].trim().toLowerCase(); if (t === 'card') cardIdx = i; else if (t === 'mdr') mdrIdx = i; else if (t === 'vat') vatIdx = i; else if (t.includes('cap')) capIdx = i; else if (t.includes('processing') || t === 'fee') feeIdx = i; } expect(cardIdx, 'A Card column should exist').toBeGreaterThanOrEqual(0); expect(mdrIdx, 'An MDR column should exist').toBeGreaterThanOrEqual(0); // Real data rows only - excludes the hidden measure row (aria-hidden) // and an empty-state "No data" placeholder row (both previously got // miscounted by earlier code as bogus zero-value rate entries). const rows = ratesTable.locator('tbody tr:not([aria-hidden="true"])'); const rowCount = await rows.count(); console.log(`Row count (excluding hidden measure row): ${rowCount}`); const bodyText = await ratesTable.locator('tbody').innerText(); const isEmptyState = /no data/i.test(bodyText) && rowCount <= 1; if (isEmptyState) { console.log('✓ No discount rates configured - "No data" empty state correctly shown'); // Scope to a real text-bearing element - a plain `text=/no data/i` // locator also matches a hidden SVG icon label with the same // text, which is never actually visible. await expect(ratesTable.locator('article, span, div').filter({ hasText: /^No data$/i }).first(), 'Empty state should show "No data"').toBeVisible(); } else { console.log(`✓ Found ${rowCount} configured discount rate row(s), validating each`); expect(rowCount, 'There should be at least one configured rate row').toBeGreaterThan(0); // Read a numeric value the same safe way used for the Discounts page // breakdown table: the value sits in the last <article> in the cell, // separate from an embedded currency/percent icon's <style> content. const readCellNum = async (row: import('@playwright/test').Locator, idx: number): Promise<number> => { if (idx < 0) return 0; const cell = row.locator('td').nth(idx); const valArticle = cell.locator('article').last(); const txt = (await valArticle.textContent().catch(() => '')) || (await cell.textContent().catch(() => '')) || ''; const n = parseFloat(txt.replace(/[^0-9.\-]/g, '')); return isNaN(n) ? 0 : n; }; for (let r = 0; r < rowCount; r++) { const row = rows.nth(r); const cardText = (await row.locator('td').nth(cardIdx).innerText().catch(() => '')).trim(); const mdr = await readCellNum(row, mdrIdx); const vat = vatIdx >= 0 ? await readCellNum(row, vatIdx) : 0; const cap = capIdx >= 0 ? await readCellNum(row, capIdx) : 0; const fee = feeIdx >= 0 ? await readCellNum(row, feeIdx) : 0; console.log(` ${cardText}: MDR ${mdr}% | VAT ${vat}% | Cap ${cap} | Fee ${fee}%`); expect(cardText.length, `Row ${r + 1} should have a card scheme name`).toBeGreaterThan(0); expect(mdr, `Row ${r + 1} (${cardText}) MDR should be a plausible percentage`).toBeGreaterThanOrEqual(0); expect(mdr, `Row ${r + 1} (${cardText}) MDR should be a plausible percentage`).toBeLessThanOrEqual(100); } } }); console.log('✓ Discount rates settings test completed'); }); });