test: swap flow cypress tests (#6331)

* test: swap flow cypress tests

* fix: use default parameter

* fix: use shared token addresses

* fix: fix test

* fix: nits
This commit is contained in:
eddie 2023-04-20 13:00:43 -07:00 committed by GitHub
parent 671041360d
commit d63bcca539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 134 additions and 25 deletions

@ -1,13 +1,57 @@
import { SupportedChainId, WETH9 } from '@uniswap/sdk-core'
import { getTestSelector } from '../utils'
describe('Swap', () => { describe('Swap', () => {
const verifyAmount = (field: 'input' | 'output', amountText: string | null) => {
if (amountText === null) {
cy.get(`#swap-currency-${field} .token-amount-input`).should('not.have.value')
} else {
cy.get(`#swap-currency-${field} .token-amount-input`).should('have.value', amountText)
}
}
const verifyToken = (field: 'input' | 'output', tokenSymbol: string | null) => {
if (tokenSymbol === null) {
cy.get(`#swap-currency-${field} .token-symbol-container`).should('contain.text', 'Select token')
} else {
cy.get(`#swap-currency-${field} .token-symbol-container`).should('contain.text', tokenSymbol)
}
}
const selectOutput = (tokenSymbol: string) => {
// open token selector...
cy.contains('Select token').click()
// select token...
cy.contains(tokenSymbol).click()
cy.get('body')
.then(($body) => {
if ($body.find(getTestSelector('TokenSafetyWrapper')).length) {
return 'I understand'
}
return 'no-op' // Don't click on anything, a no-op
})
.then((content) => {
if (content !== 'no-op') {
cy.contains(content).click()
}
})
// token selector should close...
cy.contains('Search name or paste address').should('not.exist')
}
before(() => { before(() => {
cy.visit('/swap') cy.visit('/swap')
}) })
it('starts with ETH selected by default', () => { it('starts with ETH selected by default', () => {
cy.get('#swap-currency-input .token-amount-input').should('have.value', '') verifyAmount('input', '')
cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'ETH') verifyToken('input', 'ETH')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value') verifyAmount('output', null)
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select token') verifyToken('output', null)
}) })
it('can enter an amount into input', () => { it('can enter an amount into input', () => {
@ -30,24 +74,64 @@ describe('Swap', () => {
cy.get('#swap-currency-output .token-amount-input').clear().type('0.0').should('have.value', '0.0') cy.get('#swap-currency-output .token-amount-input').clear().type('0.0').should('have.value', '0.0')
}) })
it.skip('can swap ETH for DAI', () => { it('should have the correct default input/output and token selection should work', () => {
cy.get('#swap-currency-output .open-currency-select-button').click() cy.visit('/swap')
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click() verifyToken('input', 'ETH')
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0000001') verifyToken('output', null)
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click() selectOutput('WETH')
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap') cy.get(getTestSelector('swap-currency-button')).first().click()
cy.get('[data-cy="confirmation-close-icon"]').click()
verifyToken('input', 'WETH')
verifyToken('output', 'ETH')
}) })
it('add a recipient does not exist unless in expert mode', () => { it('should have the correct default input from URL params ', () => {
cy.get('#add-recipient-button').should('not.exist') cy.visit(`/swap?inputCurrency=${WETH9[SupportedChainId.GOERLI].address}`)
verifyToken('input', 'WETH')
verifyToken('output', null)
selectOutput('Ether')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'ETH')
verifyToken('output', 'WETH')
}) })
it.skip('ETH to wETH is same value (wrapped swaps have no price impact)', () => { it('should have the correct default output from URL params ', () => {
cy.get('#swap-currency-output .open-currency-select-button').click() cy.visit(`/swap?outputCurrency=${WETH9[SupportedChainId.GOERLI].address}`)
cy.get('.token-item-0xc778417E063141139Fce010982780140Aa0cD5Ab').click()
verifyToken('input', null)
verifyToken('output', 'WETH')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'WETH')
verifyToken('output', null)
selectOutput('Ether')
cy.get(getTestSelector('swap-currency-button')).first().click()
verifyToken('input', 'ETH')
verifyToken('output', 'WETH')
})
it('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
cy.visit('/swap')
selectOutput('WETH')
cy.get('#swap-currency-input .token-amount-input').clear().type('0.01') cy.get('#swap-currency-input .token-amount-input').clear().type('0.01')
cy.get('#swap-currency-output .token-amount-input').should('have.value', '0.01') cy.get('#swap-currency-output .token-amount-input').should('have.value', '0.01')
}) })
it('Opens and closes the settings menu', () => {
cy.visit('/swap')
cy.contains('Settings').should('not.exist')
cy.get(getTestSelector('swap-settings-button')).click()
cy.contains('Slippage tolerance').should('exist')
cy.contains('Transaction deadline').should('exist')
cy.contains('Auto Router API').should('exist')
cy.contains('Expert Mode').should('exist')
cy.get(getTestSelector('swap-settings-button')).click()
cy.contains('Settings').should('not.exist')
})
}) })

@ -1,4 +1,6 @@
import { getTestSelector } from '../utils' import { getClassContainsSelector, getTestSelector } from '../utils'
const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
describe('Token details', () => { describe('Token details', () => {
before(() => { before(() => {
@ -7,7 +9,7 @@ describe('Token details', () => {
it('Uniswap token should have all information populated', () => { it('Uniswap token should have all information populated', () => {
// Uniswap token // Uniswap token
cy.visit('/tokens/ethereum/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`)
// Price chart should be filled in // Price chart should be filled in
cy.get('[data-cy="chart-header"]').should('include.text', '$') cy.get('[data-cy="chart-header"]').should('include.text', '$')
@ -28,18 +30,16 @@ describe('Token details', () => {
// Links section should link out to Etherscan, More analytics, Website, Twitter // Links section should link out to Etherscan, More analytics, Website, Twitter
cy.get('[data-cy="resources-container"]').within(() => { cy.get('[data-cy="resources-container"]').within(() => {
cy.contains('Etherscan') cy.contains('Etherscan').should('have.attr', 'href').and('include', `etherscan.io/address/${UNI_ADDRESS}`)
.should('have.attr', 'href')
.and('include', 'etherscan.io/address/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
cy.contains('More analytics') cy.contains('More analytics')
.should('have.attr', 'href') .should('have.attr', 'href')
.and('include', 'info.uniswap.org/#/tokens/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') .and('include', `info.uniswap.org/#/tokens/${UNI_ADDRESS}`)
cy.contains('Website').should('have.attr', 'href').and('include', 'uniswap.org') cy.contains('Website').should('have.attr', 'href').and('include', 'uniswap.org')
cy.contains('Twitter').should('have.attr', 'href').and('include', 'twitter.com/Uniswap') cy.contains('Twitter').should('have.attr', 'href').and('include', 'twitter.com/Uniswap')
}) })
// Contract address should be displayed // Contract address should be displayed
cy.contains('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984').should('exist') cy.contains(UNI_ADDRESS).should('exist')
// Swap widget should have this token pre-selected as the “destination” token // Swap widget should have this token pre-selected as the “destination” token
cy.get(getTestSelector('token-select')).should('include.text', 'UNI') cy.get(getTestSelector('token-select')).should('include.text', 'UNI')
@ -89,4 +89,28 @@ describe('Token details', () => {
.should('include.text', 'Warning') .should('include.text', 'Warning')
.and('include.text', "This token isn't traded on leading U.S. centralized exchanges") .and('include.text', "This token isn't traded on leading U.S. centralized exchanges")
}) })
describe('Swap on Token Detail Page', () => {
const verifyOutputToken = (outputText: string) => {
cy.get(getClassContainsSelector('TokenButtonRow')).last().contains(outputText)
}
beforeEach(() => {
// On mobile widths, we just link back to /swap instead of rendering the swap component.
cy.viewport(1200, 800)
cy.visit(`/tokens/goerli/${UNI_ADDRESS}`).then(() => {
cy.wait('@eth_blockNumber')
})
})
it('should have the expected output for a tokens detail page', () => {
verifyOutputToken('UNI')
})
it('should not share swap state with the main swap page', () => {
verifyOutputToken('UNI')
cy.visit('/swap')
cy.contains('UNI').should('not.exist')
})
})
}) })

@ -186,7 +186,7 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
id="open-settings-dialog-button" id="open-settings-dialog-button"
aria-label={t`Transaction Settings`} aria-label={t`Transaction Settings`}
> >
<StyledMenuIcon /> <StyledMenuIcon data-testid="swap-settings-button" />
{expertMode ? ( {expertMode ? (
<EmojiWrapper> <EmojiWrapper>
<span role="img" aria-label="wizard-icon"> <span role="img" aria-label="wizard-icon">

@ -552,6 +552,7 @@ export default function Swap({ className }: { className?: string }) {
element={InterfaceElementName.SWAP_TOKENS_REVERSE_ARROW_BUTTON} element={InterfaceElementName.SWAP_TOKENS_REVERSE_ARROW_BUTTON}
> >
<ArrowContainer <ArrowContainer
data-testid="swap-currency-button"
onClick={() => { onClick={() => {
onSwitchTokens() onSwitchTokens()
}} }}