test(cypress): clean up types/assumptions/infura (#7046)
This commit is contained in:
parent
b4b6c347e3
commit
7978ed97a9
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
@ -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"]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user