Commit graph

652 commits

Author SHA1 Message Date
johba
70f3336024 Merge pull request 'fix: networkidle still used in stake.ts login flow (#501)' (#508) from fix/issue-501 into master 2026-03-06 17:46:13 +01:00
openhands
962b126e8b fix: networkidle still used in stake.ts login flow (#501)
Replace waitForLoadState('networkidle') in the post-login redirect with
waitForURL('**/app/stake**'). Persistent WebSocket connections prevent
networkidle from ever firing, mirroring the same fix applied to navigate.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 16:11:24 +00:00
johba
1302feef82 Merge pull request 'fix: P&L percentage line understates tax cost when taxDue > 0 (#504)' (#505) from fix/issue-504 into master 2026-03-06 17:02:17 +01:00
openhands
e4ed1474e1 fix: P&L percentage line understates tax cost when taxDue > 0 (#504)
Include taxDue in taxCostPercent computation so the Tax% and Net%
shown in the header P&L line are consistent with the Tax Cost card
and Total row, which already use taxDue + taxPaid.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 15:32:21 +00:00
johba
b2756e8c99 Merge pull request 'fix: Misleading 'Tax Paid' label — value includes unpaid tax due (#374)' (#503) from fix/issue-374 into master 2026-03-06 13:14:51 +01:00
openhands
18a2d4138e fix: Misleading 'Tax Paid' label — value includes unpaid tax due (#374)
taxPaidGes = taxDue + taxPaid, so the displayed value includes both
outstanding tax and historically paid tax. Rename the UI label from
'Tax Paid' to 'Tax Cost' to accurately reflect the combined amount.
Update the matching E2E test selector accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 11:51:45 +00:00
johba
98dac2f67e Merge pull request 'fix: wait_healthy does not fail fast when a service exits or crashes during the health-check window (#387)' (#502) from fix/issue-387 into master 2026-03-06 12:44:33 +01:00
openhands
c943db379f fix: wait_healthy does not fail fast when a service exits or crashes during the health-check window (#387) 2026-03-06 11:20:54 +00:00
johba
4daabe335d Merge pull request 'fix: health-checks.ts reads deployments-local.json directly, bypassing all env var overrides (#412)' (#500) from fix/issue-412 into master 2026-03-06 12:12:42 +01:00
openhands
ab57c5bccd fix: navigateSPA waitForLoadState networkidle times out due to persistent WebSocket connections
Replace waitForLoadState('networkidle') with a comment explaining that callers
must assert on a route-specific element. The SPA keeps persistent WebSocket
connections for blockchain event subscriptions, so networkidle never fires
within the 10 s window, causing spurious TimeoutErrors in 01-acquire-and-stake
and 02-max-stake-all-tax-rates.

Vue Router processes popstate synchronously inside page.evaluate(), so the
route transition has already started by the time evaluate() resolves. Callers'
toBeVisible() assertions (with their own timeouts) serve as the readiness gate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 10:33:04 +00:00
johba
a937f1cb4c docs: scope engineering principles to infra/tests, not frontend polling (#470)
Clarifies that the event-driven engineering principles apply to infrastructure (Docker, scripts, startup/teardown) and test/scenario execution — NOT frontend HTTP API polling.

Frontend polling (e.g. LiveStats → Ponder GraphQL every 30s) is fine. The scalability solution is caching at the proxy layer (`Cache-Control` headers via Caddy), not WebSocket subscriptions.

Relates to #447

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/470
2026-03-06 11:17:50 +01:00
openhands
97a4ef7cd3 fix: health-checks.ts reads deployments-local.json directly, bypassing all env var overrides (#412)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 10:12:28 +00:00
johba
a6c238570f Merge pull request 'fix: Swap completion detection relies on a fragile timing assumption (#415)' (#499) from fix/issue-415 into master 2026-03-06 10:55:54 +01:00
openhands
c0695e101f fix: Swap completion detection relies on a fragile timing assumption (#415)
Replace the try/catch on observing the transient 'Submitting…' button text with a
two-phase disabled→enabled check. The button gains the `disabled` attribute the
moment `swapping=true` and loses it when the swap finishes. By placing
`toBeEnabled({ timeout: 60_000 })` unconditionally after the try block, both
paths (fast RPC where disabled state cycles in <100 ms and slow RPC where it is
clearly observable) now wait for the actual ready state rather than falling
through to only a 2-second static guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 09:27:17 +00:00
johba
5bea99ddf4 Merge pull request 'fix: Dozens of bare waitForTimeout() calls remain throughout e2e tests (#418)' (#496) from fix/issue-418 into master 2026-03-06 10:15:18 +01:00
openhands
3507538fce fix: Dozens of bare waitForTimeout() calls remain throughout e2e tests (#418)
Replace all 10 bare waitForTimeout() calls in tests/e2e/usertest/helpers.ts
with proper event-driven Playwright waits per AGENTS.md Engineering Principle #3
("replace when touched"):

connectWallet():
- Remove 500ms resize-event sleep: connectButton.isVisible({ timeout: 5_000 })
  already waits for the layout to settle after the resize event
- Remove 2000ms "connector init" sleep: the subsequent isVisible check was
  already event-driven
- Replace 2x 1000ms panel-animation sleeps with
  injectedConnector.waitFor({ state: 'visible' }) — the .connectors-element
  appearing is the exact observable DOM event
- Remove 2x 2000ms "handshake" sleeps: walletDisplay.waitFor() at the end of
  the function is the correct gate for connection completion

attemptStake():
- Remove 3000ms post-goto sleep: tokenAmountSlider.waitFor() at the next line
  is the correct page-load gate
- Remove 2x 500ms debounce sleeps after fill/select: stakeButton.waitFor()
  downstream is the correct reactive-state gate
- Remove 3000ms post-transaction sleep: the button returning to "Stake" text
  (waitFor at line 619) is already the correct transaction-completion gate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 08:47:22 +00:00
openhands
92fa38e328 fix: Dozens of bare waitForTimeout() calls remain throughout e2e tests (#418)
Add eslint-disable-next-line no-restricted-syntax comments with
justification to the 10 bare waitForTimeout() calls in
tests/e2e/usertest/helpers.ts.

All waitForTimeout calls in the spec files (01–06 and all usertest
specs) were already properly documented after PR #417. helpers.ts was
the only remaining file with bare calls:
- 6 in connectWallet(): wallet connector panel animation and
  connection handshake have no observable DOM event to await
- 4 in attemptStake(): Ponder indexing lag, debounced form handlers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 08:15:48 +00:00
johba
524a6a66d9 Merge pull request 'fix: webapp-entrypoint.sh CI path bypasses contracts.env sourcing without documentation (#422)' (#491) from fix/issue-422 into master 2026-03-06 09:03:38 +01:00
openhands
34dbd48654 ci: retrigger after infra failure 2026-03-06 07:34:50 +00:00
openhands
6c54a92657 fix: webapp-entrypoint.sh CI path bypasses contracts.env sourcing without documentation (#422)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 07:24:54 +00:00
openhands
d301f75523 fix: webapp-entrypoint.sh CI path bypasses contracts.env sourcing without documentation (#422)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 07:01:07 +00:00
johba
8c893d68e1 Merge pull request 'fix: total computed has no undefined guard — shows initial stake amount during loading (#424)' (#488) from fix/issue-424 into master 2026-03-06 07:54:19 +01:00
openhands
0063e94007 fix: \total\ computed has no undefined guard — shows initial stake amount during loading (#424)
When profit or taxPaidGes were undefined (data still loading), the
computed returned props.amount due to the ?? 0 fallbacks. The computed
now returns undefined until both values are loaded, and the template
guard is simplified to total !== undefined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 06:31:49 +00:00
johba
37d7339fbf Merge pull request 'fix: commaNumber silently returns '0' for NaN and falsy values (#427)' (#485) from fix/issue-427 into master 2026-03-06 07:20:27 +01:00
openhands
04fbca939f fix: \commaNumber\ silently returns '0' for NaN and falsy values (#427)
Replace truthiness guard with Number.isFinite() so NaN and Infinity are
explicitly rejected rather than silently masked. Zero is now handled by
toLocaleString, which returns '0' correctly. Add test cases for NaN and
Infinity.
2026-03-06 05:51:50 +00:00
johba
67c0ed953a Merge pull request 'fix: getErrorMessage silently ignores viem's shortMessage (#430)' (#484) from fix/issue-430 into master 2026-03-06 06:41:25 +01:00
openhands
fc008fb9c1 fix: correct TypeScript cast for shortMessage in getErrorMessage (#430)
The direct cast of Error to Record<string, unknown> is rejected by
TypeScript because the types don't sufficiently overlap. Cast via
unknown first to satisfy the compiler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 05:13:27 +00:00
openhands
a8a5d1ab93 fix: getErrorMessage silently ignores viem's shortMessage (#430)
viem's BaseError extends Error, so the instanceof Error branch was
firing and returning error.message before the isRecord branch could
check shortMessage. Check shortMessage first inside instanceof Error
so terse viem messages are shown to users instead of verbose full ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 05:02:10 +00:00
johba
d9329d70b3 Merge pull request 'fix: CollapseActive.vue: fixed 5-second delay in unstakePosition() should be replaced with polling (#448)' (#480) from fix/issue-448 into master 2026-03-06 05:52:04 +01:00
openhands
4aee33ad74 ci: retrigger after infra failure 2026-03-06 04:29:45 +00:00
openhands
372f49f6a5 fix: wrap unstakePosition polling loop in try/finally to prevent loading lock (#448)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 04:18:52 +00:00
openhands
e85ff85950 fix: CollapseActive.vue: fixed 5-second delay in unstakePosition() should be replaced with polling (#448)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 03:44:04 +00:00
johba
becfb98198 Merge pull request 'fix: Add cache headers to Ponder GraphQL proxy in Caddy (#447)' (#477) from fix/issue-447 into master 2026-03-06 04:32:02 +01:00
openhands
8b39bf3000 fix: Add cache headers to Ponder GraphQL proxy in Caddy (#447) 2026-03-06 03:07:24 +00:00
openhands
1abe51b348 fix: Add cache headers to Ponder GraphQL proxy in Caddy (#447) 2026-03-06 02:30:56 +00:00
johba
b711860152 Merge pull request 'fix: sellAllKrk uses amountOutMinimum: 0n with no throw on 0 output (#450)' (#474) from fix/issue-450 into master 2026-03-06 03:25:33 +01:00
openhands
d0e651ffc9 fix: sellAllKrk uses amountOutMinimum: 0n with no throw on 0 output (#450)
Replace console.warn with a thrown Error when wethReceived <= 0n so any
caller without a return-value check is protected, not just always-leave.spec.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 01:51:23 +00:00
johba
61f9e07e60 Merge pull request 'fix: E2E test files use file-level eslint-disable for no-restricted-syntax, suppressing all future rules in that group (#451)' (#473) from fix/issue-451 into master 2026-03-06 02:44:16 +01:00
openhands
6b7ac781fb fix: E2E test files use file-level eslint-disable for no-restricted-syntax, suppressing all future rules in that group (#451)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 01:12:26 +00:00
johba
1ceb6647f7 Merge pull request 'fix: KRK fees to feeDestination undocumented (#458)' (#471) from fix/issue-458 into master 2026-03-06 02:01:28 +01:00
openhands
e09a995733 fix: KRK fees to feeDestination undocumented (#458) 2026-03-06 00:32:18 +00:00
openhands
496a464baf fix: KRK fees to feeDestination undocumented (#458) 2026-03-06 00:01:28 +00:00
johba
7dc0c52664 Merge pull request 'fix: e2e test uses getByRole('combobox', { name: 'Tax' }) against a label 'Position Cost (Tax Rate)' (#467)' (#469) from fix/issue-467 into master 2026-03-06 00:10:42 +01:00
openhands
660204ac14 fix: e2e test uses getByRole('combobox', { name: 'Tax' }) against a label 'Position Cost (Tax Rate)' (#467) 2026-03-05 22:41:00 +00:00
johba
89134800c2 Merge pull request 'fix: evaluator: add stakeKrk and unstakeKrk browser helpers (#460)' (#466) from fix/issue-460 into master 2026-03-05 16:34:25 +01:00
openhands
4e6182acc6 fix: evaluator: add stakeKrk and unstakeKrk browser helpers (#460)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 15:09:54 +00:00
openhands
ad9a113a9c fix: evaluator: add stakeKrk and unstakeKrk browser helpers (#460) 2026-03-05 14:38:13 +00:00
openhands
b7bbbb9b89 fix: evaluator: add stakeKrk and unstakeKrk browser helpers (#460)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 14:37:56 +00:00
johba
0b5752ca52 Merge pull request 'fix: evaluator: add sellKrk browser helper (uses sell widget from #456) (#461)' (#465) from fix/issue-461 into master 2026-03-05 15:25:47 +01:00
openhands
c891b3c617 fix: address review findings in sellKrk helper
- Fix max-button race: wait for input to be non-empty after clicking Max
  (setMax is async, composable calls loadKrkBalance() before setting value)
- Add on-chain confirmation via WETH Transfer event polling (mirrors buyKrk)
  so balance query happens after the swap is mined, not just UI-idle
- Use Pick<SellConfig, 'rpcUrl' | 'accountAddress'> since krkAddress is unused
- Add page heading assertion after navigate (consistent with buyKrk)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 13:58:14 +00:00