chore: token details test (#5830)
* init * fix * init * remove old token test * fixes * remove extraneous tokens test * respond to mike * oops
This commit is contained in:
parent
9f4a1f48a5
commit
3b765b4f05
92
cypress/e2e/token-details.test.ts
Normal file
92
cypress/e2e/token-details.test.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { getTestSelector } from '../utils'
|
||||||
|
|
||||||
|
describe('Token details', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Uniswap token should have all information populated', () => {
|
||||||
|
// Uniswap token
|
||||||
|
cy.visit('/tokens/ethereum/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
|
||||||
|
|
||||||
|
// Price chart should be filled in
|
||||||
|
cy.get('[data-cy="chart-header"]').should('include.text', '$')
|
||||||
|
cy.get('[data-cy="price-chart"]').should('exist')
|
||||||
|
|
||||||
|
// Stats should have: TVL, 24H Volume, 52W low, 52W high
|
||||||
|
cy.get(getTestSelector('token-details-stats')).should('exist')
|
||||||
|
cy.get(getTestSelector('token-details-stats')).within(() => {
|
||||||
|
cy.get('[data-cy="tvl"]').should('include.text', '$')
|
||||||
|
cy.get('[data-cy="volume-24h"]').should('include.text', '$')
|
||||||
|
cy.get('[data-cy="52w-low"]').should('include.text', '$')
|
||||||
|
cy.get('[data-cy="52w-high"]').should('include.text', '$')
|
||||||
|
})
|
||||||
|
|
||||||
|
// About section should have description of token
|
||||||
|
cy.get(getTestSelector('token-details-about-section')).should('exist')
|
||||||
|
cy.contains('UNI is the governance token for Uniswap').should('exist')
|
||||||
|
|
||||||
|
// 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('More analytics')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('include', 'info.uniswap.org/#/tokens/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
|
||||||
|
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')
|
||||||
|
|
||||||
|
// Swap widget should have this token pre-selected as the “destination” token
|
||||||
|
cy.get(getTestSelector('token-select')).should('include.text', 'UNI')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('token with warning and low trading volume should have all information populated', () => {
|
||||||
|
// Shiba predator token, low trading volume and also has warning modal
|
||||||
|
cy.visit('/tokens/ethereum/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
|
||||||
|
|
||||||
|
// Should have missing price chart when price unavailable (expected for this token)
|
||||||
|
if (cy.get('[data-cy="chart-header"]').contains('Price Unavailable')) {
|
||||||
|
cy.get('[data-cy="missing-chart"]').should('exist')
|
||||||
|
}
|
||||||
|
// Stats should have: TVL, 24H Volume, 52W low, 52W high
|
||||||
|
cy.get(getTestSelector('token-details-stats')).should('exist')
|
||||||
|
cy.get(getTestSelector('token-details-stats')).within(() => {
|
||||||
|
cy.get('[data-cy="tvl"]').should('exist')
|
||||||
|
cy.get('[data-cy="volume-24h"]').should('exist')
|
||||||
|
cy.get('[data-cy="52w-low"]').should('exist')
|
||||||
|
cy.get('[data-cy="52w-high"]').should('exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
// About section should have description of token
|
||||||
|
cy.get(getTestSelector('token-details-about-section')).should('exist')
|
||||||
|
cy.contains('QOM is the Shiba Predator').should('exist')
|
||||||
|
|
||||||
|
// 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/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
|
||||||
|
cy.contains('More analytics')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('include', 'info.uniswap.org/#/tokens/0xa71d0588EAf47f12B13cF8eC750430d21DF04974')
|
||||||
|
cy.contains('Website').should('have.attr', 'href').and('include', 'qom')
|
||||||
|
cy.contains('Twitter').should('have.attr', 'href').and('include', 'twitter.com/ShibaPredator1')
|
||||||
|
})
|
||||||
|
|
||||||
|
// Contract address should be displayed
|
||||||
|
cy.contains('0xa71d0588EAf47f12B13cF8eC750430d21DF04974').should('exist')
|
||||||
|
|
||||||
|
// Swap widget should have this token pre-selected as the “destination” token
|
||||||
|
cy.get(getTestSelector('token-select')).should('include.text', 'QOM')
|
||||||
|
|
||||||
|
// Warning label should show if relevant ([spec](https://www.notion.so/3f7fce6f93694be08a94a6984d50298e))
|
||||||
|
cy.get('[data-cy="token-safety-message"]')
|
||||||
|
.should('include.text', 'Warning')
|
||||||
|
.and('include.text', "This token isn't traded on leading U.S. centralized exchanges")
|
||||||
|
})
|
||||||
|
})
|
@ -50,7 +50,7 @@ export default function TokenSafetyMessage({ warning, tokenAddress }: TokenSafet
|
|||||||
const { heading, description } = getWarningCopy(warning)
|
const { heading, description } = getWarningCopy(warning)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Label color={textColor} backgroundColor={backgroundColor}>
|
<Label data-cy="token-safety-message" color={textColor} backgroundColor={backgroundColor}>
|
||||||
<TitleRow>
|
<TitleRow>
|
||||||
{warning.canProceed ? <AlertTriangle size="16px" /> : <Slash size="16px" />}
|
{warning.canProceed ? <AlertTriangle size="16px" /> : <Slash size="16px" />}
|
||||||
<Title marginLeft="7px">{warning.message}</Title>
|
<Title marginLeft="7px">{warning.message}</Title>
|
||||||
|
@ -103,9 +103,8 @@ export function AboutSection({ address, chainId, description, homepageUrl, twitt
|
|||||||
<ThemedText.SubHeaderSmall>
|
<ThemedText.SubHeaderSmall>
|
||||||
<Trans>Links</Trans>
|
<Trans>Links</Trans>
|
||||||
</ThemedText.SubHeaderSmall>
|
</ThemedText.SubHeaderSmall>
|
||||||
<ResourcesContainer>
|
<ResourcesContainer data-cy="resources-container">
|
||||||
<Resource
|
<Resource
|
||||||
data-testid="token-details-about-section-explorer-link"
|
|
||||||
name={chainId === SupportedChainId.MAINNET ? 'Etherscan' : 'Block Explorer'}
|
name={chainId === SupportedChainId.MAINNET ? 'Etherscan' : 'Block Explorer'}
|
||||||
link={`${baseExplorerUrl}${address === 'NATIVE' ? '' : 'address/' + address}`}
|
link={`${baseExplorerUrl}${address === 'NATIVE' ? '' : 'address/' + address}`}
|
||||||
/>
|
/>
|
||||||
|
@ -275,7 +275,7 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ChartHeader>
|
<ChartHeader data-cy="chart-header">
|
||||||
{displayPrice.value ? (
|
{displayPrice.value ? (
|
||||||
<>
|
<>
|
||||||
<TokenPrice>{formatDollar({ num: displayPrice.value, isPrice: true })}</TokenPrice>
|
<TokenPrice>{formatDollar({ num: displayPrice.value, isPrice: true })}</TokenPrice>
|
||||||
@ -294,7 +294,7 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
|||||||
{!chartAvailable ? (
|
{!chartAvailable ? (
|
||||||
<MissingPriceChart width={width} height={graphHeight} message={!!displayPrice.value && missingPricesMessage} />
|
<MissingPriceChart width={width} height={graphHeight} message={!!displayPrice.value && missingPricesMessage} />
|
||||||
) : (
|
) : (
|
||||||
<svg width={width} height={graphHeight} style={{ minWidth: '100%' }}>
|
<svg data-cy="price-chart" width={width} height={graphHeight} style={{ minWidth: '100%' }}>
|
||||||
<AnimatedInLineChart
|
<AnimatedInLineChart
|
||||||
data={prices}
|
data={prices}
|
||||||
getX={getX}
|
getX={getX}
|
||||||
@ -411,7 +411,7 @@ function MissingPriceChart({ width, height, message }: { width: number; height:
|
|||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const midPoint = height / 2 + 45
|
const midPoint = height / 2 + 45
|
||||||
return (
|
return (
|
||||||
<StyledMissingChart width={width} height={height} style={{ minWidth: '100%' }}>
|
<StyledMissingChart data-cy="missing-chart" width={width} height={height} style={{ minWidth: '100%' }}>
|
||||||
<path
|
<path
|
||||||
d={`M 0 ${midPoint} Q 104 ${midPoint - 70}, 208 ${midPoint} T 416 ${midPoint}
|
d={`M 0 ${midPoint} Q 104 ${midPoint - 70}, 208 ${midPoint} T 416 ${midPoint}
|
||||||
M 416 ${midPoint} Q 520 ${midPoint - 70}, 624 ${midPoint} T 832 ${midPoint}`}
|
M 416 ${midPoint} Q 520 ${midPoint - 70}, 624 ${midPoint} T 832 ${midPoint}`}
|
||||||
|
@ -45,9 +45,19 @@ export const StatsWrapper = styled.div`
|
|||||||
|
|
||||||
type NumericStat = number | undefined | null
|
type NumericStat = number | undefined | null
|
||||||
|
|
||||||
function Stat({ value, title, description }: { value: NumericStat; title: ReactNode; description?: ReactNode }) {
|
function Stat({
|
||||||
|
dataCy,
|
||||||
|
value,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
}: {
|
||||||
|
dataCy: string
|
||||||
|
value: NumericStat
|
||||||
|
title: ReactNode
|
||||||
|
description?: ReactNode
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<StatWrapper>
|
<StatWrapper data-cy={`${dataCy}`}>
|
||||||
<MouseoverTooltip text={description}>{title}</MouseoverTooltip>
|
<MouseoverTooltip text={description}>{title}</MouseoverTooltip>
|
||||||
<StatPrice>{formatNumber(value, NumberType.FiatTokenStats)}</StatPrice>
|
<StatPrice>{formatNumber(value, NumberType.FiatTokenStats)}</StatPrice>
|
||||||
</StatWrapper>
|
</StatWrapper>
|
||||||
@ -71,11 +81,13 @@ export default function StatsSection(props: StatsSectionProps) {
|
|||||||
<TokenStatsSection>
|
<TokenStatsSection>
|
||||||
<StatPair>
|
<StatPair>
|
||||||
<Stat
|
<Stat
|
||||||
|
dataCy="tvl"
|
||||||
value={TVL}
|
value={TVL}
|
||||||
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
|
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
|
||||||
title={<Trans>TVL</Trans>}
|
title={<Trans>TVL</Trans>}
|
||||||
/>
|
/>
|
||||||
<Stat
|
<Stat
|
||||||
|
dataCy="volume-24h"
|
||||||
value={volume24H}
|
value={volume24H}
|
||||||
description={
|
description={
|
||||||
<Trans>
|
<Trans>
|
||||||
@ -86,8 +98,8 @@ export default function StatsSection(props: StatsSectionProps) {
|
|||||||
/>
|
/>
|
||||||
</StatPair>
|
</StatPair>
|
||||||
<StatPair>
|
<StatPair>
|
||||||
<Stat value={priceLow52W} title={<Trans>52W low</Trans>} />
|
<Stat dataCy="52w-low" value={priceLow52W} title={<Trans>52W low</Trans>} />
|
||||||
<Stat value={priceHigh52W} title={<Trans>52W high</Trans>} />
|
<Stat dataCy="52w-high" value={priceHigh52W} title={<Trans>52W high</Trans>} />
|
||||||
</StatPair>
|
</StatPair>
|
||||||
</TokenStatsSection>
|
</TokenStatsSection>
|
||||||
</StatsWrapper>
|
</StatsWrapper>
|
||||||
|
Loading…
Reference in New Issue
Block a user