fix: use theme token for .clickable-link colour in dark mode - #600
akashchamp wants to merge 1 commit into
Conversation
.clickable-link hardcoded #3f51b5 in clients-list.component.ts and client-view.component.ts, so it never picked up the dark theme and rendered at 2.43:1 against the #1e1e1e card, well under the 4.5:1 WCAG AA minimum for normal text. Swaps both to var(--primary-text), the token _common.scss already documents for exactly this case (a palette colour drawn as text on a card surface) rather than var(--primary-color): --primary-color is 3.15:1 on the light theme's white card, so it would have traded the dark-mode failure for a new light-mode one. --primary-text keeps light mode's current ~8:1 (2471a3 on white) and brings dark mode to 5.29:1 (3498db on #1e1e1e), both comfortably clearing AA. Adds a regression test to e2e/accessibility.spec.ts that populates one client row, switches to dark mode via the header toggle per the issue's own reproduction steps, and asserts axe's color-contrast check passes for .clickable-link. Confirmed it fails against the unfixed colour (2.42:1, matching the issue's measurement) and passes against the fix (5.29:1). Closes apache#575 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2a2d39f to
b7f072e
Compare
E2E — mocked backend🎭 E2E Tests✅ All green — 365 passed · 0 failed · 1 skipped · 1 flaky, across 30 spec files in 7m 25s.
|
| Spec | ✅ | ❌ | ⏭️ | 🔒 | Time |
|---|---|---|---|---|---|
| accessibility.spec.ts | 5 | 0 | 0 | 0 | 32.9s |
| all-functions-read-shortcut.spec.ts | 5 | 0 | 0 | 0 | 9.8s |
| branded-deployment.spec.ts | 9 | 0 | 0 | 0 | 18.0s |
| breadcrumb.spec.ts | 2 | 0 | 0 | 0 | 6.1s |
| client-date-picker-revisit.spec.ts | 1 | 0 | 0 | 0 | 6.0s |
| client-servicing-gaps.spec.ts | 14 | 0 | 0 | 0 | 1m 2s |
| client.spec.ts | 1 | 0 | 0 | 0 | 3.7s |
| date-picker-revisit.spec.ts | 6 | 0 | 0 | 0 | 28.2s |
| deployment-customization.spec.ts | 19 | 0 | 0 | 0 | 37.4s |
| e2e-journey.spec.ts | 81 | 0 | 0 | 0 | 2m 50s |
| feature-coverage.spec.ts | 48 | 0 | 0 | 0 | 1m 36s |
| functional-coverage.spec.ts | 42 | 0 | 0 | 0 | 1m 34s |
| global-search-nav-shortcuts.spec.ts | 4 | 0 | 0 | 0 | 8.6s |
| global-search-navigation.spec.ts | 8 | 0 | 0 | 0 | 17.5s |
| group-detail.spec.ts | 8 | 0 | 0 | 0 | 26.2s |
| guidance-tour.spec.ts | 5 | 0 | 1 | 0 | 11.0s |
| keyboard-shortcuts.spec.ts | 5 | 0 | 0 | 0 | 7.9s |
| list-pagination.spec.ts | 12 | 0 | 0 | 0 | 40.3s |
| client-empty-account-cta.spec.ts | 1 | 0 | 0 | 0 | 6.1s |
| loan-portfolio-summary.spec.ts | 4 | 0 | 0 | 0 | 14.4s |
| loan-product-down-payment.spec.ts | 13 | 0 | 0 | 0 | 1m 6s |
| loan-schedule-type-gating.spec.ts | 5 | 0 | 0 | 0 | 18.0s |
| loan-servicing-gaps.spec.ts | 14 | 0 | 0 | 0 | 54.8s |
| rbac-feature-flag.spec.ts | 11 | 0 | 0 | 0 | 19.0s |
| rbac-route-protection.spec.ts | 18 | 0 | 0 | 0 | 1m 40s |
| report-enhancements.spec.ts | 2 | 0 | 0 | 0 | 6.1s |
| reporting.spec.ts | 2 | 0 | 0 | 0 | 5.0s |
| scheduler-jobs.spec.ts | 3 | 0 | 0 | 0 | 11.4s |
| two-factor-authentication.spec.ts | 10 | 0 | 0 | 0 | 18.5s |
| working-capital-loan-actions.spec.ts | 7 | 0 | 0 | 0 | 33.6s |
All 366 tests — click to expand
accessibility.spec.ts
- ✅ Runtime accessibility › client list has no blocking violations —
4.8s - ✅ Runtime accessibility › client list links meet color contrast in dark mode —
3.7s - ✅ Runtime accessibility › client form has no blocking violations —
4.2s - ✅ Runtime accessibility › banner and dashboard content have no blocking violations —
14.9s - ✅ Runtime accessibility › create office dialog has no blocking violations —
5.2s
all-functions-read-shortcut.spec.ts
- ✅ ALL_FUNCTIONS_READ shortcut › grants read access to the Clients list without any explicit READ_CLIENT permission —
1.8s - ✅ ALL_FUNCTIONS_READ shortcut › does not grant the Create Client action —
1.9s - ✅ ALL_FUNCTIONS_READ shortcut › does not grant Create Client even combined with an explicit READ_CLIENT permission —
2.2s - ✅ ALL_FUNCTIONS_READ shortcut › a user with the real CREATE_CLIENT permission still sees the button —
2.0s - ✅ ALL_FUNCTIONS_READ shortcut › ALL_FUNCTIONS (full superuser) still sees the Create Client button —
1.9s
branded-deployment.spec.ts
- ✅ a fully branded deployment › wears the institution’s name and mark, not Fineract’s —
2.5s - ✅ a fully branded deployment › carries the institution’s palette into its own chrome and into Ionic —
1.6s - ✅ a fully branded deployment › drops the sections the institution does not run —
1.6s - ✅ a fully branded deployment › renames and reorders entries to the institution’s vocabulary —
1.6s - ✅ a fully branded deployment › offers the institution’s own systems beside Fineract’s screens —
2.0s - ✅ a fully branded deployment › restates the labels the institution words differently —
2.7s - ✅ a fully branded deployment › keeps a readable palette in dark mode, with a label colour to match —
1.6s - ✅ a fully branded deployment › does not leak a light colour into the dark palette —
1.6s - ✅ a fully branded deployment › reports no configuration defects for the published example —
2.9s
breadcrumb.spec.ts
- ✅ a single-crumb page shows no breadcrumb trail —
2.7s - ✅ a nested page shows a trail, and the ancestor crumb navigates back —
3.3s
client-date-picker-revisit.spec.ts
- ✅ Client form date pickers › stay usable on a second visit to the create form —
6.0s
client-servicing-gaps.spec.ts
- ✅ Client transfers › proposing a transfer sends the destination, the date and the format that parses it —
4.8s - ✅ Client transfers › a one-step transfer omits the date the platform refuses —
4.9s - ✅ Client transfers › the client’s own office is not offered as a destination —
4.5s - ✅ Client transfers › accepting a transfer sends a note and nothing else —
4.7s - ✅ Client transfers › accepting with no note sends an empty body —
4.4s - ✅ Client transfers › rejecting a transfer is offered while one is pending —
4.2s - ✅ Client transfers › withdrawing is offered from on hold, which is the only way back —
5.3s - ✅ Client transfers › answers to a transfer are not offered when none is pending —
3.5s - ✅ Client staff and default savings account › assigning a member of staff sends the staff id —
4.1s - ✅ Client staff and default savings account › unassigning echoes the current holder back, which the platform requires —
5.2s - ✅ Client staff and default savings account › unassigning is not offered when nobody is assigned —
3.5s - ✅ Client staff and default savings account › the assigned officer is shown on the header —
3.5s - ✅ Client staff and default savings account › setting the default savings account sends the account id —
5.5s - ✅ Undoing a rejection › posts the command name the platform recognises, not the menu identifier —
4.3s
client.spec.ts
- ✅ Client Management › should create a new client —
3.7s
date-picker-revisit.spec.ts
- ✅ Date pickers on revisited forms › office form keeps its pickers usable on every visit —
4.0s - ✅ Date pickers on revisited forms › staff form keeps its pickers usable on every visit —
4.6s - ✅ Date pickers on revisited forms › holiday form keeps its pickers usable on every visit —
4.2s - ✅ Date pickers on revisited forms › teller form keeps its pickers usable on every visit —
3.9s - ✅ Date pickers on revisited forms › accounting closure form keeps its pickers usable on every visit —
4.6s - ✅ Date pickers on revisited forms › floating rate form keeps its pickers usable on every visit —
6.9s(retried 1×)
deployment-customization.spec.ts
- ✅ with no overlay mounted › boots, keeps the shipped branding, and shows the full menu —
1.6s - ✅ with no overlay mounted › does not ask for an overlay this deployment has not declared —
1.7s - ✅ with no overlay mounted › logs no federation parse error on load —
2.5s - ✅ branding › applies colour and density tokens to the document —
1.6s - ✅ branding › recolours Ionic through the same tokens —
1.6s - ✅ branding › renames the product in the header and the tab title —
3.0s - ✅ branding › serves the deployment logo and names it after the deployment —
2.8s - ✅ branding › refuses a fill that cannot carry the white text baked into the stylesheet —
2.0s - ✅ branding › accepts a light accent and derives a dark label for it —
1.6s - ✅ branding › ignores a token outside the published allow-list, and says so —
1.6s - ✅ navigation › hides an entry named by its id —
2.0s - ✅ navigation › does not hide an entry named by its labelKey —
2.6s - ✅ navigation › renames and reorders entries —
1.6s - ✅ navigation › adds an external entry that opens in a new tab —
1.6s - ✅ navigation › nests an added entry under an existing group —
1.6s - ✅ navigation › gates an added entry on permissions like any built-in one —
1.6s - ✅ navigation › drops an external entry with no usable url rather than rendering a dead link —
2.0s - ✅ layering › merges over config.json instead of replacing it —
2.6s - ✅ layering › a malformed overlay leaves the application usable —
1.6s
e2e-journey.spec.ts
- ✅ E2E: Login Flow › should display login page with all required fields —
1.3s - ✅ E2E: Login Flow › should have Sign In button disabled when fields are empty —
1.3s - ✅ E2E: Login Flow › should enable Sign In when credentials are entered —
1.4s - ✅ E2E: Login Flow › should redirect to dashboard after successful login —
2.3s - ✅ E2E: Login Flow › should display language selector on login page —
1.3s - ✅ E2E: Login Flow › should display API endpoint selector with value —
1.3s - ✅ E2E: Dashboard › should display dashboard summary cards —
1.6s - ✅ E2E: Dashboard › should display system health as Online —
1.6s - ✅ E2E: Dashboard › should display pending approvals section —
2.0s - ✅ E2E: Dashboard › should display loan and savings status distribution charts —
2.7s - ✅ E2E: Dashboard › should display system operational status —
1.6s - ✅ E2E: Dashboard › should have header with business date, render time, and logout —
1.6s - ✅ E2E: Dashboard › should have sidebar toggle button —
1.6s - ✅ E2E: Dashboard › should have global search bar in header —
1.6s - ✅ E2E: Dashboard › should have Guide button in header —
2.7s - ✅ E2E: Dashboard › should have dark mode toggle button —
1.6s - ✅ E2E: Sidebar Navigation › should have all main navigation links —
2.1s - ✅ E2E: Sidebar Navigation › should have Products section with sub-links —
1.8s - ✅ E2E: Sidebar Navigation › should have Transfers section with sub-links —
1.7s - ✅ E2E: Sidebar Navigation › should have Accounting section with sub-links —
2.8s - ✅ E2E: Sidebar Navigation › should have Security section —
1.7s - ✅ E2E: Sidebar Navigation › should have Settings section —
1.7s - ✅ E2E: Sidebar Navigation › should have Organization section —
1.7s - ✅ E2E: Sidebar Navigation › should have System section —
1.7s - ✅ E2E: Sidebar Navigation › should navigate to all major pages via sidebar —
4.7s - ✅ E2E: Offices › should display offices list with table —
1.9s - ✅ E2E: Offices › should have Create Office button —
1.9s - ✅ E2E: Offices › should navigate to office create form —
2.1s - ✅ E2E: Offices › should validate office create form - save disabled when empty —
2.1s - ✅ E2E: Offices › should fill office create form and enable save —
2.5s - ✅ E2E: Offices › should cancel office creation and return to list —
3.2s - ✅ E2E: Offices › should have search input on offices page —
1.8s - ✅ E2E: Offices › should show edit button for each office —
2.0s - ✅ E2E: Offices › should have pagination controls —
1.9s - ✅ E2E: Clients › should display clients list page —
2.0s - ✅ E2E: Clients › should display client data in table —
2.0s - ✅ E2E: Clients › should show ACTIVE status badge —
2.8s - ✅ E2E: Clients › should have Create Client button —
1.8s - ✅ E2E: Clients › should show empty state when no clients exist —
1.8s - ✅ E2E: Clients › should have search input and status filter —
1.8s - ✅ E2E: Clients › should have pagination controls —
1.8s - ✅ E2E: Client Creation › should navigate to client create form —
2.1s - ✅ E2E: Client Creation › should display all required client form fields, across the wizard steps —
3.5s - ✅ E2E: Client Creation › should display optional client form fields, across the wizard steps —
2.8s - ✅ E2E: Client Creation › should have Next disabled until the current step is valid —
2.7s - ✅ E2E: Client Creation › should populate office dropdown from API —
2.3s - ✅ E2E: Client Creation › should fill client form and enable save on the last step —
3.3s - ✅ E2E: Client Creation › should submit client and redirect to clients list —
3.4s - ✅ E2E: Client Creation › should cancel client creation and return to clients list —
2.9s - ✅ E2E: Client Creation › should have add office quick-action button —
2.1s - ✅ E2E: Client Creation › should have help icons for form fields —
1.8s - ✅ E2E: Client Creation › should have calendar buttons for date fields —
2.7s - ✅ E2E: Client Creation › should have pre-filled dates in Submitted On and Activation Date —
2.6s - ✅ E2E: Client Creation › should have Active checkbox checked by default —
2.2s - ✅ E2E: Client Creation › should handle Entity legal form showing fullname field —
4.3s - ✅ E2E: Loan Products Page › should display loan products list page —
1.9s - ✅ E2E: Loan Products Page › should have Create Loan Product button —
1.9s - ✅ E2E: Loan Products Page › should display table with correct headers —
1.8s - ✅ E2E: Loan Products Page › should show empty state when no products exist —
1.9s - ✅ E2E: Loan Products Page › should have search input —
1.8s - ✅ E2E: Loan Products Page › should navigate to loan product create form —
3.0s - ✅ E2E: Savings Products Page › should display savings products list page —
1.9s - ✅ E2E: Other Products Pages › Fixed Deposit Products page loads —
1.9s - ✅ E2E: Other Products Pages › Recurring Deposit Products page loads —
1.9s - ✅ E2E: Other Products Pages › Share Products page loads —
1.9s - ✅ E2E: Other Products Pages › Tax Components page loads —
1.8s - ✅ E2E: Other Products Pages › Tax Groups page loads —
1.8s - ✅ E2E: Other Products Pages › Floating Rates page loads —
2.9s - ✅ E2E: Loans Portfolio › should display loans portfolio page —
1.9s - ✅ E2E: Loans Portfolio › should have Create Loan Account button —
1.9s - ✅ E2E: Loans Portfolio › should display table with correct headers —
1.9s - ✅ E2E: Loans Portfolio › should show empty state when no loans exist —
1.8s - ✅ E2E: Loans Portfolio › should have search input —
1.8s - ✅ E2E: Loans Portfolio › should have pagination controls —
2.9s - ✅ E2E: Header & Global Elements › should display Fineract logo and title in header —
1.6s - ✅ E2E: Header & Global Elements › should display logged-in username —
1.6s - ✅ E2E: Header & Global Elements › should display office name for user —
1.6s - ✅ E2E: Header & Global Elements › should have Logout button —
1.7s - ✅ E2E: Header & Global Elements › should have language selector in header —
1.6s - ✅ E2E: Header & Global Elements › should display render time —
2.6s - ✅ E2E: Header & Global Elements › should display business date —
1.6s
feature-coverage.spec.ts
- ✅ Navigation & Sidebar › all main navigation links are visible in sidebar —
2.2s - ✅ Navigation & Sidebar › sidebar navigation routes to correct pages —
2.9s - ✅ Navigation & Sidebar › navigating to /accounting redirects to /accounting/chart-of-accounts —
2.7s - ✅ Navigation & Sidebar › navigating to /organization redirects to /organization/offices —
3.5s - ✅ Navigation & Sidebar › navigating to /system redirects to /system/data-tables —
2.8s - ✅ Navigation & Sidebar › header shows logged-in user info —
2.0s - ✅ Navigation & Sidebar › help tour button is visible and interactive —
1.6s - ✅ Navigation & Sidebar › logout button is visible —
1.6s - ✅ Navigation & Sidebar › language selector is present —
1.6s - ✅ Dashboard › dashboard shows key metrics cards —
2.5s - ✅ Dashboard › dashboard shows pending approvals section —
1.6s - ✅ Dashboard › dashboard shows loan and savings status distribution —
1.6s - ✅ Dashboard › dashboard shows system operational status —
1.6s - ✅ Groups › groups page renders with title —
1.8s - ✅ Groups › groups page has create button —
1.7s - ✅ Centers › centers page renders with title —
2.7s - ✅ Centers › centers page has create button —
1.8s - ✅ Organization › offices page loads with list —
1.8s - ✅ Organization › staff page loads —
1.8s - ✅ Organization › funds page loads —
1.8s - ✅ Organization › payment types page loads —
1.8s - ✅ Accounting › chart of accounts loads —
1.8s - ✅ Accounting › journal entries page loads —
2.0s - ✅ Accounting › accounting closures loads —
2.8s - ✅ Accounting › accounting rules loads —
1.8s - ✅ Accounting › financial activity mappings loads —
1.8s - ✅ Accounting › charges page loads —
1.8s - ✅ Security › users page loads —
1.8s - ✅ Security › roles page loads —
1.8s - ✅ Security › audit logs page loads —
3.0s - ✅ Security › leftover audit trails path lands on audits, not the dashboard —
3.0s - ✅ Products - Loan & Savings › loan products page loads —
1.8s - ✅ Products - Loan & Savings › savings products page loads —
1.8s - ✅ Products - Loan & Savings › tax components page loads —
1.8s - ✅ Products - Loan & Savings › tax groups page loads —
2.7s - ✅ Products - Loan & Savings › floating rates page loads —
1.8s - ✅ Products - Loan & Savings › savings accounts page loads —
1.9s - ✅ Settings › global configurations page loads —
1.8s - ✅ Settings › holidays page loads —
1.8s - ✅ Settings › working days page loads —
1.8s - ✅ System › data tables page loads —
1.8s - ✅ System › bulk import page loads —
1.9s - ✅ System › delinquency page loads —
1.7s - ✅ Tellers › tellers page loads with create button —
1.7s - ✅ Transfers › account transfer page loads —
1.7s - ✅ Transfers › standing instructions page loads —
2.1s - ✅ Transfers › SI history page loads —
1.6s - ✅ Embedded Fintech › asset owners page loads —
1.6s
functional-coverage.spec.ts
- ✅ Client CRUD Workflow › should complete full client creation flow — Person —
3.2s - ✅ Client CRUD Workflow › should complete full client creation flow — Entity —
3.0s - ✅ Client CRUD Workflow › should cancel client creation and return to list —
1.8s - ✅ Client CRUD Workflow › should disable office and legal form in edit mode —
3.1s - ✅ Client View & Status Transitions › should display client view with correct details —
2.5s - ✅ Client View & Status Transitions › should show actions menu for pending client (status 100) —
3.0s - ✅ Client View & Status Transitions › should show actions menu for active client (status 300) —
3.5s - ✅ Client View & Status Transitions › should show actions menu for closed client (status 600) —
3.0s - ✅ Client View & Status Transitions › should show New Account menu for active client —
3.0s - ✅ Client View & Status Transitions › should navigate from client view to client list via breadcrumb —
3.2s - ✅ Client View & Status Transitions › should navigate back from client view —
2.6s - ✅ Client View Tabs › should display all expected tabs on client view —
2.6s - ✅ Client View Tabs › should switch between client view tabs —
3.8s - ✅ Search & Filter Interactions › should have search input on clients page and accept input —
1.7s - ✅ Search & Filter Interactions › should have office filter on groups page —
1.8s - ✅ Search & Filter Interactions › should have office filter on loans page —
1.5s - ✅ Search & Filter Interactions › should have search input on charges page —
1.5s - ✅ Navigation Flow Verification › should navigate full client lifecycle: list → create → back → list —
1.9s - ✅ Navigation Flow Verification › should navigate from dashboard to all top-level pages via sidebar —
3.4s - ✅ Navigation Flow Verification › should go from loan products → create → back —
1.9s - ✅ Office CRUD › should validate office create form — save disabled when empty —
1.7s - ✅ Office CRUD › should validate office create form — save enabled when filled —
2.1s - ✅ Office CRUD › should cancel office creation —
1.9s - ✅ Organization Create Flows › staff create form loads —
1.9s - ✅ Organization Create Flows › funds create form loads —
1.6s - ✅ Organization Create Flows › payment types create form loads —
2.1s - ✅ Accounting CRUD › accounting closure create form loads —
1.7s - ✅ Accounting CRUD › accounting rule create form loads —
1.6s - ✅ Accounting CRUD › financial activity mapping create form loads —
1.6s - ✅ Accounting CRUD › charge create form loads —
1.8s - ✅ Accounting CRUD › chart of accounts create form loads —
1.6s - ✅ Settings CRUD › global configurations page has editable toggle —
2.1s - ✅ Settings CRUD › holiday create form loads —
1.9s - ✅ Settings CRUD › working days page has save button —
2.0s - ✅ System CRUD › data table create form loads —
1.7s - ✅ System CRUD › delinquency page has create buttons for ranges and buckets —
2.0s - ✅ Security CRUD › role create form loads —
1.6s - ✅ Security CRUD › audit logs search form has date range —
2.7s - ✅ Security CRUD › audit logs list exports the loaded page as CSV —
1.8s - ✅ Reporting — Run Report Flow › should navigate to report and verify report parameters —
2.5s - ✅ Teller CRUD › teller create form loads —
1.8s - ✅ Create Office Dialog from Client Form › should open create office dialog from client create form —
2.0s
global-search-nav-shortcuts.spec.ts
- ✅ Global search navigation shortcuts › offers a settings page the entity search cannot return —
1.8s - ✅ Global search navigation shortcuts › navigates to the page behind a shortcut —
2.5s - ✅ Global search navigation shortcuts › keeps the results open across the mousedown that starts a click, so a slow render cannot race the dropdown closed —
2.1s - ✅ Global search navigation shortcuts › withholds a shortcut the user has no permission to reach —
2.3s
global-search-navigation.spec.ts
- ✅ Global search navigation › does not query the backend for a single character —
2.3s - ✅ Global search navigation › sends one request for a phrase typed straight through —
2.8s - ✅ Global search navigation › opens the client behind a client result —
1.9s - ✅ Global search navigation › opens the loan behind a loan result —
2.4s - ✅ Global search navigation › opens the savings account behind a savings result —
1.9s - ✅ Global search navigation › clears the query and closes the dropdown after a selection —
1.8s - ✅ Global search navigation › closes the dropdown when focus leaves without a selection —
1.9s - ✅ Global search navigation › shows nothing rather than an empty dropdown when there are no matches —
2.4s
group-detail.spec.ts
- ✅ Group detail › custom field tabs expose the app keyboard and panel contract at 1280px —
3.5s - ✅ Group detail › custom field tabs expose the app keyboard and panel contract at 390px —
3.0s - ✅ Group detail › asks for the associations, and shows every member rather than only the active ones —
2.6s - ✅ Group detail › closes a group with the reason id and a Fineract-formatted date —
4.7s - ✅ Group detail › does not offer a client who is already a member, and associates the one it does —
3.1s - ✅ Group detail › unassigns a committee role by the assignment id, not the role id —
3.2s - ✅ Group detail › offers a retry when the group cannot be loaded —
3.2s - ✅ Group detail › says so when no closure reason has been defined —
2.8s
guidance-tour.spec.ts
- ✅ the guided tour › highlights the System Status card, not the sidebar, on the dashboard tour —
1.9s - ✅ the guided tour › presents the card as a dialog named and described by its own copy —
1.4s - ✅ the guided tour › announces the step counter as a polite live region —
2.0s - ✅ the guided tour › closes on Escape and hands focus back to the Guide button —
1.9s - ✅ the guided tour › names an unmatched route after itself instead of handing it the dashboard tour —
2.5s - ⏭️ the guided tour at a phone viewport › opens from the overflow menu as a full-width bottom sheet —
1.3s
keyboard-shortcuts.spec.ts
- ✅ Alt+C jumps straight to Create Client from anywhere —
1.6s - ✅ Alt+G jumps to Create Group —
2.0s - ✅ Alt+E jumps to Create Center —
1.6s - ✅ Alt+H opens the guidance tour for the current page —
1.4s - ✅ typing in the global search box does not trigger the Create Client shortcut —
1.4s
list-pagination.spec.ts
- ✅ List pagination › advances through pages and back again —
3.7s - ✅ List pagination › jumps to the last page —
2.6s - ✅ List pagination › returns to the first page when a filter changes —
3.2s - ✅ List pagination › keeps search text when paging and shows the v2 account number —
3.7s - ✅ List pagination › redirects the old search page and exposes only one client navigation item —
3.6s - ✅ List pagination › keeps an account-number search broad and disables unsupported Office sorting —
3.5s - ✅ List pagination › returns to the first page when searching —
3.9s - ✅ Profile › renders the signed-in user rather than hanging on a spinner —
2.6s - ✅ Profile › shows an error when the profile cannot be loaded —
2.5s - ✅ List load failure › reports the failure and reloads when the user retries —
3.3s - ✅ List load failure › calendars: reports the failure and reloads when the user retries —
2.7s - ✅ List load failure › accounting rules: reports the failure and reloads when the user retries —
5.0s
client-empty-account-cta.spec.ts
- ✅ empty account tabs offer the matching creation action —
6.1s
loan-portfolio-summary.spec.ts
- ✅ Loan Portfolio Summary › searching sends entities: loans and shows the grouped results —
3.3s - ✅ Loan Portfolio Summary › Edit Parameters returns from the results view to the filter form —
3.3s - ✅ Loan Portfolio Summary › checking the outstanding-amount filter sends the between min/max values —
4.0s - ✅ Loan Portfolio Summary › switching to a single-value comparison condition sends one value —
3.8s
loan-product-down-payment.spec.ts
- ✅ Loan product down payment and tranches › down payment is offered only for a progressive product —
4.0s - ✅ Loan product down payment and tranches › the percentage and auto-repayment appear only once down payment is on —
5.2s - ✅ Loan product down payment and tranches › multi-tranche disbursement reveals its tranche count, on either engine —
3.1s - ✅ Loan product down payment and tranches › submits the down payment and tranche settings it was given —
4.4s - ✅ Loan product down payment and tranches › does not send a down payment on a cumulative product —
5.9s - ✅ Loan product down payment and tranches › income recognition is offered only for a progressive product —
4.1s - ✅ Loan product down payment and tranches › the capitalisation details appear only once it is on —
4.3s - ✅ Loan product down payment and tranches › submits the income recognition settings it was given —
5.1s - ✅ Loan product down payment and tranches › does not send income recognition on a cumulative product —
5.2s - ✅ Loan product down payment and tranches › interest recalculation reveals its mandatory settings only once it is on —
3.3s - ✅ Loan product down payment and tranches › the rest interval appears only when the frequency is not the repayment period —
15.1s - ✅ Loan product down payment and tranches › submits the interest recalculation settings it was given —
3.3s - ✅ Loan product down payment and tranches › does not send recalculation settings once it is switched back off —
3.4s
loan-schedule-type-gating.spec.ts
- ✅ Loan schedule type gating › a cumulative loan offers neither progressive-only tab, and fetches neither —
3.9s - ✅ Loan schedule type gating › a progressive loan shows only the capabilities it actually has —
3.3s - ✅ Loan schedule type gating › a progressive loan with both capabilities shows both —
3.5s - ✅ Loan schedule type gating › a charged-off loan says so and offers the reversal instead —
3.8s - ✅ Loan schedule type gating › a healthy loan offers charge-off and no marker —
3.4s
loan-servicing-gaps.spec.ts
- ✅ Loan servicing gaps › edits an interest pause through PUT while preserving its existing dates —
3.8s - ✅ Loan servicing gaps › undo approval sends an empty body, without the locale the platform refuses —
4.6s - ✅ Loan servicing gaps › undo approval carries the reason when one was given —
4.2s - ✅ Loan servicing gaps › undo approval is offered only while the loan is approved —
3.5s - ✅ Loan servicing gaps › the delinquency tab shows the summary the loan carries and the tags it fetches —
4.2s - ✅ Loan servicing gaps › the data-only tabs stay hidden when the loan carries nothing for them —
3.4s - ✅ Loan servicing gaps › each data-only tab appears and renders once the loan carries its data —
3.6s - ✅ Loan servicing gaps › disburse to savings sends the date and amount, with the platform date format —
4.5s - ✅ Loan servicing gaps › disburse to savings is offered only on an approved loan —
3.4s - ✅ Loan servicing gaps › unassign loan officer sends the date, and appears only when one is assigned —
4.3s - ✅ Loan servicing gaps › unassign loan officer is hidden on a loan with no officer —
4.1s - ✅ Loan servicing gaps › undo last disbursal appears only on a multi-disbursal loan, and sends an empty body —
4.1s - ✅ Loan servicing gaps › undo last disbursal is hidden on a single-disbursal loan —
3.3s - ✅ Loan servicing gaps › close as rescheduled is offered on an active loan —
3.9s
rbac-feature-flag.spec.ts
- ✅ RBAC permission gating (rbacEnabled = true) › a limited user does not see permission-gated nav groups —
1.5s - ✅ RBAC permission gating (rbacEnabled = true) › a user with READ_USER sees only the Security entries that permission covers —
1.5s - ✅ RBAC permission gating (rbacEnabled = true) › the Security group fills in as the user is granted each of its permissions —
1.5s - ✅ RBAC permission gating (rbacEnabled = true) › a superuser (ALL_FUNCTIONS) sees all permission-gated groups —
1.7s - ✅ RBAC institution-feature gating (rbacEnabled = true) › universal institution shows Groups, Centers and Collection Sheet —
2.2s - ✅ RBAC institution-feature gating (rbacEnabled = true) › commercial bank (cb) hides all group-lending features —
1.6s - ✅ RBAC institution-feature gating (rbacEnabled = true) › credit union (cu) shows Groups but hides Centers and Collection Sheet —
1.6s - ✅ rbacEnabled = false › restores the pre-RBAC behaviour of showing everything —
2.0s - ✅ deployment navigation overrides › removes the entries the deployment names by id, leaving the rest alone —
1.6s - ✅ deployment navigation overrides › ignores a labelKey where an id is required —
2.2s - ✅ deployment navigation overrides › removes them even where RBAC is off —
1.6s
rbac-route-protection.spec.ts
- ✅ route authorization › a superuser reaches every sampled route and sees the full navigation —
13.1s - ✅ route authorization › a single-module user is confined to that module —
9.2s - ✅ route authorization › a read-only user gets the lists and not the forms —
11.4s - ✅ route authorization › a user with an empty permission list is refused everywhere and the app still works —
9.1s - ✅ route authorization › a session carrying no permissions field is treated as carrying none —
4.9s - ✅ route authorization › an unrecognised permission code grants nothing —
5.3s - ✅ route authorization › an unauthenticated visitor is asked to sign in, not told they are forbidden —
5.8s - ✅ route authorization › a deployment with RBAC turned off behaves as it did before the guard —
8.2s - ✅ the Access Denied page › says what happened, under a single heading —
3.2s - ✅ the Access Denied page › moves focus to the heading, since the user did not ask to come here —
3.2s - ✅ the Access Denied page › announces itself politely —
3.8s - ✅ the Access Denied page › names the permissions the screen wanted, so the user can ask for them —
3.1s - ✅ the Access Denied page › offers a way back that the user is allowed to take —
3.2s - ✅ the Access Denied page › is reachable by keyboard alone —
3.9s - ✅ permission feedback › a visible nav entry says what the user can do in that module —
1.5s - ✅ permission feedback › a nav entry carries no hint when there is nothing specific to say —
1.6s - ✅ navigation and routes agree › a hidden menu entry is also refused by URL, and a shown one is not —
6.0s - ✅ navigation and routes agree › the create button is withheld from a user whose create route would refuse them —
3.8s
report-enhancements.spec.ts
- ✅ Report Enhancements, Pagination, and Help Tour › should run report, show paginated data, and download CSV —
3.9s - ✅ Report Enhancements, Pagination, and Help Tour › should trigger guidance help tour and navigate steps —
2.2s
reporting.spec.ts
- ✅ Reporting › should display list of reports —
2.9s - ✅ Reporting › should navigate to run report page —
2.0s
scheduler-jobs.spec.ts
- ✅ Scheduler Jobs bulk run › Run Selected is disabled until a job is checked —
3.9s - ✅ Scheduler Jobs bulk run › Select All checks every job, and running confirms then triggers each one —
4.1s - ✅ Scheduler Jobs bulk run › declining the confirmation runs nothing —
3.4s
two-factor-authentication.spec.ts
- ✅ two-step verification › asks for a code and lets the user in once it is accepted —
1.6s - ✅ two-step verification › sends the token on every later request —
1.6s - ✅ two-step verification › keeps the user on the step when the code is wrong, and says why —
2.4s - ✅ two-step verification › accepts a correct code after a wrong one —
1.7s - ✅ two-step verification › offers the choice when there is more than one channel —
1.3s - ✅ two-step verification › says so when the account has no channel configured —
1.3s - ✅ two-step verification › returns to the choice when the code could not be sent —
1.4s - ✅ two-step verification › does not let a half-finished session reach the application —
4.1s - ✅ two-step verification › backing out returns to the password form —
1.4s - ✅ two-step verification › a deployment without a second factor signs in exactly as before —
1.6s
working-capital-loan-actions.spec.ts
- ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › shows delinquency action history and submits a new one —
4.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › shows breach action history and submits a new one —
5.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › shows near-breach action history and submits a new one —
4.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › attaches and detaches a loan originator —
3.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › adds a new charge and waives an existing one —
5.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › shows rate-change history, amortization schedule, and delinquency range tags —
3.7s - ✅ Working Capital loan delinquency, breach and near-breach actions, and originators › marks the loan as fraud, applies a discount, and changes the payment rate —
5.5s
Slowest 10 — what the shard counts should be tuned against
| Test | Spec | Time |
|---|---|---|
| Loan product down payment and tranches › the rest interval appears only when the frequency is not the repayment period | loan-product-down-payment.spec.ts |
15.1s |
| Runtime accessibility › banner and dashboard content have no blocking violations | accessibility.spec.ts |
14.9s |
| route authorization › a superuser reaches every sampled route and sees the full navigation | rbac-route-protection.spec.ts |
13.1s |
| route authorization › a read-only user gets the lists and not the forms | rbac-route-protection.spec.ts |
11.4s |
| route authorization › a single-module user is confined to that module | rbac-route-protection.spec.ts |
9.2s |
| route authorization › a user with an empty permission list is refused everywhere and the app still works | rbac-route-protection.spec.ts |
9.1s |
| route authorization › a deployment with RBAC turned off behaves as it did before the guard | rbac-route-protection.spec.ts |
8.2s |
| Date pickers on revisited forms › floating rate form keeps its pickers usable on every visit | date-picker-revisit.spec.ts |
6.9s |
| empty account tabs offer the matching creation action | client-empty-account-cta.spec.ts |
6.1s |
| Client form date pickers › stay usable on a second visit to the create form | client-date-picker-revisit.spec.ts |
6.0s |
📼 Download the HTML report, videos and traces — see the playwright-report-mocked artifact.
Generated by run 35907426177 from b7f072e. The run executed a fork branch, so treat its contents as unverified.
E2E — real Fineract🎭 E2E Tests✅ All green — 78 passed · 0 failed · 0 skipped, across 24 spec files in 6m 9s. By spec file
All 78 tests — click to expand
Slowest 10 — what the shard counts should be tuned against
📼 Download the HTML report, videos and traces — see the Generated by run 35907426177 from |
|
@akashchamp I think you should write your name atleast here |
What and why
.clickable-linkhardcoded#3f51b5inclients-list.component.tsandclient-view.component.ts, so it never picked up the dark theme and rendered at 2.43:1 against the#1e1e1ecard — well under the 4.5:1 WCAG AA minimum for normal text. Both are swapped tovar(--primary-text).That's the token
_common.scssalready documents for exactly this case — "a palette colour drawn as text on a page or card surface" — rather than the issue's suggestedvar(--primary-color):--primary-colormeasures 3.15:1 on the light theme's white card (see the comment on it in_common.scss), so that swap would have traded the dark-mode failure for a new light-mode one.--primary-textkeeps light mode's current ~8:1 (#2471a3on white) and brings dark mode to a measured 5.29:1 (#3498dbon#1e1e1e), both comfortably clearing AA. It's the same tokenheader.component.tsandtabs.component.tsalready use for this exact pattern.Closes #575
Verification
npm run lint— no new findings on the changed files (repo-wide exit reflects a pre-existing stale-suppressions condition already present onmain, confirmed by diffing lint output against an unmodified checkout byte-for-byte).npm run format:check— pass.npm run test:unit— pass (247 files, 1518 tests).npm run build— pass (the one budget warning is pre-existing, onheader.component.ts, unrelated to this change).npm run typecheck:e2e— pass.npx playwright test --project=mocked e2e/accessibility.spec.ts— pass, including a new regression test.npx playwright test --project=mocked e2e/client.spec.ts— pass (real client-creation flow through the changed components).New regression test (
e2e/accessibility.spec.ts, "client list links meet color contrast in dark mode"): populates one client row, switches to dark mode via the header toggle — the issue's own repro steps — and asserts axe-core'scolor-contrastcheck passes for.clickable-link. Confirmed both directions manually:Element has insufficient color contrast of 2.42 (foreground color: #3f51b5, background color: #1e1e1e...), matching the issue's own 2.43:1 measurement.Manual verification (mocked UI, dark mode, real browser via Playwright, not just the unit/e2e assertions): read
getComputedStyleon both live.clickable-linkelements after logging in, populating a client row, and toggling dark mode —Full-page screenshots of both states were captured locally during verification (not attached here, to keep the PR diff limited to the actual code/test change) — happy to post them in a comment if a reviewer wants the visual alongside the measured values above.
Not run: the real-backend Playwright project and the CI license/RAT/security jobs — no dependency, license, or generated-file changes here, and this change touches no route the
backendproject's specs cover.AI assistance (optional)
Checklist
src/app/api/.src/app/core/adapters/instead of direct browser globals or imperative third-party APIs. (N/A — no new component/service code; this changes two CSS custom-property references.)🤖 Generated with Claude Code