From 9fba72e28a7cc59906b5530986263c3ae4c27942 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 21 May 2021 13:36:04 +0200 Subject: [PATCH] More Swap testing with hardhat (#3968) * Played around with Hardhat * Remove API key * Clean up PR * Add more timeout * Move out code * Revert hardhat config .ts to .js * Remove commented code * Add whitespace --- __tests__/fixtures.js | 16 +++++++++++- __tests__/hardhat-utils.js | 52 ++++++++++++++++++++++++++++++++++++++ __tests__/swap-page.po.js | 7 +++++ __tests__/swap.test.js | 46 +++++++++++++++++++++++++++++++-- hardhat.config.ts | 1 + package.json | 1 + yarn.lock | 31 +++++++++++++++++++++++ 7 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 __tests__/hardhat-utils.js diff --git a/__tests__/fixtures.js b/__tests__/fixtures.js index 82ae54983c7..b3bdca76e9c 100644 --- a/__tests__/fixtures.js +++ b/__tests__/fixtures.js @@ -49,7 +49,7 @@ const FIXTURE_SEND_ADDRESS = '0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520'; const FIXTURE_SEND_AMOUNT = '0.001'; -const FIXTURE_WEB3_ADDRESS = '0xc6d5a3c98ec9073b54fa0969957bd582e8d874bf '; +const FIXTURE_WEB3_ADDRESS = '0xc6d5a3c98ec9073b54fa0969957bd582e8d874bf'; const FIXTURE_MYC_STORAGE_KEY = 'MYC_Storage'; @@ -163,6 +163,20 @@ const FIXTURE_HARDHAT = { uuid: '356a192b-7913-504c-9457-4d18c28d46e6', balance: '9998866308480000000000', mtime: 1621347441875 + }, + { + ticker: 'DAI', + name: 'DAI Stablecoin', + decimal: 18, + support: {}, + social: {}, + networkId: 'Ethereum', + type: 'erc20', + isCustom: false, + contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + uuid: 'e1f698bf-cb85-5405-b563-14774af14bf1', + balance: '9998866308480000000000', + mtime: 1621347441875 } ], transactions: [], diff --git a/__tests__/hardhat-utils.js b/__tests__/hardhat-utils.js new file mode 100644 index 00000000000..99fda45da8c --- /dev/null +++ b/__tests__/hardhat-utils.js @@ -0,0 +1,52 @@ +import { Contract } from '@ethersproject/contracts'; +import { JsonRpcProvider } from '@ethersproject/providers'; + +import { FIXTURE_WEB3_ADDRESS } from './fixtures'; + +export const resetFork = async () => { + const provider = new JsonRpcProvider('http://127.0.0.1:8546/'); + + await provider.send('hardhat_reset', [ + { + forking: { + jsonRpcUrl: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}` + } + } + ]); +}; + +// Transfers DAI to the test address +export const setupDAI = async () => { + const provider = new JsonRpcProvider('http://127.0.0.1:8546/'); + + await provider.send('hardhat_impersonateAccount', ['0xf977814e90da44bfa03b6295a0616a897441acec']); + + const signer = await provider.getSigner('0xf977814e90da44bfa03b6295a0616a897441acec'); + + const abi = [ + // Read-Only Functions + 'function balanceOf(address owner) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function symbol() view returns (string)', + + // Authenticated Functions + 'function transfer(address to, uint amount) returns (boolean)', + + // Events + 'event Transfer(address indexed from, address indexed to, uint amount)' + ]; + + // send ERC20 + const erc20 = new Contract('0x6b175474e89094c44da98b954eedeac495271d0f', abi, signer); + const tx = await erc20.populateTransaction.transfer( + FIXTURE_WEB3_ADDRESS, + '100000000000000000000' + ); + const sent = await signer.sendTransaction(tx); + + await sent.wait(); + + await provider.send('hardhat_stopImpersonatingAccount', [ + '0xf977814e90da44bfa03b6295a0616a897441acec' + ]); +}; diff --git a/__tests__/swap-page.po.js b/__tests__/swap-page.po.js index d2b25072575..ede59d70e01 100644 --- a/__tests__/swap-page.po.js +++ b/__tests__/swap-page.po.js @@ -1,3 +1,4 @@ +import { getByTestId } from '@testing-library/testcafe'; import { Selector, t } from 'testcafe'; import BasePage from './base-page.po'; @@ -17,6 +18,12 @@ export default class SwapPage extends BasePage { await t.typeText(Selector('input[name="swap-from"]').parent(), FIXTURE_SEND_AMOUNT); } + async fillFormERC20() { + await t.click(getByTestId('asset-selector-option-ETH')); + await t.click(getByTestId('asset-selector-option-DAI')); + await t.typeText(Selector('input[name="swap-from"]').parent(), FIXTURE_SEND_AMOUNT); + } + async setupMock() { await setupEthereumMock(FIXTURE_HARDHAT_PRIVATE_KEY, 1); } diff --git a/__tests__/swap.test.js b/__tests__/swap.test.js index 0e90898816a..c07f684ea9e 100644 --- a/__tests__/swap.test.js +++ b/__tests__/swap.test.js @@ -1,7 +1,13 @@ -import { getByTestId, queryAllByTestId, queryByText } from '@testing-library/testcafe'; +import { + getByTestId, + queryAllByTestId, + queryAllByText, + queryByText +} from '@testing-library/testcafe'; import { injectLS } from './clientScripts'; import { FIXTURE_HARDHAT, FIXTURES_CONST, PAGES } from './fixtures'; +import { resetFork, setupDAI } from './hardhat-utils'; import SwapPage from './swap-page.po'; import { findByTKey } from './translation-utils'; @@ -11,9 +17,10 @@ fixture('Swap') .clientScripts({ content: injectLS(FIXTURE_HARDHAT) }) .page(PAGES.SWAP); -test('can do a swap', async (t) => { +test('can do an ETH swap', async (t) => { await swapPage.waitPageLoaded(); await swapPage.setupMock(); + await resetFork(); await swapPage.fillForm(); await t.wait(FIXTURES_CONST.TIMEOUT); @@ -31,3 +38,38 @@ test('can do a swap', async (t) => { .expect(queryAllByTestId('SUCCESS').with({ timeout: FIXTURES_CONST.HARDHAT_TIMEOUT }).exists) .ok({ timeout: FIXTURES_CONST.HARDHAT_TIMEOUT }); }); + +test('can do an ERC20 swap', async (t) => { + await swapPage.waitPageLoaded(); + await swapPage.setupMock(); + await resetFork(); + await setupDAI(); + + await swapPage.fillFormERC20(); + await t.wait(FIXTURES_CONST.TIMEOUT); + + const button = await getByTestId('confirm-swap'); + await t.click(button); + + const approve = await queryAllByText(findByTKey('APPROVE_SWAP')) + .with({ + timeout: FIXTURES_CONST.HARDHAT_TIMEOUT + }) + .nth(1); + await t.expect(approve.exists).ok({ timeout: FIXTURES_CONST.HARDHAT_TIMEOUT }); + await t.click(approve); + + await t.wait(FIXTURES_CONST.HARDHAT_TIMEOUT); + + const send = await queryByText(findByTKey('CONFIRM_TRANSACTION')).with({ + timeout: FIXTURES_CONST.HARDHAT_TIMEOUT + }); + await t.expect(send.exists).ok({ timeout: FIXTURES_CONST.HARDHAT_TIMEOUT }); + await t.click(send); + + await t.wait(FIXTURES_CONST.HARDHAT_TIMEOUT); + + await t + .expect(queryAllByTestId('SUCCESS').count) + .eql(2, { timeout: FIXTURES_CONST.HARDHAT_TIMEOUT }); +}); diff --git a/hardhat.config.ts b/hardhat.config.ts index f12afb82b4b..58388788c8b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,4 +1,5 @@ import { HardhatUserConfig } from 'hardhat/config'; +import '@nomiclabs/hardhat-ethers'; const config: HardhatUserConfig = { networks: { diff --git a/package.json b/package.json index dc58c936e41..738abf4122a 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@ethersproject/bignumber": "5.1.1", "@ethersproject/bytes": "5.1.0", "@ethersproject/constants": "5.1.0", + "@ethersproject/contracts": "5.1.1", "@ethersproject/providers": "5.1.2", "@ethersproject/transactions": "5.1.1", "@ethersproject/units": "5.1.0", diff --git a/yarn.lock b/yarn.lock index abf822c2af5..50487f22302 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1380,6 +1380,21 @@ rustbn.js "~0.2.0" util.promisify "^1.0.1" +"@ethersproject/abi@^5.1.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.1.2.tgz#a8e75cd0455e6dc9e4861c3d1c22bbe436c1d775" + integrity sha512-uMhoQVPX0UtfzTpekYQSEUcJGDgsJ25ifz+SV6PDETWaUFhcR8RNgb1QPTASP13inW8r6iy0/Xdq9D5hK2pNvA== + dependencies: + "@ethersproject/address" "^5.1.0" + "@ethersproject/bignumber" "^5.1.0" + "@ethersproject/bytes" "^5.1.0" + "@ethersproject/constants" "^5.1.0" + "@ethersproject/hash" "^5.1.0" + "@ethersproject/keccak256" "^5.1.0" + "@ethersproject/logger" "^5.1.0" + "@ethersproject/properties" "^5.1.0" + "@ethersproject/strings" "^5.1.0" + "@ethersproject/abstract-provider@5.1.0", "@ethersproject/abstract-provider@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz#1f24c56cda5524ef4ed3cfc562a01d6b6f8eeb0b" @@ -1453,6 +1468,22 @@ dependencies: "@ethersproject/bignumber" "^5.1.0" +"@ethersproject/contracts@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.1.1.tgz#c66cb6d618fcbd73e20a6b808e8f768b2b781d0b" + integrity sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw== + dependencies: + "@ethersproject/abi" "^5.1.0" + "@ethersproject/abstract-provider" "^5.1.0" + "@ethersproject/abstract-signer" "^5.1.0" + "@ethersproject/address" "^5.1.0" + "@ethersproject/bignumber" "^5.1.0" + "@ethersproject/bytes" "^5.1.0" + "@ethersproject/constants" "^5.1.0" + "@ethersproject/logger" "^5.1.0" + "@ethersproject/properties" "^5.1.0" + "@ethersproject/transactions" "^5.1.0" + "@ethersproject/hash@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.1.0.tgz#40961d64837d57f580b7b055e0d74174876d891e"