diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index f6308b0f14..a1e9cf6fc0 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -1,4 +1,4 @@ -name: 'E2E Smoke' +name: 'Cypress Test' # concurrency: # group: pr-workflow-${{ github.ref }} @@ -116,7 +116,7 @@ jobs: run: |+ #!/bin/bash yarn preview & - yarn test:e2e -c baseUrl='http://127.0.0.1:4173/' -e grepTags=smoke,NETWORK=Ethereum + yarn test-e2e -c baseUrl='http://127.0.0.1:4173/' -e grepTags=smoke,NETWORK=Ethereum env: DISPLAY: :0.0 diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index 0cb4af026e..8649a988e8 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -1,4 +1,4 @@ -name: 'E2E Regression' +name: 'E2E Testing Schedule' on: schedule: @@ -54,7 +54,7 @@ jobs: - name: Run Cypress Test run: |+ #!/bin/bash - yarn test:e2e -c baseUrl='https://kyberswap.com/' -e grepTags=regression,NETWORK=${{ matrix.network }} + yarn test-schedule -c baseUrl='https://kyberswap.com/' -e grepTags=regression,NETWORK=${{ matrix.network }} env: DISPLAY: :0.0 diff --git a/cypress.config.ts b/cypress.config.ts index ff52e33d50..1085451248 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -13,8 +13,6 @@ export default defineConfig({ }, userAgent: 'synpress', chromeWebSecurity: true, - // video: false, - // videoCompression: false, viewportWidth: 1920, viewportHeight: 1080, env: { @@ -22,20 +20,10 @@ export default defineConfig({ grepOmitFiltered: true, }, e2e: { - testIsolation: false, setupNodeEvents(on, config) { // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config) synpressPlugins(on, config) - const options = { - printLogsToFile: 'always', - outputRoot: config.projectRoot + '/target/', - specRoot: 'cypress/e2e/specs', - outputTarget: { - 'cypress-logs|json': 'json', - }, - } - require('cypress-terminal-report/src/installLogsPrinter')(on, options) on('after:run', async results => { if (results) { const register = new client.Registry() diff --git a/cypress/e2e/pages/header.po.cy.ts b/cypress/e2e/pages/header.po.cy.ts deleted file mode 100644 index e7641eb8dc..0000000000 --- a/cypress/e2e/pages/header.po.cy.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - CrossChainLocators, - HeaderLocators, - LimitOrderLocators, - NetworkLocators, - SwapPageLocators, - TokenCatalogLocators, - WalletLocators, -} from '../selectors/selectors.cy' - -export interface myCallbackType { - (myArgument: T): void -} -export const Header = { - connectWallet() { - cy.get(WalletLocators.btnConnectWallet).should('be.visible').click() - cy.connectWallet() - }, - - getStatusConnectedWallet() { - cy.get(WalletLocators.statusConnected, { timeout: 10000 }).should('be.visible') - }, -} diff --git a/cypress/e2e/pages/pools-page.po.cy.ts b/cypress/e2e/pages/pools-page.po.cy.ts deleted file mode 100644 index 2975f3b1a5..0000000000 --- a/cypress/e2e/pages/pools-page.po.cy.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { PoolLocators } from '../selectors/selectors.cy' - -export enum CustomRange { - FullRange = 'Full Range', - Safe = 'Safe', - Common = 'Common', - Expert = 'Expert', -} -export type FarmingRange = { - minPrice: string - maxPrice: string -} -export const PoolsPage = { - open(chain: string) { - cy.visit('/pools/' + chain) - }, - searchByPoolAddress(poolAddress: string) { - cy.get(PoolLocators.txtSearchPool).clear().type(poolAddress) - cy.wait(2000) - }, - selectCustomRange(range: CustomRange) { - cy.get('button').contains(range).click() - }, - selectFarmingRange(farmingRange: FarmingRange) { - cy.get('[role=button]').contains('Farming Ranges').click() - cy.get(PoolLocators.txtPriceValue).eq(0).clear().type(farmingRange.minPrice) - cy.get(PoolLocators.txtPriceValue).eq(1).clear().type(farmingRange.maxPrice) - }, - getCurrentPrice() { - return cy - .get(PoolLocators.lblCurrentPrice) - .invoke('text') - .then(currenPriceValue => { - return currenPriceValue - }) - }, - addLiquidity(poolAddress: string, amountIn: string, customRange?: CustomRange, farmingRange?: FarmingRange) { - PoolsPage.searchByPoolAddress(poolAddress) - cy.get('button').contains('Add Liquidity').click() - cy.get(PoolLocators.btnZapIn).click() - if (typeof customRange != 'undefined') { - PoolsPage.selectCustomRange(customRange) - } - if (typeof farmingRange != 'undefined') { - PoolsPage.selectFarmingRange(farmingRange) - } - cy.get(PoolLocators.txtAmountIn).type(amountIn) - cy.wait(20000) - cy.go('back') - }, -} diff --git a/cypress/e2e/pages/swap-page.po.cy.ts b/cypress/e2e/pages/swap-page.po.cy.ts index af6d09aed8..36e67bad01 100644 --- a/cypress/e2e/pages/swap-page.po.cy.ts +++ b/cypress/e2e/pages/swap-page.po.cy.ts @@ -1,137 +1,127 @@ -import { - CrossChainLocators, - HeaderLocators, - LimitOrderLocators, - NetworkLocators, - SwapPageLocators, - TokenCatalogLocators, - WalletLocators, -} from '../selectors/selectors.cy' - -export const NETWORK = Cypress.env('NETWORK') +import { CrossChainLocators, HeaderLocators, LimitOrderLocators, NetworkLocators, SwapPageLocators, TokenCatalogLocators, WalletLocators } from "../selectors/selectors.cy" export interface myCallbackType { - (myArgument: T): void + (myArgument: T): void } export const SwapPage = { - open(url: string) { - cy.visit('/' + url) - cy.url().should('include', url) - cy.closeTutorialPopup() - }, - - selectTokenIn(): TokenCatalog { - cy.selectToken(SwapPageLocators.dropdownTokenIn) - return new TokenCatalog() - }, - selectTokenOut(): TokenCatalog { - cy.selectToken(SwapPageLocators.dropdownTokenOut) - return new TokenCatalog() - }, - - getCurrentTokenIn(text: myCallbackType) { - cy.getContent(SwapPageLocators.dropdownTokenIn, text) - }, - - getCurrentTokenOut(text: myCallbackType) { - cy.getContent(SwapPageLocators.dropdownTokenOut, text) - }, - - connectWallet() { - cy.get(WalletLocators.btnConnectWallet).should('be.visible').click() - cy.connectWallet() - }, - - getStatusConnectedWallet() { - cy.get(WalletLocators.statusConnected, { timeout: 10000 }).should('be.visible') - }, - - goToLimitOrder() { - cy.get(LimitOrderLocators.btnLimit).click() - }, - - goToCrossChain() { - cy.get(CrossChainLocators.btnCrossChain).click() - }, - - goToFarmPage() { - cy.get(HeaderLocators.dropdownEarn).click({ force: true }) - cy.get(HeaderLocators.lblFarms).click({ force: true }) - }, - - goToPoolPage() { - cy.get(HeaderLocators.dropdownEarn).click({ force: true }) - cy.get(HeaderLocators.lblPools).click({ force: true }) - }, - - goToMyPoolsPage() { - cy.get(HeaderLocators.dropdownEarn).click({ force: true }) - cy.get(HeaderLocators.lblMyPools).click({ force: true }) - }, + open(url: string) { + cy.visit('/' + url) + cy.url().should('include', url) + cy.closeTutorialPopup() + }, + + selectTokenIn(): TokenCatalog { + cy.selectToken(SwapPageLocators.dropdownTokenIn) + return new TokenCatalog() + }, + selectTokenOut(): TokenCatalog { + cy.selectToken(SwapPageLocators.dropdownTokenOut) + return new TokenCatalog() + }, + + getCurrentTokenIn(text: myCallbackType) { + cy.getContent(SwapPageLocators.dropdownTokenIn, text) + }, + + getCurrentTokenOut(text: myCallbackType) { + cy.getContent(SwapPageLocators.dropdownTokenOut, text) + }, + + connectWallet() { + cy.get(WalletLocators.btnConnectWallet).should('be.visible').click() + cy.connectWallet() + }, + + getStatusConnectedWallet() { + cy.get(WalletLocators.statusConnected, { timeout: 10000 }).should('be.visible') + }, + + goToLimitOrder() { + cy.get(LimitOrderLocators.btnLimit).click() + }, + + goToCrossChain() { + cy.get(CrossChainLocators.btnCrossChain).click() + }, + + goToFarmPage() { + cy.get(HeaderLocators.dropdownEarn).click({ force: true }) + cy.get(HeaderLocators.lblFarms).click({ force: true }) + }, + + goToPoolPage() { + cy.get(HeaderLocators.dropdownEarn).click({ force: true }) + cy.get(HeaderLocators.lblPools).click({ force: true }) + }, + + goToMyPoolsPage() { + cy.get(HeaderLocators.dropdownEarn).click({ force: true }) + cy.get(HeaderLocators.lblMyPools).click({ force: true }) + }, } export class Network { - selectNetwork(network: string) { - cy.get(NetworkLocators.btnSelectNetwork, { timeout: 30000 }).should('be.visible').click() - cy.get(NetworkLocators.btnNetwork).contains(network).click({ force: true }) - } + selectNetwork(network: string) { + cy.get(NetworkLocators.btnSelectNetwork, { timeout: 30000 }).should('be.visible').click() + cy.get(NetworkLocators.btnNetwork).contains(network).click({ force: true }) + } } export class TokenCatalog { - searchToken(value: string) { - cy.searchToken(value) - } - - selectImportTab() { - cy.selectImportTab() - } - - selectFavoriteToken(tokenSymbol: string) { - cy.selectFavoriteToken(tokenSymbol) - } - - selectTokenBySymbol(tokenSymbol: string) { - this.searchToken(tokenSymbol) - cy.selectTokenBySymbol(tokenSymbol) - } - - addFavoriteToken(tokenSymbol: Array) { - tokenSymbol.forEach(element => { - this.searchToken(element) - cy.wait(2000) - cy.addFavoriteToken() - }) - } - - removeFavoriteToken(tokenSymbol: string) { - cy.removeFavoriteToken(tokenSymbol) - } - - importNewTokens(address: Array) { - address.forEach(element => { - SwapPage.selectTokenIn() - cy.importNewToken(element) - }) - } - - deleteImportedToken(value: string) { - cy.deleteImportedToken(value) - } - - clearAllImportedTokens() { - cy.clearAllImportedTokens() - } - - getFavoriteTokens(list: myCallbackType) { - cy.getList(TokenCatalogLocators.lblFavoriteToken, list) - } - - getWhitelistTokens(list: myCallbackType) { - cy.getList(TokenCatalogLocators.lblTokenSymbol, list) - } - - getNoResultsFound(text: myCallbackType) { - cy.getContent(TokenCatalogLocators.lblNotFound, text) - } -} + searchToken(value: string) { + cy.searchToken(value) + } + + selectImportTab() { + cy.selectImportTab() + } + + selectFavoriteToken(tokenSymbol: string) { + cy.selectFavoriteToken(tokenSymbol) + } + + selectTokenBySymbol(tokenSymbol: string) { + this.searchToken(tokenSymbol) + cy.selectTokenBySymbol(tokenSymbol) + } + + addFavoriteToken(tokenSymbol: Array) { + tokenSymbol.forEach(element => { + this.searchToken(element) + cy.wait(2000) + cy.addFavoriteToken() + }); + } + + removeFavoriteToken(tokenSymbol: string) { + cy.removeFavoriteToken(tokenSymbol) + } + + importNewTokens(address: Array) { + address.forEach(element => { + SwapPage.selectTokenIn() + cy.importNewToken(element) + }) + } + + deleteImportedToken(value: string) { + cy.deleteImportedToken(value) + } + + clearAllImportedTokens() { + cy.clearAllImportedTokens() + } + + getFavoriteTokens(list: myCallbackType) { + cy.getList(TokenCatalogLocators.lblFavoriteToken, list) + } + + getWhitelistTokens(list: myCallbackType) { + cy.getList(TokenCatalogLocators.lblTokenSymbol, list) + } + + getNoResultsFound(text: myCallbackType) { + cy.getContent(TokenCatalogLocators.lblNotFound, text) + } +} \ No newline at end of file diff --git a/cypress/e2e/selectors/constants.cy.ts b/cypress/e2e/selectors/constants.cy.ts index 5914bc8043..4b778d56eb 100644 --- a/cypress/e2e/selectors/constants.cy.ts +++ b/cypress/e2e/selectors/constants.cy.ts @@ -1,105 +1,99 @@ export const UNWHITELIST_SYMBOL_TOKENS = ['KNNC', 'KCCN'] -export const NORESULTS_TEXT = 'No results found.' -export const NOTOKENS_TEXT = 'Select a token' -export const DEFAULT_NETWORK = 'Ethereum' -export const NETWORK: string = Cypress.env('NETWORK') +export const NORESULTS_TEXT = "No results found." +export const NOTOKENS_TEXT = "Select a token" +export const DEFAULT_NETWORK = "Ethereum" +export const NETWORK = Cypress.env('NETWORK') export const DEFAULT_URL = `swap/${NETWORK}`.toLowerCase() + export enum TAG { - smoke = 'smoke', - regression = 'regression', - zap = 'zap', + smoke = 'smoke', + regression = 'regression', } export const TOKEN_SYMBOLS = { - Ethereum: ['BAND', 'ETH', 'USDT', 'USDC', '1INCH'], - Arbitrum: ['ANGLE', 'ARB', 'USDT', 'USDC.e', 'BOB'], - Optimism: ['BOND', 'ETH', 'USDT', 'USDC', 'BOB'], - Avalanche: ['AAVE.e', 'sAVAX', 'USDT.e', 'USDC.e', 'BUSD.e'], - BNB: ['RICE', 'BUSD', 'USDT', 'USDC', 'BOB'], + 'Ethereum': ['BAND', 'USDC', 'USDT', 'ETH', '1INCH'], + 'Arbitrum': ['ANGLE', 'ARB', 'USDT', 'USDC.e', 'BOB'], + 'Optimism': ['BOND', 'USDC.e', 'USDT', 'ETH', 'BOB'], + 'Avalanche': ['AAVE.e', 'sAVAX', 'USDT.e', 'USDC.e', 'BUSD.e'], + 'BNB': ['RICE', 'BUSD', 'USDT', 'USDC', 'BOB'] } -export const NETWORK_LIST = [ - 'Ethereum', - 'Arbitrum', - 'Optimism', - 'Avalanche', - 'BNB Chain', - 'Polygon PoS', - 'Fantom', - 'Linea', - 'Base', -] +export const NETWORK_LIST = ['Ethereum', 'Arbitrum', 'Optimism', 'Avalanche', 'BNB Chain', 'Polygon PoS', 'Fantom', 'Linea', 'Base'] export const UNWHITELIST_TOKENS = { - Ethereum: [ - { - symbol: 'SCOOBY', - address: '0xAd497eE6a70aCcC3Cbb5eB874e60d87593B86F2F', - }, - { - symbol: 'UNIBOT', - address: '0x25127685dc35d4dc96c7feac7370749d004c5040', - }, - { - symbol: 'BGB', - address: '0x19de6b897ed14a376dda0fe53a5420d2ac828a28', - }, - ], - Arbitrum: [ - { - symbol: 'OHM', - address: '0xf0cb2dc0db5e6c66b9a70ac27b06b878da017028', - }, - { - symbol: 'GBL', - address: '0xe9a264e9d45ff72e1b4a85d77643cdbd4c950207', - }, - { - symbol: 'Y2K', - address: '0x65c936f008bc34fe819bce9fa5afd9dc2d49977f', - }, - ], - Optimism: [ - { - symbol: 'CHI', - address: '0xca0e54b636db823847b29f506bffee743f57729d', - }, - { - symbol: 'ACX', - address: '0xFf733b2A3557a7ed6697007ab5D11B79FdD1b76B', - }, - { - symbol: 'PSP', - address: '0xd3594e879b358f430e20f82bea61e83562d49d48', - }, - ], - Avalanche: [ - { - symbol: 'RADIO', - address: '0x02bfd11499847003de5f0f5aa081c43854d48815', - }, - { - symbol: 'EUROC', - address: '0xc891eb4cbdeff6e073e859e987815ed1505c2acd', - }, - { - symbol: 'MELD', - address: '0x333000333b26ee30214b4af6419d9ab07a450400', - }, - ], - BNB: [ - { - symbol: 'TUSD', - address: '0x40af3827f39d0eacbf4a168f8d4ee67c121d11c9', - }, - { - symbol: 'ARA', - address: '0x5542958fa9bd89c96cb86d1a6cb7a3e644a3d46e', - }, - { - symbol: 'FLASH', - address: '0xc3111096b3b46873393055dea14036ea603cfa95', - }, - ], -} + "Ethereum": + [ + { + symbol: 'SCOOBY', + address: '0xAd497eE6a70aCcC3Cbb5eB874e60d87593B86F2F', + }, + { + symbol: 'UNIBOT', + address: '0x25127685dc35d4dc96c7feac7370749d004c5040', + }, + { + symbol: 'BGB', + address: '0x19de6b897ed14a376dda0fe53a5420d2ac828a28', + }, + ], + "Arbitrum": [ + { + symbol: 'OHM', + address: '0xf0cb2dc0db5e6c66b9a70ac27b06b878da017028', + }, + { + symbol: 'GBL', + address: '0xe9a264e9d45ff72e1b4a85d77643cdbd4c950207', + }, + { + symbol: 'Y2K', + address: '0x65c936f008bc34fe819bce9fa5afd9dc2d49977f', + }, + ], + "Optimism": + [ + { + symbol: 'CHI', + address: '0xca0e54b636db823847b29f506bffee743f57729d', + }, + { + symbol: 'ACX', + address: '0xFf733b2A3557a7ed6697007ab5D11B79FdD1b76B', + }, + { + symbol: 'PSP', + address: '0xd3594e879b358f430e20f82bea61e83562d49d48', + }, + ], + "Avalanche": + [ + { + symbol: 'RADIO', + address: '0x02bfd11499847003de5f0f5aa081c43854d48815', + }, + { + symbol: 'EUROC', + address: '0xc891eb4cbdeff6e073e859e987815ed1505c2acd', + }, + { + symbol: 'MELD', + address: '0x333000333b26ee30214b4af6419d9ab07a450400', + }, + ], + "BNB": + [ + { + symbol: 'TUSD', + address: '0x40af3827f39d0eacbf4a168f8d4ee67c121d11c9', + }, + { + symbol: 'ARA', + address: '0x5542958fa9bd89c96cb86d1a6cb7a3e644a3d46e', + }, + { + symbol: 'FLASH', + address: '0xc3111096b3b46873393055dea14036ea603cfa95', + } + ], +} \ No newline at end of file diff --git a/cypress/e2e/selectors/selectors.cy.ts b/cypress/e2e/selectors/selectors.cy.ts index 3ac8d89c5f..369b57a13b 100644 --- a/cypress/e2e/selectors/selectors.cy.ts +++ b/cypress/e2e/selectors/selectors.cy.ts @@ -13,7 +13,7 @@ export const TokenCatalogLocators = { btnUnderstand: '[data-testid=button-confirm-import-token]', btnClearAll: '[data-testid=button-clear-all-import-token]', btnAllTab: '[data-testid=tab-all]', - btnImportTab: '[data-testid=tab-import]', + btnImportTab: '[data-testid=tab-import]' } export const SwapPageLocators = { @@ -30,7 +30,7 @@ export const LimitOrderLocators = { txtSellingRate: '[data-testid=input-selling-rate]', lblBalanceIn: '[data-testid=limit-order-input-tokena] [data-testid=balance]', lblErrorMessage: '[data-testid=error-message]', - btnGetStarted: '[data-testid=get-started-button]', + btnGetStarted: '[data-testid=get-started-button]' } export const CrossChainLocators = { @@ -38,7 +38,7 @@ export const CrossChainLocators = { btnNetworkIn: '[data-testid=swap-currency-input] [data-testid=network-button]', btnNetworkOut: '[data-testid=swap-currency-output] [data-testid=network-button]', btnUnderstand: '[data-testid=understand-button]', - rechartsSurface: '.recharts-surface', //it's in the library so don't use data-testid + rechartsSurface: '.recharts-surface' //it's in the library so don't use data-testid } export const WalletLocators = { @@ -63,12 +63,4 @@ export const HeaderLocators = { export const FarmLocators = { lblApr: '[data-testid=apr-value]', lblTvl: '[data-testid=tvl-value]', -} - -export const PoolLocators = { - txtSearchPool: 'input[data-testid="search-pool"]', - txtPriceValue: 'input[data-testid="price-value"]', - txtAmountIn: '[data-testid="token-amount-input"]', - lblCurrentPrice: '[data-testid="current-price"]', - btnZapIn: '[data-testid="zap-in-btn"]', -} +} \ No newline at end of file diff --git a/cypress/e2e/specs/connect-wallet.e2e.cy.ts b/cypress/e2e/specs/connect-wallet.e2e.cy.ts deleted file mode 100644 index aa43af977c..0000000000 --- a/cypress/e2e/specs/connect-wallet.e2e.cy.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Network, SwapPage } from '../pages/swap-page.po.cy' -import { DEFAULT_NETWORK, DEFAULT_URL, NETWORK, TAG } from '../selectors/constants.cy' - -const wallet = new Network() - -describe('Metamask Extension tests', { tags: TAG.regression }, () => { - before(() => { - SwapPage.open(DEFAULT_URL) - SwapPage.connectWallet() - cy.acceptMetamaskAccess() - SwapPage.getStatusConnectedWallet() - }) - - it('Redirects to swap page when a user has already connected a wallet', { tags: TAG.smoke }, () => { - cy.url().should('include', '/swap') - }) - - it('Should approve permission to switch network', () => { - if (NETWORK !== DEFAULT_NETWORK) { - SwapPage.getStatusConnectedWallet() - wallet.selectNetwork(NETWORK) - cy.allowMetamaskToAddAndSwitchNetwork().then(approved => { - expect(approved).to.be.true - }) - } - }) -}) diff --git a/cypress/e2e/specs/constants.ts b/cypress/e2e/specs/constants.ts deleted file mode 100644 index 0ab7fc596f..0000000000 --- a/cypress/e2e/specs/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -const noResultsText = 'No results found.' -const noTokensText = 'Select a token' -const unListedToken = ['KNNC', 'KCCN'] diff --git a/cypress/e2e/specs/cross-chain.e2e.cy.ts b/cypress/e2e/specs/cross-chain.e2e.cy.ts index 23a99c3338..7d19e2715a 100644 --- a/cypress/e2e/specs/cross-chain.e2e.cy.ts +++ b/cypress/e2e/specs/cross-chain.e2e.cy.ts @@ -6,30 +6,26 @@ describe(`Cross-chain on ${NETWORK}`, { tags: TAG.regression }, () => { beforeEach(() => { SwapPage.open(DEFAULT_URL) SwapPage.connectWallet() - SwapPage.getStatusConnectedWallet() - - SwapPage.goToCrossChain() - CrossChain.checkLoadedPage().then((checked) => { - if (checked === true) { - CrossChain.closeUnderstandPopup() - } - }) }) describe('Select network', () => { + beforeEach(() => { + cy.acceptMetamaskAccess() + SwapPage.getStatusConnectedWallet() + + SwapPage.goToCrossChain() + CrossChain.checkLoadedPage().then((checked) => { + if (checked === true) { + CrossChain.closeUnderstandPopup() + } + }) + }) it('The network should be changed successfully', () => { - const networkIn = CrossChain.changeNetwork([NETWORK]) + const networkIn = CrossChain.changeNetwork([NETWORK, DEFAULT_NETWORK]) CrossChain.selectNetworkIn(networkIn) - if (networkIn != DEFAULT_NETWORK) { - cy.allowMetamaskToAddAndSwitchNetwork().then(approved => { - expect(approved).to.be.true - }) - } - else { - cy.allowMetamaskToSwitchNetwork().then(approved => { - expect(approved).to.be.true - }) - } + cy.allowMetamaskToAddAndSwitchNetwork().then(approved => { + expect(approved).to.be.true + }) CrossChain.getCurrentNetworkIn().then((currentNetworkIn) => { expect(currentNetworkIn).to.equal(networkIn) }) diff --git a/cypress/e2e/specs/limit-order.e2e.cy.ts b/cypress/e2e/specs/limit-order.e2e.cy.ts index 9c3030c544..b85c69f8e7 100644 --- a/cypress/e2e/specs/limit-order.e2e.cy.ts +++ b/cypress/e2e/specs/limit-order.e2e.cy.ts @@ -17,13 +17,15 @@ describe(`Limit Order on ${NETWORK}`, { tags: TAG.regression }, () => { describe('Add/remove/select token with favorite tokens list', () => { beforeEach(() => { - if (NETWORK === 'BNB' || NETWORK === 'Ethereum') { - netw.selectNetwork(NETWORK) + netw.selectNetwork(NETWORK) + if (NETWORK === 'Ethereum') { cy.allowMetamaskToSwitchNetwork().then(approved => { expect(approved).to.be.true }) } else { - cy.changeMetamaskNetwork(NETWORK) + cy.allowMetamaskToAddAndSwitchNetwork().then(approved => { + expect(approved).to.be.true + }) } SwapPage.goToLimitOrder() LimitOder.checkGetStartedDisplay().then((checked) => { diff --git a/cypress/e2e/specs/swap-page.e2e.cy.ts b/cypress/e2e/specs/swap-page.e2e.cy.ts index bc93ebf5c0..087e2fa7f8 100644 --- a/cypress/e2e/specs/swap-page.e2e.cy.ts +++ b/cypress/e2e/specs/swap-page.e2e.cy.ts @@ -1,14 +1,5 @@ -import { SwapPage, TokenCatalog } from '../pages/swap-page.po.cy' -import { - DEFAULT_URL, - NETWORK, - NORESULTS_TEXT, - NOTOKENS_TEXT, - TAG, - TOKEN_SYMBOLS, - UNWHITELIST_SYMBOL_TOKENS, - UNWHITELIST_TOKENS, -} from '../selectors/constants.cy' +import { SwapPage, TokenCatalog } from "../pages/swap-page.po.cy" +import { DEFAULT_URL, NETWORK, NORESULTS_TEXT, NOTOKENS_TEXT, TAG, TOKEN_SYMBOLS, UNWHITELIST_SYMBOL_TOKENS, UNWHITELIST_TOKENS } from "../selectors/constants.cy" const unWhitelistTokens = UNWHITELIST_TOKENS[NETWORK] const tokenSymbols = TOKEN_SYMBOLS[NETWORK] @@ -16,164 +7,169 @@ const tokenSymbols = TOKEN_SYMBOLS[NETWORK] const arrAddress = [unWhitelistTokens[0].address, unWhitelistTokens[1].address, unWhitelistTokens[2].address] const arrSymbol = [unWhitelistTokens[0].symbol, unWhitelistTokens[1].symbol, unWhitelistTokens[2].symbol] -const tokenCatalog = new TokenCatalog() + +const tokenCatalog = new TokenCatalog(); + describe(`Token Catalog on ${NETWORK}`, { tags: TAG.regression }, () => { - before(() => { - SwapPage.open(DEFAULT_URL) - SwapPage.connectWallet() - SwapPage.getStatusConnectedWallet() - }) - - describe('Select token in favorite tokens list', () => { - it('Should be selected tokenIn in favorite tokens list successfully', () => { - SwapPage.selectTokenIn().getFavoriteTokens(arr => { - tokenCatalog.selectFavoriteToken(arr[1]) - SwapPage.getCurrentTokenIn(text => { - expect(text).to.equal(arr[1]) - }) - }) + beforeEach(() => { + SwapPage.open(DEFAULT_URL) + SwapPage.connectWallet() + SwapPage.getStatusConnectedWallet() }) - it('Should be selected tokenOut in favorite tokens list successfully', () => { - SwapPage.selectTokenOut().getFavoriteTokens(arr => { - tokenCatalog.selectFavoriteToken(arr[2]) - SwapPage.getCurrentTokenOut(text => { - expect(text).to.equal(arr[2]) + describe('Select token in favorite tokens list', () => { + it('Should be selected tokenIn in favorite tokens list successfully', () => { + SwapPage.selectTokenIn().getFavoriteTokens((arr) => { + tokenCatalog.selectFavoriteToken(arr[1]) + SwapPage.getCurrentTokenIn((text) => { + expect(text).to.equal(arr[1]) + }) + }) }) - }) - }) - }) - describe('Remove/add token with favorite tokens list', () => { - it('Should be removed tokenIn from favorite tokens list', () => { - SwapPage.selectTokenIn().getFavoriteTokens(arr => { - tokenCatalog.removeFavoriteToken(arr[1]) - cy.wait(2000) - tokenCatalog.getFavoriteTokens(list => { - expect(list).not.to.include.members([arr[1]]) + it('Should be selected tokenOut in favorite tokens list successfully', () => { + SwapPage.selectTokenOut().getFavoriteTokens((arr) => { + tokenCatalog.selectFavoriteToken(arr[2]) + SwapPage.getCurrentTokenOut((text) => { + expect(text).to.equal(arr[2]) + }) + }) }) - }) }) - it('Should be added tokenIn to favorite tokens list', () => { - SwapPage.selectTokenIn().addFavoriteToken([tokenSymbols[0]]) - tokenCatalog.getFavoriteTokens(list => { - expect(list).to.include.members([tokenSymbols[0]]) - }) - }) + describe('Remove/add token with favorite tokens list', () => { + it('Should be removed tokenIn from favorite tokens list', () => { + SwapPage.selectTokenIn().getFavoriteTokens((arr) => { + tokenCatalog.removeFavoriteToken(arr[1]) + cy.wait(2000) + tokenCatalog.getFavoriteTokens((list) => { + expect(list).not.to.include.members([arr[1]]) + }) + }) + }) - it('Should be removed tokenOut from favorite tokens list', () => { - SwapPage.selectTokenOut().getFavoriteTokens(arr => { - tokenCatalog.removeFavoriteToken(arr[2]) - cy.wait(2000) - tokenCatalog.getFavoriteTokens(list => { - expect(list).not.to.include.members([arr[2]]) + it('Should be added tokenIn to favorite tokens list', () => { + SwapPage.selectTokenIn().addFavoriteToken([tokenSymbols[0]]) + tokenCatalog.getFavoriteTokens((list) => { + expect(list).to.include.members([tokenSymbols[0]]) + }) }) - }) - }) - it('Should be added tokenOut to favorite tokens list', () => { - SwapPage.selectTokenOut().addFavoriteToken([tokenSymbols[0]]) - tokenCatalog.getFavoriteTokens(list => { - expect(list).to.include.members([tokenSymbols[0]]) - }) - }) - }) - - describe('Select token by symbol', () => { - it('Should be selected tokenIn by symbol successfully', () => { - SwapPage.selectTokenIn().selectTokenBySymbol(tokenSymbols[0]) - SwapPage.getCurrentTokenIn(text => { - expect(text).to.equal(tokenSymbols[0]) - }) - }) + it('Should be removed tokenOut from favorite tokens list', () => { + SwapPage.selectTokenOut().getFavoriteTokens((arr) => { + tokenCatalog.removeFavoriteToken(arr[2]) + cy.wait(2000) + tokenCatalog.getFavoriteTokens((list) => { + expect(list).not.to.include.members([arr[2]]) + }) + }) + }) - it('Should be selected tokenOut by symbol successfully', () => { - SwapPage.selectTokenOut().selectTokenBySymbol(tokenSymbols[1]) - SwapPage.getCurrentTokenOut(text => { - expect(text).to.equal(tokenSymbols[1]) - }) + it('Should be added tokenOut to favorite tokens list', () => { + SwapPage.selectTokenOut().addFavoriteToken([tokenSymbols[0]]) + tokenCatalog.getFavoriteTokens((list) => { + expect(list).to.include.members([tokenSymbols[0]]) + }) + }) }) - it('Should be unselected tokenIn not exist in whitelist', () => { - SwapPage.selectTokenIn().searchToken(UNWHITELIST_SYMBOL_TOKENS[0]) - tokenCatalog.getNoResultsFound(text => { - expect(text).to.equal(NORESULTS_TEXT) - }) - }) + describe('Select token by symbol', () => { + it('Should be selected tokenIn by symbol successfully', () => { + SwapPage.selectTokenIn().selectTokenBySymbol(tokenSymbols[0]) + SwapPage.getCurrentTokenIn((text) => { + expect(text).to.equal(tokenSymbols[0]) + }) + }) - it('Should be unselected tokenOut not exist in whitelist', () => { - SwapPage.selectTokenOut().searchToken(UNWHITELIST_SYMBOL_TOKENS[0]) - tokenCatalog.getNoResultsFound(text => { - expect(text).to.equal(NORESULTS_TEXT) - }) - }) - }) - - describe('Import and delete token', () => { - it('Should be imported then deleted tokenIn successfully', () => { - tokenCatalog.importNewTokens(arrAddress) - SwapPage.selectTokenIn().selectImportTab() - tokenCatalog.getWhitelistTokens(list => { - expect(list).to.include.members(arrSymbol) - }) - - tokenCatalog.deleteImportedToken(arrSymbol[2]) - tokenCatalog.getWhitelistTokens(list => { - expect(list).not.to.include.members([arrSymbol[2]]) - }) - - tokenCatalog.clearAllImportedTokens() - tokenCatalog.getNoResultsFound(text => { - expect(text).to.equal(NORESULTS_TEXT) - }) + it('Should be selected tokenOut by symbol successfully', () => { + SwapPage.selectTokenOut().selectTokenBySymbol(tokenSymbols[1]) + SwapPage.getCurrentTokenOut((text) => { + expect(text).to.equal(tokenSymbols[1]) + }) + }) + + it('Should be unselected tokenIn not exist in whitelist', () => { + SwapPage.selectTokenIn().searchToken(UNWHITELIST_SYMBOL_TOKENS[0]) + tokenCatalog.getNoResultsFound((text) => { + expect(text).to.equal(NORESULTS_TEXT) + }) + }) + + it('Should be unselected tokenOut not exist in whitelist', () => { + SwapPage.selectTokenOut().searchToken(UNWHITELIST_SYMBOL_TOKENS[0]) + tokenCatalog.getNoResultsFound((text) => { + expect(text).to.equal(NORESULTS_TEXT) + }) + }) }) - it('Should be imported then deleted tokenOut successfully', () => { - tokenCatalog.importNewTokens(arrAddress) - SwapPage.selectTokenOut().selectImportTab() - tokenCatalog.getWhitelistTokens(list => { - expect(list).to.include.members(arrSymbol) - }) - - tokenCatalog.deleteImportedToken(arrSymbol[1]) - tokenCatalog.getWhitelistTokens(list => { - expect(list).not.to.include.members([arrSymbol[1]]) - }) - - tokenCatalog.clearAllImportedTokens() - tokenCatalog.getNoResultsFound(text => { - expect(text).to.equal(NORESULTS_TEXT) - }) + describe('Import and delete token', () => { + it('Should be imported then deleted tokenIn successfully', () => { + tokenCatalog.importNewTokens(arrAddress) + SwapPage.selectTokenIn().selectImportTab() + tokenCatalog.getWhitelistTokens((list) => { + expect(list).to.include.members(arrSymbol) + }) + + tokenCatalog.deleteImportedToken(arrSymbol[2]) + tokenCatalog.getWhitelistTokens((list) => { + expect(list).not.to.include.members([arrSymbol[2]]) + }) + + tokenCatalog.clearAllImportedTokens() + tokenCatalog.getNoResultsFound((text) => { + expect(text).to.equal(NORESULTS_TEXT) + }) + }) + + it('Should be imported then deleted tokenOut successfully', () => { + tokenCatalog.importNewTokens(arrAddress) + SwapPage.selectTokenOut().selectImportTab() + tokenCatalog.getWhitelistTokens((list) => { + expect(list).to.include.members(arrSymbol) + }) + + tokenCatalog.deleteImportedToken(arrSymbol[1]) + tokenCatalog.getWhitelistTokens((list) => { + expect(list).not.to.include.members([arrSymbol[1]]) + }) + + tokenCatalog.clearAllImportedTokens() + tokenCatalog.getNoResultsFound((text) => { + expect(text).to.equal(NORESULTS_TEXT) + }) + }) }) - }) +}) - describe(`E2E Token Catalog`, () => { +describe(`E2E Token Catalog`, () => { + beforeEach(() => { + SwapPage.open(DEFAULT_URL) + SwapPage.connectWallet() + cy.acceptMetamaskAccess() + SwapPage.getStatusConnectedWallet() + }) it('Should be selected tokenIn and tokenOut to swap', { tags: TAG.smoke }, () => { - tokenCatalog.importNewTokens([arrAddress[2]]) - SwapPage.getCurrentTokenIn(text => { - expect(text).to.equal(arrSymbol[2]) - }) - - SwapPage.selectTokenOut().getFavoriteTokens(arr => { - tokenCatalog.selectFavoriteToken(arr[1]) - SwapPage.getCurrentTokenOut(text => { - expect(text).to.equal(arr[1]) - }) - }) - - SwapPage.selectTokenOut() - tokenCatalog.deleteImportedToken(arrSymbol[2]) - tokenCatalog.getNoResultsFound(text => { - expect(text).to.equal(NORESULTS_TEXT) - }) - SwapPage.getCurrentTokenIn(text => { - expect(text).to.equal(NOTOKENS_TEXT) - }) + tokenCatalog.importNewTokens([arrAddress[2]]) + SwapPage.getCurrentTokenIn((text) => { + expect(text).to.equal(arrSymbol[2]) + }) + + SwapPage.selectTokenOut().getFavoriteTokens((arr) => { + tokenCatalog.selectFavoriteToken(arr[1]) + SwapPage.getCurrentTokenOut((text) => { + expect(text).to.equal(arr[1]) + }) + }) + + SwapPage.selectTokenOut() + tokenCatalog.deleteImportedToken(arrSymbol[2]) + tokenCatalog.getNoResultsFound((text) => { + expect(text).to.equal(NORESULTS_TEXT) + }) + SwapPage.getCurrentTokenIn((text) => { + expect(text).to.equal(NOTOKENS_TEXT) + }) }) - }) - afterEach(() => { - cy.reload() - }) -}) +}) \ No newline at end of file diff --git a/cypress/e2e/specs/zap-in-simulator-test.mjs b/cypress/e2e/specs/zap-in-simulator-test.mjs deleted file mode 100644 index a951e60ccb..0000000000 --- a/cypress/e2e/specs/zap-in-simulator-test.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import test from 'node:test' -import assert from 'node:assert/strict' - -import output from '../../../target/cypress-logs/zap.e2e.cy.json' assert {type: 'json'} -import { simulateTenderly,getTokenInFromZapEncodeData } from '../../support/tenderly.js'; -import 'dotenv/config' -const suite = output['cypress/e2e/specs/zap.e2e.cy.ts']; -const testcases = Object.keys(suite) - -testcases.forEach((testcase)=>{ - test(testcase, async () => { - const zapInData = suite[testcase] - .filter(log => { - return log.type == 'cons:debug' && log.message.includes('zap data') && log.severity.includes('success') - }) - .slice(-1) - .pop()['message'].replace('zap data,\n', '') - - const data = JSON.parse(zapInData) - data.chainId = process.env.CHAIN_ID - data.tokenIn = getTokenInFromZapEncodeData(data) - - const result = await simulateTenderly(data) - console.log(result) - assert.equal(result.success, true) - }) -}) \ No newline at end of file diff --git a/cypress/e2e/specs/zap.e2e.cy.ts b/cypress/e2e/specs/zap.e2e.cy.ts deleted file mode 100644 index d713ce4f81..0000000000 --- a/cypress/e2e/specs/zap.e2e.cy.ts +++ /dev/null @@ -1,40 +0,0 @@ -import arbitrumTestCases from '../../fixtures/zap/arbitrum.json' -import avalancheTestCases from '../../fixtures/zap/avalanche.json' -import bscTestCases from '../../fixtures/zap/bsc.json' -import ethereumTestCases from '../../fixtures/zap/ethereum.json' -import optimismTestCases from '../../fixtures/zap/optimism.json' -import { CustomRange, FarmingRange, PoolsPage } from '../pages/pools-page.po.cy' -import { Network, SwapPage } from '../pages/swap-page.po.cy' -import { DEFAULT_NETWORK, DEFAULT_URL, NETWORK, TAG } from '../selectors/constants.cy' - -const wallet = new Network() - -const DataSet = { - Arbitrum: arbitrumTestCases, - Ethereum: ethereumTestCases, - Avalanche: avalancheTestCases, - 'BNB Chain': bscTestCases, - Optimism: optimismTestCases, -} -describe('Zap In', { tags: TAG.zap }, () => { - const zapTestData = DataSet[NETWORK] - before(() => { - SwapPage.open(DEFAULT_URL) - SwapPage.connectWallet() - if (NETWORK !== DEFAULT_NETWORK) { - cy.acceptMetamaskAccess() - SwapPage.getStatusConnectedWallet() - wallet.selectNetwork(NETWORK) - cy.allowMetamaskToAddAndSwitchNetwork().then(approved => { - expect(approved).to.be.true - }) - SwapPage.goToPoolPage() - } - }) - - zapTestData.forEach(testData => { - it(`${NETWORK}: ${testData.pair} ${testData.feeTier}`, function () { - PoolsPage.addLiquidity(testData.id, testData.amountIn, testData.customRange as CustomRange, testData.farmingRange) - }) - }) -}) diff --git a/cypress/fixtures/zap/arbitrum.json b/cypress/fixtures/zap/arbitrum.json deleted file mode 100644 index 1ca8325fe1..0000000000 --- a/cypress/fixtures/zap/arbitrum.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "id": "0x83fe9065ed68506a0d2ece59cd71c43bbff6e450", - "amountIn": "100", - "pair": "wstETH-axl.wstET", - "feeTier": "0.008%", - "farmingRange": { - "minPrice": "0.999", - "maxPrice": "1.2" - } - }, - { - "id": "0xdf03ca6c633f784ac5e062dd708b15728b488621", - "amountIn": "100", - "pair": "ETH-ARB", - "feeTier": "0.25%", - "customRange": "Full Range" - }, - { - "id": "0xc23f1d198477c0bcae0cac2ec734ceda438a8990", - "amountIn": "100", - "pair": "USDC-USDC.e", - "feeTier": "0.008%", - "customRange": "Safe" - } -] diff --git a/cypress/fixtures/zap/avalanche.json b/cypress/fixtures/zap/avalanche.json deleted file mode 100644 index fe51488c70..0000000000 --- a/cypress/fixtures/zap/avalanche.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/cypress/fixtures/zap/bsc.json b/cypress/fixtures/zap/bsc.json deleted file mode 100644 index fe51488c70..0000000000 --- a/cypress/fixtures/zap/bsc.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/cypress/fixtures/zap/ethereum.json b/cypress/fixtures/zap/ethereum.json deleted file mode 100644 index fe51488c70..0000000000 --- a/cypress/fixtures/zap/ethereum.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/cypress/fixtures/zap/optimism.json b/cypress/fixtures/zap/optimism.json deleted file mode 100644 index fe51488c70..0000000000 --- a/cypress/fixtures/zap/optimism.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/cypress/support/KSZAPRouterABI.json b/cypress/support/KSZAPRouterABI.json deleted file mode 100644 index be4e790ca7..0000000000 --- a/cypress/support/KSZAPRouterABI.json +++ /dev/null @@ -1,268 +0,0 @@ -[ - { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "internalType": "bytes", "name": "_clientData", "type": "bytes" }], - "name": "ClientData", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "internalType": "string", "name": "reason", "type": "string" }], - "name": "Error", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "internalType": "address", "name": "_executor", "type": "address" }, - { "indexed": true, "internalType": "bool", "name": "_grantOrRevoke", "type": "bool" } - ], - "name": "ExecutorWhitelisted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, - { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "internalType": "contract IERC20", "name": "_token", "type": "address" }, - { "indexed": false, "internalType": "uint256", "name": "_amount", "type": "uint256" }, - { "indexed": false, "internalType": "bool", "name": "_isNative", "type": "bool" }, - { "indexed": false, "internalType": "bool", "name": "_isPermit", "type": "bool" } - ], - "name": "TokenCollected", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "internalType": "address", "name": "user", "type": "address" }, - { "indexed": false, "internalType": "bool", "name": "grantOrRevoke", "type": "bool" } - ], - "name": "UpdateGuardian", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "internalType": "address", "name": "user", "type": "address" }, - { "indexed": false, "internalType": "bool", "name": "grantOrRevoke", "type": "bool" } - ], - "name": "UpdateOperator", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "internalType": "address", "name": "_validator", "type": "address" }, - { "indexed": true, "internalType": "bool", "name": "_grantOrRevoke", "type": "bool" } - ], - "name": "ValidatorWhitelisted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": true, "internalType": "uint8", "name": "_dexType", "type": "uint8" }, - { "indexed": true, "internalType": "contract IERC20", "name": "_srcToken", "type": "address" }, - { "indexed": true, "internalType": "uint256", "name": "_srcAmount", "type": "uint256" }, - { "indexed": false, "internalType": "address", "name": "_validator", "type": "address" }, - { "indexed": false, "internalType": "address", "name": "_executor", "type": "address" }, - { "indexed": false, "internalType": "bytes", "name": "_zapInfo", "type": "bytes" }, - { "indexed": false, "internalType": "bytes", "name": "_extraData", "type": "bytes" }, - { "indexed": false, "internalType": "bytes", "name": "_initialData", "type": "bytes" }, - { "indexed": false, "internalType": "bytes", "name": "_zapResults", "type": "bytes" } - ], - "name": "ZapExecuted", - "type": "event" - }, - { "inputs": [], "name": "disableLogic", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, - { "inputs": [], "name": "enableLogic", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "guardians", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "operators", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" }, - { "internalType": "address", "name": "recipient", "type": "address" } - ], - "name": "rescueFunds", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "user", "type": "address" }, - { "internalType": "bool", "name": "grantOrRevoke", "type": "bool" } - ], - "name": "updateGuardian", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "user", "type": "address" }, - { "internalType": "bool", "name": "grantOrRevoke", "type": "bool" } - ], - "name": "updateOperator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "_executors", "type": "address[]" }, - { "internalType": "bool", "name": "_grantOrRevoke", "type": "bool" } - ], - "name": "whitelistExecutors", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address[]", "name": "_validators", "type": "address[]" }, - { "internalType": "bool", "name": "_grantOrRevoke", "type": "bool" } - ], - "name": "whitelistValidators", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "whitelistedExecutor", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [{ "internalType": "address", "name": "", "type": "address" }], - "name": "whitelistedValidator", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "uint8", "name": "dexType", "type": "uint8" }, - { "internalType": "contract IERC20", "name": "srcToken", "type": "address" }, - { "internalType": "uint256", "name": "srcAmount", "type": "uint256" }, - { "internalType": "bytes", "name": "zapInfo", "type": "bytes" }, - { "internalType": "bytes", "name": "extraData", "type": "bytes" }, - { "internalType": "bytes", "name": "permitData", "type": "bytes" } - ], - "internalType": "struct IKSZapRouter.ZapDescription", - "name": "_desc", - "type": "tuple" - }, - { - "components": [ - { "internalType": "address", "name": "validator", "type": "address" }, - { "internalType": "address", "name": "executor", "type": "address" }, - { "internalType": "uint32", "name": "deadline", "type": "uint32" }, - { "internalType": "bytes", "name": "executorData", "type": "bytes" }, - { "internalType": "bytes", "name": "clientData", "type": "bytes" } - ], - "internalType": "struct IKSZapRouter.ZapExecutionData", - "name": "_exe", - "type": "tuple" - } - ], - "name": "zapIn", - "outputs": [{ "internalType": "bytes", "name": "zapResults", "type": "bytes" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { "internalType": "uint8", "name": "dexType", "type": "uint8" }, - { "internalType": "contract IERC20", "name": "srcToken", "type": "address" }, - { "internalType": "uint256", "name": "srcAmount", "type": "uint256" }, - { "internalType": "bytes", "name": "zapInfo", "type": "bytes" }, - { "internalType": "bytes", "name": "extraData", "type": "bytes" }, - { "internalType": "bytes", "name": "permitData", "type": "bytes" } - ], - "internalType": "struct IKSZapRouter.ZapDescription", - "name": "_desc", - "type": "tuple" - }, - { - "components": [ - { "internalType": "address", "name": "validator", "type": "address" }, - { "internalType": "address", "name": "executor", "type": "address" }, - { "internalType": "uint32", "name": "deadline", "type": "uint32" }, - { "internalType": "bytes", "name": "executorData", "type": "bytes" }, - { "internalType": "bytes", "name": "clientData", "type": "bytes" } - ], - "internalType": "struct IKSZapRouter.ZapExecutionData", - "name": "_exe", - "type": "tuple" - } - ], - "name": "zapInWithNative", - "outputs": [{ "internalType": "bytes", "name": "zapResults", "type": "bytes" }], - "stateMutability": "payable", - "type": "function" - } -] diff --git a/cypress/support/constants.js b/cypress/support/constants.js deleted file mode 100644 index 74357698ef..0000000000 --- a/cypress/support/constants.js +++ /dev/null @@ -1,36 +0,0 @@ -const BIG_AMOUNT = '11579208923731619542357098500868790785326998466564056' -const NATIVE_TOKEN_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' -const FROM_WALLET_ADDRESS = '0x0193a8a52d77e27bdd4f12e0cdd52d8ff1d97d68' -const MAX_UINT = '10000000000000000000000000000000000000000000000000000000000000000000' -const ZAP_ROUTER_ADDESS = '0x30c5322e4e08ad500c348007f92f120ab4e2b79e' - -const Network = { - MAINNET: 1, - BSC: 56, - POLYGON: 137, - ZKEVM: 1101, - AVALANCHE: 43114, - FANTOM: 250, - ARBITRUM: 42161, - OPTIMISM: 10, - BASE: 8453, -} -const Holders = { - [Network.MAINNET]: {}, - [Network.POLYGON]: {}, - [Network.ARBITRUM]: { - '0xaf88d065e77c8cC2239327C5EDb3A432268e5831': '0xa843392198862f98d17e3aa1421b08f2c2020cff', //USDC - '0x5979D7b546E38E414F7E9822514be443A4800529': '0x513c7e3a9c69ca3e22550ef58ac1c0088e918fff', // wstETH - '0x9cfB13E6c11054ac9fcB92BA89644F30775436e4': '0x9cfb13e6c11054ac9fcb92ba89644f30775436e4', // axl.wstETH - }, -} - -module.exports = { - NATIVE_TOKEN_ADDRESS, - FROM_WALLET_ADDRESS, - BIG_AMOUNT, - MAX_UINT, - ZAP_ROUTER_ADDESS, - Network, - Holders, -} diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index ae7df02f44..070521e240 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -15,19 +15,9 @@ import '@cypress/grep' import registerCypressGrep from '@cypress/grep/src/support' import '@synthetixio/synpress/support/index' -import installLogsCollector from 'cypress-terminal-report/src/installLogsCollector' import './commands' import './connectWalletCommands' import './selectTokenCommands' -const configOption = { - collectTypes: ['cons:debug'], - filterLog: function (args: [installLogsCollector.LogType, string, installLogsCollector.Severity]) { - const [logType, message] = args - return logType === 'cons:debug' && message.includes('zap data') - }, -} - -installLogsCollector(configOption) registerCypressGrep() diff --git a/cypress/support/erc20.json b/cypress/support/erc20.json deleted file mode 100644 index 78e48df019..0000000000 --- a/cypress/support/erc20.json +++ /dev/null @@ -1,308 +0,0 @@ -[ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "guy", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "guy", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "redeem", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - } -] diff --git a/cypress/support/tenderly.js b/cypress/support/tenderly.js deleted file mode 100644 index 1e385f0649..0000000000 --- a/cypress/support/tenderly.js +++ /dev/null @@ -1,295 +0,0 @@ -const axios = require('axios') -const { Interface } = require('@ethersproject/abi') -const { StaticJsonRpcProvider } = require('@ethersproject/providers') -require('dotenv').config() - -const { TENDERLY_USER, TENDERLY_PROJECT, TENDERLY_ACCESS_KEY } = process.env -const { - FROM_WALLET_ADDRESS, - NATIVE_TOKEN_ADDRESS, - ZAP_ROUTER_ADDESS, - BIG_AMOUNT, - MAX_UINT, - Holders, -} = require('./constants.js') - -const projectBase = `account/${TENDERLY_USER}/project/${TENDERLY_PROJECT}` - -const KSZapABI = require('./KSZAPRouterABI.json') -const Erc20ABI = require('./erc20.json') -const { Console } = require('console') -const erc20Interface = new Interface(Erc20ABI) -const ksZapRouterInterface = new Interface(KSZapABI) - -const anAxiosOnTenderly = () => - axios.create({ - baseURL: 'https://api.tenderly.co/api/v1', - headers: { - 'X-Access-Key': TENDERLY_ACCESS_KEY || '', - 'Content-Type': 'application/json', - }, - }) -class TenderlySimulation { - maxGasLimit = 80000000 - constructor() {} - async setup(chainId) { - this.chainId = chainId - const tAxios = anAxiosOnTenderly() - const resp = await tAxios.post(`${projectBase}/fork`, { - network_id: chainId, - }) - - const forkId = resp.data.simulation_fork.id - const lastTx = resp.data.root_transaction.id - this.forkId = forkId - this.lastTx = lastTx - this.tAxios = anAxiosOnTenderly() - } - - async applyOverride(contractAddress) { - const balanceFns = ['balanceOf', 'balances', '_balances', 'shares'] - const allowanceFns = ['allowance', 'allowances', '_allowances', 'allowed'] - const overrideStorageObj = await this.tAxios - .get(`https://api.tenderly.co/api/v1/public-contracts/${this.chainId}/${contractAddress}`) - .then(response => { - if ('states' in response.data.data) { - let fns = response.data.data.states.map(state => state.name) - const allowanceFnName = getMatch(allowanceFns, fns) - const balanceFnName = getMatch(balanceFns, fns) - - if (allowanceFnName.length == 0) { - throw new Error('Cannot find allowance method name for token ' + contractAddress) - } - if (balanceFnName.length == 0) { - throw new Error('Cannot find balance method name for token ' + contractAddress) - } - - const addBalance = constructAddBalanceFn(balanceFnName[0]) - const addAllowance = constructAddBAllowanceFn(allowanceFnName[0]) - - const balanceStorage = addBalance(FROM_WALLET_ADDRESS, BIG_AMOUNT) - const allowanceStorage = addAllowance(FROM_WALLET_ADDRESS, ZAP_ROUTER_ADDESS, BIG_AMOUNT) - const value = { ...balanceStorage, ...allowanceStorage } - const overrides = { - networkID: `${this.chainId}`, - stateOverrides: { - [`${contractAddress}`]: { - value: value, - }, - }, - } - return overrides - } else { - return {} - } - }) - return overrideStorageObj - } - async encodeState(tokenIn) { - try { - if (tokenIn.toLowerCase() == NATIVE_TOKEN_ADDRESS.toLowerCase()) { - return { - [`${FROM_WALLET_ADDRESS}`]: { - balance: `${BIG_AMOUNT}`, - }, - } - } else { - const stateOverridesPayload = await this.applyOverride(tokenIn) - if (isObjectEmpty(stateOverridesPayload)) { - return {} - } else { - const encodeState = await this.tAxios - .post(`${projectBase}/contracts/encode-states`, stateOverridesPayload) - .catch(function (error) { - console.log('Tenderly_generate_override_storage', error) - }) - - return Object.keys(encodeState.data.stateOverrides).reduce((acc, contract) => { - const _storage = encodeState.data.stateOverrides[contract].value - acc[contract] = { - storage: _storage, - } - return acc - }, {}) - } - } - } catch (e) { - console.log(`TenderlySimulation_encode-states:`, e.response.data.error.message) - return {} - } - } - - async simulate(params, stateOverrides = {}) { - let _params = { - network_id: this.chainId, - from: params.from, - to: params.to, - save: true, - root: this.lastTx, - value: params.value || '0', - gas: this.maxGasLimit, - input: params.data, - state_objects: {}, - } - try { - if (stateOverrides) { - _params.state_objects = stateOverrides - } - const { data } = await this.tAxios.post(`${projectBase}/fork/${this.forkId}/simulate`, _params) - const lastTx = data.simulation.id - if (data.transaction.status) { - this.lastTx = lastTx - return { - success: true, - gasUsed: data.transaction.gas_used, - tenderlyUrl: `https://dashboard.tenderly.co/${TENDERLY_USER}/${TENDERLY_PROJECT}/fork/${this.forkId}/simulation/${lastTx}`, - // transaction: data.transaction, - } - } else { - return { - success: false, - tenderlyUrl: `https://dashboard.tenderly.co/${TENDERLY_USER}/${TENDERLY_PROJECT}/fork/${this.forkId}/simulation/${lastTx}`, - error: `Simulation failed: ${data.transaction.error_info.error_message} at ${data.transaction.error_info.address}`, - } - } - } catch (e) { - console.error(`TenderlySimulation_simulate:`, e) - return { - success: false, - tenderlyUrl: '', - } - } - } -} - -const getForkRpcUrl = async chainId => { - const RPCs = { - 1101: process.env.POLYGON_ZKEVM_NODE_URL, - 59144: process.env.LINEA_NODE_URL, - 8453: process.env.BASE_NODE_URL, - 137: process.env.POLYGON_NODE_URL, - 534352: process.env.SCROLL_NODE_URL, - 42161: process.env.ARBITRUM_NODE_URL, - } - const rpcUrl = RPCs[chainId] ?? (await createFork(chainId)) - return rpcUrl -} - -const isObjectEmpty = objectName => { - return objectName && Object.keys(objectName).length === 0 && objectName.constructor === Object -} - -function allowTokenTransferProxyParams(tokenAddress, holderAddress, routerAddress) { - return { - from: holderAddress, - to: tokenAddress, - data: erc20Interface.encodeFunctionData('approve', [routerAddress, MAX_UINT]), - value: '0', - } -} - -async function simulateTenderly(input) { - const { data, chainId, tokenIn } = input - // Holders[chainId] - // const holder = '0xa843392198862f98d17e3aa1421b08f2c2020cff' - - const ts = new TenderlySimulation() - await ts.setup(chainId) - const stateOverrideObj = await ts.encodeState(tokenIn) - let holder = FROM_WALLET_ADDRESS - - /** - * Some token cannot find allowance and balance function to override state, - * so this step will finding the holder via scanner - * then fake allowance for kyber router - */ - if (isObjectEmpty(stateOverrideObj)) { - holder = Holders[chainId][tokenIn] - if (tokenIn.toLowerCase() != NATIVE_TOKEN_ADDRESS.toLowerCase()) { - const allowParams = allowTokenTransferProxyParams(tokenIn, holder, ZAP_ROUTER_ADDESS) - const allowanceTx = await ts.simulate({ - from: holder, - ...allowParams, - }) - if (!allowanceTx.success) console.log(allowanceTx.url) - } - } - - let zapInParams = { - from: holder, - data: data, - to: ZAP_ROUTER_ADDESS, - value: input.value || '0', - } - - return await ts.simulate(zapInParams, stateOverrideObj) -} - -function getMatch(a, b) { - var matches = [] - for (var i = 0; i < a.length; i++) { - for (var e = 0; e < b.length; e++) { - if (a[i] === b[e]) matches.push(a[i]) - } - } - return matches -} - -function constructAddBalanceFn(varName) { - return (address, amount) => { - return { - [`${varName}[${address}]`]: amount, - } - } -} - -function constructAddBAllowanceFn(varName) { - return (address, spender, amount) => { - return { - [`${varName}[${address}][${spender}]`]: amount, - } - } -} -async function estimateGas(input) { - const rpc = await getForkRpcUrl(input.chain) - const provider = new StaticJsonRpcProvider(rpc, Number(input.chain)) - let txObject = { - from: input.to, - data: input.encodedSwapData, - value: 0, - to: input.routerAddress, - } - - try { - const result = await provider.estimateGas(txObject) - return { - success: true, - gasUsed: result.toNumber().toString(), - } - } catch (error) { - return { - success: false, - error: error, - } - } -} - -function getTokenInFromZapEncodeData(zapInData) { - let funcSig = zapInData['data'].slice(0, 10) - switch (funcSig) { - case '0x0779b145': - return NATIVE_TOKEN_ADDRESS - case '0xbea67258': - let decode = ksZapRouterInterface.decodeFunctionData('zapIn', zapInData['data']) - const tokenInAddress = decode[0][1] - return tokenInAddress - default: - throw 'function selector' - } -} -module.exports = { - simulateTenderly, - getForkRpcUrl, - estimateGas, - getTokenInFromZapEncodeData, -} diff --git a/package.json b/package.json index 03ce74aef3..4601d8a960 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "start-dev": "vite --mode dev --host", "start-stg": "vite --mode stg --host", "start-prod": "vite --mode production --host", - "test:e2e": "synpress run -cf cypress.config.ts", - "test:zap-sim": "node --test --test-reporter spec cypress/e2e/specs/zap-in-simulator-test.mjs" + "test-e2e": "synpress run -cf cypress.config.ts", + "test-schedule": "synpress run -cf cypress.config.ts" }, "browserslist": [ "chrome >= 52", @@ -177,7 +177,6 @@ "@vitejs/plugin-react": "^3.1.0", "babel-plugin-lodash": "^3.3.4", "babel-plugin-macros": "^3.1.0", - "cypress-terminal-report": "^5.3.9", "env-cmd": "^10.1.0", "eslint": "^8.38.0", "eslint-config-prettier": "^8.5.0", diff --git a/src/components/InputStepCounter/InputStepCounter.tsx b/src/components/InputStepCounter/InputStepCounter.tsx index 2992b5fdb8..826d647349 100644 --- a/src/components/InputStepCounter/InputStepCounter.tsx +++ b/src/components/InputStepCounter/InputStepCounter.tsx @@ -159,7 +159,6 @@ const StepCounter = ({ { diff --git a/src/pages/AddLiquidityV2/index.tsx b/src/pages/AddLiquidityV2/index.tsx index b76daa5a2d..02520b9c48 100644 --- a/src/pages/AddLiquidityV2/index.tsx +++ b/src/pages/AddLiquidityV2/index.tsx @@ -1458,7 +1458,6 @@ export default function AddLiquidity() { diff --git a/src/pages/AddLiquidityV2/styled.tsx b/src/pages/AddLiquidityV2/styled.tsx index f739a445eb..2a4672f85f 100644 --- a/src/pages/AddLiquidityV2/styled.tsx +++ b/src/pages/AddLiquidityV2/styled.tsx @@ -298,7 +298,7 @@ export const MethodSelector = ({ > - + Zap In