diff --git a/cypress/e2e/swap.test.ts b/cypress/e2e/swap.test.ts
index e05a317550..d6ccb0bbc3 100644
--- a/cypress/e2e/swap.test.ts
+++ b/cypress/e2e/swap.test.ts
@@ -1,13 +1,57 @@
+import { SupportedChainId, WETH9 } from '@uniswap/sdk-core'
+
+import { getTestSelector } from '../utils'
+
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(() => {
cy.visit('/swap')
})
it('starts with ETH selected by default', () => {
- cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
- cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'ETH')
- cy.get('#swap-currency-output .token-amount-input').should('not.have.value')
- cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select token')
+ verifyAmount('input', '')
+ verifyToken('input', 'ETH')
+ verifyAmount('output', null)
+ verifyToken('output', null)
})
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')
})
- it.skip('can swap ETH for DAI', () => {
- cy.get('#swap-currency-output .open-currency-select-button').click()
- cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click()
- cy.get('#swap-currency-input .token-amount-input').clear().type('0.0000001')
- cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
- cy.get('#swap-button').click()
- cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
- cy.get('[data-cy="confirmation-close-icon"]').click()
+ it('should have the correct default input/output and token selection should work', () => {
+ cy.visit('/swap')
+ verifyToken('input', 'ETH')
+ verifyToken('output', null)
+
+ selectOutput('WETH')
+ cy.get(getTestSelector('swap-currency-button')).first().click()
+
+ verifyToken('input', 'WETH')
+ verifyToken('output', 'ETH')
})
- it('add a recipient does not exist unless in expert mode', () => {
- cy.get('#add-recipient-button').should('not.exist')
+ it('should have the correct default input from URL params ', () => {
+ 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)', () => {
- cy.get('#swap-currency-output .open-currency-select-button').click()
- cy.get('.token-item-0xc778417E063141139Fce010982780140Aa0cD5Ab').click()
+ it('should have the correct default output from URL params ', () => {
+ cy.visit(`/swap?outputCurrency=${WETH9[SupportedChainId.GOERLI].address}`)
+
+ 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-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')
+ })
})
diff --git a/cypress/e2e/token-details.test.ts b/cypress/e2e/token-details.test.ts
index 622d155af9..5971dc50e9 100644
--- a/cypress/e2e/token-details.test.ts
+++ b/cypress/e2e/token-details.test.ts
@@ -1,4 +1,6 @@
-import { getTestSelector } from '../utils'
+import { getClassContainsSelector, getTestSelector } from '../utils'
+
+const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
describe('Token details', () => {
before(() => {
@@ -7,7 +9,7 @@ describe('Token details', () => {
it('Uniswap token should have all information populated', () => {
// Uniswap token
- cy.visit('/tokens/ethereum/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
+ cy.visit(`/tokens/ethereum/${UNI_ADDRESS}`)
// Price chart should be filled in
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
cy.get('[data-cy="resources-container"]').within(() => {
- cy.contains('Etherscan')
- .should('have.attr', 'href')
- .and('include', 'etherscan.io/address/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
+ cy.contains('Etherscan').should('have.attr', 'href').and('include', `etherscan.io/address/${UNI_ADDRESS}`)
cy.contains('More analytics')
.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('Twitter').should('have.attr', 'href').and('include', 'twitter.com/Uniswap')
})
// 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
cy.get(getTestSelector('token-select')).should('include.text', 'UNI')
@@ -89,4 +89,28 @@ describe('Token details', () => {
.should('include.text', 'Warning')
.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')
+ })
+ })
})
diff --git a/src/components/Settings/index.tsx b/src/components/Settings/index.tsx
index 35c8a3d819..cf4d2a7d1e 100644
--- a/src/components/Settings/index.tsx
+++ b/src/components/Settings/index.tsx
@@ -186,7 +186,7 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
id="open-settings-dialog-button"
aria-label={t`Transaction Settings`}
>
-
+
{expertMode ? (
diff --git a/src/pages/Swap/index.tsx b/src/pages/Swap/index.tsx
index ff6ca4c298..1cf9f2a828 100644
--- a/src/pages/Swap/index.tsx
+++ b/src/pages/Swap/index.tsx
@@ -552,6 +552,7 @@ export default function Swap({ className }: { className?: string }) {
element={InterfaceElementName.SWAP_TOKENS_REVERSE_ARROW_BUTTON}
>
{
onSwitchTokens()
}}