[DO NOT MERGE] feat(e2e): replace Mockttp with Go-based mock server#27904
[DO NOT MERGE] feat(e2e): replace Mockttp with Go-based mock server#27904
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Audited all .thenCallback() usages across the test suite to inform the Go MockServer migration strategy. Found 80 usages across 15 files outside of MockServerE2E.ts itself, concentrated in api-mocking/mock-responses/. Chose Option A (defer migration) given the volume and semantic complexity of the dynamic responses involved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…atch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erE2E Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ockttpCompat Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Support asPriority() in CallbackBridge: sort handlers by priority descending so higher-priority handlers always win regardless of registration order, matching mockttp semantics - Track all bridge requests in _seenRequests so getMockedEndpoints() exposes analytics event payloads to getEventsPayloads() - Route metametrics mock through bridge (function response) so segment event bodies are captured and queryable in swap segment tests - Fix STX UUID deduplication: generate unique UUID per submitTransactions call and respond dynamically to batchStatus for each UUID - Restore correct catch-all SSE mock order in swap-mocks.ts (asPriority(1) now properly loses to specific mocks at priority 999) - Go proxy: add callback bridge forwarding (control.go, main.go, proxy.go) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| }[] { | ||
| return this._seenRequests.map(({ url, bodyText }) => ({ | ||
| url, | ||
| method: 'POST', |
There was a problem hiding this comment.
getSeenRequests hardcodes method ignoring actual request method
Medium Severity
CallbackBridge.getSeenRequests() destructures only url and bodyText from each SeenBridgeRequest, discarding the stored method field. It then hardcodes method: 'POST' for every returned request. This means all seen requests are reported as POST regardless of their actual HTTP method, which corrupts the data available to getMockedEndpoints() and downstream analytics event tracking via getEventsPayloads().
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-go@v5 | ||
| with: | ||
| go-version: '1.21' |
There was a problem hiding this comment.
Go version mismatch between CI and go.mod
High Severity
The CI freshness check installs Go 1.21 but tests/mock-server/go.mod declares go 1.24.2. Since Go 1.21+ treats the go directive as a minimum version requirement, the build step will either fail or silently auto-download Go 1.24.2 via toolchain management, making the freshness check unreliable. The go-version in CI needs to match (or exceed) the version in go.mod.
| } | ||
|
|
||
| w.WriteHeader(resp.StatusCode) | ||
| w.Write(respBody) |
There was a problem hiding this comment.
Go forwarder drops all response headers from upstream
Medium Severity
The Forward method reads the upstream response body and writes the status code and body to the client, but never copies response headers (e.g., Content-Type, Transfer-Encoding) from resp.Header to w.Header(). Forwarded responses to real services like Anvil/Ganache lose their Content-Type: application/json header, which can cause the app's HTTP client to misparse RPC responses.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #27904 +/- ##
==========================================
+ Coverage 82.52% 82.54% +0.02%
==========================================
Files 4800 4825 +25
Lines 123748 123877 +129
Branches 27576 27594 +18
==========================================
+ Hits 102122 102255 +133
Misses 14567 14567
+ Partials 7059 7055 -4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…ry check path - Add `thenCallback` and `asPriority` to `MockttpCompatRule` interface so `.forPost(url).asPriority(n).thenCallback(handler)` (used in cardholder-mocks.ts) type-checks correctly. Resolves TS2339 in CI lint:tsc job. - Implement both in `makeRule` via a URL predicate fed to `makeTerminal`, consistent with how `.matching(pred).asPriority(n)` already works. - Fix `git diff --exit-code tests/bin/` → `../bin/` in ci.yml: the check runs from `tests/mock-server/` so the relative path was resolving to a non-existent `tests/mock-server/tests/bin/`, causing `fatal: ambiguous argument` and a false positive failure on every run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on Linux The Go mock server was spawned with --defaults <json> which passes all default mock rules as a single command-line argument. On Linux CI runners, this JSON can exceed the kernel ARG_MAX limit, causing `spawn E2BIG` errors and failing all Android E2E tests. Fix: Remove --defaults from the spawn call entirely. Instead, after the binary becomes healthy, POST each static (non-function) default mock rule individually to the existing POST /mocks control API endpoint. Function-based rules continue to go through the callback bridge as before. Also removes the now-unused _serializeEvents() private method. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: Key changes analyzed:
Since the mock server is the backbone of all E2E tests (every test that uses fixtures relies on it), ALL test tags must be run to validate the new infrastructure works correctly across all feature areas. The risk is high because:
All tags are selected to ensure comprehensive validation of the new infrastructure. Performance Test Selection: |
|
|
✅ E2E Fixture Validation — Schema is up to date |





Description
Replaces the Node.js/Mockttp-based E2E mock server with a compiled Go binary for improved performance, reliability, and CI portability.
What changed and why:
tests/mock-server/): A self-contained Go binary that handles proxy interception, URL/body matching, rule storage (thread-safe), request forwarding with port translation, live request tracking, and default mock deserialization. Built for darwin-arm64, darwin-amd64, linux-arm64, linux-amd64.tests/api-mocking/GoMockServer.ts): Manages the Go binary lifecycle (start/stop/reset) and exposes the same interface as MockServerE2E so call sites need minimal changes.tests/api-mocking/MockttpCompat.ts): A compatibility shim that lets existing test code keep using Mockttp-style.thenReply()/testSpecificMockpatterns while the Go server handles the actual interception.FixtureHelper.tsnow starts/stopsGoMockServerinstead ofMockServerE2E.MOCK_SERVER_CONTROLresource type for the Go server's control port.build.yml): Fails CI if the committed binaries are stale vs the Go source, preventing silent drift.thenCallbackmigration deferred: 80 occurrences across 15 files (polymarket 29, ramps 12, perps 11, etc.) are too risky to convert in one PR. The MockttpCompat shim routesthenCallbackcalls through the existing mockttp layer; each file will be migrated in a domain-specific follow-up.Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
N/A — infrastructure change, no UI impact.
After
N/A — infrastructure change, no UI impact.
Pre-merge author checklist
Pre-merge reviewer checklist
Note
High Risk
High risk because it replaces core E2E network interception with a new Go proxy/control-plane plus a Node callback bridge, and updates many tests/types to the new
MockttpCompatinterface; failures could broadly break smoke/regression suites and CI.Overview
Replaces the E2E mock server implementation: fixtures now start
GoMockServer(a spawned Go binary) instead of the previous Node/Mockttp server, and a newMockttpCompatTypeScript shim preserves the existing.forGet/.forPost(...).thenReply/thenJson/thenCallbackstyle APIs.Adds a Go mock server with a control API and forwarding logic under
tests/mock-server/, including rule storage/matching, live-request tracking, and port-translation forwarding; static default mocks are now posted over HTTP instead of passed via a large CLI arg, and dynamic.thenCallbackmocks run via a Node “callback bridge” that the Go proxy consults first.Updates test infra and a few mocks for compatibility: introduces a dedicated control-port allocation (
MOCK_SERVER_CONTROL), switches many tests/helpers to type againstMockttpCompat, tweaks swap/smart-tx and metametrics mocks to ensure dynamic behavior and request-payload visibility, re-enables the multi-SRP identity smoke test, and adds CI checks to fail when committed mock-server binaries drift from Go sources (plus ignores.worktrees/).Written by Cursor Bugbot for commit 47677ef. This will update automatically on new commits. Configure here.