Skip to content

Playwright full-flow: assert payment actually settles + exercise the KYC route#108

Merged
AquiGorka merged 2 commits into
mainfrom
feat/playwright-kyc-step
Jun 2, 2026
Merged

Playwright full-flow: assert payment actually settles + exercise the KYC route#108
AquiGorka merged 2 commits into
mainfrom
feat/playwright-kyc-step

Conversation

@AquiGorka

Copy link
Copy Markdown
Contributor

Summary

  • Tighten the playwright full-flow suite so it actually fails when the payment doesn't settle. The previous assertions accepted UI scaffolding visibility regardless of whether anything landed protocol-side — the suite passed against backends silently returning errors.
  • Exercise the new public KYC route (#/entities/register?provider=<ppPubkey>) introduced by Migrate all per-PP API calls to URL-scoped paths + KYC submission route provider-console#37: connect Freighter → sign SEP-43/raw challenge → submit name → success card.
  • Fix three pre-existing test bugs the loose assertions had hidden: silent psql-based cleanup, stale council_pps accumulation, and a wrong-pubkey fill in Step 8.

Bugs the loose assertions hid

# Bug Surfaced now via
1 Step 12 asserted only #pos-status visible + non-empty. moonlight-pay writes BOTH success and failure text into that element. Step 12 now reads the text and fails on `failed
2 Step 13 asserted "balance display OR tx list visible" — both render on a freshly-loaded page regardless of any payment. Step 13 now queries pay-platform.transactions for a COMPLETED IN row with wallet_public_key = merchant.publicKey and asserts sum(amount_stroops) > 0.
3 beforeAll used execSync("psql …") to truncate stale rows — psql isn't in the test-runner container, the call no-op'd ("DB cleanup skipped"). Replaced with helpers/db.ts:cleanupPayPlatformDb() using node-pg, now truncating councils, pay_accounts, AND council_pps CASCADE. Adds pg + @types/pg to playwright/package.json.
4 Step 8 filled #pp-pk with profiles.provider.publicKey (the operator wallet pubkey), but provider-console registers a derived PP keypair — pay-platform stored the wrong key and instant-execute 500'd with "PP not found or inactive". New Step 6b discovers the actual PP pubkey via helpers/db.ts:fetchActivePpPublicKey(); Step 8 now fills it with ppPublicKey.
5 provider-platform's add-bundle gate requires the submitter's entity row to be APPROVED. pay-service (the bundle submitter for POS-instant) is auto-created as UNVERIFIED via SEP-10 first-time auth and never promoted — bundle would 403. Step 6b registers pay-service as APPROVED via helpers/register-entity.ts (SEP-43/raw signed-challenge POST to /providers/:pp/entities).

New surface

  • helpers/db.ts — node-pg helpers: cleanup, PP discovery, completed-inbound-stroops query.
  • helpers/register-entity.ts — the SEP-43/raw signed-challenge flow against POST /providers/:pp/entities.
  • New steps:
    • Step 6b (after council approval, before admin onboarding) — discover PP pubkey + register pay-service as APPROVED.
    • Step 13b (after merchant verification) — exercise the new public KYC route end-to-end with the POS user's Freighter wallet.

Test plan

Companion / follow-up

None — this is a test-only PR on local-dev. No changes to platform behaviour.

AquiGorka added 2 commits June 2, 2026 08:43
…UI scaffolding

The full-flow playwright suite was passing on a backend that returned errors:

1. Step 12 asserted only `#pos-status` visible + non-empty. moonlight-pay
   writes both success and failure text into that element, so "Payment
   processing failed: 500" was an unconditional green.
2. Step 13 asserted "merchant page has #balance-display OR #tx-list
   visible" — both are UI scaffolding present on a freshly-loaded page,
   regardless of whether any payment landed.
3. The `beforeAll` cleanup tried to TRUNCATE pay-platform tables via
   `execSync("psql …")` — psql isn't in the test-runner container, so the
   cleanup silently no-op'd with "DB cleanup skipped (psql not available)".
   Deterministic keys + uncleaned `council_pps` left stale PP rows that
   pay-platform randomly picked, 500'ing half the time.
4. Step 8 filled `#pp-pk` with `profiles.provider.publicKey` — the
   operator wallet pubkey, not the derived PP keypair the operator's
   provider-console flow actually registers. pay-platform stored the wrong
   key and instant-execute's bundle submission 500'd with "PP not found
   or inactive".
5. provider-platform's add-bundle gates on the submitter's entity row
   being APPROVED. pay-platform's pay-service identity auto-creates as
   UNVERIFIED via SEP-10 first-time auth and is never promoted — bundle
   submission would 403 if the right PP got picked. The loose Step 12
   assertion hid this entirely.

Fixes:

* Replace the execSync(psql) cleanup with a node-pg client
  (helpers/db.ts:cleanupPayPlatformDb) that authoritatively truncates
  `councils`, `pay_accounts`, AND `council_pps`. Adds `pg` + `@types/pg`
  to playwright/package.json.
* helpers/db.ts:fetchActivePpPublicKey() discovers the derived PP pubkey
  from provider-platform's DB after Step 4. New Step 6b fills it for
  later use, and Step 8 fills `#pp-pk` with it instead of the operator
  pubkey.
* Step 6b also registers pay-service as APPROVED via a new
  helpers/register-entity.ts (the SEP-43/raw signed-challenge flow
  matching provider-platform's POST /providers/:pp/entities). Mirrors
  what a real deployment seeds at install time.
* New Step 13b exercises the public KYC route at
  #/entities/register?provider=<pp_pk> end-to-end (POS user wallet,
  Stellar Wallets Kit modal, signed-challenge submission, success card).
  Independent of the payment flow; smokes the new UI added in
  provider-console#37.
* Step 12 now reads `#pos-status` text and fails on
  `failed|reject|error|expired|insufficient`. Step 13 queries
  pay-platform's `transactions` table directly for a COMPLETED IN
  transaction for the merchant — protocol-level proof that the bundle
  landed, not just that UI scaffolding rendered.

Net result: the suite that previously passed against a backend silently
500'ing now actually verifies the payment settles end-to-end.
…e KYC UI

Previously Step 6b registered pay-service via a direct
fetch(/providers/:pp/entities/challenge) → sign → POST /entities call —
faster but it bypassed the very route this PR exists to validate. Move
the registration onto the public KYC route at
provider-console#/entities/register?provider=<pp> so Step 6b exercises the
real flow: Stellar Wallets Kit modal → Freighter sign-challenge popup →
name submission → success card.

* helpers/keys.ts adds the pay-service identity to DerivedProfiles. The
  ROLES enum already exposed PAY_SERVICE; only the profile return was
  missing.
* The full-flow test creates a payServiceCtx in beforeAll (its own
  Chromium + Freighter, Friendbot-funded by createUserContext) and closes
  it in afterAll.
* Step 6b now opens a page in payServiceCtx, navigates to the KYC route,
  drives the modal-then-popup approval pattern Step 12 already uses, and
  asserts the success card renders.
* Step 13b (the previous POS-user UI smoke) is removed — Step 6b now
  covers the same UI path with a more meaningful identity (the bundle
  submitter), so 13b became redundant.
* helpers/register-entity.ts (API-direct SEP-43/raw flow) is removed — no
  remaining consumers.
@AquiGorka AquiGorka merged commit c018d73 into main Jun 2, 2026
7 of 8 checks passed
@AquiGorka AquiGorka deleted the feat/playwright-kyc-step branch June 2, 2026 13:25
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.

1 participant