test(e2e): cross-chain swaps - #7990
Conversation
…wswap into e2e/cross-chain-swaps
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThe PR adds cross-chain Playwright coverage for NEAR Intents and Bungee. It adds bridge fixtures and mocks, SocketVerifier interception, route-panel assertions, E2E feature-flag controls, and workflow RPC configuration. ChangesCross-chain E2E coverage
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant CrossChainSwapTests
participant SwapPage
participant BungeeMock
participant NearIntentsMock
participant mockSocketVerifier
CrossChainSwapTests->>SwapPage: configure provider and start swap
SwapPage->>BungeeMock: request quote and bridge data
SwapPage->>NearIntentsMock: request tokens and quote
SwapPage->>mockSocketVerifier: verify SocketVerifier calls
mockSocketVerifier-->>SwapPage: return mocked or patched RPC results
BungeeMock-->>SwapPage: return scaled quote and transaction data
NearIntentsMock-->>SwapPage: return fixture-backed quote and status
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
…wswap into e2e/cross-chain-swaps # Conflicts: # apps/cowswap-e2e-tests/src/pages/SwapPage.ts
…wswap into e2e/cross-chain-swaps
…wswap into e2e/cross-chain-swaps # Conflicts: # apps/cowswap-e2e-tests/src/fixtures/shared.ts # apps/cowswap-e2e-tests/src/mocks/bungee.ts # apps/cowswap-e2e-tests/src/mocks/nearIntents.ts
…wswap into e2e/cross-chain-swaps
…wswap into e2e/cross-chain-swaps
…wswap into e2e/cross-chain-swaps
shoom3301
left a comment
There was a problem hiding this comment.
✅ AI Review (Claude Sonnet 5, worked ~45m): security hardening finding, addressed in latest commit
Finding: [NON-BLOCKING] bridgingSdk.ts's e2e signature bypass shipped as live code in every deployed bundle — now fixed
- Lifecycle:
fixed-by-current-pr(wasout-of-scope-hardening/ P3 at review time) - Location:
apps/cowswap-frontend/src/tradingSdk/bridgingSdk.ts:44 - The e2e-only
recoverDepositAddressstub (bypasses Near Intents' real ECDSA attestation check) was gated only by the runtime globalwindow.__COWSWAP_E2E__. That flag is only ever set by the Playwright fixture (apps/cowswap-e2e-tests/src/fixtures/shared.ts), so it isn't remotely triggerable — but the branch still shipped as live, unstripped code in every production/staging/preview bundle, keyed on a client-side value with no build-time gate. - Fixed in
a45006bd2: the condition is nowprocess.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && window.__COWSWAP_E2E__. Every deployed build (prod, staging, Vercel preview) runs the production webpack build (NODE_ENV === 'production'), so Terser now dead-code-eliminates the whole branch — the bypass has no live path in any shipped bundle. Verified:tsc/eslintclean, and CC-01/02/26/27 (the Near-Intents-dependent cross-chain specs) still pass against a freshly started dev server (NODE_ENV === 'development') with the fix in place.
Review scope and related context
- Ran a targeted
security-reviewpass on this finding specifically (triggered by the diff touching bridge-recipient signature verification). Attempted DeepSec PR-mode via the fast-path helper scoped to this PR's 19 changed files; it resolved dependencies but failed at the AI-agent step (Missing AI credentials for --agent codex, exit 1, no artifact) — blocked on missingAI_GATEWAY_API_KEY/OPENAI_API_KEYin this environment. The verdict below rests on code inspection (traced the realrecoverDepositAddresscheck in@cowprotocol/sdk-bridging's compiled output) plus a targeted Playwright re-run, not DeepSec. - Confirmed via repo-wide grep that
window.__COWSWAP_E2E__'s only writer is the Playwright fixture; no URL param, extension hook, or other production code path sets it. - Noted for context, not filed separately:
libs/common-hooks/src/useFeatureFlags.tsuses the samewindow.__COWSWAP_E2E_FEATURE_FLAGS__pattern without theNODE_ENVguard. Lower stakes (overrides feature-flag values, not a cryptographic check) so I didn't block on it, but applying the same guard there would be a small, free consistency win if the author wants it in this PR. - No other blocking findings surfaced from the CoW institutional-memory scan (wallet storage, Safe, permit, widget/CSP, balances-watcher) — this PR's diff doesn't touch any of those surfaces.
🤖 Prompt for AI agents
This finding is already fixed on the current PR head (commit a45006bd2). No action needed unless
extending the same NODE_ENV production-build guard to libs/common-hooks/src/useFeatureFlags.ts's
window.__COWSWAP_E2E_FEATURE_FLAGS__ check, which currently lacks it (lower severity: overrides
feature-flag values, not a signature check).
Generated using the pr-review skill from the CoW Protocol skills repo.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (8)
apps/cowswap-frontend/src/tradingSdk/bridgingSdk.ts (2)
44-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFix the garbled sentence in the comment.
Line 48 merges two clauses: "Only the local/CI dev server e2e tests actually run against (
NODE_ENV === 'development') ever evaluates it". The sentence is unreadable.📝 Proposed wording
-// there and gets stripped by Terser. Only the local/CI dev server e2e tests actually run against -// (`NODE_ENV === 'development'`) ever evaluates it, so a real deployed bundle has no live code path +// there and gets stripped by Terser. Only the local/CI dev server that e2e tests run against +// (`NODE_ENV === 'development'`) evaluates it, so a real deployed bundle has no live code path // that can disable this signature check, no matter what `window.__COWSWAP_E2E__` is set to.🤖 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 `@apps/cowswap-frontend/src/tradingSdk/bridgingSdk.ts` around lines 44 - 49, Rewrite the garbled sentence in the comment near the NODE_ENV check for clear grammar, preserving the meaning that only local or CI development-server E2E tests run with NODE_ENV === 'development' and evaluate this branch.
35-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe duplicated attestor address can drift from the SDK value.
NEAR_INTENTS_E2E_ATTESTATOR_ADDRESScopies a non-exported SDK constant. If the SDK rotates the attestor address, this copy stays stale and the bypass returns a wrong address without any failure signal. Consider asserting the value in an e2e test, or deriving it from the SDK if any export path exists.🤖 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 `@apps/cowswap-frontend/src/tradingSdk/bridgingSdk.ts` around lines 35 - 37, The duplicated NEAR Intents attestor address in NEAR_INTENTS_E2E_ATTESTATOR_ADDRESS can become stale when the SDK value changes. Derive this address from an available `@cowprotocol/sdk-bridging` export if possible; otherwise add an e2e assertion that verifies NEAR_INTENTS_E2E_ATTESTATOR_ADDRESS matches the SDK’s ATTESTATOR_ADDRESS.libs/common-hooks/src/useFeatureFlags.ts (1)
22-28: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueThe override branch returns a new object on every render.
When
__COWSWAP_E2E_FEATURE_FLAGS__is set, each render produces a fresh object. Consumers that put the result in a dependency array or a memo comparison then re-run on every render. This only affects e2e runs, but it can change timing-sensitive behavior that the tests assert on. Wrapping the merge inuseMemokeyed onflagskeeps the identity stable.🤖 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 `@libs/common-hooks/src/useFeatureFlags.ts` around lines 22 - 28, Update the override branch in useFeatureFlags to memoize the merged feature flags with useMemo, using flags as the dependency so the result remains stable across renders when the e2e override is unchanged.apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts (1)
8-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConfirm the stubbed selectors match the current SDK functions.
The selectors
0xeee54b0dand0xf75d4a35are hardcoded, and the comment notes a typo in the real signature (validateRotueId). If the SDK changes either signature, the stub silently stops matching and Bungee tests fail against a real RPC withRouteIdNotFound(). Deriving the selectors with viem'stoFunctionSelectorfrom the signature strings makes the mismatch visible in the source.🤖 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 `@apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts` around lines 8 - 11, Update STUBBED_SELECTORS to derive both values with viem’s toFunctionSelector from the exact current SDK signatures, including the validateRotueId spelling, instead of hardcoding hexadecimal selectors. Keep the existing selector-matching behavior unchanged while making signature changes visible in the source.apps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.ts (1)
52-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffConsider a data-testid instead of matching styled-components class hashes.
detailContentwalks to an ancestor whose class contains__Label-. That string comes frombabel-plugin-styled-components'sdisplayNameoutput. If the build disablesdisplayName(common in production-mode builds) or the plugin changes its naming, every row locator here breaks at once with no clear signal. Addingdata-testidtoConfirmDetailsItem'sLabel/Contentwould remove the coupling to build tooling.🤖 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 `@apps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.ts` around lines 52 - 64, Replace the styled-components class selector in BridgeRoutePanel.detailContent with stable data-testid attributes added to ConfirmDetailsItem’s Label and Content elements. Locate each matching label by its test ID, then select the corresponding content element while preserving exact text matching and occurrence handling; update amountValue only as needed to use the revised detailContent flow.apps/cowswap-e2e-tests/src/mocks/bungee.ts (2)
50-50: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueBoth bridge mock installers discard the
context.route()promise.context.route()returns aPromise<void>. Each installer applies thevoidoperator to it, so a registration rejection is swallowed and the handler is not guaranteed to be installed before the page starts loading.
apps/cowswap-e2e-tests/src/mocks/bungee.ts#L50-L50: makeinstallBungeereturnPromise<BungeeMock>andawait context.route(...).apps/cowswap-e2e-tests/src/mocks/nearIntents.ts#L31-L31: makeinstallNearIntentsreturnPromise<NearIntentsMock>andawait context.route(...).If you change both signatures, also
awaitthe two calls inapps/cowswap-e2e-tests/src/fixtures/shared.tsat Lines 130-131. Confirm the convention used by the existing mock installers first, so the new mocks stay consistent with the suite.🤖 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 `@apps/cowswap-e2e-tests/src/mocks/bungee.ts` at line 50, Update installBungee in apps/cowswap-e2e-tests/src/mocks/bungee.ts at line 50 to return Promise<BungeeMock> and await context.route(...). Update installNearIntents in apps/cowswap-e2e-tests/src/mocks/nearIntents.ts at line 31 to return Promise<NearIntentsMock> and await context.route(...). Then await both installer calls in apps/cowswap-e2e-tests/src/fixtures/shared.ts at lines 130-131, following the existing mock-installer convention.
138-182: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
toUsdloses precision for tokens with 18 decimals.
Number(amount)is used on a raw base-unit string. For the committed USDC fixture (6 decimals) the value stays well inside the safe integer range, so the current behavior is correct. If a future fixture uses an 18-decimal token, a scaled base-unit amount exceedsNumber.MAX_SAFE_INTEGERand the derived USD values silently drift.The
valueInUsdfields only feed display and price-impact math in the mock, so this is not a current defect. Consider a short comment recording the 6-decimal assumption, so a later 18-decimal fixture does not hit a silent rounding trap.🤖 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 `@apps/cowswap-e2e-tests/src/mocks/bungee.ts` around lines 138 - 182, Add a concise comment adjacent to toUsd documenting that its Number-based conversion assumes fixture token amounts, such as the committed USDC data, remain within safe integer precision (6 decimals), and that 18-decimal amounts may lose precision. Do not change the current conversion behavior.apps/cowswap-e2e-tests/src/mocks/nearIntents.ts (1)
6-10: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
FIXTURES_DIRandloadFixtureduplicatebungee.ts.Both constants and the helper are byte-identical to
apps/cowswap-e2e-tests/src/mocks/bungee.tsLines 6-10. Extract them into one shared module, for examplesrc/mocks/bridge/loadFixture.ts, and import it in both mocks.As per coding guidelines: "Code MUST prefer existing shared utilities and hooks over creating near-duplicates."
♻️ Proposed shared helper
Add
apps/cowswap-e2e-tests/src/mocks/bridge/loadFixture.ts:import { readFileSync } from 'node:fs' import path from 'node:path' const FIXTURES_DIR = path.join(__dirname, 'fixtures') export function loadFixture(name: string): unknown { return JSON.parse(readFileSync(path.join(FIXTURES_DIR, name), 'utf8')) as unknown }Then in
nearIntents.ts:-import { readFileSync } from 'node:fs' -import path from 'node:path' - import type { BrowserContext, Route } from '`@playwright/test`' -const FIXTURES_DIR = path.join(__dirname, 'bridge', 'fixtures') - -function loadFixture(name: string): unknown { - return JSON.parse(readFileSync(path.join(FIXTURES_DIR, name), 'utf8')) as unknown -} +import { loadFixture } from './bridge/loadFixture'🤖 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 `@apps/cowswap-e2e-tests/src/mocks/nearIntents.ts` around lines 6 - 10, Extract the duplicated FIXTURES_DIR and loadFixture logic from nearIntents.ts and bungee.ts into a shared bridge/loadFixture module, preserving the existing fixture path and JSON parsing behavior. Export loadFixture from the shared module and update both mocks to import and reuse it, removing their local constants, helper definitions, and now-unused imports.Source: Coding guidelines
🤖 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 `@apps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.ts`:
- Line 22: Update the expandToggle initialization in BridgeRoutePanel to target
the trade-details accordion specifically, using its container selector or a
stable TradeDetailsAccordion hook instead of the page-wide [aria-expanded]
locator; preserve selecting the accordion’s expand control.
In `@apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts`:
- Around line 121-125: Replace address string comparisons with areAddressesEqual
from `@cowprotocol/cow-sdk`: in
apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts lines 121-125, update
the comparison in the STUBBED_SELECTORS branch; in
apps/cowswap-e2e-tests/src/tests/cross-chain-swaps.spec.ts lines 188-191, update
the recipient assertion to expect areAddressesEqual(swapRecipientAddress,
wallet.address) to be false. Add or reuse the required import in both files.
- Around line 71-74: The SocketVerifier route must be installed before
navigation proceeds. In apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts
lines 71-74, update mockSocketVerifier to return Promise<void> and await
context.route(...); in
apps/cowswap-e2e-tests/src/tests/cross-chain-swaps.spec.ts lines 74-85, await
the mockSocketVerifier(context) call.
In `@apps/cowswap-e2e-tests/src/tests/cross-chain-swaps.spec.ts`:
- Around line 545-547: Update the parity assertions in the cross-chain swap test
to read the form value once, then compare the route-panel value using a retrying
matcher rather than a second one-time getAttribute snapshot. Apply the same
pattern to the bridgeMinToDeposit/swapMinToReceive assertion, preserving the
existing expected-value relationships.
---
Nitpick comments:
In `@apps/cowswap-e2e-tests/src/mocks/bungee.ts`:
- Line 50: Update installBungee in apps/cowswap-e2e-tests/src/mocks/bungee.ts at
line 50 to return Promise<BungeeMock> and await context.route(...). Update
installNearIntents in apps/cowswap-e2e-tests/src/mocks/nearIntents.ts at line 31
to return Promise<NearIntentsMock> and await context.route(...). Then await both
installer calls in apps/cowswap-e2e-tests/src/fixtures/shared.ts at lines
130-131, following the existing mock-installer convention.
- Around line 138-182: Add a concise comment adjacent to toUsd documenting that
its Number-based conversion assumes fixture token amounts, such as the committed
USDC data, remain within safe integer precision (6 decimals), and that
18-decimal amounts may lose precision. Do not change the current conversion
behavior.
In `@apps/cowswap-e2e-tests/src/mocks/nearIntents.ts`:
- Around line 6-10: Extract the duplicated FIXTURES_DIR and loadFixture logic
from nearIntents.ts and bungee.ts into a shared bridge/loadFixture module,
preserving the existing fixture path and JSON parsing behavior. Export
loadFixture from the shared module and update both mocks to import and reuse it,
removing their local constants, helper definitions, and now-unused imports.
In `@apps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.ts`:
- Around line 52-64: Replace the styled-components class selector in
BridgeRoutePanel.detailContent with stable data-testid attributes added to
ConfirmDetailsItem’s Label and Content elements. Locate each matching label by
its test ID, then select the corresponding content element while preserving
exact text matching and occurrence handling; update amountValue only as needed
to use the revised detailContent flow.
In `@apps/cowswap-e2e-tests/src/support/mockSocketVerifier.ts`:
- Around line 8-11: Update STUBBED_SELECTORS to derive both values with viem’s
toFunctionSelector from the exact current SDK signatures, including the
validateRotueId spelling, instead of hardcoding hexadecimal selectors. Keep the
existing selector-matching behavior unchanged while making signature changes
visible in the source.
In `@apps/cowswap-frontend/src/tradingSdk/bridgingSdk.ts`:
- Around line 44-49: Rewrite the garbled sentence in the comment near the
NODE_ENV check for clear grammar, preserving the meaning that only local or CI
development-server E2E tests run with NODE_ENV === 'development' and evaluate
this branch.
- Around line 35-37: The duplicated NEAR Intents attestor address in
NEAR_INTENTS_E2E_ATTESTATOR_ADDRESS can become stale when the SDK value changes.
Derive this address from an available `@cowprotocol/sdk-bridging` export if
possible; otherwise add an e2e assertion that verifies
NEAR_INTENTS_E2E_ATTESTATOR_ADDRESS matches the SDK’s ATTESTATOR_ADDRESS.
In `@libs/common-hooks/src/useFeatureFlags.ts`:
- Around line 22-28: Update the override branch in useFeatureFlags to memoize
the merged feature flags with useMemo, using flags as the dependency so the
result remains stable across renders when the e2e override is unchanged.
🪄 Autofix
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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 67662252-c96a-4e15-ae65-c1988ffea65c
📒 Files selected for processing (19)
.github/workflows/e2e-pw-nightly.yml.github/workflows/e2e-pw-smoke.ymlapps/cowswap-e2e-tests/.env.exampleapps/cowswap-e2e-tests/AGENTS.mdapps/cowswap-e2e-tests/src/fixtures/shared.tsapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/bungee-dest-tokens.jsonapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/bungee-intermediate-tokens.jsonapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/bungee-quote.jsonapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/near-attestation.jsonapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/near-dest-tokens.jsonapps/cowswap-e2e-tests/src/mocks/bridge/fixtures/near-quote.jsonapps/cowswap-e2e-tests/src/mocks/bungee.tsapps/cowswap-e2e-tests/src/mocks/nearIntents.tsapps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.tsapps/cowswap-e2e-tests/src/pages/SwapPage.tsapps/cowswap-e2e-tests/src/support/mockSocketVerifier.tsapps/cowswap-e2e-tests/src/tests/cross-chain-swaps.spec.tsapps/cowswap-frontend/src/tradingSdk/bridgingSdk.tslibs/common-hooks/src/useFeatureFlags.ts
|
Addressed the 8 nitpick comments from CodeRabbit's review. Replied inline to the 4 actionable comments; summarizing the nitpicks here since they weren't individually threaded. Fixed (6):
Not changing, with reasoning:
|
…wswap into e2e/cross-chain-swaps # Conflicts: # apps/cowswap-e2e-tests/src/support/mockApproveSimulation.ts
…e-slot postedOrder mock
…ask 8 removes it)
…cross-chain-swaps
What changed
cross-chain-swaps.spec.ts, 8 new Playwright specs covering the cross-chain swap UI: provider selection (Bungee/Near Intents), ETH-flow (native ETH) as the sell leg, Solana/Bitcoin as destination chains, and swap/bridge "Expected to receive" / "Min. to receive" parity (CC-01, CC-02, CC-03, CC-13, CC-15, CC-17, CC-26, CC-27).mocks/bungee.ts,mocks/nearIntents.ts, plus captured quote/route JSON fixtures) and aBridgeRoutePanelpage object for the swap/bridge route breakdown.mockSocketVerifier.tsto stub Bungee's on-chainvalidateRotueId/validateSocketRequestpreflight calls so its quote path doesn't need a real chain.bridgingSdk.ts: bypasses Near Intents'recoverDepositAddresssignature check behindwindow.__COWSWAP_E2E__, since a mocked quote/attestation pair can't carry a real signature from Near's attestor key.useFeatureFlags.ts: readswindow.__COWSWAP_E2E_FEATURE_FLAGS__and merges it over LaunchDarkly's flags, since LD's SDK never issues an evaluation request without a configured client-side ID and its API can't be mocked over HTTP instead.REACT_APP_NETWORK_URL_1(mainnet RPC) toe2e-pw-nightly.yml/e2e-pw-smoke.ymland.env.example, since these specs run against Mainnet→Base rather than Sepolia.apps/cowswap-e2e-tests/AGENTS.md.Why
Cross-chain swap/bridge is a live user-facing flow with no prior Playwright coverage. Two real constraints shaped the approach rather than a straightforward mock:
windowinstead.Given those, CC-02/CC-03/CC-26/CC-27 exercise Mainnet USDC → Base USDC (the one route with a valid signed Near fixture) rather than every pairing named in the original spec, and CC-15/CC-17 stop at the recipient-requirement UI states rather than asserting on a real resolved Solana/Bitcoin quote (no valid fixture exists for either). Full scope notes are in the spec file's module doc comment and in
AGENTS.md.QA Testing
Preview URL QA:
Developer verification:
cross-chain-swaps.spec.tsare the actual regression coverage here; they aren't independently reproducible through the preview alone since they rely on mocked Bungee/Near Intents responses and a mocked wallet private key.mockSocketVerifier/bungee.ts/nearIntents.tsfixture wiring is exercised by those same specs.Reviewer note:
bridgingSdk.ts,useFeatureFlags.ts) both branch only on window flags (__COWSWAP_E2E__,__COWSWAP_E2E_FEATURE_FLAGS__) that only Playwright'saddInitScriptsets — worth confirming neither path is reachable in a real browser session.Preview URLs
Summary by CodeRabbit