Commit 9b52fea5 authored by lynn's avatar lynn Committed by GitHub

test: swap details dropdown unit test (#6349)

* init for swap details dropdown test

* more tests

* complete tests, ready for review

* add to dev deps

* init

* merge main

* init

* use test constants

* use constants

* change address

* more comprehensive tests

* merge with constants

* move noop

* add eslint rule

* return null in noop

* merge

* update snapshot

* constant name

* snapshot change

* lint

* undo eslint change

* Update src/components/swap/SwapDetailsDropdown.test.tsx
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* Update src/components/swap/SwapDetailsDropdown.test.tsx
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* Update src/components/swap/SwapDetailsDropdown.test.tsx
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* respond comments

* update snapshot

* merge main

* user event instead

* add act

* import fix

---------
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>
parent b92b2866
import userEvent from '@testing-library/user-event'
import { TEST_ALLOWED_SLIPPAGE, TEST_TOKEN_1, TEST_TRADE_EXACT_INPUT, toCurrencyAmount } from 'test-utils/constants'
import { act, render, screen } from 'test-utils/render'
import SwapDetailsDropdown from './SwapDetailsDropdown'
describe('SwapDetailsDropdown.tsx', () => {
it('renders a trade', () => {
const { asFragment } = render(
<SwapDetailsDropdown
trade={TEST_TRADE_EXACT_INPUT}
syncing={false}
loading={false}
allowedSlippage={TEST_ALLOWED_SLIPPAGE}
/>
)
expect(asFragment()).toMatchSnapshot()
})
it('renders loading state', () => {
render(
<SwapDetailsDropdown trade={undefined} syncing={true} loading={true} allowedSlippage={TEST_ALLOWED_SLIPPAGE} />
)
expect(screen.getByText('Fetching best price...')).toBeInTheDocument()
})
it('is interactive once loaded', async () => {
TEST_TRADE_EXACT_INPUT.gasUseEstimateUSD = toCurrencyAmount(TEST_TOKEN_1, 1)
render(
<SwapDetailsDropdown
trade={TEST_TRADE_EXACT_INPUT}
syncing={false}
loading={false}
allowedSlippage={TEST_ALLOWED_SLIPPAGE}
/>
)
expect(screen.getByTestId('swap-details-header-row')).toBeInTheDocument()
expect(screen.getByTestId('trade-price-container')).toBeInTheDocument()
await act(() => userEvent.click(screen.getByTestId('swap-details-header-row')))
expect(screen.getByTestId('advanced-swap-details')).toBeInTheDocument()
expect(screen.getByTestId('swap-route-info')).toBeInTheDocument()
})
})
......@@ -118,7 +118,12 @@ export default function SwapDetailsDropdown({ trade, syncing, loading, allowedSl
element={InterfaceElementName.SWAP_DETAILS_DROPDOWN}
shouldLogImpression={!showDetails}
>
<StyledHeaderRow onClick={() => setShowDetails(!showDetails)} disabled={!trade} open={showDetails}>
<StyledHeaderRow
data-testid="swap-details-header-row"
onClick={() => setShowDetails(!showDetails)}
disabled={!trade}
open={showDetails}
>
<RowFixed style={{ position: 'relative' }} align="center">
{Boolean(loading || syncing) && (
<StyledPolling>
......@@ -128,7 +133,7 @@ export default function SwapDetailsDropdown({ trade, syncing, loading, allowedSl
</StyledPolling>
)}
{trade ? (
<LoadingOpacityContainer $loading={syncing}>
<LoadingOpacityContainer $loading={syncing} data-testid="trade-price-container">
<TradePrice price={trade.executionPrice} />
</LoadingOpacityContainer>
) : loading || syncing ? (
......@@ -159,11 +164,11 @@ export default function SwapDetailsDropdown({ trade, syncing, loading, allowedSl
<AnimatedDropdown open={showDetails}>
<AutoColumn gap="sm" style={{ padding: '0', paddingBottom: '8px' }}>
{trade ? (
<StyledCard>
<StyledCard data-testid="advanced-swap-details">
<AdvancedSwapDetails trade={trade} allowedSlippage={allowedSlippage} syncing={syncing} />
</StyledCard>
) : null}
{trade ? <SwapRoute trade={trade} syncing={syncing} /> : null}
{trade ? <SwapRoute data-testid="swap-route-info" trade={trade} syncing={syncing} /> : null}
</AutoColumn>
</AnimatedDropdown>
</AutoColumn>
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SwapDetailsDropdown.tsx renders a trade 1`] = `
<DocumentFragment>
.c0 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c20 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: auto;
}
.c37 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: 100%;
}
.c1 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c21 {
width: auto;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
gap: 4px;
}
.c38 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
gap: 1px;
}
.c4 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c22 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: -4px;
}
.c22 > * {
margin: 4px !important;
}
.c39 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: -1px;
}
.c39 > * {
margin: 1px !important;
}
.c6 {
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
.c9 {
color: #0D111C;
}
.c44 {
color: #7780A0;
}
.c17 {
width: 100%;
height: 1px;
background-color: #D2D9EE;
}
.c11 {
width: 100%;
padding: 1rem;
border-radius: 16px;
}
.c12 {
border: 1px solid #B8C0DC;
}
.c3 {
display: grid;
grid-auto-rows: auto;
grid-row-gap: 8px;
}
.c18 {
display: grid;
grid-auto-rows: auto;
}
.c7 {
-webkit-filter: none;
filter: none;
opacity: 1;
-webkit-transition: opacity 0.2s ease-in-out;
transition: opacity 0.2s ease-in-out;
}
.c15 {
display: inline-block;
height: inherit;
}
.c16 {
color: #7780A0;
}
.c14 {
padding: 0;
}
.c33 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background: #E8ECFB;
border: unset;
border-radius: 0.5rem;
color: #000;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
padding: 4px 6px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
font-weight: 500;
}
.c29 {
width: 20px;
height: 20px;
border-radius: 50%;
background: radial-gradient(white 60%,#ffffff00 calc(70% + 1px));
box-shadow: 0 0 1px white;
}
.c28 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.c41 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}
.c42 {
z-index: 1;
}
.c43 {
position: absolute;
left: -10px !important;
}
.c26 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.c27 {
display: grid;
grid-template-columns: 24px 1fr 24px;
}
.c30 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
padding: 0.1rem 0.5rem;
position: relative;
}
.c40 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 4px 4px;
}
.c31 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: absolute;
width: calc(100%);
z-index: 1;
opacity: 0.5;
}
.c32 path {
stroke: #98A1C0;
}
.c34 {
background-color: #E8ECFB;
border-radius: 8px;
display: grid;
font-size: 12px;
grid-gap: 4px;
grid-auto-flow: column;
-webkit-box-pack: start;
-webkit-justify-content: start;
-ms-flex-pack: start;
justify-content: start;
padding: 4px 6px 4px 4px;
z-index: 1020;
}
.c35 {
background-color: #B8C0DC;
border-radius: 4px;
color: #7780A0;
font-size: 10px;
padding: 2px 4px;
z-index: 1021;
}
.c36 {
word-break: normal;
}
.c23 {
height: 16px;
width: 16px;
}
.c23:hover {
-webkit-filter: brightness(1.3);
filter: brightness(1.3);
}
.c24 {
line-height: 1rem;
color: #40B66B;
}
.c19 {
padding: 12px 8px 12px 12px;
border-radius: 16px;
border: 1px solid #D2D9EE;
cursor: pointer;
}
.c25 {
margin-left: 8px;
height: 20px;
stroke-width: 2px;
-webkit-transition: -webkit-transform 0.1s;
-webkit-transition: transform 0.1s;
transition: transform 0.1s;
-webkit-transform: none;
-ms-transform: none;
transform: none;
stroke: #98A1C0;
cursor: pointer;
}
.c25:hover {
opacity: 0.8;
}
.c8 {
background-color: transparent;
border: none;
cursor: pointer;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 0;
grid-template-columns: 1fr auto;
grid-gap: 0.25rem;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
text-align: left;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 8px 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.c2 {
width: 100%;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
border-radius: inherit;
padding: 8px 12px;
margin-top: 0;
min-height: 32px;
}
.c13 {
padding: 12px;
border: 1px solid #D2D9EE;
}
.c5 {
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
cursor: pointer;
}
.c10 {
-webkit-transform: none;
-ms-transform: none;
transform: none;
-webkit-transition: -webkit-transform 0.1s linear;
-webkit-transition: transform 0.1s linear;
transition: transform 0.1s linear;
}
@supports (-webkit-background-clip:text) and (-webkit-text-fill-color:transparent) {
.c24 {
background-image: linear-gradient(90deg,#2172e5 0%,#54e521 163.16%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
<div
class="c0 c1 c2"
style="margin-top: 0px;"
>
<div
class="c3"
style="width: 100%; margin-bottom: -8px;"
>
<div
class="c0 c1 c4 c5"
data-testid="swap-details-header-row"
>
<div
class="c0 c1 c6"
style="position: relative;"
>
<div
class="c7"
data-testid="trade-price-container"
>
<button
class="c8"
title="1 DEF = 1.00 ABC "
>
<div
class="c9 css-zhpkf8"
>
1 DEF = 1.00 ABC
</div>
</button>
</div>
</div>
<div
class="c0 c1 c6"
>
<svg
class="c10"
fill="none"
height="24"
stroke="#98A1C0"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="6 9 12 15 18 9"
/>
</svg>
</div>
</div>
<div
style="height: 0px; overflow: hidden; width: 100%; will-change: height;"
>
<div>
<div
class="c3"
style="padding: 0px 0px 8px 0px;"
>
<div
class="c0 c11 c12 c13"
data-testid="advanced-swap-details"
>
<div
class="c0 c11 c14"
>
<div
class="c3"
>
<div
class="c0 c1 c4"
>
<div
class="c0 c1 c6"
>
<div
class="c15"
>
<div>
<div
class="css-zhpkf8"
>
Expected Output
</div>
</div>
</div>
</div>
<div
class="c9 css-q4yjm0"
>
0.000000000000001 DEF
</div>
</div>
<div
class="c0 c1 c4"
>
<div
class="c0 c1 c6"
>
<div
class="c15"
>
<div>
<div
class="css-zhpkf8"
>
Price Impact
</div>
</div>
</div>
</div>
<div
class="c9 css-q4yjm0"
>
<div
class="c16 css-1aekuku"
>
105567.37%
</div>
</div>
</div>
<div
class="c17"
/>
<div
class="c0 c1 c4"
>
<div
class="c0 c1 c6"
style="margin-right: 20px;"
>
<div
class="c15"
>
<div>
<div
class="css-zhpkf8"
>
Minimum received after slippage (2.00%)
</div>
</div>
</div>
</div>
<div
class="css-q4yjm0"
>
0.00000000000000098 DEF
</div>
</div>
</div>
</div>
</div>
<div
class="c18 c19"
data-testid="swap-route-info"
>
<div
class="c0 c1 c4"
>
<div
class="c20 c21 c22"
width="auto"
>
<svg
class="c23"
fill="none"
height="20"
viewBox="0 0 23 20"
width="23"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<lineargradient
gradientTransform="rotate(95)"
id="AutoRouterIconGradient0"
x1="0"
x2="1"
y1="0"
y2="0"
>
<stop
id="stop1"
offset="0"
stop-color="#2274E2"
/>
<stop
id="stop1"
offset="0.5"
stop-color="#2274E2"
/>
<stop
id="stop2"
offset="1"
stop-color="#3FB672"
/>
</lineargradient>
</defs>
<path
d="M16 16C10 16 9 10 5 10M16 16C16 17.6569 17.3431 19 19 19C20.6569 19 22 17.6569 22 16C22 14.3431 20.6569 13 19 13C17.3431 13 16 14.3431 16 16ZM5 10C9 10 10 4 16 4M5 10H1.5M16 4C16 5.65685 17.3431 7 19 7C20.6569 7 22 5.65685 22 4C22 2.34315 20.6569 1 19 1C17.3431 1 16 2.34315 16 4Z"
stroke="url(#AutoRouterIconGradient0)"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
/>
</svg>
<div
class="c9 c24 css-1aekuku"
>
Auto Router
</div>
</div>
<svg
class="c25"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<line
x1="12"
x2="12"
y1="5"
y2="19"
/>
<line
x1="5"
x2="19"
y1="12"
y2="12"
/>
</svg>
</div>
<div
style="height: 0px; overflow: hidden; width: 100%; will-change: height;"
>
<div>
<div
class="c20 c21 c22"
style="padding-top: 12px; margin: 0px;"
width="auto"
>
<div
class="c26 css-vurnku"
>
<div
class="c0 c1 c27"
>
<div
class="c28"
>
<img
alt="ABC logo"
class="c29"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
</div>
<div
class="c0 c1 c30"
>
<div
class="c31"
>
<svg
class="c32"
>
dot_line.svg
</svg>
</div>
<div
class="c33 c34"
>
<div
class="c33 c35"
>
<div
class="c36 css-15li2d9"
>
V3
</div>
</div>
<div
class="c36 css-1aekuku"
style="min-width: auto;"
>
100%
</div>
</div>
<div
class="c37 c38 c39"
style="justify-content: space-evenly; z-index: 2;"
width="100%"
>
<div
class="c15"
>
<div>
<div
class="c33 c40"
>
<div
class="css-mbnpt3"
>
<div
class="c41"
>
<div
class="c42"
>
<div
class="c28"
>
<img
alt="DEF logo"
class="c29"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
</div>
</div>
<div
class="c43"
>
<div
class="c28"
>
<img
alt="ABC logo"
class="c29"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
</div>
</div>
</div>
</div>
<div
class="css-1aekuku"
>
1%
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="c28"
>
<img
alt="DEF logo"
class="c29"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
</div>
</div>
</div>
<div
class="c17"
/>
<div
class="c44 css-65u4ng"
>
This route optimizes your total output by considering split routes, multiple hops, and the gas cost of each step.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</DocumentFragment>
`;
......@@ -3,6 +3,7 @@ import 'jest-styled-components' // adds style diffs to snapshot tests
import type { createPopper } from '@popperjs/core'
import { useWeb3React } from '@web3-react/core'
import ResizeObserver from 'resize-observer-polyfill'
import { Readable } from 'stream'
import { mocked } from 'test-utils/mocked'
import { TextDecoder, TextEncoder } from 'util'
......@@ -16,6 +17,8 @@ if (typeof global.TextEncoder === 'undefined') {
global.TextDecoder = TextDecoder as typeof global.TextDecoder
}
global.ResizeObserver = ResizeObserver
global.matchMedia =
global.matchMedia ||
function () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment