Files
tom goriunovandGitHub ebbee2ba57 Multichain explorer v2 (#3259)
* Support redirect to a correct view from search

* show domains on address page

* migrate to new API version to display address domains

* another api update

* new design for chain widget on home page + tests

* chain widget styles for mobile devices

* ecosystems page

* update types

* add ecosystems to navigation

* address portfolio: pt.1

* portfolio tokens list

* filter portfolio by chain

* skip redirect when navigating to search result by clicking on "show all results" link

* net worth block design

* add filter input to chain select and fix tokens table

* calculate address portfolio

* adjust card logic

* support custom token types in multichain explorer

* handle case when new worth is 0

* add text filter to tokens list

* fixes

* demo envs

* portfolio tests

* ecosystems test

* change signature for getTokenTypes function

* fix adding token to the wallet from the list

* lazy load all address domains

* show contract creator and implementations info

* fix tests

* add poor reputation tokens toggle

* tweaks

* dim celo native tokens

* disable env validator

* fix tests

* remove tokens with 0 usd value from top tokens

* fixes

* preserve selected chain when switching tabs on address page

* add hints to stats widgets on home page

* update envs for demo

* fix portfolio cards and home page

* update styles for contract creator and implementations

* fix select issues

* add chains from cluster to network menu

* hide csv export link on empty logs page

* update screenshots

* rollback select fix

* update cut length calculation for portfolio cards

* fix chain select

* update screenshots

* fix tests

* more fixes

* add sorting to ecosystems table

* fix test

* fixes

* fix loading state in ecosystems page

* review fixes

* fix tests
2026-02-25 10:45:09 +01:00

155 lines
4.0 KiB
TypeScript

import { Box } from '@chakra-ui/react';
import React from 'react';
import * as chainDataMock from 'mocks/multichain/chains';
import * as tokenMock from 'mocks/tokens/tokenInfo';
import { stableHover } from 'playwright/helpers/stableHover';
import { test, expect } from 'playwright/lib';
import TokenEntity, { Icon } from './TokenEntity';
const variants = [ 'subheading', 'content' ] as const;
test.use({ viewport: { width: 300, height: 100 } });
test.describe('variant', () => {
variants.forEach((variant) => {
test(`${ variant }`, async({ render }) => {
const component = await render(
<TokenEntity
token={ tokenMock.tokenInfo }
variant={ variant }
/>,
);
await expect(component).toHaveScreenshot();
});
test(`${ variant } with chain data`, async({ render, mockAssetResponse }) => {
const LOGO_URL = 'https://example.com/logo.png';
const chainLogoUrl = chainDataMock.chainA.logo;
await mockAssetResponse(LOGO_URL, './playwright/mocks/image_s.jpg');
await mockAssetResponse(chainLogoUrl as string, './playwright/mocks/image_svg.svg');
const component = await render(
<TokenEntity
token={{
type: 'ERC-20',
name: 'This token is the best token ever',
symbol: 'DUCK DUCK DUCK',
address_hash: tokenMock.tokenInfo.address_hash,
icon_url: LOGO_URL,
reputation: 'ok',
}}
chain={ chainDataMock.chainA }
/>,
);
await expect(component).toHaveScreenshot();
});
});
});
test('icon in heading variant', async({ render, mockAssetResponse }) => {
const chainLogoUrl = chainDataMock.chainA.logo;
await mockAssetResponse(tokenMock.tokenInfo.icon_url as string, './playwright/mocks/image_s.jpg');
await mockAssetResponse(chainLogoUrl as string, './playwright/mocks/image_svg.svg');
const component = await render(
<Icon
token={ tokenMock.tokenInfo }
variant="heading"
chain={ chainDataMock.chainA }
/>,
);
await expect(component).toHaveScreenshot();
});
test('with logo, long name and symbol', async({ page, render }) => {
const LOGO_URL = 'https://example.com/logo.png';
await page.route(LOGO_URL, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
await render(
<TokenEntity
token={{
type: 'ERC-20',
name: 'This token is the best token ever',
symbol: 'DUCK DUCK DUCK',
address_hash: tokenMock.tokenInfo.address_hash,
icon_url: LOGO_URL,
reputation: 'ok',
}}
/>,
);
await stableHover(page.getByText(/this/i));
await expect(page).toHaveScreenshot();
await stableHover(page.getByText(/duc/i));
await expect(page).toHaveScreenshot();
});
test('scam token', async({ page, render, mockEnvs }) => {
await mockEnvs([
[ 'NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED', 'true' ],
]);
const LOGO_URL = 'https://example.com/logo.png';
await page.route(LOGO_URL, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
await render(
<TokenEntity
token={{
type: 'ERC-20',
name: 'Duck Token',
symbol: 'DUCK',
address_hash: tokenMock.tokenInfo.address_hash,
icon_url: LOGO_URL,
reputation: 'scam',
}}
/>,
);
await expect(page).toHaveScreenshot();
});
test('loading', async({ render }) => {
const component = await render(
<TokenEntity
token={ tokenMock.tokenInfo }
isLoading
/>,
);
await expect(component).toHaveScreenshot();
});
test('customization', async({ render }) => {
const component = await render(
<Box
borderWidth="1px"
borderColor="orange.500"
>
<TokenEntity
token={ tokenMock.tokenInfo }
p={ 2 }
maxW="200px"
borderWidth="1px"
borderColor="blue.700"
/>
</Box>,
);
await expect(component).toHaveScreenshot();
});