Skip to content

Commit 453944e

Browse files
racitoresseaonajpurimetamaskbotmicaelae
authored
test: MMQA-224 add test eth to weth (#31278)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Add tests based on PR #30896 1. Add ETH to WETH swap 2. Add send swap ETH to WETH (removed the previous one) <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 3. What is the improvement/solution? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/31278?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 4. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Signed-off-by: dan437 <[email protected]> Co-authored-by: seaona <[email protected]> Co-authored-by: Jyoti Puri <[email protected]> Co-authored-by: MetaMask Bot <[email protected]> Co-authored-by: Micaela Estabillo <[email protected]> Co-authored-by: Daniel <[email protected]> Co-authored-by: MetaMask Bot <[email protected]> Co-authored-by: Derek Brans <[email protected]> Co-authored-by: Guillaume Roux <[email protected]> Co-authored-by: David Murdoch <[email protected]> Co-authored-by: George Marshall <[email protected]> Co-authored-by: Amanda Yeoh <[email protected]> Co-authored-by: Nick Gambino <[email protected]> Co-authored-by: Mark Stacey <[email protected]>
1 parent 1bb5fae commit 453944e

File tree

5 files changed

+577
-211
lines changed

5 files changed

+577
-211
lines changed

test/e2e/page-objects/pages/swap/swap-page.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class SwapPage {
1919
text: 'Close',
2020
};
2121

22+
private readonly transactionHeader = '[data-testid="awaiting-swap-header"]';
23+
2224
constructor(driver: Driver) {
2325
this.driver = driver;
2426
}
@@ -54,11 +56,34 @@ class SwapPage {
5456
});
5557
}
5658

59+
async swapProcessingMessageCheck(message: string): Promise<void> {
60+
await this.driver.wait(async () => {
61+
const confirmedTxs = await this.driver.findElements({
62+
css: this.transactionHeader,
63+
text: message,
64+
});
65+
return confirmedTxs.length === 1;
66+
}, 10000);
67+
}
68+
5769
async submitSwap(): Promise<void> {
5870
console.log('Submit Swap');
5971
await this.driver.clickElement(this.swapButton);
72+
await this.driver.delay(1500);
73+
// console.log('Processing Swap');
74+
// await this.swapProcessingMessageCheck('Processing');
75+
console.log('Swap Transaction complete');
76+
await this.swapProcessingMessageCheck('Transaction complete');
6077
await this.driver.clickElement(this.closeButton);
6178
}
79+
80+
async dismissManualTokenWarning(): Promise<void> {
81+
console.log('Dismiss manual token warning');
82+
await this.driver.clickElement({
83+
text: 'Continue swapping',
84+
tag: 'button',
85+
});
86+
}
6287
}
6388

6489
export default SwapPage;
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
import { Suite } from 'mocha';
2+
import { MockttpServer } from 'mockttp';
3+
import {
4+
logInWithBalanceValidation,
5+
openActionMenuAndStartSendFlow,
6+
withFixtures,
7+
} from '../../helpers';
8+
import FixtureBuilder from '../../fixture-builder';
9+
import HeaderNavbar from '../../page-objects/pages/header-navbar';
10+
import SettingsPage from '../../page-objects/pages/settings/settings-page';
11+
import AdvancedSettings from '../../page-objects/pages/settings/advanced-settings';
12+
import HomePage from '../../page-objects/pages/home/homepage';
13+
import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants';
14+
import { NATIVE_TOKEN_SYMBOL, SwapSendPage } from './swap-send-test-utils';
15+
16+
async function mockSwapQuotes(mockServer: MockttpServer) {
17+
return [
18+
await mockServer
19+
.forGet('https://swap.api.cx.metamask.io/token/1')
20+
.thenCallback(() => ({
21+
statusCode: 200,
22+
json: {
23+
symbol: 'WETH',
24+
type: 'erc20',
25+
aggregators: [
26+
'metamask',
27+
'aave',
28+
'coinGecko',
29+
'oneInch',
30+
'pmm',
31+
'zerion',
32+
'lifi',
33+
'socket',
34+
'squid',
35+
'sonarwatch',
36+
'uniswapLabs',
37+
'coinmarketcap',
38+
'rango',
39+
],
40+
occurrences: 13,
41+
iconUrl:
42+
'https://raw.githubusercontent.com/MetaMask/contract-metadata/master/images/weth.svg',
43+
address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
44+
name: 'Wrapped Ether',
45+
decimals: 18,
46+
},
47+
})),
48+
await mockServer
49+
.forPost('https://transaction.api.cx.metamask.io/networks/1/getFees')
50+
.thenCallback(() => ({
51+
statusCode: 200,
52+
json: {
53+
blockNumber: 22017409,
54+
id: 'b6d9c5f3-4fee-4470-be1b-6c574fe61315',
55+
txs: [
56+
{
57+
cancelFees: [],
58+
return: '0x',
59+
status: 1,
60+
gasUsed: 188186,
61+
gasLimit: 241302,
62+
fees: [
63+
{
64+
maxFeePerGas: 6393950816,
65+
maxPriorityFeePerGas: 1000000004,
66+
gas: 241302,
67+
balanceNeeded: 1542873120043734,
68+
currentBalance: 30009434625664560,
69+
error: '',
70+
},
71+
],
72+
feeEstimate: 821886724082654,
73+
baseFeePerGas: 3367416938,
74+
maxFeeEstimate: 1542873119802432,
75+
},
76+
],
77+
},
78+
})),
79+
80+
await mockServer
81+
.forGet('https://swap.api.cx.metamask.io/v2/networks/1/quotes')
82+
.thenCallback(() => ({
83+
statusCode: 200,
84+
json: [
85+
{
86+
aggregator: 'WETH',
87+
aggregatorType: 'CONTRACT',
88+
destinationToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
89+
sourceToken: '0x0000000000000000000000000000000000000000',
90+
sourceAmount: '10000000000000000000',
91+
destinationAmount: '10000000000000000000',
92+
trade: {
93+
data: '0xd0e30db0',
94+
from: '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1',
95+
to: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
96+
value: '10000000000000000000',
97+
},
98+
sender: '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1',
99+
recipient: '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1',
100+
error: null,
101+
gasParams: {
102+
maxGas: 500000,
103+
averageGas: 300000,
104+
estimatedRefund: 0,
105+
gasMultiplier: 1,
106+
},
107+
fee: 0,
108+
approvalNeeded: null,
109+
priceSlippage: null,
110+
sourceTokenRate: 1,
111+
destinationTokenRate: 0.9999285710414016,
112+
},
113+
],
114+
})),
115+
116+
await mockServer
117+
.forGet('https://swap.api.cx.metamask.io/networks/1')
118+
.thenCallback(() => ({
119+
statusCode: 200,
120+
json: {
121+
active: true,
122+
networkId: 1,
123+
chainId: 1,
124+
chainName: 'Ethereum Mainnet',
125+
nativeCurrency: {
126+
name: 'Ether',
127+
symbol: 'ETH',
128+
decimals: 18,
129+
address: '0x0000000000000000000000000000000000000000',
130+
},
131+
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/ETH.png',
132+
blockExplorerUrl: 'https://etherscan.io',
133+
networkType: 'L1',
134+
aggregators: [
135+
'airswapV3',
136+
'airswapV4',
137+
'oneInchV4',
138+
'oneInchV5',
139+
'paraswap',
140+
'pmm',
141+
'zeroEx',
142+
'openOcean',
143+
'hashFlow',
144+
'wrappedNative',
145+
'kyberSwap',
146+
'airSwapV4_3',
147+
'hashFlowV3',
148+
],
149+
refreshRates: {
150+
quotes: 30,
151+
quotesPrefetching: 30,
152+
stxGetTransactions: 10,
153+
stxBatchStatus: 1,
154+
stxStatusDeadline: 160,
155+
stxMaxFeeMultiplier: 2,
156+
},
157+
parameters: {
158+
refreshRates: {
159+
quotes: 30,
160+
quotesPrefetching: 30,
161+
stxGetTransactions: 10,
162+
stxBatchStatus: 1,
163+
},
164+
stxStatusDeadline: 160,
165+
stxMaxFeeMultiplier: 2,
166+
},
167+
},
168+
})),
169+
];
170+
}
171+
172+
describe('Swap-Send ETH', function () {
173+
describe('to non-contract address with data that matches swap data signature', function (this: Suite) {
174+
it('submits a transaction successfully with max amount', async function () {
175+
await withFixtures(
176+
{
177+
fixtures: new FixtureBuilder()
178+
.withNetworkControllerOnMainnet()
179+
.withTokensController({
180+
allTokens: {
181+
'0x1': {
182+
'0x5cfe73b6021e818b776b421b1c4db2474086a7e1': [
183+
{
184+
address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
185+
symbol: 'WETH',
186+
decimals: 18,
187+
isERC721: false,
188+
aggregators: [],
189+
},
190+
],
191+
},
192+
},
193+
})
194+
.build(),
195+
title: this.test?.fullTitle(),
196+
testSpecificMock: mockSwapQuotes,
197+
localNodeOptions: [
198+
{
199+
type: 'anvil',
200+
options: {
201+
chainId: 1,
202+
hardfork: 'london',
203+
loadState:
204+
'./test/e2e/seeder/network-states/swap-state/withSwapContracts.json',
205+
},
206+
},
207+
],
208+
},
209+
async ({ driver }) => {
210+
const swapSendPage = new SwapSendPage(driver);
211+
await logInWithBalanceValidation(driver);
212+
213+
const homePage = new HomePage(driver);
214+
await homePage.check_pageIsLoaded();
215+
await homePage.check_expectedTokenBalanceIsDisplayed('50', 'WETH');
216+
await homePage.check_expectedTokenBalanceIsDisplayed('25', 'ETH');
217+
218+
// disable smart transactions
219+
const headerNavbar = new HeaderNavbar(driver);
220+
await headerNavbar.check_pageIsLoaded();
221+
await headerNavbar.openSettingsPage();
222+
223+
const settingsPage = new SettingsPage(driver);
224+
await settingsPage.check_pageIsLoaded();
225+
await settingsPage.clickAdvancedTab();
226+
const advancedSettingsPage = new AdvancedSettings(driver);
227+
await advancedSettingsPage.check_pageIsLoaded();
228+
await advancedSettingsPage.toggleSmartTransactions();
229+
await settingsPage.closeSettingsPage();
230+
231+
// START SWAP AND SEND FLOW
232+
await openActionMenuAndStartSendFlow(driver);
233+
234+
await swapSendPage.fillRecipientAddressInput(DEFAULT_FIXTURE_ACCOUNT);
235+
await swapSendPage.fillAmountInput('1');
236+
237+
await swapSendPage.verifyMaxButtonClick(
238+
['ETH', 'ETH'],
239+
['24.99945808355143', '24.99945808355143'],
240+
);
241+
242+
await swapSendPage.fillAmountInput('10');
243+
await swapSendPage.verifyAssetSymbolsAndAmounts(
244+
[NATIVE_TOKEN_SYMBOL, NATIVE_TOKEN_SYMBOL],
245+
['10', '10'],
246+
);
247+
248+
await swapSendPage.fillAmountInput('10');
249+
250+
const ETH_WETH_TOKEN_INPUTS = [
251+
[NATIVE_TOKEN_SYMBOL, 'WETH'],
252+
['10', '10'],
253+
];
254+
const ETH_WETH_FIAT_INPUTS = [
255+
['USD', 'USD'],
256+
['1,700.00', '1,701.09'],
257+
];
258+
259+
await swapSendPage.clickOnAsset('WETH', 'dest');
260+
await swapSendPage.verifyAssetSymbolsAndAmounts(
261+
ETH_WETH_TOKEN_INPUTS[0],
262+
ETH_WETH_TOKEN_INPUTS[1],
263+
);
264+
265+
await swapSendPage.verifySwitchPrimaryCurrency(
266+
ETH_WETH_TOKEN_INPUTS,
267+
ETH_WETH_FIAT_INPUTS,
268+
);
269+
270+
await swapSendPage.verifyQuoteDisplay(
271+
'1 ETH = 1 WETH',
272+
'0.0129028 ETH',
273+
'≈ $21.93',
274+
);
275+
276+
await swapSendPage.submitSwap();
277+
await swapSendPage.verifyHistoryEntry(
278+
'Send ETH as WETH',
279+
'Confirmed',
280+
'-10 ETH',
281+
'',
282+
);
283+
284+
await homePage.goToTokensTab();
285+
await homePage.check_expectedTokenBalanceIsDisplayed('60', 'WETH');
286+
// https://github.com/MetaMask/metamask-extension/issues/31427
287+
// await homePage.check_expectedTokenBalanceIsDisplayed(
288+
// '14.99994',
289+
// 'ETH',
290+
// );
291+
292+
driver.summarizeErrorsAndExceptions();
293+
},
294+
);
295+
});
296+
});
297+
});

0 commit comments

Comments
 (0)