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:
lynn 2023-01-18 13:36:30 -05:00 committed by GitHub
parent 9f4a1f48a5
commit 3b765b4f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 10 deletions

@ -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>