test(cypress): clean up types/assumptions/infura (#7046)

This commit is contained in:
Zach Pomerantz 2023-08-01 22:13:19 -07:00 committed by GitHub
parent b4b6c347e3
commit 7978ed97a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 93 additions and 219 deletions

@ -100,6 +100,23 @@ jobs:
path: build
if-no-files-found: error
cypress-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: ./.github/actions/cache-on-main
with:
path: node_modules/.cache
key: ${{ runner.os }}-cypress-tsc-${{ github.run_id }}
restore-keys: ${{ runner.os }}-cypress-tsc-
- run: yarn typecheck:cypress
- if: failure() && github.ref_name == 'main'
uses: ./.github/actions/report
with:
name: Cypress typecheck
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TEST_REPORTER_WEBHOOK }}
# Allows for parallel re-runs of cypress tests without re-building.
cypress-rerun:
runs-on: ubuntu-latest

@ -1,7 +1,6 @@
import codeCoverageTask from '@cypress/code-coverage/task'
import { defineConfig } from 'cypress'
import { setupHardhatEvents } from 'cypress-hardhat'
import { unlinkSync } from 'fs'
export default defineConfig({
projectId: 'yp82ef',
@ -9,22 +8,11 @@ export default defineConfig({
chromeWebSecurity: false,
experimentalMemoryManagement: true, // better memory management, see https://github.com/cypress-io/cypress/pull/25462
retries: { runMode: 2 },
videoCompression: false,
video: false, // GH provides 2 CPUs, and cypress video eats one up, see https://github.com/cypress-io/cypress/issues/20468#issuecomment-1307608025
e2e: {
async setupNodeEvents(on, config) {
await setupHardhatEvents(on, config)
codeCoverageTask(on, config)
// Delete recorded videos for specs that passed without flakes.
on('after:spec', async (spec, results) => {
if (results && results.video) {
// If there were no failures (including flakes), delete the recorded video.
if (!results.tests?.some((test) => test.attempts.some((attempt) => attempt?.state === 'failed'))) {
unlinkSync(results.video)
}
}
})
return config
},
baseUrl: 'http://localhost:3000',

@ -52,7 +52,7 @@ This becomes more relevant as you work with data on the blockchain, as you'll ne
```
cy.hardhat().then(async (hardhat) => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`, { ethereum: 'hardhat' })
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
@ -68,7 +68,7 @@ cy.hardhat().then(async (hardhat) => {
```
```
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`, { ethereum: 'hardhat' })
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.get('#swap-currency-output .token-amount-input').type('1').should('have.value', '1')
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
@ -87,7 +87,6 @@ cy.hardhat().then(async (hardhat) => {
### Working with the blockchain (ie hardhat)
Our tests use a local hardhat node to simulate blockchain transactions. This can be accessed with `cy.hardhat().then((hardhat) => ...)`.
Currently, tests using hardhat must opt-in in when they load the page: `cy.visit('/swap', { ethereum: 'hardhat' })`. This will not be necessary once we've totally migrated to hardhat.
By default, automining is turned on, so that any transaction that you send to the blockchain is mined immediately. If you want to assert on intermediate states (between sending a transaction and mining it), you can turn off automining: `cy.hardhat({ automine: false })`.

@ -9,36 +9,29 @@ describe('Add Liquidity', () => {
})
})
it('loads the two correct tokens', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/500')
it('loads the token pair', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH/500')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'ETH')
cy.contains('0.05% fee tier')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/add/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'ETH')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('not.contain.text', 'ETH')
it('does not crash if token is duplicated', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('not.contain.text', 'UNI')
})
it.skip('token not in storage is loaded', () => {
cy.visit('/add/0x07865c6e87b9f70255377e024ace6630c1eaa37f/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'USDC')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'UNI')
})
it.skip('single token can be selected', () => {
cy.visit('/add/0x07865c6e87b9f70255377e024ace6630c1eaa37f')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'USDC')
it('single token can be selected', () => {
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'UNI')
})
it.skip('loads fee tier distribution', () => {
it('loads fee tier distribution', () => {
cy.fixture('feeTierDistribution.json').then((feeTierDistribution) => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req: CyHttpMessages.IncomingHttpRequest) => {
if (hasQuery(req, 'FeeTierDistributionQuery')) {
req.alias = 'FeeTierDistributionQuery'
if (hasQuery(req, 'FeeTierDistribution')) {
req.alias = 'FeeTierDistribution'
req.reply({
body: {
@ -53,12 +46,10 @@ describe('Add Liquidity', () => {
}
})
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
cy.wait('@FeeTierDistributionQuery')
cy.visit('/add/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH')
cy.wait('@FeeTierDistribution')
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.3% fee tier')
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40%')
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40% select')
})
})
})

@ -3,7 +3,7 @@ import { getTestSelector } from '../../utils'
describe('Mini Portfolio account drawer', () => {
beforeEach(() => {
cy.intercept(/api.uniswap.org\/v1\/graphql/, cy.spy().as('gqlSpy'))
cy.visit('/swap', { ethereum: 'hardhat' })
cy.visit('/swap')
})
it('fetches balances when account button is first hovered', () => {

@ -94,9 +94,7 @@ describe('mini-portfolio activity history', () => {
})
it('should deduplicate activity history by nonce', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`, { ethereum: 'hardhat' }).hardhat({
automine: false,
})
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`).hardhat({ automine: false })
// Input swap info.
cy.get('#swap-currency-input .token-amount-input').clear().type('1').should('have.value', '1')

@ -52,7 +52,7 @@ describe('Testing nfts', () => {
cy.visit('/')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('mini-portfolio-navbar')).contains('NFTs').click()
cy.get(getTestSelector('mini-portfolio-nft')).click()
cy.get(getTestSelector('mini-portfolio-nft')).first().click()
cy.get(getTestSelector('mini-portfolio-navbar')).should('not.be.visible')
})
})

@ -17,9 +17,7 @@ function initiateSwap() {
describe('Permit2', () => {
function setupInputs(inputToken: Token, outputToken: Token) {
// Sets up a swap between inputToken and outputToken.
cy.visit(`/swap/?inputCurrency=${inputToken.address}&outputCurrency=${outputToken.address}`, {
ethereum: 'hardhat',
})
cy.visit(`/swap/?inputCurrency=${inputToken.address}&outputCurrency=${outputToken.address}`)
cy.get('#swap-currency-input .token-amount-input').type('0.01')
}

@ -1,25 +1,7 @@
describe('Remove Liquidity', () => {
it('eth remove', () => {
it('loads the token pair', () => {
cy.visit('/remove/v2/ETH/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'UNI')
})
it('eth remove swap order', () => {
cy.visit('/remove/v2/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/ETH')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'UNI')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'ETH')
})
it('loads the two correct tokens', () => {
cy.visit('/remove/v2/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'UNI')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/remove/v2/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'WETH')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'WETH')
})
})

@ -7,7 +7,7 @@ import { getBalance, getTestSelector } from '../../utils'
describe('Swap errors', () => {
it('wallet rejection', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`, { ethereum: 'hardhat' })
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.hardhat().then((hardhat) => {
// Stub the wallet to reject any transaction.
cy.stub(hardhat.wallet, 'sendTransaction').log(false).rejects(new Error('user cancelled'))
@ -28,7 +28,7 @@ describe('Swap errors', () => {
})
it('transaction past deadline', () => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`, { ethereum: 'hardhat' })
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${USDC_MAINNET.address}`)
cy.hardhat({ automine: false })
getBalance(USDC_MAINNET).then((initialBalance) => {
// Enter amount to swap
@ -63,7 +63,7 @@ describe('Swap errors', () => {
})
it('slippage failure', () => {
cy.visit(`/swap?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`, { ethereum: 'hardhat' })
cy.visit(`/swap?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
cy.hardhat({ automine: false }).then(async (hardhat) => {
await hardhat.fund(hardhat.wallet, CurrencyAmount.fromRawAmount(USDC_MAINNET, 500e6))
await hardhat.mine()
@ -113,9 +113,7 @@ describe('Swap errors', () => {
cy.get(getTestSelector('web3-status-connected')).should('not.contain', 'Pending')
cy.get(getTestSelector('popups')).contains('Swapped')
cy.get(getTestSelector('popups')).contains('Swap failed')
getBalance(DAI).then((currentDaiBalance) => {
expect(currentDaiBalance).to.be.closeTo(initialBalance + 200, 1)
})
getBalance(DAI).should('be.closeTo', initialBalance + 200, 1)
})
})
})

@ -3,7 +3,7 @@ import { getTestSelector } from '../../utils'
describe('Swap settings', () => {
it('Opens and closes the settings menu', () => {
cy.visit('/swap', { featureFlags: [FeatureFlag.uniswapXEnabled], ethereum: 'hardhat' })
cy.visit('/swap', { featureFlags: [FeatureFlag.uniswapXEnabled] })
cy.contains('Settings').should('not.exist')
cy.get(getTestSelector('open-settings-dialog-button')).click()
cy.contains('Max slippage').should('exist')

@ -52,7 +52,7 @@ describe('Swap', () => {
})
it('swaps ETH for USDC', () => {
cy.visit('/swap', { ethereum: 'hardhat' })
cy.visit('/swap')
cy.hardhat({ automine: false })
getBalance(USDC_MAINNET).then((initialBalance) => {
// Select USDC

@ -6,9 +6,7 @@ const WETH = WETH9[ChainId.MAINNET]
describe('Swap wrap', () => {
beforeEach(() => {
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${WETH.address}`, { ethereum: 'hardhat' }).hardhat({
automine: false,
})
cy.visit(`/swap?inputCurrency=ETH&outputCurrency=${WETH.address}`).hardhat({ automine: false })
})
it('ETH to wETH is same value (wrapped swaps have no price impact)', () => {

@ -93,9 +93,7 @@ describe('Token details', () => {
beforeEach(() => {
// On mobile widths, we just link back to /swap instead of rendering the swap component.
cy.viewport(1200, 800)
cy.visit(`/tokens/ethereum/${UNI_MAINNET.address}`, {
ethereum: 'hardhat',
}).then(() => {
cy.visit(`/tokens/ethereum/${UNI_MAINNET.address}`).then(() => {
cy.wait('@eth_blockNumber')
cy.scrollTo('top')
})
@ -145,7 +143,7 @@ describe('Token details', () => {
})
it('should show a L2 token even if the user is connected to a different network', () => {
cy.visit('/tokens', { ethereum: 'hardhat' })
cy.visit('/tokens')
cy.get(getTestSelector('tokens-network-filter-selected')).click()
cy.get(getTestSelector('tokens-network-filter-option-arbitrum')).click()
cy.get(getTestSelector('tokens-network-filter-selected')).should('contain', 'Arbitrum')

@ -36,7 +36,7 @@ describe('Token explore', () => {
.then(function ($elem) {
cy.wrap($elem.text()).as('yearlyEthVol')
})
expect(cy.get('@dailyEthVol')).to.not.equal(cy.get('@yearlyEthVol'))
cy.get('@dailyEthVol').should('not.equal', cy.get('@yearlyEthVol'))
})
it('should navigate to token detail page when row clicked', () => {

@ -2,8 +2,8 @@ import { getTestSelector } from '../../utils'
import { DISCONNECTED_WALLET_USER_STATE } from '../../utils/user-state'
describe('disconnect wallet', () => {
it('should not clear state', () => {
cy.visit('/swap', { ethereum: 'hardhat' })
it('should clear state', () => {
cy.visit('/swap')
cy.get('#swap-currency-input .token-amount-input').clear().type('1')
// Verify wallet is connected
@ -28,7 +28,7 @@ describe('disconnect wallet', () => {
describe('connect wallet', () => {
it('should load state', () => {
cy.visit('/swap', { ethereum: 'hardhat', userState: DISCONNECTED_WALLET_USER_STATE })
cy.visit('/swap', { userState: DISCONNECTED_WALLET_USER_STATE })
// Connect the wallet
cy.get(getTestSelector('navbar-connect-wallet')).contains('Connect').click()

@ -12,7 +12,7 @@ function switchChain(chain: string) {
describe('network switching', () => {
beforeEach(() => {
cy.visit('/swap', { ethereum: 'hardhat' })
cy.visit('/swap')
cy.get(getTestSelector('web3-status-connected'))
})
@ -123,14 +123,14 @@ describe('network switching', () => {
describe('network switching from URL param', () => {
it('should switch network from URL param', () => {
cy.visit('/swap?chain=polygon', { ethereum: 'hardhat' })
cy.visit('/swap?chain=polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
})
it('should be able to switch network after loading from URL param', () => {
cy.visit('/swap?chain=polygon', { ethereum: 'hardhat' })
cy.visit('/swap?chain=polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')

@ -5,7 +5,6 @@ import { Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge'
import { FeatureFlag } from '../../src/featureFlags'
import { UserState } from '../../src/state/user/reducer'
import { CONNECTED_WALLET_USER_STATE } from '../utils/user-state'
import { injected } from './ethereum'
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
@ -16,12 +15,6 @@ declare global {
interface VisitOptions {
serviceWorker?: true
featureFlags?: Array<FeatureFlag>
/**
* The mock ethereum provider to inject into the page.
* @default 'goerli'
*/
// TODO(INFRA-175): Migrate all usage of 'goerli' to 'hardhat'.
ethereum?: 'goerli' | 'hardhat'
/**
* Initial user state.
* @default {@type import('../utils/user-state').CONNECTED_WALLET_USER_STATE}
@ -39,8 +32,7 @@ Cypress.Commands.overwrite(
if (typeof url !== 'string') throw new Error('Invalid arguments. The first argument to cy.visit must be the path.')
// Add a hash in the URL if it is not present (to use hash-based routing correctly with queryParams).
let hashUrl = url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url
if (options?.ethereum === 'goerli') hashUrl += `${url.includes('?') ? '&' : '?'}chain=goerli`
const hashUrl = url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url
return cy
.intercept('/service-worker.js', options?.serviceWorker ? undefined : { statusCode: 404 })
@ -68,11 +60,7 @@ Cypress.Commands.overwrite(
}
// Inject the mock ethereum provider.
if (options?.ethereum === 'hardhat') {
win.ethereum = provider
} else {
win.ethereum = injected
}
win.ethereum = provider
},
})
)

@ -1,72 +0,0 @@
/**
* Updates cy.visit() to include an injected window.ethereum provider.
*/
import { Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge'
import { JsonRpcProvider } from '@ethersproject/providers'
import { Wallet } from '@ethersproject/wallet'
import { ChainId } from '@uniswap/sdk-core'
// todo: figure out how env vars actually work in CI
// const TEST_PRIVATE_KEY = Cypress.env('INTEGRATION_TEST_PRIVATE_KEY')
const TEST_PRIVATE_KEY = '0xe580410d7c37d26c6ad1a837bbae46bc27f9066a466fb3a66e770523b4666d19'
// address of the above key
const TEST_ADDRESS_NEVER_USE = new Wallet(TEST_PRIVATE_KEY).address
const CHAIN_ID = ChainId.GOERLI
const HEXLIFIED_CHAIN_ID = `0x${CHAIN_ID.toString(16)}`
const provider = new JsonRpcProvider('https://goerli.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 5)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
export const injected = new (class extends Eip1193Bridge {
chainId = CHAIN_ID
async sendAsync(...args: any[]) {
console.debug('sendAsync called', ...args)
return this.send(...args)
}
async send(...args: any[]) {
console.debug('send called', ...args)
const isCallbackForm = typeof args[0] === 'object' && typeof args[1] === 'function'
let callback
let method
let params
if (isCallbackForm) {
callback = args[1]
method = args[0].method
params = args[0].params
} else {
method = args[0]
params = args[1]
}
if (method === 'eth_requestAccounts' || method === 'eth_accounts') {
if (isCallbackForm) {
callback({ result: [TEST_ADDRESS_NEVER_USE] })
} else {
return Promise.resolve([TEST_ADDRESS_NEVER_USE])
}
}
if (method === 'eth_chainId') {
if (isCallbackForm) {
callback(null, { result: HEXLIFIED_CHAIN_ID })
} else {
return Promise.resolve(HEXLIFIED_CHAIN_ID)
}
}
try {
const result = await super.send(method, params)
console.debug('result received', method, params, result)
if (isCallbackForm) {
callback(null, { result })
} else {
return result
}
} catch (error) {
if (isCallbackForm) {
callback(error, null)
} else {
throw error
}
}
}
})(signer, provider)

@ -9,13 +9,8 @@ beforeEach(() => {
req.headers['origin'] = 'https://app.uniswap.org'
})
// Infura uses a test endpoint, which allow-lists http://localhost:3000 instead.
cy.intercept(/infura.io/, (req) => {
req.headers['referer'] = 'http://localhost:3000'
req.headers['origin'] = 'http://localhost:3000'
req.alias = req.body.method
req.continue()
})
// Infura is disabled for cypress tests - calls should be routed through the connected wallet instead.
cy.intercept(/infura.io/, { statusCode: 404 })
// Log requests to hardhat.
cy.intercept(/:8545/, logJsonRpc)
@ -49,7 +44,7 @@ function logJsonRpc(req: CyHttpMessages.IncomingHttpRequest) {
const log = Cypress.log({
autoEnd: false,
name: req.body.method,
message: req.body.params?.map((param: unknown) =>
message: req.body.params?.map((param: any) =>
typeof param === 'object' ? '{...}' : param?.toString().substring(0, 10)
),
})

@ -1,18 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"esModuleInterop": true,
"composite": false,
"incremental": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"noEmit": true,
"strict": true,
"isolatedModules": false,
"noImplicitAny": false,
"target": "ES5",
"tsBuildInfoFile": "../node_modules/.cache/tsbuildinfo/cypress", // avoid clobbering the build tsbuildinfo
"types": ["cypress", "node"],
"jsx": "react"
},
"exclude": ["node_modules"],
"include": ["**/*.ts"],
"watchOptions": {
"excludeDirectories": ["node_modules"]
}
}

@ -1,5 +1,6 @@
import { ConnectionType } from '../../src/connection/types'
import { UserState } from '../../src/state/user/reducer'
export const CONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWallet: 'INJECTED' }
export const CONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWallet: ConnectionType.INJECTED }
export const DISCONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWallet: undefined }

@ -27,6 +27,7 @@
"lint": "yarn eslint --ignore-path .gitignore --cache --cache-location node_modules/.cache/eslint/ .",
"typecheck": "tsc",
"typecheck:cloud": "tsc -p functions/tsconfig.json",
"typecheck:cypress": "tsc -p cypress/tsconfig.json",
"test": "craco test",
"test:cloud": "NODE_OPTIONS=--experimental-vm-modules yarn jest functions --config=functions/jest.config.json",
"cypress:open": "cypress open --browser chrome --e2e",

@ -1,5 +1,5 @@
import store from 'state'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { updateUserRouterPreference } from 'state/user/reducer'
import { fireEvent, render, screen } from 'test-utils/render'

@ -7,7 +7,7 @@ import Toggle from 'components/Toggle'
import { isUniswapXSupportedChain } from 'constants/chains'
import { useUniswapXEnabled } from 'featureFlags/flags/uniswapx'
import { useAppDispatch } from 'state/hooks'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { useRouterPreference } from 'state/user/hooks'
import { updateDisabledUniswapX } from 'state/user/reducer'
import styled from 'styled-components/macro'

@ -11,7 +11,7 @@ import useTransactionDeadline from 'hooks/useTransactionDeadline'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { ReactNode } from 'react'
import { AlertTriangle } from 'react-feather'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { InterfaceTrade } from 'state/routing/types'
import { getTransactionCount, isClassicTrade } from 'state/routing/utils'
import { useRouterPreference, useUserSlippageTolerance } from 'state/user/hooks'

@ -1,7 +1,7 @@
import { renderHook } from '@testing-library/react'
import { CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { DAI, USDC_MAINNET } from 'constants/tokens'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { TradeState } from 'state/routing/types'
import { useRouterPreference } from 'state/user/hooks'
import { mocked } from 'test-utils/mocked'

@ -3,7 +3,7 @@ import { useWeb3React } from '@web3-react/core'
import { WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import { DebounceSwapQuoteVariant, useDebounceSwapQuoteFlag } from 'featureFlags/flags/debounceSwapQuote'
import { useMemo } from 'react'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { ClassicTrade, InterfaceTrade, QuoteMethod, TradeState } from 'state/routing/types'
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
import { useRouterPreference } from 'state/user/hooks'

@ -4,7 +4,8 @@ import { useRoutingAPIForPrice } from 'featureFlags/flags/priceRoutingApi'
import { useUniswapXEnabled } from 'featureFlags/flags/uniswapx'
import { useUniswapXSyntheticQuoteEnabled } from 'featureFlags/flags/uniswapXUseSyntheticQuote'
import { useMemo } from 'react'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/slice'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { currencyAddressForSwapQuote } from 'state/routing/utils'
import { useUserDisabledUniswapX } from 'state/user/hooks'

@ -2,7 +2,7 @@ import { Currency, CurrencyAmount, NativeCurrency, Percent, Token, TradeType } f
import useAutoSlippageTolerance from 'hooks/useAutoSlippageTolerance'
import { useBestTrade } from 'hooks/useBestTrade'
import { useMemo } from 'react'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { ClassicTrade, TradeState } from 'state/routing/types'
import { isClassicTrade } from 'state/routing/utils'

@ -19,7 +19,7 @@ import { PropsWithChildren, useEffect, useRef, useState } from 'react'
import { X } from 'react-feather'
import { Text } from 'rebass'
import { useAppDispatch } from 'state/hooks'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { isClassicTrade } from 'state/routing/utils'
import { SwapInfo } from 'state/swap/hooks'
import { useRouterPreference, useUserDisabledUniswapX } from 'state/user/hooks'

@ -9,6 +9,7 @@ import { trace } from 'tracing/trace'
import {
QuoteMethod,
QuoteState,
RouterPreference,
RoutingConfig,
SwapRouterNativeAssets,
TradeResult,
@ -22,12 +23,6 @@ if (UNISWAP_API_URL === undefined) {
throw new Error(`UNISWAP_API_URL must be a defined environment variable`)
}
export enum RouterPreference {
X = 'uniswapx',
API = 'api',
CLIENT = 'client',
}
// This is excluded from `RouterPreference` enum because it's only used
// internally for token -> USDC trades to get a USD value.
export const INTERNAL_ROUTER_PREFERENCE_PRICE = 'price' as const

@ -18,6 +18,12 @@ export enum QuoteMethod {
CLIENT_SIDE_FALLBACK = 'CLIENT_SIDE_FALLBACK', // If client-side was used after the routing-api call failed.
}
export enum RouterPreference {
X = 'uniswapx',
API = 'api',
CLIENT = 'client',
}
// from https://github.com/Uniswap/routing-api/blob/main/lib/handlers/schema.ts
type TokenInRoute = Pick<Token, 'address' | 'chainId' | 'symbol' | 'decimals'>

@ -6,10 +6,10 @@ import { AVERAGE_L1_BLOCK_TIME } from 'constants/chainInfo'
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
import ms from 'ms.macro'
import { useMemo } from 'react'
import { INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/slice'
import { INTERNAL_ROUTER_PREFERENCE_PRICE } from 'state/routing/slice'
import { useGetQuoteQuery } from 'state/routing/slice'
import { ClassicTrade, InterfaceTrade, QuoteMethod, QuoteState, TradeState } from './types'
import { ClassicTrade, InterfaceTrade, QuoteMethod, QuoteState, RouterPreference, TradeState } from './types'
const TRADE_NOT_FOUND = { state: TradeState.NO_ROUTE_FOUND, trade: undefined } as const
const TRADE_LOADING = { state: TradeState.LOADING, trade: undefined } as const

@ -11,7 +11,7 @@ import { isAvalanche, isBsc, isMatic, nativeOnChain } from 'constants/tokens'
import { toSlippagePercent } from 'utils/slippage'
import { getApproveInfo, getWrapInfo } from './gas'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from './slice'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE } from './slice'
import {
ClassicQuoteData,
ClassicTrade,
@ -21,6 +21,7 @@ import {
PoolType,
QuoteMethod,
QuoteState,
RouterPreference,
SwapRouterNativeAssets,
TradeFillType,
TradeResult,

@ -2,7 +2,7 @@ import { act } from '@testing-library/react'
import { Percent } from '@uniswap/sdk-core'
import { USDC_MAINNET } from 'constants/tokens'
import store from 'state'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { renderHook } from 'test-utils/render'
import {

@ -7,7 +7,7 @@ import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
import JSBI from 'jsbi'
import { useCallback, useMemo } from 'react'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { UserAddedToken } from 'types/tokens'
import { BASES_TO_TRACK_LIQUIDITY_FOR, PINNED_PAIRS } from '../../constants/routing'

@ -1,5 +1,5 @@
import { createStore, Store } from 'redux'
import { RouterPreference } from 'state/routing/slice'
import { RouterPreference } from 'state/routing/types'
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
import { updateVersion } from '../global/actions'

@ -1,9 +1,9 @@
import { createSlice } from '@reduxjs/toolkit'
import { ConnectionType } from 'connection/types'
import { SupportedLocale } from 'constants/locales'
import { RouterPreference } from 'state/routing/slice'
import { ConnectionType } from '../../connection/types'
import { SupportedLocale } from '../../constants/locales'
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
import { RouterPreference } from '../../state/routing/types'
import { updateVersion } from '../global/actions'
import { SerializedPair, SerializedToken, SlippageTolerance } from './types'

@ -30,9 +30,5 @@
"types": ["jest"],
"useUnknownInCatchVariables": false
},
"exclude": ["node_modules"],
"include": ["src/**/*", "src/**/*.json"],
"watchOptions": {
"excludeDirectories": ["node_modules"]
}
}