From 4625ed1aa5b2ef5ea96257e798b91423ae5d2233 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 5 Jun 2019 15:52:15 +0400 Subject: [PATCH] add a test for adding custom token --- src/components/forms/TextField/index.jsx | 4 +- src/components/layout/Button/index.jsx | 5 +- src/components/layout/ButtonLink/index.jsx | 21 ++-- .../Tokens/screens/AddCustomToken/index.jsx | 10 +- .../Tokens/screens/TokenList/index.jsx | 3 + src/routes/safe/components/Balances/index.jsx | 7 +- src/test/safe.dom.funds.test.js | 5 +- src/test/tokens.dom.adding.test.js | 104 ++++++++++-------- src/test/utils/DOMNavigation/tokens.js | 18 ++- 9 files changed, 108 insertions(+), 69 deletions(-) diff --git a/src/components/forms/TextField/index.jsx b/src/components/forms/TextField/index.jsx index dc28ae26..00f57137 100644 --- a/src/components/forms/TextField/index.jsx +++ b/src/components/forms/TextField/index.jsx @@ -29,6 +29,7 @@ class TextField extends React.PureComponent { text, inputAdornment, classes, + testId, ...rest } = this.props const helperText = value ? text : undefined @@ -36,7 +37,7 @@ class TextField extends React.PureComponent { const underline = meta.active || (meta.visited && !meta.valid) const inputRoot = helperText ? classes.root : undefined - const inputProps = { ...restInput, autoComplete: 'off' } + const inputProps = { ...restInput, autoComplete: 'off', 'data-testid': testId } const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot } return ( @@ -51,6 +52,7 @@ class TextField extends React.PureComponent { inputProps={inputProps} onChange={onChange} value={value} + // data-testid={testId} /> ) } diff --git a/src/components/layout/Button/index.jsx b/src/components/layout/Button/index.jsx index 41808b76..faf4e088 100644 --- a/src/components/layout/Button/index.jsx +++ b/src/components/layout/Button/index.jsx @@ -12,6 +12,7 @@ const styles = { type Props = { minWidth?: number, minHeight?: number, + testId: string, } const calculateStyleBased = (minWidth, minHeight) => ({ @@ -19,10 +20,10 @@ const calculateStyleBased = (minWidth, minHeight) => ({ minHeight: minHeight && `${minHeight}px`, }) -const GnoButton = ({ minWidth, minHeight, ...props }: Props) => { +const GnoButton = ({ minWidth, minHeight, testId = '', ...props }: Props) => { const style = calculateStyleBased(minWidth, minHeight) - return diff --git a/src/routes/safe/components/Balances/index.jsx b/src/routes/safe/components/Balances/index.jsx index 0d7c8892..a26de433 100644 --- a/src/routes/safe/components/Balances/index.jsx +++ b/src/routes/safe/components/Balances/index.jsx @@ -26,6 +26,9 @@ import SendModal from './SendModal' import Receive from './Receive' import { styles } from './style' +export const MANAGE_TOKENS_BUTTON_TEST_ID = 'manage-tokens-btn' +export const BALANCE_ROW_TEST_ID = 'balance-row' + type State = { hideZero: boolean, showToken: boolean, @@ -128,7 +131,7 @@ class Balances extends React.Component { Hide zero balances - Manage Tokens + Manage Tokens { defaultFixed > {(sortedData: Array) => sortedData.map((row: any, index: number) => ( - + {autoColumns.map((column: Column) => ( {column.id === BALANCE_TABLE_ASSET_ID ? : row[column.id]} diff --git a/src/test/safe.dom.funds.test.js b/src/test/safe.dom.funds.test.js index 9a913ceb..6f57e940 100644 --- a/src/test/safe.dom.funds.test.js +++ b/src/test/safe.dom.funds.test.js @@ -13,6 +13,7 @@ import { calculateBalanceOf } from '~/routes/safe/store/actions/fetchTokenBalanc import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens' import 'jest-dom/extend-expect' import updateSafe from '~/routes/safe/store/actions/updateSafe' +import { BALANCE_ROW_TEST_ID } from '~/routes/safe/components/Balances' afterEach(cleanup) @@ -37,7 +38,7 @@ describe('DOM > Feature > Funds', () => { await sleep(1300) // Open send funds modal - const balanceRows = SafeDom.getAllByTestId('balance-row') + const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID) expect(balanceRows[0]).toHaveTextContent(`${ethAmount} ETH`) const sendButton = SafeDom.getByTestId('balance-send-btn') fireEvent.click(sendButton) @@ -91,7 +92,7 @@ describe('DOM > Feature > Funds', () => { await sleep(1000) // Open send funds modal - const balanceRows = SafeDom.getAllByTestId('balance-row') + const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID) expect(balanceRows.length).toBe(2) const sendButtons = SafeDom.getAllByTestId('balance-send-btn') expect(sendButtons.length).toBe(2) diff --git a/src/test/tokens.dom.adding.test.js b/src/test/tokens.dom.adding.test.js index 84d55895..a77c734a 100644 --- a/src/test/tokens.dom.adding.test.js +++ b/src/test/tokens.dom.adding.test.js @@ -1,65 +1,83 @@ // @flow import { getWeb3 } from '~/logic/wallets/getWeb3' -import { type Match } from 'react-router-dom' -import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements' +import { fireEvent } from '@testing-library/react' +import { getFirstTokenContract } from '~/test/utils/tokenMovements' import { aNewStore } from '~/store' import { aMinedSafe } from '~/test/builder/safe.redux.builder' -import { travelToTokens } from '~/test/builder/safe.dom.utils' +import { renderSafeView } from '~/test/builder/safe.dom.utils' import { sleep } from '~/utils/timer' -import { buildMatchPropsFrom } from '~/test/utils/buildReactRouterProps' -import { tokenListSelector } from '~/logic/tokens/store/selectors' -import { testToken } from '~/test/builder/tokens.dom.utils' +import { clickOnManageTokens, clickOnAddCustomToken } from '~/test/utils/DOMNavigation' import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens' -import * as enhancedFetchModule from '~/utils/fetch' +import { + ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID, + ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID, + ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID, + ADD_CUSTOM_TOKEN_FORM, +} from '~/routes/safe/components/Balances/Tokens/screens/AddCustomToken' +import { BALANCE_ROW_TEST_ID } from '~/routes/safe/components/Balances/' +import 'jest-dom/extend-expect' -describe('DOM > Feature > Add new ERC 20 Tokens', () => { +// https://github.com/testing-library/@testing-library/react/issues/281 +const originalError = console.error +beforeAll(() => { + console.error = (...args) => { + if (/Warning.*not wrapped in act/.test(args[0])) { + return + } + originalError.call(console, ...args) + } +}) + +afterAll(() => { + console.error = originalError +}) + +describe('DOM > Feature > Add custom ERC 20 Tokens', () => { let web3 let accounts - let firstErc20Token - let secondErc20Token + let erc20Token beforeAll(async () => { web3 = getWeb3() accounts = await web3.eth.getAccounts() - firstErc20Token = await getFirstTokenContract(web3, accounts[0]) - secondErc20Token = await getSecondTokenContract(web3, accounts[0]) - - // $FlowFixMe - enhancedFetchModule.enhancedFetch = jest.fn() - enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({ - results: [ - { - address: firstErc20Token.address, - name: 'First Token Example', - symbol: 'FTE', - decimals: 18, - logoUri: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Earth_simple_icon.png', - }, - ], - })) + erc20Token = await getFirstTokenContract(web3, accounts[0]) }) - it('adds a second erc 20 token filling the form', async () => { + it('adds and displays an erc 20 token after filling the form', async () => { // GIVEN const store = aNewStore() const safeAddress = await aMinedSafe(store) - await store.dispatch(fetchTokensModule.fetchTokens(safeAddress)) - const TokensDom = await travelToTokens(store, safeAddress) + await store.dispatch(fetchTokensModule.fetchTokens()) + const TokensDom = renderSafeView(store, safeAddress) await sleep(400) - const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent) - expect(tokens.length).toBe(2) - testToken(tokens[0].props.token, 'FTE', false) - testToken(tokens[1].props.token, 'ETH', true) + // WHEN - await clickOnAddToken(TokensDom) - await fillAddress(TokensDom, secondErc20Token) - await fillHumanReadableInfo(TokensDom) - // THEN - const match: Match = buildMathPropsFrom(safeAddress) - const tokenList = tokenListSelector(store.getState(), { match }) - expect(tokenList.count()).toBe(3) - testToken(tokenList.get(0), 'FTE', false) - testToken(tokenList.get(1), 'ETH', true) - testToken(tokenList.get(2), 'TKN', true) + clickOnManageTokens(TokensDom) + clickOnAddCustomToken(TokensDom) + await sleep(200) + + // Fill address + const addTokenForm = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_FORM) + const addressInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID) + fireEvent.change(addressInput, { target: { value: erc20Token.address } }) + await sleep(500) + + // Check if it loaded symbol/decimals correctly + const symbolInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID) + const decimalsInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID) + + const tokenSymbol = await erc20Token.symbol() + const tokenDecimals = await erc20Token.decimals() + expect(symbolInput.value).toBe(tokenSymbol) + expect(decimalsInput.value).toBe(tokenDecimals.toString()) + + // Submit form + fireEvent.submit(addTokenForm) + await sleep(300) + + // check if token is displayed + const balanceRows = TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID) + expect(balanceRows.length).toBe(2) + expect(balanceRows[1]).toHaveTextContent(tokenSymbol) }) }) diff --git a/src/test/utils/DOMNavigation/tokens.js b/src/test/utils/DOMNavigation/tokens.js index ac885a0e..b40ff245 100644 --- a/src/test/utils/DOMNavigation/tokens.js +++ b/src/test/utils/DOMNavigation/tokens.js @@ -1,8 +1,16 @@ // @flow -import { fireEvent } from '@testing-library/reactß' +import { fireEvent } from '@testing-library/react' +import { MANAGE_TOKENS_BUTTON_TEST_ID } from '~/routes/safe/components/Balances' +import { ADD_CUSTOM_TOKEN_BUTTON_TEST_ID } from '~/routes/safe/components/Balances/Tokens/screens/TokenList' -const clickOnManageTokens = (dom) => { - const btn = dom.findByTestId() +export const clickOnManageTokens = (dom: any): void => { + const btn = dom.getByTestId(MANAGE_TOKENS_BUTTON_TEST_ID) - -} \ No newline at end of file + fireEvent.click(btn) +} + +export const clickOnAddCustomToken = (dom: any): void => { + const btn = dom.getByTestId(ADD_CUSTOM_TOKEN_BUTTON_TEST_ID) + + fireEvent.click(btn) +}