Skip to content
Merged
Show file tree
Hide file tree
Changes from 219 commits
Commits
Show all changes
221 commits
Select commit Hold shift + click to select a range
d1d7127
chore: remove cypress e2e tests
shoom3301 Aug 5, 2026
a5c272c
test: add selectors to UI elements
shoom3301 Aug 5, 2026
18fab35
feat: e2e tests with playwright
shoom3301 Aug 5, 2026
2da1da7
ci: run e2e tests
shoom3301 Aug 5, 2026
43cd90a
chore: update deps
shoom3301 Aug 5, 2026
723359b
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
a679806
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 5, 2026
e25eec2
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 5, 2026
f6b38cc
chore: update e2e commands
shoom3301 Aug 5, 2026
08ef466
Merge remote-tracking branch 'origin/feat/e2e-playwright-3' into feat…
shoom3301 Aug 5, 2026
6b80b09
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
5da64a7
chore: delete
shoom3301 Aug 5, 2026
bfa0940
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
50aa99b
chore: delete cypress
shoom3301 Aug 5, 2026
4197c03
chore: fix test
shoom3301 Aug 5, 2026
4df32b5
Merge branch 'feat/e2e-playwright-1' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
3fc5d52
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
68b00de
chore: fix links
shoom3301 Aug 5, 2026
0a3a1c3
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
e3bed5c
chore: revert
shoom3301 Aug 5, 2026
02ce9ec
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 5, 2026
a67c3c7
chore: revert
shoom3301 Aug 5, 2026
7ecbda7
refactor: use setupTestConditions in tests
shoom3301 Aug 6, 2026
93fddb7
chore: add account activities locator
shoom3301 Aug 6, 2026
9ee9c1e
refactor: decompose mockSwapFulfillment
shoom3301 Aug 6, 2026
3c7a128
refactor: use types from sdk
shoom3301 Aug 6, 2026
c39705b
test: e2e [MO-06]
shoom3301 Aug 6, 2026
c4298c1
docs: add E2E SPEC SKILL
shoom3301 Aug 6, 2026
feb8fd4
docs: add E2E SCENARIO SKILL
shoom3301 Aug 6, 2026
4f712cf
chore: clean up
shoom3301 Aug 6, 2026
62021d2
test: e2e [LO-02]
shoom3301 Aug 6, 2026
4d91d20
test: e2e [MO-07]
shoom3301 Aug 6, 2026
75c59ee
test: e2e [MO-07] snackbar
shoom3301 Aug 6, 2026
5cad625
refactor: approve test
shoom3301 Aug 6, 2026
dcbf4cb
chore: add test
shoom3301 Aug 6, 2026
cdc302f
test: e2e [MO-09]
shoom3301 Aug 7, 2026
da5150e
test: e2e [MO-10]
shoom3301 Aug 7, 2026
ab0bd16
refactor: align market-orders tests to doc
shoom3301 Aug 7, 2026
f82fbd0
test: e2e [MO-03]
shoom3301 Aug 7, 2026
93acbf2
test: e2e [MO-08]
shoom3301 Aug 7, 2026
1e223f3
test: e2e [MO-11]
shoom3301 Aug 7, 2026
a4f8245
test: e2e [MO-22]
shoom3301 Aug 7, 2026
8cd093f
test: e2e [MO-30]
shoom3301 Aug 8, 2026
72db874
test: e2e [MO-42]
shoom3301 Aug 8, 2026
42eb059
test: e2e [MO-45]
shoom3301 Aug 8, 2026
e61b3a1
test: e2e [MO-46]
shoom3301 Aug 8, 2026
252b363
test: e2e [MO-54]
shoom3301 Aug 8, 2026
bb62509
refactor: simplify e2e tests
shoom3301 Aug 8, 2026
5f83da6
test: e2e MO-61
shoom3301 Aug 9, 2026
e3121c0
test: e2e MO-70 MO-71
shoom3301 Aug 9, 2026
abedb95
chore: remove slack notification from smoke
shoom3301 Aug 10, 2026
95593d4
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 10, 2026
62fd48a
chore: clean up code
shoom3301 Aug 10, 2026
4b19a9f
chore: mark as smoke
shoom3301 Aug 10, 2026
a04ff59
chore: fix test
shoom3301 Aug 10, 2026
deec696
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 10, 2026
1cb2163
Merge branch 'feat/e2e-playwright' of https://github.com/cowprotocol/…
shoom3301 Aug 10, 2026
8d7b3aa
Merge branch 'feat/e2e-playwright-1' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
463b1f8
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
547708c
chore: fix test
shoom3301 Aug 10, 2026
2dfc961
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
b966b53
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 10, 2026
ba7d7aa
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 10, 2026
c92fe9c
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 10, 2026
28b73a3
chore: fix test
shoom3301 Aug 10, 2026
262e569
Merge remote-tracking branch 'origin/e2e/market-orders' into e2e/mark…
shoom3301 Aug 10, 2026
ca5b801
chore: fix test
shoom3301 Aug 10, 2026
252d0c7
feat(e2e): speed up updaters
shoom3301 Aug 10, 2026
a487256
test: add selectors to UI elements
shoom3301 Aug 5, 2026
43167ba
chore: fix test
shoom3301 Aug 5, 2026
fd0fb46
Merge commit 'refs/pull/7959/head' of https://github.com/cowprotocol/…
shoom3301 Aug 10, 2026
eddec69
Merge branch 'feat/e2e-playwright-1' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
806375f
Merge remote-tracking branch 'origin/feat/e2e-playwright-2' into feat…
shoom3301 Aug 10, 2026
eea34b8
test: e2e MO-61
shoom3301 Aug 10, 2026
fcbfb4e
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 10, 2026
0d64709
Merge branch 'feat/e2e-playwright-1' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
ef92a74
test: e2e MO-14
shoom3301 Aug 10, 2026
199a9ab
test: e2e MO-47
shoom3301 Aug 10, 2026
7986cbc
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
4ce63d4
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 10, 2026
2f9b6ac
chore: fix review issues
shoom3301 Aug 11, 2026
b6a1aa9
chore: address review comments
shoom3301 Aug 11, 2026
87961b3
chore: update bundle sizes [automatic]
cowswap-release-sync[bot] Aug 11, 2026
bee89cc
chore: address review comments
shoom3301 Aug 11, 2026
da89b12
Merge remote-tracking branch 'origin/feat/e2e-playwright-2' into feat…
shoom3301 Aug 11, 2026
a53f387
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 11, 2026
7bfcaf8
chore: update lock
shoom3301 Aug 11, 2026
afdff68
chore: fix workflows
shoom3301 Aug 11, 2026
f822251
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 11, 2026
e490975
Merge branch 'feat/e2e-playwright-1' of https://github.com/cowprotoco…
shoom3301 Aug 11, 2026
1617843
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 11, 2026
4af9613
test: e2e cross-chain swaps
shoom3301 Aug 11, 2026
dd355fc
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 11, 2026
d18d76e
chore: fix lock
shoom3301 Aug 11, 2026
b997fa0
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 11, 2026
388e897
docs: update e2e AGENTS.md
shoom3301 Aug 11, 2026
75bc9aa
chore: make tests stable
shoom3301 Aug 12, 2026
7f8cd6e
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
89a21e5
chore: update tests id
shoom3301 Aug 12, 2026
0fc344e
chore: update comments
shoom3301 Aug 12, 2026
4fcdd1a
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
a81dfd8
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 12, 2026
797279d
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 12, 2026
24d23ce
test(e2e): mock all rpc node requests
shoom3301 Aug 12, 2026
8fb9e01
test(e2e): improve rpc node mocks
shoom3301 Aug 12, 2026
8523c86
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
fe6b0cb
refactor: simplify e2e mocks
shoom3301 Aug 12, 2026
9e31d9f
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
bbacd5f
chore: merge changes
shoom3301 Aug 12, 2026
cefa072
chore: fix locator
shoom3301 Aug 12, 2026
b4b35a9
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
c623450
chore: fix allowance mock
shoom3301 Aug 12, 2026
8e90a15
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 12, 2026
a45006b
chore: improve recoverDepositAddress hack
shoom3301 Aug 12, 2026
4597958
Merge branch 'feat/e2e-playwright-3' into e2e/market-orders
elena-zh Aug 12, 2026
b91870f
chore: improve code
shoom3301 Aug 12, 2026
a273179
chore: improve tests stability
shoom3301 Aug 12, 2026
5397421
test(e2e): add [CS-129] enable Hooks via settings toggle
elena-zh Aug 12, 2026
bdd7e39
chore: improve tests stability
shoom3301 Aug 13, 2026
6aab3ab
chore: remove test
shoom3301 Aug 13, 2026
f9b0726
chore: update test ids
shoom3301 Aug 13, 2026
8b083e4
chore: add smoke tags
shoom3301 Aug 13, 2026
4558f5f
chore: change slack channel
shoom3301 Aug 13, 2026
5e7b4ba
docs(e2e): update readme
shoom3301 Aug 13, 2026
30dff46
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 13, 2026
83e4bf7
chore: make tests stable
shoom3301 Aug 13, 2026
ba42d68
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 13, 2026
db9e09b
chore: fix mockSocketVerifier
shoom3301 Aug 13, 2026
1af51b3
chore: update docs
shoom3301 Aug 13, 2026
7aa1942
chore: fix workers count
shoom3301 Aug 13, 2026
29a00d0
chore: revert config
shoom3301 Aug 13, 2026
3f00b97
chore: improve selectors
shoom3301 Aug 13, 2026
403d1c0
chore: fix BridgeRoutePanel.expand
shoom3301 Aug 13, 2026
115609d
chore: fix config
shoom3301 Aug 13, 2026
b8372f9
chore: mock token nonce call
shoom3301 Aug 13, 2026
01bb3f1
chore: fix test
shoom3301 Aug 13, 2026
9e4bcc4
chore: adjust config
shoom3301 Aug 13, 2026
4f0cae1
feat(e2e): add OrdersMock, a multi-order registry replacing the singl…
shoom3301 Aug 13, 2026
999afd9
chore: fix config
shoom3301 Aug 13, 2026
de8060e
feat(e2e): add seedOpenOrder/wasCancelRequested/markCancelled to Orde…
shoom3301 Aug 13, 2026
415fb18
feat(e2e): add trackEthFlowOrder to OrdersMock, completing the merged…
shoom3301 Aug 13, 2026
6e02a5b
feat(e2e): wire OrdersMock into the mocks fixture as mocks.orders
shoom3301 Aug 13, 2026
fff52c0
refactor(e2e): migrate market-orders.spec.ts to mocks.orders
shoom3301 Aug 13, 2026
b79eaa1
fix(e2e): restore tradePage destructuring in market-orders.spec.ts (T…
shoom3301 Aug 13, 2026
f68596d
refactor(e2e): migrate cross-chain-swaps.spec.ts to mocks.orders
shoom3301 Aug 13, 2026
90cd46b
refactor(e2e): migrate limit-orders.spec.ts to mocks.orders
shoom3301 Aug 13, 2026
68ffe34
refactor(e2e): remove old order mocks
shoom3301 Aug 13, 2026
aa3351d
Merge remote-tracking branch 'origin/e2e/cross-chain-swaps' into e2e/…
shoom3301 Aug 13, 2026
08d4834
chore: bump workers
shoom3301 Aug 13, 2026
c66d30e
chore: remove tokens mock
shoom3301 Aug 13, 2026
513a336
chore: fix socketVerifier mock
shoom3301 Aug 13, 2026
36d390d
chore: fix tooltip
shoom3301 Aug 13, 2026
f8e6458
chore: remove rpcProxy
shoom3301 Aug 14, 2026
12bdd87
refactor: extract mockRpcNodeRequest
shoom3301 Aug 14, 2026
0e127c0
refactor: extract mockContractViewCall
shoom3301 Aug 14, 2026
184b224
refactor: simplify installSocketVerifier
shoom3301 Aug 14, 2026
1141d70
refactor: remove real RPC calls
shoom3301 Aug 14, 2026
56f613c
refactor: refactor allowance mock
shoom3301 Aug 14, 2026
b18c323
chore: fix allowance mock
shoom3301 Aug 14, 2026
b9fadd4
chore: fix mocks
shoom3301 Aug 14, 2026
af132dd
chore: mock wallet rpc
shoom3301 Aug 14, 2026
fa537ce
chore: local workers 6
shoom3301 Aug 14, 2026
701415c
chore: fix installSocketVerifier
shoom3301 Aug 14, 2026
b3cac77
chore: fix nonces
shoom3301 Aug 14, 2026
39d4c1b
chore: fix wallet connection flack
shoom3301 Aug 14, 2026
7930b0b
chore: disable analytics in e2e
shoom3301 Aug 14, 2026
12c0a4f
fix: fix wallet connection flaky
shoom3301 Aug 14, 2026
789bf4a
chore: fix unlock screen flack
shoom3301 Aug 14, 2026
c3b06c5
chore: fix allowance mock chainId
shoom3301 Aug 14, 2026
41ef380
chore: fix navigation flacky test
shoom3301 Aug 15, 2026
cf53898
refactor: simplify mockEthFlowTransaction
shoom3301 Aug 15, 2026
5e8048d
chore: add test
shoom3301 Aug 15, 2026
33713f2
refactor: simplify approve mock
shoom3301 Aug 15, 2026
6801744
chore: refactor mock ethFlow tx
shoom3301 Aug 15, 2026
ec30088
refactor: remove rpc url from mocks
shoom3301 Aug 15, 2026
061ad82
chore: fix order fill flak
shoom3301 Aug 15, 2026
a4756b0
Merge branch 'e2e/exp' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 15, 2026
5a676c1
chore: merge
shoom3301 Aug 15, 2026
c42ee01
chore: merge
shoom3301 Aug 15, 2026
bc627d2
chore: revert fix
shoom3301 Aug 15, 2026
3a608b6
refactor: finalize mockContractViewCall
shoom3301 Aug 15, 2026
8ee90ce
chore: fix CS-118 flacky
shoom3301 Aug 15, 2026
89ed41b
chore: fix eth-flow calls parsing
shoom3301 Aug 17, 2026
9d23465
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 24, 2026
e80cbc6
Merge branch 'feat/e2e-playwright-2' of https://github.com/cowprotoco…
shoom3301 Aug 24, 2026
4870ddb
Merge branch 'feat/e2e-playwright-3' of https://github.com/cowprotoco…
shoom3301 Aug 24, 2026
8adfe91
Merge branch 'e2e/market-orders' of https://github.com/cowprotocol/co…
shoom3301 Aug 24, 2026
ca2f199
Merge branch 'e2e/cross-chain-swaps' of https://github.com/cowprotoco…
shoom3301 Aug 24, 2026
0d3cb25
chore: fix lock
shoom3301 Aug 24, 2026
f936bdb
fix: fix flaky tests
shoom3301 Aug 24, 2026
d06a98d
fix: fix flaky tests
shoom3301 Aug 24, 2026
e16e192
fix: fix flaky tests
shoom3301 Aug 24, 2026
d47d1e8
fix: fix flaky tests
shoom3301 Aug 24, 2026
bd55b6d
fix: fix flaky tests
shoom3301 Aug 24, 2026
6f22972
fix: fix flaky tests
shoom3301 Aug 24, 2026
28daa99
fix: fix flaky tests
shoom3301 Aug 24, 2026
3024103
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 25, 2026
2ee012c
chore: rearrange files
shoom3301 Aug 25, 2026
b84604a
chore: cut scope
shoom3301 Aug 25, 2026
a12fd80
chore: cut scope
shoom3301 Aug 25, 2026
48b25ca
chore: fix flaky tests
shoom3301 Aug 25, 2026
064c387
feat(cowswap): adjust app for e2e tests
shoom3301 Aug 25, 2026
7c6a4ac
test(e2e): add smoke cases of market-orders
shoom3301 Aug 25, 2026
bec9d9f
chore: fix build
shoom3301 Aug 25, 2026
4541a76
chore: fix build
shoom3301 Aug 25, 2026
1357ebe
Merge branch 'e2e-tests/p1' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 25, 2026
dc7d7ed
Merge branch 'e2e-tests/p2' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 25, 2026
ce8341f
chore: reduce scope
shoom3301 Aug 25, 2026
78a5dd0
Merge branch 'e2e-tests/p1' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 25, 2026
7902def
chore: reduce scope
shoom3301 Aug 25, 2026
36def1a
Merge branch 'e2e-tests/p2' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 25, 2026
c6eab4b
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 27, 2026
f1aaeed
chore: pnpm lock
shoom3301 Aug 27, 2026
e275d6c
Merge branch 'e2e-tests/p1' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 27, 2026
5391e3b
Merge branch 'e2e-tests/p2' of https://github.com/cowprotocol/cowswap…
shoom3301 Aug 27, 2026
abe1241
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Aug 27, 2026
cea1f1c
chore: fix locator
shoom3301 Aug 28, 2026
3d42b14
refactor: centralize test-ids
shoom3301 Aug 28, 2026
4e5313c
refactor(e2e): use SupportedChainId
shoom3301 Aug 28, 2026
3743de2
chore: simplify code
shoom3301 Aug 28, 2026
173f889
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions apps/cowswap-e2e-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ For scenarios that just need *a connected wallet that signs*, import the
mock-wallet entrypoint instead of the Synpress one:

```ts
import { SupportedChainId } from '@cowprotocol/cow-sdk'

import { test, expect } from '../fixtures/mockWallet'
import { CHAIN_IDS } from '../support/constants'

test('my scenario', async ({ wallet, page }) => {
wallet.stubRpc('wallet_getCapabilities', () => ({ '0xaa36a7': { atomic: { status: 'supported' } } }))
await wallet.openApp({ chainId: CHAIN_IDS.SEPOLIA }) // boots already connected
await wallet.openApp({ chainId: SupportedChainId.SEPOLIA }) // boots already connected
// …
expect(wallet.rpcCalls('wallet_getCapabilities').length).toBeGreaterThan(0)
})
Expand Down Expand Up @@ -197,10 +198,10 @@ normally configures allowances at runtime instead:

```ts
test('[MO-XX] approval', async ({ wallet, mocks, swapPage }) => {
mocks.allowances.set(wallet.address, CHAIN_IDS.SEPOLIA, {
mocks.allowances.set(wallet.address, SupportedChainId.SEPOLIA, {
'0xfff9976782d46cc05630d1f6ebab18b2324d6b14': '5000000',
})
await wallet.openApp({ chainId: CHAIN_IDS.SEPOLIA })
await wallet.openApp({ chainId: SupportedChainId.SEPOLIA })
// ...
expect(mocks.allowances.reads().length).toBeGreaterThan(0)
})
Expand Down
3 changes: 2 additions & 1 deletion apps/cowswap-e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"dependencies": {
"viem": "2.48.8",
"@cowprotocol/cow-sdk": "9.2.6",
"@cowprotocol/sdk-order-book": "4.0.2"
"@cowprotocol/sdk-order-book": "4.0.2",
"@cowprotocol/test-ids": "workspace:*"
},
"devDependencies": {
"@playwright/test": "1.49.1",
Expand Down
9 changes: 5 additions & 4 deletions apps/cowswap-e2e-tests/src/fixtures/mockWallet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { toHex, type Hex } from 'viem'

import { SupportedChainId } from '@cowprotocol/cow-sdk'

import { expect, test as base, type BrowserContext, type Page } from '@playwright/test'

import { sharedFixtures, type SharedFixtures } from './shared'

import { E2E_WALLET_INFO, injectedShim } from '../mockWallet/injectedShim'
import { seedAutoConnect } from '../mockWallet/seedAutoConnect'
import { createWalletEngine, type RpcCallRecord, type RpcStub, type WalletEngine } from '../mockWallet/walletEngine'
import { CHAIN_IDS, type SupportedChainId } from '../support/constants'

export interface MockWalletApi {
readonly address: string
Expand Down Expand Up @@ -106,7 +107,7 @@ export const test = base.extend<MockWalletFixtures & MockWalletOptions>({
async ({ context, page, mockWalletKey, mockWalletAutoConnect }, use) => {
const engine = createWalletEngine({
privateKey: resolvePrivateKey(mockWalletKey),
chainId: CHAIN_IDS.SEPOLIA,
chainId: SupportedChainId.SEPOLIA,
emit: (event, payload) => {
page
.evaluate(
Expand All @@ -124,12 +125,12 @@ export const test = base.extend<MockWalletFixtures & MockWalletOptions>({
await context.addInitScript(injectedShim, {
...E2E_WALLET_INFO,
address: engine.address,
chainIdHex: toHex(CHAIN_IDS.SEPOLIA),
chainIdHex: toHex(SupportedChainId.SEPOLIA),
})
if (mockWalletAutoConnect) {
await context.addInitScript(seedAutoConnect, {
rdns: E2E_WALLET_INFO.rdns,
defaultChainId: CHAIN_IDS.SEPOLIA,
defaultChainId: SupportedChainId.SEPOLIA,
})
}

Expand Down
16 changes: 8 additions & 8 deletions apps/cowswap-e2e-tests/src/fixtures/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { CHAIN_IDS, type SupportedChainId } from '../support/constants'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

import type { Page } from '@playwright/test'
import type { MetaMask } from '@synthetixio/synpress/playwright'

const CHAIN_NAME_BY_ID: Record<SupportedChainId, string> = {
[CHAIN_IDS.MAINNET]: 'Mainnet',
[CHAIN_IDS.ARBITRUM]: 'Arbitrum',
[CHAIN_IDS.BASE]: 'Base',
[CHAIN_IDS.BNB]: 'BNB',
[CHAIN_IDS.GNOSIS]: 'Gnosis',
[CHAIN_IDS.SEPOLIA]: 'Sepolia',
const CHAIN_NAME_BY_ID: Partial<Record<SupportedChainId, string>> = {
[SupportedChainId.MAINNET]: 'Mainnet',
[SupportedChainId.ARBITRUM_ONE]: 'Arbitrum',
[SupportedChainId.BASE]: 'Base',
[SupportedChainId.BNB]: 'BNB',
[SupportedChainId.GNOSIS_CHAIN]: 'Gnosis',
[SupportedChainId.SEPOLIA]: 'Sepolia',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

export interface WalletApi {
Expand Down
14 changes: 9 additions & 5 deletions apps/cowswap-e2e-tests/src/pages/AccountModal.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import type { Page, Locator } from '@playwright/test'

/**
* The wallet-details side panel opened from the header's connected-wallet button. It has no
* `role="dialog"` and no dedicated close button locator (the panel's own `X` has no accessible
* name) — `#web3-status-connected` is a toggle, so clicking it again is the panel's close action
* too.
* The wallet-details panel opened from the header's connected-wallet button. Since the
* Dialog/surfaces refactor (`AccountModal.container.tsx`'s `<Dialog>`) it's a real modal with its
* own backdrop and `role="dialog"` — the backdrop now covers `#web3-status-connected`, so clicking
* the toggle button again no longer closes it (the click is intercepted by the dialog's own
* overlay). Closing goes through the dialog's `ModalHeader` close button instead, which the shared
* `CloseIconButton` primitive gives an accessible `aria-label="Close"`.
*/
export class AccountModal {
readonly page: Page
readonly toggleButton: Locator
readonly closeButton: Locator
readonly activitiesList: Locator
/** Confirms cancellation in `RequestCancellationModal`, opened via an activity row's "Cancel order" link. */
readonly requestCancellationButton: Locator

constructor(page: Page) {
this.page = page
this.toggleButton = page.locator('#web3-status-connected')
this.closeButton = page.getByRole('dialog').getByRole('button', { name: 'Close' })
this.activitiesList = page.locator('#account-activities-list')
this.requestCancellationButton = page.getByRole('button', { name: 'Request cancellation' })
}
Expand All @@ -26,7 +30,7 @@ export class AccountModal {
}

async close(): Promise<void> {
await this.toggleButton.click()
await this.closeButton.click()
await this.activitiesList.waitFor({ state: 'hidden' })
}
}
12 changes: 6 additions & 6 deletions apps/cowswap-e2e-tests/src/pages/BridgeRoutePanel.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import type { Page, Locator } from '@playwright/test'

/**
Expand All @@ -20,12 +22,10 @@ export class BridgeRoutePanel {

constructor(page: Page) {
this.page = page
// Scoped by class substring (babel-plugin-styled-components names it after its own export,
// `SummaryClickable`), not just `[aria-expanded]` — the app header's nav dropdown also renders
// `aria-expanded`, and an unscoped `.first()` would resolve to whichever renders first in DOM
// order.
this.expandToggle = page.locator('.trade-details-accordion-toggle').first()
this.bridgeQuoteDetails = page.locator('.collapsible-bridge-route').first()
// Not just `[aria-expanded]` — the app header's nav dropdown also renders `aria-expanded`, and
// an unscoped `.first()` would resolve to whichever renders first in DOM order.
this.expandToggle = page.locator(`[data-testid="${TEST_IDS.tradeDetailsAccordionToggle}"]`).first()
this.bridgeQuoteDetails = page.locator(`[data-testid="${TEST_IDS.collapsibleBridgeRoute}"]`).first()
// Not an exact match: `BridgeRouteTitle` renders "Swap on" and "CoW Protocol" either side of a
// protocol icon, which can add whitespace/alt text into the element's normalized text content.
this.swapStopTitle = page.getByText(/Swap on.*CoW Protocol/)
Expand Down
6 changes: 4 additions & 2 deletions apps/cowswap-e2e-tests/src/pages/ConfirmModal.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import { Page, Locator, expect } from '@playwright/test'

export class ConfirmModal {
Expand All @@ -18,8 +20,8 @@ export class ConfirmModal {
await this.confirmButton.click()
}

/** One of the modal's labeled `.confirm-order-amount` rows (e.g. "Maximum sent", "Expected to receive", "Minimum receive"). */
/** One of the modal's labeled `confirmOrderAmount` rows (e.g. "Maximum sent", "Expected to receive", "Minimum receive"). */
amountRow(label: string): Locator {
return this.page.locator('.confirm-order-amount', { hasText: label })
return this.page.locator(`[data-testid="${TEST_IDS.confirmOrderAmount}"]`, { hasText: label })
}
}
4 changes: 3 additions & 1 deletion apps/cowswap-e2e-tests/src/pages/HeaderPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import type { Page, Locator } from '@playwright/test'

/** The app-wide header (network selector, wallet status) — present on every route, not just Swap. */
Expand All @@ -11,7 +13,7 @@ export class HeaderPage {
this.page = page
this.header = page.locator('#cowswap-app-header')
this.networkDialog = page.getByRole('dialog')
this.snackbarPopup = page.locator('.snackbar-popup').first()
this.snackbarPopup = page.locator(`[data-testid="${TEST_IDS.snackbarPopup}"]`).first()
}

/**
Expand Down
8 changes: 5 additions & 3 deletions apps/cowswap-e2e-tests/src/pages/LimitPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import { expect } from '@playwright/test'

import type { TradePage } from './TradePage'
Expand All @@ -19,17 +21,17 @@ export class LimitPage implements TradePage {

constructor(page: Page) {
this.page = page
this.inputAmount = page.locator('#input-currency-input .token-amount-input')
this.inputAmount = page.locator(`#input-currency-input [data-testid="${TEST_IDS.tokenAmountInput}"]`)
this.limitPriceInput = page.locator('#rate-limit-amount-input')
this.placeOrderButton = page.locator('#do-trade-button')
this.unlockButton = page.locator('#unlock-limit-orders-btn')
this.arrowSeparator = page.locator('#currency-arrow-separator')
this.orderSubmittedHeading = page.getByRole('heading', { name: 'Order Submitted' })
this.continueButton = page.getByRole('button', { name: /continue/i })
this.myOrdersButton = page.getByRole('button', { name: 'My orders' })
this.openOrdersTab = page.locator('.orders-table_tab', { hasText: 'Open' })
this.openOrdersTab = page.locator(`[data-testid="${TEST_IDS.ordersTableTab}"]`, { hasText: 'Open' })
this.ordersTable = page.locator('#orders-table')
this.tradeFormActionButton = page.locator('.trade-form-blank-button')
this.tradeFormActionButton = page.locator(`[data-testid="${TEST_IDS.tradeFormBlankButton}"]`)
}

async goto(opts: { chainId: number; sell?: string; buy?: string }): Promise<void> {
Expand Down
54 changes: 27 additions & 27 deletions apps/cowswap-e2e-tests/src/pages/SwapPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import { expect } from '@playwright/test'

import { BridgeRoutePanel } from './BridgeRoutePanel'
Expand Down Expand Up @@ -42,7 +44,7 @@ export class SwapPage implements TradePage {
readonly routePanel: BridgeRoutePanel
/** `AddressInputPanel`'s wrapping `ReceiverPanel` — `id="recipient"` set by `SetRecipient`. */
readonly recipientPanel: Locator
/** `AddressInputPanel.tsx`'s default className on the `<input>` itself. */
/** `ReceiverPanelBody.container.tsx`'s `data-testid` on the `<input>` itself. */
readonly recipientInput: Locator
readonly recipientPasteButton: Locator
/** Hardcoded id on `ReceiverConfirmationRow.pure.tsx`'s "confirm this is the right chain" checkbox. */
Expand All @@ -66,58 +68,56 @@ export class SwapPage implements TradePage {

constructor(page: Page) {
this.page = page
this.inputAmount = page.locator('#input-currency-input .token-amount-input')
this.outputAmount = page.locator('#output-currency-input .token-amount-input')
this.inputAmount = page.locator(`#input-currency-input [data-testid="${TEST_IDS.tokenAmountInput}"]`)
this.outputAmount = page.locator(`#output-currency-input [data-testid="${TEST_IDS.tokenAmountInput}"]`)
// `CurrencySelectButton` sets `aria-label="Selected token: <symbol>"`, which is a more
// reliable read of the selected currency than the (truncatable) rendered symbol text.
// `.open-currency-select-button` is a real styled-components class (also targeted by
// `ReceiptModal.styled.ts`'s CSS), not a bare test hook — kept as a class per the "used in
// CSS" rule instead of converting it to a `data-testid`.
this.sellTokenSelect = page.locator('#input-currency-input .open-currency-select-button')
this.buyTokenSelect = page.locator('#output-currency-input .open-currency-select-button')
// The wallet balance shown under each amount field: `TokenAmount` sets the
// exact-precision value + symbol (e.g. "0.5 WETH") as the `title` attribute,
// which is the only titled element in either panel outside USD-values mode.
this.sellBalance = page.locator('#input-currency-input .currency-balance-text > span')
this.buyBalance = page.locator('#output-currency-input .currency-balance-text > span')
this.sellFiatAmount = page.locator('#input-currency-input [data-testid="fiat-amount"]')
this.buyFiatAmount = page.locator('#output-currency-input [data-testid="fiat-amount"]')
this.sellBalance = page.locator(`#input-currency-input [data-testid="${TEST_IDS.currencyBalanceText}"] > span`)
this.buyBalance = page.locator(`#output-currency-input [data-testid="${TEST_IDS.currencyBalanceText}"] > span`)
this.sellFiatAmount = page.locator(`#input-currency-input [data-testid="${TEST_IDS.fiatAmount}"]`)
this.buyFiatAmount = page.locator(`#output-currency-input [data-testid="${TEST_IDS.fiatAmount}"]`)
// Only the output panel receives `priceImpactParams` (`TradeWidgetForm`), so price impact
// only ever renders next to the buy-side USD estimation.
this.priceImpact = page.locator('#output-currency-input [data-testid="price-impact"]')
this.priceImpact = page.locator(`#output-currency-input [data-testid="${TEST_IDS.priceImpact}"]`)
// `HoverTooltip`'s mouseenter/mouseleave handlers sit on the innermost wrapper div around the
// "(X%)" text, not on the outer `[data-testid]` span — hovering the outer span can land the
// pointer outside that inner div's box and never open the tooltip.
this.priceImpactTooltipTrigger = this.priceImpact.locator('div div')
// `ReceiveAmount` renders as a sibling of `#output-currency-input`, not inside it — its
// "Receive (incl. fees)" label and the `HelpTooltip` icon next to it are the label's next
// sibling. That sibling is `HelpTooltip`'s outer `HelpTooltipContainer` span, one level above
// the real `HoverTooltip` hitbox div (same quirk as `priceImpactTooltipTrigger` above, but
// nested one div deeper here: `ReferenceElement` div > listener div > icon-wrapper div) —
// `div div` matches both the listener div and the icon-wrapper div nested inside it, so take
// the first (outermost, document-order-first) match to land on the listener div itself.
this.receiveAmountLabel = page.getByText('Receive (incl. fees)', { exact: true })
this.receiveAmountTooltipTrigger = this.receiveAmountLabel
.locator('xpath=following-sibling::*[1]')
.locator('div div')
.first()
// The exact "<amount> <symbol>" value lives in `ReceiveAmountValue`'s own `title`, one level
// above `TokenAmount`'s inner titled span — same convention as `sellBalance`/`buyBalance`.
this.receiveAmountValue = this.receiveAmountLabel.locator('xpath=../..').locator('[title]').first()
// `ReceiveAmount` wraps its label + `HelpTooltip` icon in its own `[data-testid]` div — no more
// sibling/ancestor traversal needed to reach the tooltip's real `HoverTooltip` hitbox div.
this.receiveAmountLabel = page.locator(`[data-testid="${TEST_IDS.receiveAmountLabel}"]`)
// `div div` matches both the listener div and the icon-wrapper div nested inside it (same
// quirk as `priceImpactTooltipTrigger` above), so take the first (outermost) match to land on
// the listener div itself.
this.receiveAmountTooltipTrigger = this.receiveAmountLabel.locator('div div').first()
// The exact "<amount> <symbol>" value lives directly on `ReceiveAmountValue`'s own `title` +
// `data-testid`.
this.receiveAmountValue = page.locator(`[data-testid="${TEST_IDS.receiveAmountValue}"]`)
this.swapButton = page.locator('#do-trade-button')
this.approveButton = page.locator('#approve-trade-button')
this.primaryActionButton = page.locator('#do-trade-button, #approve-trade-button')
this.arrowSeparator = page.locator('#currency-arrow-separator')
this.maxButton = page.getByRole('button', { name: /^max$/i })
this.openOrders = page.locator('[data-testid="open-orders-list"]')
this.openOrders = page.locator(`[data-testid="${TEST_IDS.openOrdersList}"]`)
this.unlockButton = page.locator('#unlock-cross-chain-swap-btn')
this.orderProgressBarModal = page.locator('#order-progress-bar-modal')
this.tokens = new TokenSelector(page)
this.routePanel = new BridgeRoutePanel(page)
this.recipientPanel = page.locator('#recipient')
this.recipientInput = page.locator('input.recipient-address-input')
this.recipientInput = page.locator(`input[data-testid="${TEST_IDS.recipientAddressInput}"]`)
this.recipientPasteButton = this.recipientPanel.getByText('Paste', { exact: true })
this.recipientConfirmationCheckbox = page.locator('#receiver-confirmation')
this.approveModeSelector = page.locator('.approve-mode-selector')
this.approveModeSelector = page.locator(`[data-testid="${TEST_IDS.approveModeSelector}"]`)
this.settingsDialogButton = page.locator('#open-settings-dialog-button')
this.tradeFormActionButton = page.locator('.trade-form-blank-button')
this.tradeFormActionButton = page.locator(`[data-testid="${TEST_IDS.tradeFormBlankButton}"]`)
this.slippageInput = page.locator('#slippage-input')
this.wrapButton = page.getByRole('button', { name: 'Wrap', exact: true })
this.unwrapButton = page.getByRole('button', { name: 'Unwrap', exact: true })
Expand Down
10 changes: 6 additions & 4 deletions apps/cowswap-e2e-tests/src/pages/TwapPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TEST_IDS } from '@cowprotocol/test-ids'

import { expect } from '@playwright/test'

import type { TradePage } from './TradePage'
Expand All @@ -15,13 +17,13 @@ export class TwapPage implements TradePage {

constructor(page: Page) {
this.page = page
this.inputAmount = page.locator('#input-currency-input .token-amount-input')
this.partsInput = page.locator('[data-testid="twap-parts-input"]')
this.durationInput = page.locator('[data-testid="twap-duration-input"]')
this.inputAmount = page.locator(`#input-currency-input [data-testid="${TEST_IDS.tokenAmountInput}"]`)
this.partsInput = page.locator(`[data-testid="${TEST_IDS.twapPartsInput}"]`)
this.durationInput = page.locator(`[data-testid="${TEST_IDS.twapDurationInput}"]`)
this.placeOrderButton = page.locator('#do-trade-button')
this.unlockButton = page.locator('#unlock-advanced-orders-btn')
this.arrowSeparator = page.locator('#currency-arrow-separator')
this.tradeFormActionButton = page.locator('.trade-form-blank-button')
this.tradeFormActionButton = page.locator(`[data-testid="${TEST_IDS.tradeFormBlankButton}"]`)
}

async goto(opts: { chainId: number; sell?: string; buy?: string }): Promise<void> {
Expand Down
11 changes: 0 additions & 11 deletions apps/cowswap-e2e-tests/src/support/constants.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
export const CHAIN_IDS = {
MAINNET: 1,
GNOSIS: 100,
BNB: 56,
ARBITRUM: 42161,
BASE: 8453,
SEPOLIA: 11155111,
} as const

export type SupportedChainId = (typeof CHAIN_IDS)[keyof typeof CHAIN_IDS]

export const RPC_PROXY_PORT_ENV = 'E2E_RPC_PROXY_PORT'

// The port is baked into the cached MetaMask profile at cache-build time (the wallet
Expand Down
Loading
Loading