From afcd2f67c974ab7aa4019aab7aa888cb7dc277fb Mon Sep 17 00:00:00 2001 From: JaySoni1 Date: Sun, 5 Apr 2026 05:32:20 +0530 Subject: [PATCH 1/9] WEB-901 Page title for Fixed Deposits shows raw translation key instead of text --- src/assets/translations/cs-CS.json | 1 + src/assets/translations/de-DE.json | 1 + src/assets/translations/en-US.json | 1 + src/assets/translations/es-CL.json | 1 + src/assets/translations/es-MX.json | 1 + src/assets/translations/fr-FR.json | 1 + src/assets/translations/it-IT.json | 1 + src/assets/translations/ko-KO.json | 1 + src/assets/translations/lt-LT.json | 1 + src/assets/translations/lv-LV.json | 1 + src/assets/translations/ne-NE.json | 1 + src/assets/translations/pt-PT.json | 1 + src/assets/translations/sw-SW.json | 1 + 13 files changed, 13 insertions(+) diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index 57c47c5f9e..416c7fa6d7 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3347,6 +3347,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabulka úrokových sazeb na účtu s pevným vkladem", "Fixed Deposit Account Standing Instructions": "Pokyny k trvalému vkladovému účtu", "Fixed Deposit Account Transactions": "Transakce na pevném vkladovém účtu", + "Fixed Deposit Account Details": "Detaily účtu terminovaného vkladu", "Fixed Deposit Account View": "Pohled na účet s pevným vkladem", "Fixed Deposit Products": "Produkty s pevným vkladem", "Fixed Deposit Products defines the rules, default settings": "Produkty s pevným vkladem definují pravidla, výchozí nastavení a omezení pro nabídky finančních
pevných vkladů (také označované jako termínované vklady). Produkt s pevným vkladem poskytuje pro klienty finanční instituce šablonu pro více účtů s pevným vkladem.", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index 3480977de6..c2c86a676c 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3348,6 +3348,7 @@ "Fineract": "Apache Fineract®", "Fixed Deposit Account Standing Instructions": "Anweisungen zum Festgeldkonto", "Fixed Deposit Account Transactions": "Transaktionen mit Festgeldkonten", + "Fixed Deposit Account Details": "Festgeldkonto-Details", "Fixed Deposit Account View": "Ansicht Festgeldkonto", "Fixed Deposit Products": "Festgeldprodukte", "Fixed Deposit Products defines the rules, default settings": "Festgeldprodukte definiert die Regeln, Standardeinstellungen und Einschränkungen für die Festgeldangebote eines Finanzinstituts (auch als Termineinlagen bezeichnet). Ein Festgeldprodukt bietet eine Vorlage für mehrere Festgeldkonten für die Kunden des Finanzinstituts.", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index ada00c97bb..b5ef46cb5f 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3382,6 +3382,7 @@ "FilterByLoanIdOrError": "Filter by loan Id or error", "Fineract": "Apache Fineract®", "Fixed Deposit Account Charges": "Fixed Deposit Account Charges", + "Fixed Deposit Account Details": "Fixed Deposit Account Details", "Fixed Deposit Account Interest Rate Chart": "Fixed Deposit Account Interest Rate Chart", "Fixed Deposit Account Standing Instructions": "Fixed Deposit Account Standing Instructions", "Fixed Deposit Account Transactions": "Fixed Deposit Account Transactions", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index 1358687fd6..ea6dd234f6 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3348,6 +3348,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Fijo", "Fixed Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Fijo", "Fixed Deposit Account Transactions": "Transacciones de cuenta de Depósito Fijo", + "Fixed Deposit Account Details": "Detalles de cuenta de depósito a plazo", "Fixed Deposit Account View": "Vista de cuenta de Depósito Fijo", "Fixed Deposit Products": "Productos de Depósito Fijo", "Fixed Deposit Products defines the rules, default settings": "Los productos de Depósito Fijo definen las reglas, la configuración predeterminada y las restricciones para las ofertas de Depósito Fijo de una institución financiera (también conocidos como depósitos a plazo). Un producto de Depósito Fijo proporciona una plantilla para múltiples cuentas de Depósito Fijo para los clientes de la institución financiera.", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 6bac81bca0..1089d7f950 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3381,6 +3381,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Fijo", "Fixed Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Fijo", "Fixed Deposit Account Transactions": "Transacciones de cuenta de Depósito Fijo", + "Fixed Deposit Account Details": "Detalles de cuenta de depósito a plazo", "Fixed Deposit Account View": "Vista de cuenta de Depósito Fijo", "Fixed Deposit Products": "Productos de Depósito Fijo", "Fixed Deposit Products defines the rules, default settings": "Los productos de Depósito Fijo definen las reglas, la configuración predeterminada y las restricciones para las ofertas de Depósito Fijo de una institución financiera (también conocidos como depósitos a plazo). Un producto de Depósito Fijo proporciona una plantilla para múltiples cuentas de Depósito Fijo para los clientes de la institución financiera.", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index 3ae1be0819..5f2e412f0b 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3350,6 +3350,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tableau des taux d’intérêt des comptes de dépôt fixe", "Fixed Deposit Account Standing Instructions": "Instructions permanentes pour les comptes de dépôt à terme", "Fixed Deposit Account Transactions": "Opérations sur compte de dépôt fixe", + "Fixed Deposit Account Details": "Détails du compte de dépôt à terme", "Fixed Deposit Account View": "Vue du compte de dépôt fixe", "Fixed Deposit Products": "Produits de dépôt fixe", "Fixed Deposit Products defines the rules, default settings": "Les produits de dépôt fixe définissent les règles, les paramètres par défaut et les contraintes pour les offres de dépôt fixe d'une institution financière (également appelées dépôts à terme). Un produit de dépôt à terme fournit un modèle pour plusieurs comptes de dépôt à terme pour les clients de l'institution financière.", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index e452fde1b9..da5816c9ec 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3345,6 +3345,7 @@ "Fixed Deposit Account Interest Rate Chart": "Grafico dei tassi di interesse del conto di deposito fisso", "Fixed Deposit Account Standing Instructions": "Istruzioni per la permanenza del Conto di Deposito Fisso", "Fixed Deposit Account Transactions": "Operazioni di Conto Deposito Fisso", + "Fixed Deposit Account Details": "Dettagli conto deposito vincolato", "Fixed Deposit Account View": "Visualizzazione del conto di deposito fisso", "Fixed Deposit Products": "Prodotti a deposito fisso", "Fixed Deposit Products defines the rules, default settings": "Prodotti a deposito fisso definisce le regole, le impostazioni predefinite e i vincoli per le offerte di deposito fisso di un istituto finanziario (noti anche come depositi a termine). Un prodotto di deposito fisso fornisce un modello per più conti di deposito fisso per i clienti dell'istituto finanziario.", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index 29e7628d68..983eb37ab9 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "정기예금 이자율 차트", "Fixed Deposit Account Standing Instructions": "정기예금 계좌 예금 안내", "Fixed Deposit Account Transactions": "정기예금 거래", + "Fixed Deposit Account Details": "정기 예금 계좌 세부 정보", "Fixed Deposit Account View": "정기예금계좌조회", "Fixed Deposit Products": "정기예금 상품", "Fixed Deposit Products defines the rules, default settings": "정기 예금 상품은 금융 기관의
정기 예금 상품(정기 예금이라고도 함)에 대한 규칙, 기본 설정 및 제약 조건을 정의합니다. 정기 예금 상품은 금융 기관의 고객을 위해 여러 정기 예금 계좌에 대한 템플릿을 제공합니다.", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index fd9461aedf..ec949a4cc0 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3347,6 +3347,7 @@ "Fixed Deposit Account Interest Rate Chart": "Fiksuoto indėlio sąskaitos palūkanų normos diagrama", "Fixed Deposit Account Standing Instructions": "Fiksuoto indėlio sąskaitos nuolatinės instrukcijos", "Fixed Deposit Account Transactions": "Fiksuoto indėlio sąskaitos operacijos", + "Fixed Deposit Account Details": "Terminuotojo indėlio sąskaitos rekvizitai", "Fixed Deposit Account View": "Fiksuoto indėlio sąskaitos vaizdas", "Fixed Deposit Products": "Fiksuoto indėlio produktai", "Fixed Deposit Products defines the rules, default settings": "Terminuotųjų indėlių produktai apibrėžia finansų įstaigos
terminuotųjų indėlių pasiūlymų (taip pat vadinamų terminuotais indėliais) taisykles, numatytuosius nustatymus ir apribojimus. Terminuoto indėlio produktas suteikia šabloną kelioms terminuoto indėlio sąskaitoms finansų įstaigos klientams.", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 15b253d3f3..2c240dd7ee 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "Fiksētā depozīta konta procentu likmju diagramma", "Fixed Deposit Account Standing Instructions": "Fiksētā depozīta konta pastāvēšanas instrukcijas", "Fixed Deposit Account Transactions": "Fiksētā depozīta konta darījumi", + "Fixed Deposit Account Details": "Termiņnoguldījuma konta informācija", "Fixed Deposit Account View": "Fiksētā depozīta konta skats", "Fixed Deposit Products": "Fiksētā depozīta produkti", "Fixed Deposit Products defines the rules, default settings": "Fiksēto depozītu produkti definē noteikumus, noklusējuma iestatījumus un ierobežojumus finanšu iestādes
fiksēto noguldījumu piedāvājumiem (saukti arī par termiņnoguldījumiem). Fiksētā depozīta produkts nodrošina veidni vairākiem fiksēto depozītu kontiem finanšu iestādes klientiem.", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index e5c737704f..81d8332330 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3344,6 +3344,7 @@ "Fixed Deposit Account Interest Rate Chart": "फिक्स्ड डिपोजिट खाता ब्याज दर चार्ट", "Fixed Deposit Account Standing Instructions": "फिक्स्ड डिपोजिट खाता स्थायी निर्देशनहरू", "Fixed Deposit Account Transactions": "फिक्स्ड डिपोजिट खाता लेनदेन", + "Fixed Deposit Account Details": "मुद्दती निक्षेप खाता विवरण", "Fixed Deposit Account View": "फिक्स्ड डिपोजिट खाता दृश्य", "Fixed Deposit Products": "फिक्स्ड डिपोजिट उत्पादनहरू", "Fixed Deposit Products defines the rules, default settings": "फिक्स्ड डिपोजिट उत्पादनहरूले नियमहरू, पूर्वनिर्धारित सेटिङहरू, र वित्तीय संस्थाको
फिक्स्ड डिपोजिट प्रस्तावहरू (समय निक्षेपहरू पनि भनिन्छ) को लागि बाधाहरू परिभाषित गर्दछ। एक फिक्स्ड डिपोजिट उत्पादनले वित्तीय संस्थाका ग्राहकहरूको लागि बहु मुद्दती निक्षेप खाताहरूको लागि टेम्प्लेट प्रदान गर्दछ।", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index 8fa2fcbfd7..3d08cc58b6 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "Gráfico de taxas de juros de contas de depósito fixo", "Fixed Deposit Account Standing Instructions": "Instruções permanentes da conta de depósito fixo", "Fixed Deposit Account Transactions": "Transações de conta de depósito fixo", + "Fixed Deposit Account Details": "Detalhes da conta de depósito a prazo", "Fixed Deposit Account View": "Visualização de conta de depósito fixo", "Fixed Deposit Products": "Produtos de Depósito Fixo", "Fixed Deposit Products defines the rules, default settings": "Produtos de Depósito Fixo definem as regras, configurações padrão e restrições para as ofertas de depósito fixo de uma instituição financeira (também chamados de depósitos a prazo). Um produto de depósito fixo fornece um modelo para múltiplas contas de depósito fixo para os clientes da instituição financeira.", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index ee0e47ce6d..41cf393975 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3342,6 +3342,7 @@ "Fixed Deposit Account Interest Rate Chart": "Chati ya Kiwango cha Riba cha Akaunti ya Amana isiyobadilika", "Fixed Deposit Account Standing Instructions": "Maelekezo ya Kudumu ya Akaunti ya Amana", "Fixed Deposit Account Transactions": "Miamala ya Akaunti ya Amana isiyobadilika", + "Fixed Deposit Account Details": "Maelezo ya Akaunti ya Amana ya Kudumu", "Fixed Deposit Account View": "Mtazamo wa Akaunti ya Amana isiyobadilika", "Fixed Deposit Products": "Bidhaa za Amana zisizohamishika", "Fixed Deposit Products defines the rules, default settings": "Bidhaa za Amana Isiyobadilika hufafanua sheria, mipangilio chaguo-msingi na vikwazo kwa
matoleo ya amana isiyobadilika ya taasisi ya fedha (pia hujulikana kama amana za muda). Bidhaa ya amana isiyobadilika hutoa kiolezo cha akaunti nyingi za amana zisizobadilika kwa wateja wa taasisi ya fedha.", From c48a3de9eff34f9a541b78b3c2efddfa4c53793c Mon Sep 17 00:00:00 2001 From: Shubham Kumar Date: Mon, 6 Apr 2026 21:34:56 +0530 Subject: [PATCH 2/9] WEB-905 fix: replace className with class in Angular template (#3473) --- .../clients/clients-view/general-tab/general-tab.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/clients/clients-view/general-tab/general-tab.component.html b/src/app/clients/clients-view/general-tab/general-tab.component.html index 17def703bb..dc79a22d26 100644 --- a/src/app/clients/clients-view/general-tab/general-tab.component.html +++ b/src/app/clients/clients-view/general-tab/general-tab.component.html @@ -35,7 +35,7 @@

{{ 'labels.heading.Performance History' | translate }}

-
+

{{ 'labels.heading.Upcoming Charges' | translate }}

From b5cff5192b22d508979bf64a343d123dc865da91 Mon Sep 17 00:00:00 2001 From: Soni Jay Date: Mon, 6 Apr 2026 21:49:52 +0530 Subject: [PATCH 3/9] WEB-904 Missing localization key for Share Account Details page title (#3472) --- src/app/shares/shares-routing.module.ts | 2 +- src/assets/translations/cs-CS.json | 1 + src/assets/translations/de-DE.json | 1 + src/assets/translations/en-US.json | 1 + src/assets/translations/es-CL.json | 1 + src/assets/translations/es-MX.json | 1 + src/assets/translations/fr-FR.json | 1 + src/assets/translations/it-IT.json | 1 + src/assets/translations/ko-KO.json | 1 + src/assets/translations/lt-LT.json | 1 + src/assets/translations/lv-LV.json | 1 + src/assets/translations/ne-NE.json | 1 + src/assets/translations/pt-PT.json | 1 + src/assets/translations/sw-SW.json | 1 + 14 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app/shares/shares-routing.module.ts b/src/app/shares/shares-routing.module.ts index 4a9fc4072f..27826566ac 100644 --- a/src/app/shares/shares-routing.module.ts +++ b/src/app/shares/shares-routing.module.ts @@ -59,7 +59,7 @@ const routes: Routes = [ { path: 'general', component: GeneralTabComponent, - data: { title: 'Shares Account General', breadcrumb: 'General', routeParamBreadcrumb: false }, + data: { title: 'Shares Account Details', breadcrumb: 'General', routeParamBreadcrumb: false }, resolve: { sharesAccountData: SharesAccountViewResolver } diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index 416c7fa6d7..ef6fc8c3c6 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3592,6 +3592,7 @@ "Share Products Dividends": "Sdílejte produkty Dividendy", "Share products define the rules, default settings": "Sdílené produkty definují pravidla, výchozí nastavení a omezení pro akcie a dividendy finanční instituce. Sdílený produkt poskytuje šablonu pro více účtů, které jsou nebo budou drženy klienty finanční instituce.", "Shares": "akcie", + "Shares Account Details": "Detaily účtu akcií", "Shares Account Actions": "Akce na účtu akcií", "Shares Account Charges": "Poplatky na účtu akcií", "Shares Account Dividends": "Akcie Účet Dividendy", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index c2c86a676c..e3197f12e1 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3593,6 +3593,7 @@ "Share Products Dividends": "Dividenden für Aktienprodukte", "Share products define the rules, default settings": "Aktienprodukte definieren die Regeln, Standardeinstellungen und Einschränkungen für die Aktien und Dividenden eines Finanzinstituts. Ein Aktienprodukt bietet eine Vorlage für mehrere Konten, die von den Kunden des Finanzinstituts geführt werden oder werden.", "Shares": "Anteile", + "Shares Account Details": "Details zum Aktienkonto", "Shares Account Actions": "Gibt Kontoaktionen frei", "Shares Account Charges": "Gebühren für das Aktienkonto", "Shares Account Dividends": "Dividenden auf dem Aktienkonto", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index b5ef46cb5f..e4d8649960 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3727,6 +3727,7 @@ "Share Products Dividends": "Share Products Dividends", "Share products define the rules, default settings": "Share products define the rules, default settings, and constraints for a financial institution's Shares and dividends. A share product provides a template for multiple accounts that are or will be held by the financial institution's clients.", "Shares": "Shares", + "Shares Account Details": "Shares Account Details", "Shares Account Actions": "Shares Account Actions", "Shares Account Charges": "Shares Account Charges", "Shares Account Dividends": "Shares Account Dividends", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index ea6dd234f6..dedfb8a717 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3594,6 +3594,7 @@ "Share Products Dividends": "Dividendos de Productos de Acciones", "Share products define the rules, default settings": "Los productos de acciones definen las reglas, la configuración predeterminada y las restricciones para las acciones y los dividendos de una institución financiera. Un producto de acciones proporciona una plantilla para múltiples cuentas que son o serán propiedad de los clientes de la institución financiera.", "Shares": "Acciones", + "Shares Account Details": "Detalles de la cuenta de acciones", "Shares Account Actions": "Acciones de la cuenta de acciones", "Shares Account Charges": "Comisiones de la cuenta de acciones", "Shares Account Dividends": "Dividendos de cuentas de acciones", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 1089d7f950..84989b34d5 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3627,6 +3627,7 @@ "Share Products Dividends": "Dividendos de Productos de Acciones", "Share products define the rules, default settings": "Los productos de acciones definen las reglas, la configuración predeterminada y las restricciones para las acciones y los dividendos de una institución financiera. Un producto de acciones proporciona una plantilla para múltiples cuentas que son o serán propiedad de los clientes de la institución financiera.", "Shares": "Acciones", + "Shares Account Details": "Detalles de la cuenta de acciones", "Shares Account Actions": "Acciones de la cuenta de acciones", "Shares Account Charges": "Comisiones de la cuenta de acciones", "Shares Account Dividends": "Dividendos de cuentas de acciones", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index 5f2e412f0b..8f1200198e 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3595,6 +3595,7 @@ "Share Products Dividends": "Partager les dividendes des produits", "Share products define the rules, default settings": "Les produits d'actions définissent les règles, les paramètres par défaut et les contraintes applicables aux actions et aux dividendes d'une institution financière. Un produit d'actions fournit un modèle pour plusieurs comptes qui sont ou seront détenus par les clients de l'institution financière.", "Shares": "Actions", + "Shares Account Details": "Détails du compte d'actions", "Shares Account Actions": "Actions sur le compte de partage", "Shares Account Charges": "Frais de compte d’actions", "Shares Account Dividends": "Dividendes du compte d'actions", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index da5816c9ec..db72422436 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3591,6 +3591,7 @@ "Share Products Dividends": "Condividi i dividendi dei prodotti", "Share products define the rules, default settings": "I prodotti azionari definiscono le regole, le impostazioni predefinite e i vincoli per le azioni e i dividendi di un istituto finanziario. Un prodotto azionario fornisce un modello per più conti che sono o saranno detenuti dai clienti dell'istituto finanziario.", "Shares": "Azioni", + "Shares Account Details": "Dettagli del conto azioni", "Shares Account Actions": "Condivide le azioni dell'account", "Shares Account Charges": "Condivide le spese del conto", "Shares Account Dividends": "Dividendi del conto azionario", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index 983eb37ab9..c43d930b75 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3592,6 +3592,7 @@ "Share Products Dividends": "제품 배당금 공유", "Share products define the rules, default settings": "주식 상품은 금융 기관의 주식 및 배당금에 대한 규칙, 기본 설정 및 제약 조건을 정의합니다. 공유 상품은 금융 기관의 고객이 보유하고 있거나 보유하게 될 여러 계좌에 대한 템플릿을 제공합니다.", "Shares": "주식", + "Shares Account Details": "주식 계좌 세부 정보", "Shares Account Actions": "공유 계정 작업", "Shares Account Charges": "주식 계정 비용", "Shares Account Dividends": "주식 계좌 배당금", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index ec949a4cc0..1eeb96fe25 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3593,6 +3593,7 @@ "Share Products Dividends": "Dalintis produktais dividendais", "Share products define the rules, default settings": "Bendrinimo produktai apibrėžia taisykles, numatytuosius nustatymus ir apribojimus finansų įstaigos akcijoms ir dividendams. Dalijimosi produktas suteikia šabloną kelioms paskyroms, kurias turi arba turės finansų įstaigos klientai.", "Shares": "Akcijos", + "Shares Account Details": "Akcijų sąskaitos informacija", "Shares Account Actions": "Bendrina paskyros veiksmus", "Shares Account Charges": "Dalijasi sąskaitos mokesčiais", "Shares Account Dividends": "Dalina sąskaitos dividendus", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 2c240dd7ee..6312eb8a5f 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3592,6 +3592,7 @@ "Share Products Dividends": "Dalieties Produkti Dividendes", "Share products define the rules, default settings": "Kopīgošanas produkti nosaka noteikumus, noklusējuma iestatījumus un ierobežojumus finanšu iestādes akcijām un dividendēm. Dalīšanas produkts nodrošina veidni vairākiem kontiem, kas pieder vai būs finanšu iestādes klientiem.", "Shares": "Akcijas", + "Shares Account Details": "Akciju konta informācija", "Shares Account Actions": "Kopīgošanas konta darbības", "Shares Account Charges": "Akciju konta izmaksas", "Shares Account Dividends": "Akciju konta dividendes", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index 81d8332330..9e14a70a8c 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3590,6 +3590,7 @@ "Share Products Dividends": "शेयर उत्पादन लाभांश", "Share products define the rules, default settings": "शेयर उत्पादनहरूले वित्तीय संस्थाको शेयर र लाभांशका लागि नियमहरू, पूर्वनिर्धारित सेटिङहरू, र अवरोधहरू परिभाषित गर्दछ। एक सेयर उत्पादनले वित्तीय संस्थाका ग्राहकहरूद्वारा आयोजित वा राख्ने बहु खाताहरूको लागि टेम्प्लेट प्रदान गर्दछ।", "Shares": "सेयरहरू", + "Shares Account Details": "सेयर खाता विवरण", "Shares Account Actions": "साझेदारी खाता कार्यहरू", "Shares Account Charges": "शेयर खाता शुल्कहरू", "Shares Account Dividends": "शेयर खाता लाभांश", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index 3d08cc58b6..7e9b0d2762 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3592,6 +3592,7 @@ "Share Products Dividends": "Compartilhe dividendos de produtos", "Share products define the rules, default settings": "Os produtos de ações definem as regras, configurações padrão e restrições para as ações e dividendos de uma instituição financeira. Um produto de ações fornece um modelo para várias contas que são ou serão mantidas pelos clientes da instituição financeira.", "Shares": "Ações", + "Shares Account Details": "Detalhes da conta de ações", "Shares Account Actions": "Compartilha ações da conta", "Shares Account Charges": "Encargos da conta de ações", "Shares Account Dividends": "Dividendos da conta de ações", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index 41cf393975..0eefd2ec3a 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3588,6 +3588,7 @@ "Share Products Dividends": "Shiriki Gawio la Bidhaa", "Share products define the rules, default settings": "Bidhaa zinazoshirikiwa hufafanua sheria, mipangilio chaguo-msingi na vikwazo vya Hisa na gawio la taasisi ya fedha. Bidhaa inayoshirikiwa hutoa kiolezo cha akaunti nyingi ambazo zinashikiliwa au zitashikiliwa na wateja wa taasisi ya fedha.", "Shares": "Hisa", + "Shares Account Details": "Maelezo ya Akaunti ya Hisa", "Shares Account Actions": "Vitendo vya Akaunti ya Hisa", "Shares Account Charges": "Inashiriki Malipo ya Akaunti", "Shares Account Dividends": "Gawio la Akaunti ya Hisa", From d6305a97139db9b116a17d5b23796cff6309155b Mon Sep 17 00:00:00 2001 From: Soni Jay Date: Mon, 6 Apr 2026 21:56:05 +0530 Subject: [PATCH 4/9] WEB-903 Page title for Recurring Deposit Account shows raw translation key instead of text (#3471) --- src/assets/translations/cs-CS.json | 1 + src/assets/translations/de-DE.json | 1 + src/assets/translations/en-US.json | 1 + src/assets/translations/es-CL.json | 1 + src/assets/translations/es-MX.json | 1 + src/assets/translations/fr-FR.json | 1 + src/assets/translations/it-IT.json | 1 + src/assets/translations/ko-KO.json | 1 + src/assets/translations/lt-LT.json | 1 + src/assets/translations/lv-LV.json | 1 + src/assets/translations/ne-NE.json | 1 + src/assets/translations/pt-PT.json | 1 + src/assets/translations/sw-SW.json | 1 + 13 files changed, 13 insertions(+) diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index ef6fc8c3c6..66e3a4d947 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3527,6 +3527,7 @@ "Provisioning criteria definitions": "Vyplňte všechny definice kritérií poskytování.", "Precedes of": "Předchází", "Recurring Deposit Account Charges": "Opakované poplatky za vkladový účet", + "Recurring Deposit Account Details": "Detaily účtu opakovaného vkladu", "Recurring Deposit Account Interest Rate Chart": "Graf úrokových sazeb pro opakující se vkladový účet", "Recurring Deposit Account Standing Instructions": "Pokyny k trvalému vkladovému účtu", "Recurring Deposit Account Transactions": "Opakující se transakce na vkladovém účtu", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index e3197f12e1..1d7f0d4f8f 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3528,6 +3528,7 @@ "Provisioning criteria definitions": "Bitte füllen Sie alle Definitionen der Bereitstellungskriterien aus.", "Precedes of": "Präzedenzfälle von", "Recurring Deposit Account Charges": "Wiederkehrende Kontogebühren", + "Recurring Deposit Account Details": "Details zum wiederkehrenden Einzahlungskonto", "Recurring Deposit Account Interest Rate Chart": "Zinssatztabelle für wiederkehrende Einlagenkonten", "Recurring Deposit Account Standing Instructions": "Anweisungen zum Kontostand für wiederkehrende Einlagen", "Recurring Deposit Account Transactions": "Wiederkehrende Transaktionen auf dem Einlagenkonto", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index e4d8649960..a50615a16d 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3649,6 +3649,7 @@ "Precedes of": "Precedes of", "RecurringDepositAccountCreateBusinessEvent": "Recurring Deposit Account Create Business Event", "Recurring Deposit Account Charges": "Recurring Deposit Account Charges", + "Recurring Deposit Account Details": "Recurring Deposit Account Details", "Recurring Deposit Account Interest Rate Chart": "Recurring Deposit Account Interest Rate Chart", "Recurring Deposit Account Standing Instructions": "Recurring Deposit Account Standing Instructions", "Recurring Deposit Account Transactions": "Recurring Deposit Account Transactions", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index dedfb8a717..cbe57757d7 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3529,6 +3529,7 @@ "Provisioning criteria definitions": "Complete todas las definiciones de criterios de aprovisionamiento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Comisiones recurrentes de la cuenta de depósito", + "Recurring Deposit Account Details": "Detalles de la cuenta de depósito recurrente", "Recurring Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Recurrentes", "Recurring Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Recurrente", "Recurring Deposit Account Transactions": "Transacciones recurrentes en cuentas de depósito", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 84989b34d5..ed7ac84882 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3562,6 +3562,7 @@ "Provisioning criteria definitions": "Complete todas las definiciones de criterios de aprovisionamiento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Comisiones recurrentes de la cuenta de depósito", + "Recurring Deposit Account Details": "Detalles de la cuenta de depósito recurrente", "Recurring Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Recurrentes", "Recurring Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Recurrente", "Recurring Deposit Account Transactions": "Transacciones recurrentes en cuentas de depósito", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index 8f1200198e..ad8fd5967d 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3530,6 +3530,7 @@ "Provisioning criteria definitions": "Veuillez remplir toutes les définitions des critères de provisionnement.", "Precedes of": "Précède de", "Recurring Deposit Account Charges": "Frais de compte de dépôt récurrents", + "Recurring Deposit Account Details": "Détails du compte de dépôt récurrent", "Recurring Deposit Account Interest Rate Chart": "Tableau des taux d’intérêt des comptes de dépôt récurrents", "Recurring Deposit Account Standing Instructions": "Instructions permanentes pour les comptes de dépôt récurrents", "Recurring Deposit Account Transactions": "Opérations récurrentes sur le compte de dépôt", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index db72422436..fbbd913261 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3526,6 +3526,7 @@ "Provisioning criteria definitions": "Compila tutte le definizioni dei criteri di provisioning.", "Precedes of": "Precede di", "Recurring Deposit Account Charges": "Spese ricorrenti sul conto di deposito", + "Recurring Deposit Account Details": "Dettagli del conto di deposito ricorrente", "Recurring Deposit Account Interest Rate Chart": "Grafico del tasso di interesse del conto di deposito ricorrente", "Recurring Deposit Account Standing Instructions": "Istruzioni per la permanenza del conto di deposito ricorrente", "Recurring Deposit Account Transactions": "Transazioni ricorrenti del conto di deposito", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index c43d930b75..e578a8e696 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3527,6 +3527,7 @@ "Provisioning criteria definitions": "모든 프로비저닝 기준 정의를 입력하세요.", "Precedes of": "앞선", "Recurring Deposit Account Charges": "반복 예금 계좌 수수료", + "Recurring Deposit Account Details": "정기 적금 계좌 세부 정보", "Recurring Deposit Account Interest Rate Chart": "정기예금 계좌 이자율 차트", "Recurring Deposit Account Standing Instructions": "정기예금 계좌 유지 지침", "Recurring Deposit Account Transactions": "반복 예금 계좌 거래", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index 1eeb96fe25..7c88a81857 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3528,6 +3528,7 @@ "Provisioning criteria definitions": "Užpildykite visus teikimo kriterijų apibrėžimus.", "Precedes of": "Prieštaravimai", "Recurring Deposit Account Charges": "Pasikartojantys indėlio sąskaitos mokesčiai", + "Recurring Deposit Account Details": "Reguliariųjų indėlių sąskaitos rekvizitai", "Recurring Deposit Account Interest Rate Chart": "Periodinio indėlio sąskaitos palūkanų normų diagrama", "Recurring Deposit Account Standing Instructions": "Periodinio indėlio sąskaitos nuolatinės instrukcijos", "Recurring Deposit Account Transactions": "Periodinės indėlio sąskaitos operacijos", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 6312eb8a5f..1e2ff67dd3 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3527,6 +3527,7 @@ "Provisioning criteria definitions": "Lūdzu, aizpildiet visas nodrošināšanas kritēriju definīcijas.", "Precedes of": "Iepriekšējie", "Recurring Deposit Account Charges": "Periodiskas depozīta konta izmaksas", + "Recurring Deposit Account Details": "Regulārā noguldījuma konta informācija", "Recurring Deposit Account Interest Rate Chart": "Atkārtota depozīta konta procentu likmju diagramma", "Recurring Deposit Account Standing Instructions": "Atkārtota depozīta konta pastāvīgās lietošanas instrukcijas", "Recurring Deposit Account Transactions": "Atkārtoti depozīta konta darījumi", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index 9e14a70a8c..dfc65ab0c1 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3525,6 +3525,7 @@ "Provisioning criteria definitions": "कृपया सबै प्रावधान मापदण्ड परिभाषाहरू भर्नुहोस्।", "Precedes of": "को पूर्ववर्ती", "Recurring Deposit Account Charges": "आवर्ती जम्मा खाता शुल्कहरू", + "Recurring Deposit Account Details": "आवर्ती निक्षेप खाता विवरण", "Recurring Deposit Account Interest Rate Chart": "आवर्ती जम्मा खाता ब्याज दर चार्ट", "Recurring Deposit Account Standing Instructions": "आवर्ती जम्मा खाता स्थायी निर्देशनहरू", "Recurring Deposit Account Transactions": "आवर्ती जम्मा खाता लेनदेन", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index 7e9b0d2762..e3949db48d 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3527,6 +3527,7 @@ "Provisioning criteria definitions": "Preencha todas as definições de critérios de provisionamento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Cobranças recorrentes da conta de depósito", + "Recurring Deposit Account Details": "Detalhes da conta de depósito recorrente", "Recurring Deposit Account Interest Rate Chart": "Gráfico de taxas de juros de contas de depósito recorrente", "Recurring Deposit Account Standing Instructions": "Instruções sobre a situação da conta de depósito recorrente", "Recurring Deposit Account Transactions": "Transações recorrentes em contas de depósito", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index 0eefd2ec3a..b7b5750581 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3523,6 +3523,7 @@ "Provisioning criteria definitions": "Tafadhali jaza ufafanuzi wa vigezo vyote vya utoaji.", "Precedes of": "Hutangulia", "Recurring Deposit Account Charges": "Malipo ya Akaunti ya Amana ya Mara kwa Mara", + "Recurring Deposit Account Details": "Maelezo ya Akaunti ya Amana Inayojirudia", "Recurring Deposit Account Interest Rate Chart": "Chati ya Kiwango cha Riba cha Akaunti ya Amana ya Mara kwa Mara", "Recurring Deposit Account Standing Instructions": "Maagizo ya Kudumu ya Akaunti ya Amana", "Recurring Deposit Account Transactions": "Miamala ya Akaunti ya Amana ya Mara kwa Mara", From 8ed07c743f87b58e6e47b7c713349cdcac95ea00 Mon Sep 17 00:00:00 2001 From: Krishna Mewara <161239575+DeathGun44@users.noreply.github.com> Date: Mon, 6 Apr 2026 22:07:57 +0530 Subject: [PATCH 5/9] WEB-900: Docker-backed E2E testing infrastructure (#3463) --- .github/workflows/playwright.yml | 97 ++++++++++++++++++++++++---- Dockerfile | 2 + config/e2e/fineract.env | 40 ++++++++++++ config/e2e/nginx-e2e.conf.template | 29 +++++++++ config/e2e/postgresql-init.sh | 11 ++++ docker-compose.e2e.yml | 95 +++++++++++++++++++++++++++ package.json | 5 ++ playwright.config.ts | 28 ++++---- playwright/README.md | 79 +++++++++++++++------- playwright/fixtures/fineract-api.ts | 76 ++++++++++++++++++++++ playwright/fixtures/test-fixtures.ts | 31 +++++++++ playwright/global-setup.ts | 43 ++++++++++++ scripts/e2e-docker.sh | 76 ++++++++++++++++++++++ 13 files changed, 559 insertions(+), 53 deletions(-) create mode 100644 config/e2e/fineract.env create mode 100644 config/e2e/nginx-e2e.conf.template create mode 100755 config/e2e/postgresql-init.sh create mode 100644 docker-compose.e2e.yml create mode 100644 playwright/fixtures/fineract-api.ts create mode 100644 playwright/fixtures/test-fixtures.ts create mode 100644 playwright/global-setup.ts create mode 100755 scripts/e2e-docker.sh diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index ad70912212..d07d215520 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,22 +1,35 @@ -name: Playwright E2E Tests +name: E2E Tests (Playwright + Fineract) on: push: - branches: [main, dev, dev-angular-19] + branches: [main, dev] pull_request: - branches: [main, dev, dev-angular-19] + branches: [main, dev] + +concurrency: + group: e2e-${{ github.ref }} + cancel-in-progress: true jobs: - playwright: - name: Run Playwright Tests + e2e: + name: Playwright E2E runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 45 + + env: + CI: true + E2E_BASE_URL: http://localhost:4200 + E2E_FINERACT_URL: https://localhost:8443 + E2E_USERNAME: mifos + E2E_PASSWORD: password + E2E_TENANT_ID: default + NODE_TLS_REJECT_UNAUTHORIZED: '0' steps: - name: Checkout code uses: actions/checkout@v6 - - name: Use Node.js 22x + - name: Use Node.js 24 uses: actions/setup-node@v6 with: node-version: '24.14.0' @@ -28,13 +41,65 @@ jobs: - name: Install Playwright browsers run: npx playwright install --with-deps chromium + - name: Start E2E infrastructure + run: docker compose -f docker-compose.e2e.yml up -d --build + + - name: Wait for PostgreSQL + run: | + timeout 60 bash -c ' + until docker exec e2e-postgres pg_isready -U postgres 2>/dev/null; do + sleep 2 + done + ' + echo "✅ PostgreSQL ready" + + - name: Wait for Fineract backend + run: | + timeout 300 bash -c ' + until docker ps --filter "health=healthy" --filter "name=e2e-fineract" | grep -q healthy; do + echo " … Fineract not healthy yet" + sleep 10 + done + ' + curl -fk --retry 30 --retry-all-errors --connect-timeout 10 --retry-delay 10 \ + https://localhost:8443/fineract-provider/actuator/health + echo "" + echo "✅ Fineract ready" + + - name: Verify Fineract initialization complete + run: | + AUTH_HEADER=$(echo -n "${E2E_USERNAME}:${E2E_PASSWORD}" | base64 | tr -d '\n') + timeout 120 bash -c " + until curl -fsk \ + -H 'Fineract-Platform-TenantId: ${E2E_TENANT_ID}' \ + -H 'Authorization: Basic ${AUTH_HEADER}' \ + https://localhost:8443/fineract-provider/api/v1/offices 2>/dev/null | grep -q 'Head Office'; do + echo ' … waiting for seed data' + sleep 5 + done + " + echo "✅ Fineract initialization complete" + + - name: Wait for web-app + run: | + curl -f --retry 20 --retry-all-errors --connect-timeout 5 --retry-delay 5 \ + http://localhost:4200 > /dev/null 2>&1 + echo "✅ Web-app ready" + - name: Run Playwright tests - run: npx playwright test --reporter=html,github - env: - CI: true - FINERACT_API_URL: https://demo.mifos.community - E2E_USERNAME: mifos - E2E_PASSWORD: password + run: npx playwright test --reporter=html,github --workers=1 + + - name: Dump Docker logs on failure + if: failure() + run: | + echo "=== Fineract ===" + docker logs e2e-fineract --tail 100 2>&1 || true + echo "=== PostgreSQL ===" + docker logs e2e-postgres --tail 50 2>&1 || true + echo "=== Web-App ===" + docker logs e2e-web-app --tail 50 2>&1 || true + echo "=== Memory ===" + docker stats --no-stream || true - name: Upload Playwright report uses: actions/upload-artifact@v7 @@ -51,3 +116,9 @@ jobs: name: test-results path: test-results/ retention-days: 7 + + - name: Tear down E2E infrastructure + if: always() + run: | + docker compose -f docker-compose.e2e.yml down -v --remove-orphans + docker system prune -f diff --git a/Dockerfile b/Dockerfile index 95c6b2cb5b..220209b564 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,8 @@ ENV PATH=/usr/src/app/node_modules/.bin:$PATH ENV PUPPETEER_DOWNLOAD_HOST=$PUPPETEER_DOWNLOAD_HOST_ARG ENV PUPPETEER_CHROMIUM_REVISION=$PUPPETEER_CHROMIUM_REVISION_ARG ENV PUPPETEER_SKIP_DOWNLOAD=$PUPPETEER_SKIP_DOWNLOAD_ARG +ENV CYPRESS_INSTALL_BINARY=0 +ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 COPY ./ /usr/src/app/ diff --git a/config/e2e/fineract.env b/config/e2e/fineract.env new file mode 100644 index 0000000000..58bea3efdd --- /dev/null +++ b/config/e2e/fineract.env @@ -0,0 +1,40 @@ +# Fineract E2E Environment — PostgreSQL-only + +# ── Spring Profiles ── +SPRING_PROFILES_ACTIVE=test,diagnostics + +# ── PostgreSQL Connection (Docker service: "db") ── +FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.postgresql.Driver +FINERACT_HIKARI_JDBC_URL=jdbc:postgresql://db:5432/fineract_tenants +FINERACT_HIKARI_USERNAME=postgres +# Well-known Fineract E2E password — intentionally committed, not a secret. +FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca + +# ── Tenant Database ── +FINERACT_DEFAULT_TENANTDB_HOSTNAME=db +FINERACT_DEFAULT_TENANTDB_PORT=5432 +FINERACT_DEFAULT_TENANTDB_UID=postgres +FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca +FINERACT_DEFAULT_TENANTDB_NAME=fineract_default + +# ── SSL & HTTP ── +FINERACT_SERVER_SSL_ENABLED=true +FINERACT_INSECURE_HTTP_CLIENT=true + +# ── Node Identity ── +FINERACT_NODE_ID=1 + +# ── External Events (no ActiveMQ in E2E) ── +FINERACT_EXTERNAL_EVENTS_ENABLED=false + +# ── HikariCP Pool (tuned for E2E) ── +FINERACT_HIKARI_MINIMUM_IDLE=3 +FINERACT_HIKARI_MAXIMUM_POOL_SIZE=10 + +# ── Data Seeding ── +# INITIALIZATION_ENABLED is NOT a Fineract server env var (it belongs to +# fineract-e2e-tests-runner's Gradle Cucumber runner). Do not set it here. +# +# Liquibase auto-seeds: Head Office, default tenant config, schema. +# Domain data (products, GL accounts, clients) must be seeded via the +# FineractApiClient fixture in test beforeAll hooks. diff --git a/config/e2e/nginx-e2e.conf.template b/config/e2e/nginx-e2e.conf.template new file mode 100644 index 0000000000..a4374aa0be --- /dev/null +++ b/config/e2e/nginx-e2e.conf.template @@ -0,0 +1,29 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # ${E2E_PROXY_TARGET} is replaced by envsubst; $host/$scheme etc. are + # safe because NGINX_ENVSUBST_FILTER restricts to ^(FINERACT_|MIFOS_|...). + location /fineract-provider/ { + proxy_pass ${E2E_PROXY_TARGET}/fineract-provider/; + proxy_ssl_verify off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 30s; + proxy_read_timeout 120s; + } + + location / { + try_files $uri $uri/ /index.html; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } +} diff --git a/config/e2e/postgresql-init.sh b/config/e2e/postgresql-init.sh new file mode 100755 index 0000000000..cc29fbafd3 --- /dev/null +++ b/config/e2e/postgresql-init.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Creates the two databases Fineract requires at first boot. +# POSTGRES_USER (postgres) is the default superuser — no CREATE USER needed. +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL + CREATE DATABASE fineract_tenants; + CREATE DATABASE fineract_default; +EOSQL + +echo "✓ E2E databases created: fineract_tenants, fineract_default" diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml new file mode 100644 index 0000000000..66895ba93b --- /dev/null +++ b/docker-compose.e2e.yml @@ -0,0 +1,95 @@ +services: + db: + image: postgres:18.3-alpine + container_name: e2e-postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: skdcnwauicn2ucnaecasdsajdnizucawencascdca + PGDATA: /var/lib/postgresql/data/pgdata + volumes: + - ./config/e2e/postgresql-init.sh:/docker-entrypoint-initdb.d/01-init.sh:ro + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 5s + timeout: 5s + retries: 10 + ports: + - '5432:5432' + mem_limit: 768m + shm_size: 256m + tmpfs: + - /var/lib/postgresql/data + command: > + postgres + -c shared_buffers=128MB + -c work_mem=4MB + -c maintenance_work_mem=64MB + + fineract: + image: apache/fineract:latest + container_name: e2e-fineract + depends_on: + db: + condition: service_healthy + env_file: + - ./config/e2e/fineract.env + environment: + JAVA_TOOL_OPTIONS: >- + -Xmx1536m -Xms512m + -XX:+UseG1GC -XX:MaxGCPauseMillis=200 + -Djava.security.egd=file:/dev/./urandom + healthcheck: + test: + [ + 'CMD-SHELL', + 'wget -qO- --no-check-certificate https://localhost:8443/fineract-provider/actuator/health || exit 1' + ] + interval: 10s + timeout: 10s + retries: 60 + start_period: 120s + ports: + - '8443:8443' + mem_limit: 2g + + web-app: + build: + context: . + dockerfile: Dockerfile + args: + PUPPETEER_SKIP_DOWNLOAD_ARG: 'true' + container_name: e2e-web-app + depends_on: + fineract: + condition: service_healthy + environment: + # Nginx proxy target (internal docker DNS) + E2E_PROXY_TARGET: https://fineract:8443 + + # Angular app configuration (resolved by host browser via proxy) + FINERACT_API_URLS: http://localhost:4200 + FINERACT_API_URL: http://localhost:4200 + + FINERACT_API_PROVIDER: /fineract-provider/api + FINERACT_API_VERSION: /v1 + FINERACT_PLATFORM_TENANT_IDENTIFIER: default + MIFOS_DEFAULT_LANGUAGE: en-US + MIFOS_SUPPORTED_LANGUAGES: en-US + MIFOS_PRELOAD_CLIENTS: 'false' + MIFOS_DEFAULT_CHAR_DELIMITER: ',' + NGINX_ENVSUBST_FILTER: '^(FINERACT_|MIFOS_|ENABLE_|EXTERNAL_|E2E_PROXY_TARGET)' + volumes: + - ./config/e2e/nginx-e2e.conf.template:/etc/nginx/templates/default.conf.template:ro + ports: + - '4200:80' + mem_limit: 256m + # Override CMD: Dockerfile's /bin/sh CMD causes the nginx entrypoint to + # skip template processing (it checks $1 == "nginx"). Process both + # templates explicitly. Only substitute $E2E_PROXY_TARGET in the nginx + # template so $host, $scheme, $uri etc. are left for nginx. + command: >- + /bin/sh -c " + envsubst '$$E2E_PROXY_TARGET' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf && + envsubst < /usr/share/nginx/html/assets/env.template.js > /usr/share/nginx/html/assets/env.js && + nginx -g 'daemon off;' + " diff --git a/package.json b/package.json index 8e3657d62d..a9d1bc1941 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,11 @@ "playwright:ui": "playwright test --ui", "playwright:headed": "playwright test --headed", "playwright:debug": "playwright test --debug", + "playwright:ci": "playwright test --reporter=html,github --workers=1", + "e2e:docker": "bash scripts/e2e-docker.sh", + "e2e:docker:up": "docker compose -f docker-compose.e2e.yml up -d --build", + "e2e:docker:down": "docker compose -f docker-compose.e2e.yml down -v --remove-orphans", + "e2e:docker:logs": "docker compose -f docker-compose.e2e.yml logs -f", "headers:check": "node scripts/check-file-headers.js", "headers:add": "node scripts/add-file-headers.js" }, diff --git a/playwright.config.ts b/playwright.config.ts index 4336c65b77..a2fd55b29d 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -18,6 +18,7 @@ import { defineConfig, devices } from '@playwright/test'; * @see https://playwright.dev/docs/test-configuration */ export default defineConfig({ + globalSetup: process.env.CI ? './playwright/global-setup.ts' : undefined, // Test directory testDir: './playwright/tests', @@ -43,8 +44,8 @@ export default defineConfig({ // Global test settings use: { - // Base URL for the Angular app - baseURL: 'http://localhost:4200', + // Base URL for the Angular app (aligned with global-setup.ts) + baseURL: process.env.E2E_BASE_URL || 'http://localhost:4200', // Handle self-signed certificates from Fineract backend ignoreHTTPSErrors: true, @@ -87,19 +88,12 @@ export default defineConfig({ } ], - // Web server configuration - // In CI: builds production bundle, then serves it with e2e-server.js - // (Express + http-proxy-middleware for /fineract-provider/* proxy) - // Locally: reuses existing ng serve if running - webServer: { - command: process.env.CI ? 'npm run build && node playwright/e2e-server.js' : 'npm run start', - url: 'http://localhost:4200', - reuseExistingServer: !process.env.CI, - timeout: 180000, - // Add retry logic for server startup - ...(process.env.CI && { - stdout: 'pipe', - stderr: 'pipe' - }) - } + webServer: process.env.CI + ? undefined + : { + command: 'npm run start', + url: 'http://localhost:4200', + reuseExistingServer: true, + timeout: 180000 + } }); diff --git a/playwright/README.md b/playwright/README.md index 3e474eb252..168a2bb4bc 100644 --- a/playwright/README.md +++ b/playwright/README.md @@ -1,44 +1,54 @@ -# Playwright E2E Testing +# Playwright E2E Testing Production-grade End-to-End testing infrastructure for Mifos® X Web App using [Playwright](https://playwright.dev/). -## Prerequisites +## Running E2E with Docker (Full Stack) -Before running the tests, ensure the local environment is running: +### One-command (recommended) -1. **Backend:** Ensure Apache Fineract® is running on `https://localhost:8443` -2. **Frontend:** Serve the Angular app: - ```bash - ng serve - ``` +```bash +npm run e2e:docker # All tests +npm run e2e:docker -- --grep login # Filter by name +npm run e2e:docker -- --headed # See the browser +npm run e2e:docker -- --debug # Step through +``` -## Quick Start +### Manual control (debugging infrastructure) ```bash -# Run all tests -npm run playwright - -# Run with UI mode (recommended for debugging) -npm run playwright:ui +npm run e2e:docker:up # Start stack (Postgres + Fineract + Nginx) +npm run e2e:docker:logs # Watch logs (separate terminal) +npm run playwright # Run tests +npm run e2e:docker:down # Tear down +``` -# Run with visible browser -npm run playwright:headed +## Running Locally (without Docker) -# Debug mode (step through tests) -npm run playwright:debug -``` +1. **Backend:** Ensure Apache Fineract® is running on `https://localhost:8443` +2. **Frontend:** Serve the Angular app: + ```bash + npm run start + ``` +3. **Run tests:** + ```bash + npm run playwright + ``` ## Architecture This framework follows the **Page Object Model (POM)** pattern: -``` +```text playwright/ +├── fixtures/ +│ ├── fineract-api.ts # Typed Fineract REST client for data seeding +│ └── test-fixtures.ts # test.extend with fineractApi fixture +├── global-setup.ts # CI-only: validates backend connectivity ├── pages/ -│ ├── BasePage.ts # Abstract base class with common utilities -│ └── LoginPage.ts # Login page object +│ ├── BasePage.ts # Abstract base class with common utilities +│ └── LoginPage.ts # Login page object └── tests/ - └── login.spec.ts # Login smoke tests + └── login.spec.ts # Login smoke tests ``` ### Design Principles @@ -50,6 +60,29 @@ playwright/ | **Maintainability** | Centralized locators per page | | **CI/CD Optimization** | Artifacts only on failure | +## Data Seeding Strategy + +Fineract auto-seeds via Liquibase at boot: + +- Head Office, default tenant config, schema structure + +For domain-specific test data (clients, loans, savings), seed via API fixtures: + +```typescript +import { test } from '../fixtures/test-fixtures'; + +test.beforeAll(async ({ fineractApi }) => { + await fineractApi.createClient({ + officeId: 1, + firstname: 'Test', + lastname: 'Client' + // ... required Fineract fields + }); +}); +``` + +See `playwright/fixtures/fineract-api.ts` for all available methods. + ## Configuration ### SSL Certificate Handling diff --git a/playwright/fixtures/fineract-api.ts b/playwright/fixtures/fineract-api.ts new file mode 100644 index 0000000000..aa0d21f0f2 --- /dev/null +++ b/playwright/fixtures/fineract-api.ts @@ -0,0 +1,76 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { APIRequestContext, APIResponse, request } from '@playwright/test'; + +export class FineractApiClient { + private ctx!: APIRequestContext; + + constructor( + private baseUrl: string, + private tenantId: string, + private username: string, + private password: string + ) {} + + async init(): Promise { + this.ctx = await request.newContext({ + baseURL: this.baseUrl, + ignoreHTTPSErrors: true, + extraHTTPHeaders: { + 'Fineract-Platform-TenantId': this.tenantId, + Authorization: `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`, + 'Content-Type': 'application/json' + } + }); + } + + private async validateResponse(res: APIResponse, operation: string): Promise { + if (!res.ok()) { + throw new Error(`Fineract API error [${operation}]: ${res.status()} ${res.statusText()}`); + } + return res.json(); + } + + async healthCheck(): Promise { + const res = await this.ctx.get('/fineract-provider/actuator/health'); + return res.ok(); + } + + async getOffices(): Promise { + const res = await this.ctx.get('/fineract-provider/api/v1/offices'); + return this.validateResponse(res, 'getOffices'); + } + + async createClient(data: Record): Promise { + const res = await this.ctx.post('/fineract-provider/api/v1/clients', { data }); + return this.validateResponse(res, 'createClient'); + } + + /** + * Creates a savings account. + * @param overrides Must include mandatory Fineract fields: + * submittedOnDate, dateFormat, locale, nominalAnnualInterestRate, + * interestCompoundingPeriodType, interestPostingPeriodType, + * interestCalculationType, interestCalculationDaysInYearType + */ + async createSavingsAccount( + clientId: number, + productId: number, + overrides: Record = {} + ): Promise { + const res = await this.ctx.post('/fineract-provider/api/v1/savingsaccounts', { + data: { ...overrides, clientId, productId } + }); + return this.validateResponse(res, 'createSavingsAccount'); + } + + async dispose(): Promise { + await this.ctx?.dispose(); + } +} diff --git a/playwright/fixtures/test-fixtures.ts b/playwright/fixtures/test-fixtures.ts new file mode 100644 index 0000000000..fc01f35aab --- /dev/null +++ b/playwright/fixtures/test-fixtures.ts @@ -0,0 +1,31 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { test as base } from '@playwright/test'; + +import { FineractApiClient } from './fineract-api'; + +type E2EFixtures = { + fineractApi: FineractApiClient; +}; + +export const test = base.extend({ + fineractApi: async ({}, use) => { + const api = new FineractApiClient( + process.env.E2E_FINERACT_URL || 'https://localhost:8443', + process.env.E2E_TENANT_ID || 'default', + process.env.E2E_USERNAME || 'mifos', + process.env.E2E_PASSWORD || 'password' + ); + await api.init(); + await use(api); + await api.dispose(); + } +}); + +export { expect } from '@playwright/test'; diff --git a/playwright/global-setup.ts b/playwright/global-setup.ts new file mode 100644 index 0000000000..264ef60d42 --- /dev/null +++ b/playwright/global-setup.ts @@ -0,0 +1,43 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { request } from '@playwright/test'; + +async function globalSetup(): Promise { + const fineractUrl = process.env.E2E_FINERACT_URL || 'https://localhost:8443'; + const webAppUrl = process.env.E2E_BASE_URL || 'http://localhost:4200'; + + const ctx = await request.newContext({ ignoreHTTPSErrors: true }); + + try { + const fineractRes = await ctx.get(`${fineractUrl}/fineract-provider/actuator/health`, { + timeout: 15000 + }); + if (!fineractRes.ok()) { + throw new Error(`Fineract returned ${fineractRes.status()} at ${fineractUrl}`); + } + + const webAppRes = await ctx.get(webAppUrl, { timeout: 15000 }); + if (!webAppRes.ok()) { + throw new Error(`Web-app returned ${webAppRes.status()} at ${webAppUrl}`); + } + + console.log('✅ Global setup: Fineract + web-app verified'); + } catch (error) { + throw new Error( + `FATAL: E2E infrastructure unreachable.\n` + + `Fineract: ${fineractUrl}\nWeb-app: ${webAppUrl}\n` + + `Run: docker compose -f docker-compose.e2e.yml up -d\n` + + `Error: ${error}` + ); + } finally { + await ctx.dispose(); + } +} + +export default globalSetup; diff --git a/scripts/e2e-docker.sh b/scripts/e2e-docker.sh new file mode 100755 index 0000000000..a0f6ae9db1 --- /dev/null +++ b/scripts/e2e-docker.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +# E2E Docker Runner — boots Fineract stack, runs Playwright, tears down. +# +# Usage: +# npm run e2e:docker # Run all tests +# npm run e2e:docker -- --grep login # Filter tests +# npm run e2e:docker -- --headed # See the browser +# npm run e2e:docker -- --debug # Step through +set -euo pipefail + +# GNU timeout is required (not available by default on macOS). +# Install via: brew install coreutils +if ! command -v timeout &>/dev/null; then + echo "❌ 'timeout' command not found. On macOS: brew install coreutils" >&2 + exit 1 +fi + +COMPOSE_FILE="docker-compose.e2e.yml" + +cleanup() { + local exit_code=$? + echo "" + echo "🧹 Tearing down E2E infrastructure..." + docker compose -f "$COMPOSE_FILE" down -v --remove-orphans 2>/dev/null || true + echo "✅ Cleanup complete" + exit $exit_code +} +trap cleanup EXIT + +echo "🚀 Starting E2E infrastructure..." +docker compose -f "$COMPOSE_FILE" up -d --build + +echo "⏳ Waiting for services..." + +# Phase 1: PostgreSQL +timeout 60 bash -c ' + until docker exec e2e-postgres pg_isready -U postgres 2>/dev/null; do sleep 2; done +' +echo "✅ PostgreSQL ready" + +# Phase 2: Fineract actuator +timeout 300 bash -c ' + until docker ps --filter "health=healthy" --filter "name=e2e-fineract" | grep -q healthy; do + echo " … waiting for Fineract" + sleep 10 + done +' +echo "✅ Fineract healthy" + +# Phase 2.5: Liquibase seeding (Head Office) +E2E_USERNAME="${E2E_USERNAME:-mifos}" +E2E_PASSWORD="${E2E_PASSWORD:-password}" +E2E_TENANT_ID="${E2E_TENANT_ID:-default}" +# Portable base64: tr -d '\n' handles macOS/Linux newline differences +AUTH_HEADER=$(echo -n "${E2E_USERNAME}:${E2E_PASSWORD}" | base64 | tr -d '\n') + +timeout 120 bash -c " + until curl -fsk \ + -H 'Fineract-Platform-TenantId: ${E2E_TENANT_ID}' \ + -H 'Authorization: Basic ${AUTH_HEADER}' \ + https://localhost:8443/fineract-provider/api/v1/offices 2>/dev/null | grep -q 'Head Office'; do + echo ' … waiting for Liquibase seed data' + sleep 5 + done +" +echo "✅ Liquibase seed data ready" + +# Phase 3: Web-app +curl -f --retry 20 --retry-all-errors --connect-timeout 5 --retry-delay 3 \ + http://localhost:4200 > /dev/null 2>&1 +echo "✅ Web-app ready" + +echo "" +echo "🧪 Running Playwright tests..." +# "$@" forwards flags from: npm run e2e:docker -- --grep login +npx playwright test --workers=1 "$@" From d0ae8479870f573605d9eb6a8c7d63d02f5b57b2 Mon Sep 17 00:00:00 2001 From: Soni Jay Date: Mon, 6 Apr 2026 22:11:44 +0530 Subject: [PATCH 6/9] WEB-902 Page title for Loan Accounts displays generic General instead of Loan Account Details (#3465) --- src/app/loans/loans-routing.module.ts | 2 +- src/assets/translations/cs-CS.json | 1 + src/assets/translations/de-DE.json | 1 + src/assets/translations/en-US.json | 1 + src/assets/translations/es-CL.json | 1 + src/assets/translations/es-MX.json | 1 + src/assets/translations/fr-FR.json | 1 + src/assets/translations/it-IT.json | 1 + src/assets/translations/ko-KO.json | 1 + src/assets/translations/lt-LT.json | 1 + src/assets/translations/lv-LV.json | 1 + src/assets/translations/ne-NE.json | 1 + src/assets/translations/pt-PT.json | 1 + src/assets/translations/sw-SW.json | 1 + 14 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app/loans/loans-routing.module.ts b/src/app/loans/loans-routing.module.ts index c6270046ba..858a0ea117 100644 --- a/src/app/loans/loans-routing.module.ts +++ b/src/app/loans/loans-routing.module.ts @@ -112,7 +112,7 @@ const routes: Routes = [ { path: 'general', component: GeneralTabComponent, - data: { title: 'General', breadcrumb: 'General', routeParamBreadcrumb: false }, + data: { title: 'Loan Account Details', breadcrumb: 'General', routeParamBreadcrumb: false }, resolve: {} }, { diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index 66e3a4d947..e6b6c50250 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3403,6 +3403,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccount DelikvencePauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Detaily úvěrového účtu", "Loan Account Actions": "Akce na úvěrovém účtu", "Loan Collateral Details": "Podrobnosti o zajištění úvěru", "Loan Disbursal": "Vyplacení půjčky", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index 1d7f0d4f8f..e6855396b7 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3404,6 +3404,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Details zum Kreditkonto", "Loan Account Actions": "Aktionen zum Kreditkonto", "Loan Collateral Details": "Details zur Kreditsicherheit", "Loan Disbursal": "Kreditauszahlung", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index a50615a16d..1737ff23f4 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3537,6 +3537,7 @@ "LoanWithdrawnByApplicantBusinessEvent": "Loan Withdrawn By Applicant Business Event", "LoanWrittenOffPostBusinessEvent": "Loan Written Off Post Business Event", "LoanWrittenOffPreBusinessEvent": "Loan Written Off Pre Business Event", + "Loan Account Details": "Loan Account Details", "Loan Account Actions": "Loan Account Actions", "Loan Collateral Details": "Loan Collateral Details", "Loan Disbursal": "Loan Disbursal", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index cbe57757d7..b7846667ea 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3404,6 +3404,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "PréstamoCuentaPersonalizadoInstantáneaNegocioEvento", "LoanAccountDelinquencyPauseChangedBusinessEvent": "PréstamoCuentaMorosidadPausaCambiadoNegocioEvento", "LoanAccountSnapshotBusinessEvent": "PréstamoCuentaInstantáneaNegocioEvento", + "Loan Account Details": "Detalles de la cuenta de Crédito", "Loan Account Actions": "Acciones de la cuenta de Crédito", "Loan Collateral Details": "Detalles de la garantía del Crédito", "Loan Disbursal": "Curso del Crédito", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index ed7ac84882..82df76ed38 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3437,6 +3437,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "PréstamoCuentaPersonalizadoInstantáneaNegocioEvento", "LoanAccountDelinquencyPauseChangedBusinessEvent": "PréstamoCuentaMorosidadPausaCambiadoNegocioEvento", "LoanAccountSnapshotBusinessEvent": "PréstamoCuentaInstantáneaNegocioEvento", + "Loan Account Details": "Detalles de la cuenta de préstamo", "Loan Account Actions": "Acciones de la cuenta de Crédito", "Loan Collateral Details": "Detalles de la garantía del Crédito", "Loan Disbursal": "Dispersión del Crédito", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index ad8fd5967d..1b3e9a7e88 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3405,6 +3405,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Détails du compte de prêt", "Loan Account Actions": "Actions sur le compte de prêt", "Loan Collateral Details": "Détails de la garantie de prêt", "Loan Disbursal": "Décaissement du prêt", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index fbbd913261..975b881122 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3401,6 +3401,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Dettagli del conto di prestito", "Loan Account Actions": "Azioni del conto di prestito", "Loan Collateral Details": "Dettagli della garanzia del prestito", "Loan Disbursal": "Erogazione del prestito", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index e578a8e696..cdf5028655 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3402,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "대출계정CustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "대출계정연체 일시중지ChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "대출계정스냅샷비즈니스이벤트", + "Loan Account Details": "대출 계좌 세부 정보", "Loan Account Actions": "대출 계정 작업", "Loan Collateral Details": "대출 담보 세부정보", "Loan Disbursal": "대출금 지급", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index 7c88a81857..2b5a6882d3 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3403,6 +3403,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Paskolos sąskaitos rekvizitai", "Loan Account Actions": "Paskolos sąskaitos veiksmai", "Loan Collateral Details": "Paskolos užstato informacija", "Loan Disbursal": "Paskolos išmokėjimas", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 1e2ff67dd3..e06eb84b1b 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3402,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Kredītkonta informācija", "Loan Account Actions": "Aizdevuma konta darbības", "Loan Collateral Details": "Sīkāka informācija par aizdevuma nodrošinājumu", "Loan Disbursal": "Aizdevuma izsniegšana", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index dfc65ab0c1..83aadd0ed8 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3400,6 +3400,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "ऋण खाता विवरण", "Loan Account Actions": "ऋण खाता कार्यहरू", "Loan Collateral Details": "ऋण संपार्श्विक विवरण", "Loan Disbursal": "ऋण वितरण", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index e3949db48d..75cda39da1 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3402,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Detalhes da conta de empréstimo", "Loan Account Actions": "Ações de conta de empréstimo", "Loan Collateral Details": "Detalhes da garantia do empréstimo", "Loan Disbursal": "Desembolso de empréstimo", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index b7b5750581..335ed33324 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3398,6 +3398,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Maelezo ya Akaunti ya Mkopo", "Loan Account Actions": "Vitendo vya Akaunti ya Mkopo", "Loan Collateral Details": "Maelezo ya Dhamana ya Mkopo", "Loan Disbursal": "Utoaji wa mkopo", From 03f86aebc80ea7cbce1d5990ecfca79d7eb592d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:43:46 -0600 Subject: [PATCH 7/9] WEB-818: Update dependency lodash to v4.18.1 [SECURITY] (#3476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fc4926f4bf..2523fd9f8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.2", "lightgallery": "^2.9.0", - "lodash": "4.17.23", + "lodash": "4.18.1", "minimatch": "^3.1.4", "moment": "^2.29.4", "ngx-mat-select-search": "^8.0.2", @@ -17690,9 +17690,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.debounce": { diff --git a/package.json b/package.json index a9d1bc1941..c9dbfbfaab 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.2", "lightgallery": "^2.9.0", - "lodash": "4.17.23", + "lodash": "4.18.1", "minimatch": "^3.1.4", "moment": "^2.29.4", "ngx-mat-select-search": "^8.0.2", From 20946913c03c5acf963e36fd799ab37186cd9910 Mon Sep 17 00:00:00 2001 From: JaySoni1 Date: Tue, 7 Apr 2026 01:42:26 +0530 Subject: [PATCH 8/9] WEB-907 Fix missing and localized translations for Loan Originators page title --- src/app/loans/loans-routing.module.ts | 2 +- src/assets/translations/cs-CS.json | 3 ++- src/assets/translations/de-DE.json | 3 ++- src/assets/translations/en-US.json | 1 + src/assets/translations/es-CL.json | 3 ++- src/assets/translations/es-MX.json | 3 ++- src/assets/translations/fr-FR.json | 3 ++- src/assets/translations/it-IT.json | 3 ++- src/assets/translations/ko-KO.json | 3 ++- src/assets/translations/lt-LT.json | 3 ++- src/assets/translations/lv-LV.json | 3 ++- src/assets/translations/ne-NE.json | 3 ++- src/assets/translations/pt-PT.json | 3 ++- src/assets/translations/sw-SW.json | 3 ++- 14 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/app/loans/loans-routing.module.ts b/src/app/loans/loans-routing.module.ts index 858a0ea117..fe7cc878c5 100644 --- a/src/app/loans/loans-routing.module.ts +++ b/src/app/loans/loans-routing.module.ts @@ -279,7 +279,7 @@ const routes: Routes = [ }, { path: 'originators', - data: { title: 'Loans Originators', breadcrumb: 'Originators', routeParamBreadcrumb: false }, + data: { title: 'Loan Originators', breadcrumb: 'Originators', routeParamBreadcrumb: false }, resolve: { loanOriginatorsData: LoanOriginatorsResolver }, diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index e6b6c50250..91002afff7 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3760,7 +3760,8 @@ "Failed to update payment type. Please try again.": "Aktualizace typu platby se nezdařila. Zkuste to prosím znovu.", "Search and assign this beneficiary to an existing Mifos client account": "Vyhledejte a přiřaďte tohoto příjemce k existujícímu účtu klienta Mifos", "Failed to search clients. Please try again.": "Hledání klientů se nezdařilo. Zkuste to prosím znovu.", - "Process Remittance": "Zpracovat remitenci" + "Process Remittance": "Zpracovat remitenci", + "Loan Originators": "Poskytovatelé úvěrů" }, "permissions": { "actions": { diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index e6855396b7..3c191cbf5b 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3761,7 +3761,8 @@ "Failed to update payment type. Please try again.": "Aktualisierung des Zahlungstyps fehlgeschlagen. Bitte versuchen Sie es erneut.", "Search and assign this beneficiary to an existing Mifos client account": "Suchen und weisen Sie diesen Begünstigten einem bestehenden Mifos-Kundenkonto zu", "Failed to search clients. Please try again.": "Kundensuche fehlgeschlagen. Bitte versuchen Sie es erneut.", - "Process Remittance": "Überweisung bearbeiten" + "Process Remittance": "Überweisung bearbeiten", + "Loan Originators": "Kreditvermittler" }, "permissions": { "actions": { diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index 1737ff23f4..7d8fc6eca8 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3548,6 +3548,7 @@ "Loan Tranche Details": "Loan Tranche Details", "Loan Term Variations": "Loan Term Variations", "Loan View": "Loan View", + "Loan Originators": "Loan Originators", "Loan products define the rules, default settings": "Loan products define the rules, default settings, and constraints for a financial institution's lending offerings. A loan product provides a template for multiple loan accounts for the financial institution's clients.", "Loan": "Loan", "Loans": "Loans", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index b7846667ea..a2568cc216 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3764,7 +3764,8 @@ "Failed to update payment type. Please try again.": "Error al actualizar el tipo de pago. Intente de nuevo.", "Search and assign this beneficiary to an existing Mifos client account": "Buscar y asignar este beneficiario a una cuenta de cliente Mifos existente", "Failed to search clients. Please try again.": "Error al buscar clientes. Intente de nuevo.", - "Process Remittance": "Procesar Remesa" + "Process Remittance": "Procesar Remesa", + "Loan Originators": "Originadores de créditos" }, "permissions": { "actions": { diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 82df76ed38..487908ed83 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3780,7 +3780,8 @@ "“Maker-Checker” principle requires every tasks": "El principio \"Maker-Checker\" requiere que dos personas completen cada tarea para reducir la posibilidad de errores y uso indebido. Una persona inicia el proceso y la segunda lo completa.", "Buy Down Fees": "Tarifas de compra", "UploadDocumentHint": "Suba un PDF o imagen para generar una vista previa.", - "Process Remittance": "Procesar Remesa" + "Process Remittance": "Procesar Remesa", + "Loan Originators": "Comisionistas de créditos" }, "permissions": { "actions": { diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index 1b3e9a7e88..4fc2cfa171 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3765,7 +3765,8 @@ "Failed to update payment type. Please try again.": "Échec de la mise à jour du type de paiement. Veuillez réessayer.", "Search and assign this beneficiary to an existing Mifos client account": "Rechercher et attribuer ce bénéficiaire à un compte client Mifos existant", "Failed to search clients. Please try again.": "Échec de la recherche de clients. Veuillez réessayer.", - "Process Remittance": "Traiter le transfert" + "Process Remittance": "Traiter le transfert", + "Loan Originators": "Les courtiers en prêts" }, "permissions": { "actions": { diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index 975b881122..fd68a47ee1 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3761,7 +3761,8 @@ "Failed to update payment type. Please try again.": "Aggiornamento del tipo di pagamento non riuscito. Si prega di riprovare.", "Search and assign this beneficiary to an existing Mifos client account": "Cerca e assegna questo beneficiario a un conto cliente Mifos esistente", "Failed to search clients. Please try again.": "Ricerca clienti non riuscita. Si prega di riprovare.", - "Process Remittance": "Elabora rimessa" + "Process Remittance": "Elabora rimessa", + "Loan Originators": "Originatori di prestiti" }, "permissions": { "actions": { diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index cdf5028655..becdfa6b20 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3762,7 +3762,8 @@ "Failed to update payment type. Please try again.": "결제 유형 업데이트에 실패했습니다. 다시 시도하세요.", "Search and assign this beneficiary to an existing Mifos client account": "이 수취인을 검색하여 기존 Mifos 고객 계정에 배정하세요", "Failed to search clients. Please try again.": "고객 검색에 실패했습니다. 다시 시도하세요.", - "Process Remittance": "송금 처리" + "Process Remittance": "송금 처리", + "Loan Originators": "대출 담당자" }, "permissions": { "actions": { diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index 2b5a6882d3..ec949c96e3 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3763,7 +3763,8 @@ "Failed to update payment type. Please try again.": "Nepavyko atnaujinti mokėjimo tipo. Bandykite dar kartą.", "Search and assign this beneficiary to an existing Mifos client account": "Ieškokite ir priskirkite šį gavėją esamai Mifos kliento paskyrai", "Failed to search clients. Please try again.": "Nepavyko ieškoti klientų. Bandykite dar kartą.", - "Process Remittance": "Apdoroti pervedimą" + "Process Remittance": "Apdoroti pervedimą", + "Loan Originators": "Paskolų teikėjai" }, "permissions": { "actions": { diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index e06eb84b1b..7f73c14735 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3762,7 +3762,8 @@ "Failed to update payment type. Please try again.": "Neizdevās atjaunināt maksājuma veidu. Lūdzu, mēģiniet vēlreiz.", "Search and assign this beneficiary to an existing Mifos client account": "Meklējiet un piešķiriet šo saņēmēju esošam Mifos klienta kontam", "Failed to search clients. Please try again.": "Neizdevās meklēt klientus. Lūdzu, mēģiniet vēlreiz.", - "Process Remittance": "Apstrādāt pārvedumu" + "Process Remittance": "Apstrādāt pārvedumu", + "Loan Originators": "Aizdevumu izsniedzēji" }, "permissions": { "actions": { diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index 83aadd0ed8..ff4995ed8e 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3760,7 +3760,8 @@ "Failed to update payment type. Please try again.": "भुक्तानी प्रकार अद्यावधिक गर्न असफल भयो। कृपया पुनः प्रयास गर्नुहोस्।", "Search and assign this beneficiary to an existing Mifos client account": "यो लाभग्राहीलाई खोजेर अवस्थित Mifos ग्राहक खातामा तोक्नुहोस्", "Failed to search clients. Please try again.": "ग्राहकहरू खोज्न असफल भयो। कृपया पुनः प्रयास गर्नुहोस्।", - "Process Remittance": "रेमिट्यान्स प्रक्रिया गर्नुहोस्" + "Process Remittance": "रेमिट्यान्स प्रक्रिया गर्नुहोस्", + "Loan Originators": "ऋण सुरुवातकर्ताहरू" }, "permissions": { "actions": { diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index 75cda39da1..53f2349bc4 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3762,7 +3762,8 @@ "Failed to update payment type. Please try again.": "Falha ao atualizar o tipo de pagamento. Tente novamente.", "Search and assign this beneficiary to an existing Mifos client account": "Pesquise e atribua este beneficiário a uma conta de cliente Mifos existente", "Failed to search clients. Please try again.": "Falha ao pesquisar clientes. Tente novamente.", - "Process Remittance": "Processar remessa" + "Process Remittance": "Processar remessa", + "Loan Originators": "Agentes de Crédito" }, "permissions": { "actions": { diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index 335ed33324..f651cbeb12 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3758,7 +3758,8 @@ "Failed to update payment type. Please try again.": "Imeshindwa kusasisha aina ya malipo. Tafadhali jaribu tena.", "Search and assign this beneficiary to an existing Mifos client account": "Tafuta na uweke mpokeaji huyu kwenye akaunti ya mteja wa Mifos iliyopo", "Failed to search clients. Please try again.": "Imeshindwa kutafuta wateja. Tafadhali jaribu tena.", - "Process Remittance": "Chakata uhawilishaji" + "Process Remittance": "Chakata uhawilishaji", + "Loan Originators": "Waanzilishi wa Mikopo" }, "permissions": { "actions": { From c67e7e34a13eae79c9b5ebc3037a197e31e57530 Mon Sep 17 00:00:00 2001 From: DeathGun44 Date: Mon, 23 Mar 2026 15:05:10 +0530 Subject: [PATCH 9/9] WEB-890: Implement storageState authentication bypass for Playwright E2E Signed-off-by: DeathGun44 --- .gitignore | 1 + config/e2e/nginx-e2e.conf.template | 4 -- docker-compose.e2e.yml | 4 +- playwright.config.ts | 14 ++++-- playwright/auth.setup.ts | 53 ++++++++++++++++++++ playwright/tests/authenticated-smoke.spec.ts | 29 +++++++++++ playwright/tests/login-responsive.spec.ts | 6 ++- playwright/tests/login.spec.ts | 13 ++--- 8 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 playwright/auth.setup.ts create mode 100644 playwright/tests/authenticated-smoke.spec.ts diff --git a/.gitignore b/.gitignore index 1d420630c5..95230e8fea 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,4 @@ src/environments/.env.ts /playwright-report/ /blob-report/ /playwright/.cache/ +/playwright/.auth/ diff --git a/config/e2e/nginx-e2e.conf.template b/config/e2e/nginx-e2e.conf.template index a4374aa0be..1c0459a534 100644 --- a/config/e2e/nginx-e2e.conf.template +++ b/config/e2e/nginx-e2e.conf.template @@ -10,10 +10,6 @@ server { location /fineract-provider/ { proxy_pass ${E2E_PROXY_TARGET}/fineract-provider/; proxy_ssl_verify off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 30s; proxy_read_timeout 120s; } diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml index 66895ba93b..46a8b317ac 100644 --- a/docker-compose.e2e.yml +++ b/docker-compose.e2e.yml @@ -67,8 +67,8 @@ services: E2E_PROXY_TARGET: https://fineract:8443 # Angular app configuration (resolved by host browser via proxy) - FINERACT_API_URLS: http://localhost:4200 - FINERACT_API_URL: http://localhost:4200 + FINERACT_API_URLS: '' + FINERACT_API_URL: '' FINERACT_API_PROVIDER: /fineract-provider/api FINERACT_API_VERSION: /v1 diff --git a/playwright.config.ts b/playwright.config.ts index a2fd55b29d..9d088d4d8f 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -44,7 +44,7 @@ export default defineConfig({ // Global test settings use: { - // Base URL for the Angular app (aligned with global-setup.ts) + // Base URL for the Angular app (aligned with global-setup.ts and configurable via env for CI) baseURL: process.env.E2E_BASE_URL || 'http://localhost:4200', // Handle self-signed certificates from Fineract backend @@ -74,17 +74,25 @@ export default defineConfig({ // Global test timeout (per test) timeout: process.env.CI ? 180000 : 120000, - // Configure projects for different browsers + // Configure projects for authentication setup and browser testing projects: [ + { + name: 'setup', + testMatch: /.*\.setup\.ts/, + testDir: './playwright', + retries: process.env.CI ? 2 : 0 + }, { name: 'chromium', use: { ...devices['Desktop Chrome'], + storageState: 'playwright/.auth/user.json', // Launch options for handling SSL in headed mode launchOptions: { args: ['--ignore-certificate-errors'] } - } + }, + dependencies: ['setup'] } ], diff --git a/playwright/auth.setup.ts b/playwright/auth.setup.ts new file mode 100644 index 0000000000..c869df453e --- /dev/null +++ b/playwright/auth.setup.ts @@ -0,0 +1,53 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { test as setup, expect } from '@playwright/test'; +import fs from 'fs'; +import path from 'path'; +import { LoginPage } from './pages/login.page'; + +const authFile = 'playwright/.auth/user.json'; + +setup('authenticate', async ({ page, browser }) => { + const authPath = path.resolve(authFile); + const authDir = path.dirname(authPath); + if (!fs.existsSync(authDir)) { + fs.mkdirSync(authDir, { recursive: true }); + } + if (fs.existsSync(authPath)) { + fs.unlinkSync(authPath); + } + + const username = process.env.E2E_USERNAME || 'mifos'; + const password = process.env.E2E_PASSWORD || 'password'; + + const loginPage = new LoginPage(page); + await loginPage.navigate(); + await loginPage.loginAndWaitForDashboard(username, password); + + console.log('Auth setup: copying mifosXCredentials from sessionStorage → localStorage'); + const credsCopied = await page.evaluate(() => { + const creds = sessionStorage.getItem('mifosXCredentials'); + if (!creds) return false; + localStorage.setItem('mifosXCredentials', creds); + return true; + }); + + if (!credsCopied) { + throw new Error('CRITICAL: mifosXCredentials not found in sessionStorage. ' + 'Did the auth storage key change?'); + } + + await page.context().storageState({ path: authFile }); + console.log('Auth setup: storageState saved to', authFile); + + const verifyContext = await browser.newContext({ storageState: authFile }); + const verifyPage = await verifyContext.newPage(); + await verifyPage.goto('/#/'); + await expect(verifyPage).not.toHaveURL(/.*login.*/, { timeout: 30000 }); + await verifyContext.close(); + console.log('Auth setup: storageState verification passed ✓'); +}); diff --git a/playwright/tests/authenticated-smoke.spec.ts b/playwright/tests/authenticated-smoke.spec.ts new file mode 100644 index 0000000000..03dcb892bd --- /dev/null +++ b/playwright/tests/authenticated-smoke.spec.ts @@ -0,0 +1,29 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { test, expect } from '@playwright/test'; +test.describe('Authenticated Smoke Tests', () => { + test.beforeEach(async ({ page }) => { + // Playwright storageState only restores localStorage and cookies. + // The Fineract web app expects credentials in sessionStorage. + // We injected credentials into localStorage during auth.setup.ts, + // so we must restore them to sessionStorage before the page runs. + await page.addInitScript(() => { + const creds = localStorage.getItem('mifosXCredentials'); + if (creds) { + sessionStorage.setItem('mifosXCredentials', creds); + } + }); + }); + + test('should load dashboard without login redirect', async ({ page }) => { + await page.goto('/#/'); + + await expect(page).not.toHaveURL(/.*login.*/, { timeout: 30000 }); + await expect(page.locator('mat-toolbar')).toBeVisible({ timeout: 10000 }); + }); +}); diff --git a/playwright/tests/login-responsive.spec.ts b/playwright/tests/login-responsive.spec.ts index 6e4ab1cde5..644fc68fbd 100644 --- a/playwright/tests/login-responsive.spec.ts +++ b/playwright/tests/login-responsive.spec.ts @@ -1,4 +1,4 @@ -/** +/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public @@ -8,6 +8,8 @@ import { test, expect } from '@playwright/test'; import { LoginPage } from 'playwright/pages/login.page'; +test.use({ storageState: { cookies: [], origins: [] } }); + /** * Login Responsive Layout Tests * @@ -209,7 +211,7 @@ test.describe('Login Page - Responsive Layout', () => { for (const viewport of viewports) { await page.setViewportSize(viewport); - await page.goto('http://localhost:4200/login'); + await page.goto('/#/login'); await page.waitForLoadState('networkidle'); // Check no horizontal scroll diff --git a/playwright/tests/login.spec.ts b/playwright/tests/login.spec.ts index adc25b2022..8b8b00cb45 100644 --- a/playwright/tests/login.spec.ts +++ b/playwright/tests/login.spec.ts @@ -8,6 +8,7 @@ import { test, expect } from '@playwright/test'; import { LoginPage } from '../pages/login.page'; +test.use({ storageState: { cookies: [], origins: [] } }); /** * Login Smoke Tests @@ -68,8 +69,6 @@ test.describe('Login Page', () => { }); test('should successfully login with valid credentials', async () => { - test.skip(!!process.env.CI, 'Production build auth interceptor skips tenant header for absolute URLs'); - // Perform login with valid credentials // This uses the login() method which follows the exact codegen sequence await loginPage.loginAndWaitForDashboard('mifos', 'password'); @@ -82,12 +81,8 @@ test.describe('Login Page', () => { // Attempt login with wrong password await loginPage.login('mifos', 'wrongpassword'); - // Wait for the login attempt to process and any error notification to appear - // The app shows a snackbar notification for authentication errors - await page.waitForTimeout(3000); - - // Should remain on login page after failed attempt (URL still contains /login) - await expect(page).toHaveURL(/.*login.*/); + // Should remain on login page after failed attempt + await expect(page).toHaveURL(/.*login.*/, { timeout: 10000 }); // Verify we're still on the login page by checking form elements are visible await expect(loginPage.usernameInput).toBeVisible(); @@ -99,8 +94,6 @@ test.describe('Login Page', () => { * This is the baseline test generated from codegen. */ test('codegen baseline: login with mifos credentials', async () => { - test.skip(!!process.env.CI, 'Production build auth interceptor skips tenant header for absolute URLs'); - // This test uses the exact codegen interaction sequence await loginPage.login('mifos', 'password');