Skip to content

WEB-1029: [Playwright] Add create-client form-validation E2E spec#3717

Open
devvaansh wants to merge 2 commits into
openMF:devfrom
devvaansh:WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec
Open

WEB-1029: [Playwright] Add create-client form-validation E2E spec#3717
devvaansh wants to merge 2 commits into
openMF:devfrom
devvaansh:WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec

Conversation

@devvaansh

@devvaansh devvaansh commented Jul 14, 2026

Copy link
Copy Markdown
Member

Description

Adds a dedicated Playwright spec that exhaustively covers the client-side validator surface of the create-client form (ClientGeneralStepComponent). The existing CRUD spec (WEB-1019) exercises the happy path end-to-end and a single missing-lastname case; this spec fills the gap by targeting every individual validator in isolation without ever submitting data to Fineract.

Five tests, all pure form-behaviour:

# Scenario Validator / signal exercised
1 Empty office → Preview step absent from DOM required on mat-select; areFormvalids() gate
2 Empty firstname (PERSON) → ng-invalid + mat-form-field-invalid + mat-error required on firstname
3 Empty lastname (PERSON) → same required on lastname
4 activationDate < submittedOnDate → wrapper mat-form-field-invalid; Preview absent matDatepickerMin cross-field validator
5 legalFormId PERSON↔ENTITY toggle → name-control subtree swapped buildDependencies() tearing down firstname/lastname, adding fullname + constitutionId (and back)

Each test includes a recovery assertion: fix the bad input → Preview step must reappear, proving the failure was caused by that specific input alone.

Supporting changes:

  • proxy.localhost.conf.js — target: http → https; pathRewrite removed so Fineract receives the full /fineract-provider/… path
  • package.json — adds start:local script (ng serve --proxy-config proxy.localhost.conf.js)
  • playwright.config.ts — webServer.command updated to npm run start:local

Dependencies: Requires the Fineract Docker stack for the shared setup project auth step (npm run e2e:docker:up). Individual test bodies mock /clients/template and /fieldconfiguration/ADDRESS via page.route() so they are independent of Fineract for the form behaviour they actually test.

Related issues and discussion

#WEB-1029

Screenshots, if any

Screen.Recording.2026-07-15.at.3.07.54.PM.mov

Checklist

  • Commits squashed into one (30d56abf8)
  • Read and understood the contribution guidelines at web-app/.github/CONTRIBUTING.md

Summary by CodeRabbit

Summary by CodeRabbit

  • Development

    • Added a dedicated local start option that launches the app using local proxy settings.
    • Updated local proxy routing to use HTTPS for the fineract-provider path and improved proxy request/error handling for other local API routes.
  • Tests

    • Added Playwright end-to-end coverage for Create Client form validation, ensuring the Preview header and submit call-to-action stay hidden until the form is valid.
    • Validates required fields, date rules, and legal-form-specific sections.

@devvaansh
devvaansh requested a review from a team July 14, 2026 07:48
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "pre_merge_checks"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Adds a local Playwright start command with updated proxy configurations and introduces Create Client E2E coverage for required-field validation, activation-date ordering, and PERSON/ENTITY control switching.

Changes

Local execution and Create Client validation

Layer / File(s) Summary
Proxy handler wiring
proxy.conf.js, proxy.localhost.conf.js
Updates proxy callbacks, upstream logging, HTTPS handling, path rewriting, API key injection, and 502 error responses.
Local Playwright startup
package.json, playwright.config.ts
Adds start:local and uses it for non-CI Playwright runs.
Create Client test harness
playwright/tests/clients/create-client-form-validation.spec.ts
Adds mocked resolver responses, credentials initialization, shared test data, and request interception.
Create Client validation scenarios
playwright/tests/clients/create-client-form-validation.spec.ts
Covers required office, firstname, lastname, activation-date ordering, and dynamic PERSON/ENTITY control switching.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: alberto-art3ch

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding a Playwright create-client form-validation E2E spec.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
package.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
playwright/tests/clients/create-client-form-validation.spec.ts (2)

374-374: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use an accessible locator instead of a CSS attribute selector.

As per path instructions, we should encourage the use of stable selectors. Playwright recommends using user-facing attributes like roles and labels over implementation-tied CSS selectors like formcontrolname. Consider using a role-based locator to improve test stability and ensure accessibility behavior is validated.

♻️ Proposed refactor
-    const constitutionDropdown = page.locator('mat-select[formcontrolname="constitutionId"]');
+    const constitutionDropdown = page.getByRole('combobox', { name: 'Constitution', exact: false });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` at line 374,
Replace the constitutionDropdown CSS locator with an accessible user-facing
locator, preferably the appropriate select role and accessible name, while
preserving the existing interactions and ensuring the test validates the
control’s accessibility semantics.

Source: Path instructions


209-209: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant explicit waits.

Playwright's action methods (click, fill) and web-first assertions (expect(locator).toBeVisible()) automatically wait for the target element to become visible, enabled, and stable. Explicitly calling waitFor({ state: 'visible' }) beforehand is redundant, adds boilerplate, and can introduce brittle timing dependencies. As per path instructions, we should minimize brittle timing dependencies by leveraging Playwright's built-in auto-waiting mechanisms.

  • playwright/tests/clients/create-client-form-validation.spec.ts#L209-L209: Remove the waitFor() call; click() natively handles waiting.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L250-L250: Remove the waitFor() call; fill() natively handles waiting.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L289-L289: Remove the waitFor() call; fill() natively handles waiting.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L306-L306: Remove the waitFor() call; fill() natively handles waiting.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L365-L365: Remove the waitFor() call, and optionally pass { timeout: 10_000 } directly to the subsequent toBeVisible() assertion if an extended timeout is needed.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L382-L382: Remove the waitFor() call, and optionally pass { timeout: 10_000 } directly to the subsequent toBeVisible() assertion.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` at line 209,
Remove the redundant explicit waitFor calls in
playwright/tests/clients/create-client-form-validation.spec.ts at lines 209,
250, 289, 306, 365, and 382. Rely on the subsequent click, fill, or toBeVisible
actions for Playwright auto-waiting; preserve the existing interactions and,
where needed at lines 365 and 382, apply the 10-second timeout directly to
toBeVisible.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Line 374: Replace the constitutionDropdown CSS locator with an accessible
user-facing locator, preferably the appropriate select role and accessible name,
while preserving the existing interactions and ensuring the test validates the
control’s accessibility semantics.
- Line 209: Remove the redundant explicit waitFor calls in
playwright/tests/clients/create-client-form-validation.spec.ts at lines 209,
250, 289, 306, 365, and 382. Rely on the subsequent click, fill, or toBeVisible
actions for Playwright auto-waiting; preserve the existing interactions and,
where needed at lines 365 and 382, apply the 10-second timeout directly to
toBeVisible.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d86e749b-f258-4266-92bb-e6f6ca232916

📥 Commits

Reviewing files that changed from the base of the PR and between 56252bd and 30d56ab.

📒 Files selected for processing (4)
  • package.json
  • playwright.config.ts
  • playwright/tests/clients/create-client-form-validation.spec.ts
  • proxy.localhost.conf.js

IOhacker
IOhacker previously approved these changes Jul 14, 2026

@IOhacker IOhacker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@DavidH-1

Copy link
Copy Markdown
Contributor

@devvaansh needs update to base branch.. If I do it I cant then approve for merge

@devvaansh
devvaansh force-pushed the WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec branch from 30d56ab to b2d4490 Compare July 14, 2026 15:43
@devvaansh

devvaansh commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

@devvaansh needs update to base branch.. If I do it I cant then approve for merge.

Updated - rebased onto the latest dev tip

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
playwright/tests/clients/create-client-form-validation.spec.ts (1)

209-209: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Avoid hardcoded timeouts and rely on Playwright's auto-waiting.

Playwright's action methods (like fill and click) automatically wait for the target element to become visible and actionable. Calling waitFor with a hardcoded timeout introduces a brittle timing dependency, which contradicts the path instructions for *.spec.ts files. If a longer timeout is genuinely needed for this action due to slow rendering, consider extending the action or expect timeouts in the Playwright configuration instead.

♻️ Proposed refactor (can be applied to similar occurrences)
-    await createClientPage.firstnameInput.waitFor({ state: 'visible', timeout: 10_000 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` at line 209,
Remove the hardcoded waitFor call before interacting with firstnameInput in the
create-client form validation test, and rely on the subsequent Playwright
action’s built-in auto-waiting. Do not add another per-action timeout; use the
configured Playwright timeout only if broader adjustment is required.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Line 209: Remove the hardcoded waitFor call before interacting with
firstnameInput in the create-client form validation test, and rely on the
subsequent Playwright action’s built-in auto-waiting. Do not add another
per-action timeout; use the configured Playwright timeout only if broader
adjustment is required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0e311dd6-1c53-4c27-9ef5-59e2d6a3903d

📥 Commits

Reviewing files that changed from the base of the PR and between 30d56ab and b2d4490.

📒 Files selected for processing (4)
  • package.json
  • playwright.config.ts
  • playwright/tests/clients/create-client-form-validation.spec.ts
  • proxy.localhost.conf.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • playwright.config.ts

@devvaansh
devvaansh force-pushed the WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec branch from 8bf299d to 50cdcf4 Compare July 15, 2026 09:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
playwright/tests/clients/create-client-form-validation.spec.ts (1)

183-183: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Scope each validation-error assertion to its target field.

validationErrors.first() can match an unrelated error. Locate mat-error inside the corresponding office, firstname, or lastname wrapper instead.

Proposed adjustment
-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    await expect(officeWrapper.locator('mat-error')).toBeVisible();

-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    await expect(firstnameWrapper.locator('mat-error')).toBeVisible();

-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    await expect(lastnameWrapper.locator('mat-error')).toBeVisible();

As per path instructions, “For tests: encourage clear Arrange-Act-Assert structure, stable selectors, and minimal brittle timing dependencies.”

Also applies to: 229-229, 265-265

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` at line 183,
Update the validation assertions in the create-client form tests to scope each
error lookup to its corresponding office, firstname, or lastname field wrapper
instead of using validationErrors.first(). Preserve the existing visibility
checks while using the field-specific mat-error selector for all three affected
cases.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Around line 20-24: Update the documentation comment for the create-client form
validation spec to remove the claim that it reads the seeded “Head Office” from
live Fineract. Describe the actual prerequisite: the live backend is required,
while resolver requests and office data are mocked through MOCK_CLIENT_TEMPLATE.

In `@proxy.localhost.conf.js`:
- Around line 19-24: Update the proxy configuration around the middleware
options to replace the top-level onProxyReq and onError handlers with an on
object containing proxyReq and error callbacks. Preserve the existing request
logging and custom 502 response behavior within those callbacks.

---

Nitpick comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Line 183: Update the validation assertions in the create-client form tests to
scope each error lookup to its corresponding office, firstname, or lastname
field wrapper instead of using validationErrors.first(). Preserve the existing
visibility checks while using the field-specific mat-error selector for all
three affected cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 115cb90b-c5ec-46ea-b6d3-fb1aa8a2adbd

📥 Commits

Reviewing files that changed from the base of the PR and between b2d4490 and 50cdcf4.

📒 Files selected for processing (4)
  • package.json
  • playwright.config.ts
  • playwright/tests/clients/create-client-form-validation.spec.ts
  • proxy.localhost.conf.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • playwright.config.ts
  • package.json

Comment on lines +20 to +24
* The spec runs as a real E2E test against a live Fineract backend
* (spun up via `npm run e2e:docker:up` or a local Fineract on
* `https://localhost:8443`). It reuses the shared auth setup and
* only reads the seeded `Head Office` name to keep every case
* self-explanatory.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the live-backend requirement documentation.

This says the spec reads a seeded office from live Fineract, but Lines 140-147 mock both resolver requests and MOCK_CLIENT_TEMPLATE supplies the office. Align the comment with the actual test prerequisites.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` around lines
20 - 24, Update the documentation comment for the create-client form validation
spec to remove the claim that it reads the seeded “Head Office” from live
Fineract. Describe the actual prerequisite: the live backend is required, while
resolver requests and office data are mocked through MOCK_CLIENT_TEMPLATE.

Comment thread proxy.localhost.conf.js Outdated
@devvaansh
devvaansh force-pushed the WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec branch from 50cdcf4 to c1fc31d Compare July 15, 2026 10:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
playwright/tests/clients/create-client-form-validation.spec.ts (1)

183-183: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Scope validation errors to the control under test.

Using validationErrors.first() can produce false positives when another control displays an error.

  • playwright/tests/clients/create-client-form-validation.spec.ts#L183-L183: locate the office form-field wrapper and assert its mat-error.
  • playwright/tests/clients/create-client-form-validation.spec.ts#L229-L229: assert firstnameWrapper.locator('mat-error').
  • playwright/tests/clients/create-client-form-validation.spec.ts#L265-L265: assert lastnameWrapper.locator('mat-error').
Proposed changes
-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    const officeWrapper = page.locator('mat-form-field').filter({ has: createClientPage.officeDropdown });
+    await expect(officeWrapper.locator('mat-error')).toBeVisible();

-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    await expect(firstnameWrapper.locator('mat-error')).toBeVisible();

-    await expect(createClientPage.validationErrors.first()).toBeVisible();
+    await expect(lastnameWrapper.locator('mat-error')).toBeVisible();

As per path instructions, tests should use stable selectors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` at line 183,
Scope each validation assertion in create-client-form-validation.spec.ts to the
control being tested: at lines 183, 229, and 265, locate the corresponding
office, firstnameWrapper, and lastnameWrapper form-field wrappers and assert
visibility on their mat-error locator instead of validationErrors.first(). Use
stable selectors throughout.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Line 183: Scope each validation assertion in
create-client-form-validation.spec.ts to the control being tested: at lines 183,
229, and 265, locate the corresponding office, firstnameWrapper, and
lastnameWrapper form-field wrappers and assert visibility on their mat-error
locator instead of validationErrors.first(). Use stable selectors throughout.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 477e0f71-3ab4-42e7-af58-b8984dbcc2c5

📥 Commits

Reviewing files that changed from the base of the PR and between 50cdcf4 and c1fc31d.

📒 Files selected for processing (5)
  • package.json
  • playwright.config.ts
  • playwright/tests/clients/create-client-form-validation.spec.ts
  • proxy.conf.js
  • proxy.localhost.conf.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

@devvaansh
devvaansh force-pushed the WEB-1029-playwright-add-create-client-form-validation-e-2-e-spec branch from 80b24ed to 374b364 Compare July 16, 2026 13:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
proxy.conf.js (2)

26-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Upstream base URL is now duplicated between target: and the log strings.

Each rule's on.proxyReq/on.error handlers hardcode the same upstream base URL (https://demo.mifos.community, https://apis.mifos.community ×2) that presumably already exists in this same block's target: property. Previously the log used this.target; now it's a separate literal, so a future change to target: won't be reflected in the logs, silently producing misleading debug output.

♻️ Suggested fix (illustrated for the fineract-provider rule)
+const FINERACT_PROVIDER_TARGET = 'https://demo.mifos.community';
+
 {
   context: '/fineract-provider',
-  target: 'https://demo.mifos.community',
+  target: FINERACT_PROVIDER_TARGET,
   ...
   on: {
     proxyReq: function (proxyReq, req, res) {
-      console.log('[Proxy] Proxying:', req.method, req.url, '->', 'https://demo.mifos.community' + req.url);
+      console.log('[Proxy] Proxying:', req.method, req.url, '->', FINERACT_PROVIDER_TARGET + req.url);
     },
     error: function (err, req, res) {
       console.error(
         '[Proxy] Error while proxying request:',
         req && req.method,
         req && req.url,
-        '-> https://demo.mifos.community -',
+        '-> ' + FINERACT_PROVIDER_TARGET + ' -',
         err && err.message
       );
       ...

Same pattern applies to the /external-nationalid and /remittance-api rules.

This finding is likely shared with the equivalent pattern in `proxy.localhost.conf.js`; see the consolidated comment.

Also applies to: 57-74, 89-106

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proxy.conf.js` around lines 26 - 42, Update the proxyReq and error handlers
for each affected proxy rule to derive the upstream base URL from that rule’s
target configuration instead of hardcoding URL literals in log messages. Apply
the same change to the fineract-provider, external-nationalid, and
remittance-api handlers, preserving the existing logging and error-response
behavior.

26-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Upstream base URL duplicated between target: config and new on.* log strings, in both proxy files. Migrating off this.target-based logging replaced it with hardcoded literal URLs inside console.log/console.error, so a future change to a rule's target: won't be reflected in its own logs.

  • proxy.conf.js#L26-L106: for /fineract-provider, /external-nationalid, and /remittance-api, extract each rule's upstream base URL into a local const (e.g. FINERACT_PROVIDER_TARGET) declared alongside target:, and reference that constant from the proxyReq/error log calls instead of repeating the literal string.
  • proxy.localhost.conf.js#L49-L103: apply the same fix for /external-nationalid (https://apis.mifos.community) and /remittance-api (http://54.225.231.146:8080).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proxy.conf.js` around lines 26 - 106, The proxy configurations duplicate
upstream URLs in target settings and proxyReq/error logs. In proxy.conf.js lines
26-106, define a local target constant for each /fineract-provider,
/external-nationalid, and /remittance-api rule beside target and use it in both
logging callbacks; apply the same change in proxy.localhost.conf.js lines 49-103
for /external-nationalid and /remittance-api, preserving each rule’s existing
URL.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playwright/tests/clients/create-client-form-validation.spec.ts`:
- Around line 338-387: Complete the round-trip assertion in the test around
createClientPage by filling the required PERSON fields, including firstname and
lastname, after establishing the selected office; then, after switching back
from ENTITY to PERSON, assert the form reaches its valid next-step state (such
as the Preview step being visible). Preserve the existing subtree
presence/absence assertions and keep the test organized as setup, toggles, and
final validity verification.

---

Nitpick comments:
In `@proxy.conf.js`:
- Around line 26-42: Update the proxyReq and error handlers for each affected
proxy rule to derive the upstream base URL from that rule’s target configuration
instead of hardcoding URL literals in log messages. Apply the same change to the
fineract-provider, external-nationalid, and remittance-api handlers, preserving
the existing logging and error-response behavior.
- Around line 26-106: The proxy configurations duplicate upstream URLs in target
settings and proxyReq/error logs. In proxy.conf.js lines 26-106, define a local
target constant for each /fineract-provider, /external-nationalid, and
/remittance-api rule beside target and use it in both logging callbacks; apply
the same change in proxy.localhost.conf.js lines 49-103 for /external-nationalid
and /remittance-api, preserving each rule’s existing URL.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fc15f322-2195-4866-aa58-2d97b11ebca9

📥 Commits

Reviewing files that changed from the base of the PR and between c1fc31d and 351f9c8.

📒 Files selected for processing (5)
  • package.json
  • playwright.config.ts
  • playwright/tests/clients/create-client-form-validation.spec.ts
  • proxy.conf.js
  • proxy.localhost.conf.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • playwright.config.ts

Comment on lines +338 to +387
test('switches the name-control subtree when the legal form toggles between Person and Entity', async ({ page }) => {
// The legalForm switch is a pure client-side re-render. The office
// is filled with the seeded default so the form reaches a valid
// baseline for the final round-trip assertion.
const officeName = SEEDED_HEAD_OFFICE;
const createClientPage = new CreateClientPage(page);

await createClientPage.navigate();
await createClientPage.waitForLoad();

await createClientPage.officeDropdown.click();
await page.getByRole('option', { name: officeName, exact: false }).first().click();

// Default legal form is PERSON (`setClientForm()` patches
// `LegalFormId.PERSON` on init). PERSON should show first/last
// name controls; ENTITY-only controls must be absent.
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);

// Switch to ENTITY. `buildDependencies()` removes firstname /
// middlename / lastname and adds fullname + a
// `clientNonPersonDetails` FormGroup containing a required
// `constitutionId`.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Entity', exact: false }).first().click();

await createClientPage.fullnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.fullnameInput).toBeVisible();
await expect(createClientPage.firstnameInput).toHaveCount(0);
await expect(createClientPage.lastnameInput).toHaveCount(0);
await expect(createClientPage.middlenameInput).toHaveCount(0);

// The clientNonPersonDetails subtree contains a `constitutionId`
// mat-select that only exists in ENTITY mode. Assert it renders
// so a regression that stops swapping the subtree is caught here.
const constitutionDropdown = page.locator('mat-select[formcontrolname="constitutionId"]');
await expect(constitutionDropdown).toBeVisible();

// Switch back to PERSON — the name-control subtree must return
// and the ENTITY-only controls must be torn down.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Person', exact: false }).first().click();

await createClientPage.firstnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);
await expect(constitutionDropdown).toHaveCount(0);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Missing final assertion for the "round-trip" the docstring claims to verify.

The docstring (lines 339-341) says office is filled "so the form reaches a valid baseline for the final round-trip assertion," but firstname/lastname are never filled in this test, and after switching back to PERSON (lines 379-386) there's no assertion that the form is actually valid (e.g., Preview step visible). As written, the test can't catch a regression where switching back to PERSON fails to restore a genuinely valid form state.

✅ Proposed fix to complete the round-trip assertion
     await createClientPage.firstnameInput.waitFor({ state: 'visible', timeout: 10_000 });
     await expect(createClientPage.firstnameInput).toBeVisible();
     await expect(createClientPage.lastnameInput).toBeVisible();
     await expect(createClientPage.fullnameInput).toHaveCount(0);
     await expect(constitutionDropdown).toHaveCount(0);
+
+    // Complete the required PERSON fields to prove the round trip
+    // actually restores a valid, submittable form.
+    await createClientPage.firstnameInput.fill('Devansh');
+    await createClientPage.lastnameInput.fill('Client');
+    await createClientPage.submittedOnDateInput.fill(SUBMITTED_ON_DATE);
+    await createClientPage.submittedOnDateInput.blur();
+    await expect(createClientPage.stepHeader('Preview')).toHaveCount(1);
As per path instructions, "For tests: encourage clear Arrange-Act-Assert structure ... and minimal brittle timing dependencies," the Assert phase implied by this test's own docstring should be completed.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('switches the name-control subtree when the legal form toggles between Person and Entity', async ({ page }) => {
// The legalForm switch is a pure client-side re-render. The office
// is filled with the seeded default so the form reaches a valid
// baseline for the final round-trip assertion.
const officeName = SEEDED_HEAD_OFFICE;
const createClientPage = new CreateClientPage(page);
await createClientPage.navigate();
await createClientPage.waitForLoad();
await createClientPage.officeDropdown.click();
await page.getByRole('option', { name: officeName, exact: false }).first().click();
// Default legal form is PERSON (`setClientForm()` patches
// `LegalFormId.PERSON` on init). PERSON should show first/last
// name controls; ENTITY-only controls must be absent.
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);
// Switch to ENTITY. `buildDependencies()` removes firstname /
// middlename / lastname and adds fullname + a
// `clientNonPersonDetails` FormGroup containing a required
// `constitutionId`.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Entity', exact: false }).first().click();
await createClientPage.fullnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.fullnameInput).toBeVisible();
await expect(createClientPage.firstnameInput).toHaveCount(0);
await expect(createClientPage.lastnameInput).toHaveCount(0);
await expect(createClientPage.middlenameInput).toHaveCount(0);
// The clientNonPersonDetails subtree contains a `constitutionId`
// mat-select that only exists in ENTITY mode. Assert it renders
// so a regression that stops swapping the subtree is caught here.
const constitutionDropdown = page.locator('mat-select[formcontrolname="constitutionId"]');
await expect(constitutionDropdown).toBeVisible();
// Switch back to PERSON — the name-control subtree must return
// and the ENTITY-only controls must be torn down.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Person', exact: false }).first().click();
await createClientPage.firstnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);
await expect(constitutionDropdown).toHaveCount(0);
});
test('switches the name-control subtree when the legal form toggles between Person and Entity', async ({ page }) => {
// The legalForm switch is a pure client-side re-render. The office
// is filled with the seeded default so the form reaches a valid
// baseline for the final round-trip assertion.
const officeName = SEEDED_HEAD_OFFICE;
const createClientPage = new CreateClientPage(page);
await createClientPage.navigate();
await createClientPage.waitForLoad();
await createClientPage.officeDropdown.click();
await page.getByRole('option', { name: officeName, exact: false }).first().click();
// Default legal form is PERSON (`setClientForm()` patches
// `LegalFormId.PERSON` on init). PERSON should show first/last
// name controls; ENTITY-only controls must be absent.
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);
// Switch to ENTITY. `buildDependencies()` removes firstname /
// middlename / lastname and adds fullname + a
// `clientNonPersonDetails` FormGroup containing a required
// `constitutionId`.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Entity', exact: false }).first().click();
await createClientPage.fullnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.fullnameInput).toBeVisible();
await expect(createClientPage.firstnameInput).toHaveCount(0);
await expect(createClientPage.lastnameInput).toHaveCount(0);
await expect(createClientPage.middlenameInput).toHaveCount(0);
// The clientNonPersonDetails subtree contains a `constitutionId`
// mat-select that only exists in ENTITY mode. Assert it renders
// so a regression that stops swapping the subtree is caught here.
const constitutionDropdown = page.locator('mat-select[formcontrolname="constitutionId"]');
await expect(constitutionDropdown).toBeVisible();
// Switch back to PERSON — the name-control subtree must return
// and the ENTITY-only controls must be torn down.
await createClientPage.legalFormDropdown.click();
await page.getByRole('option', { name: 'Person', exact: false }).first().click();
await createClientPage.firstnameInput.waitFor({ state: 'visible', timeout: 10_000 });
await expect(createClientPage.firstnameInput).toBeVisible();
await expect(createClientPage.lastnameInput).toBeVisible();
await expect(createClientPage.fullnameInput).toHaveCount(0);
await expect(constitutionDropdown).toHaveCount(0);
// Complete the required PERSON fields to prove the round trip
// actually restores a valid, submittable form.
await createClientPage.firstnameInput.fill('Devansh');
await createClientPage.lastnameInput.fill('Client');
await createClientPage.submittedOnDateInput.fill(SUBMITTED_ON_DATE);
await createClientPage.submittedOnDateInput.blur();
await expect(createClientPage.stepHeader('Preview')).toHaveCount(1);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright/tests/clients/create-client-form-validation.spec.ts` around lines
338 - 387, Complete the round-trip assertion in the test around createClientPage
by filling the required PERSON fields, including firstname and lastname, after
establishing the selected office; then, after switching back from ENTITY to
PERSON, assert the form reaches its valid next-step state (such as the Preview
step being visible). Preserve the existing subtree presence/absence assertions
and keep the test organized as setup, toggles, and final validity verification.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants