Commit 1b977de2 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Playwright tests refactoring, pt.5 (#1952)

* next part of test refactoring

* more refactoring

* more refactoring

* fixes and clean-up

* fixes

* build fixes

* more fixes
parent ee968da1
...@@ -4,6 +4,7 @@ const RESTRICTED_MODULES = { ...@@ -4,6 +4,7 @@ const RESTRICTED_MODULES = {
{ name: '@chakra-ui/icons', message: 'Using @chakra-ui/icons is prohibited. Please use regular svg-icon instead (see examples in "icons/" folder)' }, { name: '@chakra-ui/icons', message: 'Using @chakra-ui/icons is prohibited. Please use regular svg-icon instead (see examples in "icons/" folder)' },
{ name: '@metamask/providers', message: 'Please lazy-load @metamask/providers or use useProvider hook instead' }, { name: '@metamask/providers', message: 'Please lazy-load @metamask/providers or use useProvider hook instead' },
{ name: '@metamask/post-message-stream', message: 'Please lazy-load @metamask/post-message-stream or use useProvider hook instead' }, { name: '@metamask/post-message-stream', message: 'Please lazy-load @metamask/post-message-stream or use useProvider hook instead' },
{ name: 'playwright/TestApp', message: 'Please use render() fixture from test() function of playwright/lib module' },
], ],
patterns: [ patterns: [
'icons/*', 'icons/*',
......
import type { AddressCollectionsResponse, AddressNFTsResponse, AddressTokenBalance } from 'types/api/address'; import type { AddressCollectionsResponse, AddressNFTsResponse, AddressTokenBalance, AddressTokensResponse } from 'types/api/address';
import * as tokens from 'mocks/tokens/tokenInfo'; import * as tokens from 'mocks/tokens/tokenInfo';
import * as tokenInstance from 'mocks/tokens/tokenInstance'; import * as tokenInstance from 'mocks/tokens/tokenInstance';
...@@ -119,35 +119,39 @@ export const erc404b: AddressTokenBalance = { ...@@ -119,35 +119,39 @@ export const erc404b: AddressTokenBalance = {
token_id: null, token_id: null,
}; };
export const erc20List = { export const erc20List: AddressTokensResponse = {
items: [ items: [
erc20a, erc20a,
erc20b, erc20b,
erc20c, erc20c,
], ],
next_page_params: null,
}; };
export const erc721List = { export const erc721List: AddressTokensResponse = {
items: [ items: [
erc721a, erc721a,
erc721b, erc721b,
erc721c, erc721c,
], ],
next_page_params: null,
}; };
export const erc1155List = { export const erc1155List: AddressTokensResponse = {
items: [ items: [
erc1155withoutName, erc1155withoutName,
erc1155a, erc1155a,
erc1155b, erc1155b,
], ],
next_page_params: null,
}; };
export const erc404List = { export const erc404List: AddressTokensResponse = {
items: [ items: [
erc404a, erc404a,
erc404b, erc404b,
], ],
next_page_params: null,
}; };
export const nfts: AddressNFTsResponse = { export const nfts: AddressNFTsResponse = {
......
export const solidityscanReportAverage = { import type { SolidityscanReport } from 'types/api/contract';
export const solidityscanReportAverage: SolidityscanReport = {
scan_report: { scan_report: {
contractname: 'foo',
scan_status: 'scan_done', scan_status: 'scan_done',
scan_summary: { scan_summary: {
issue_severity_distribution: { issue_severity_distribution: {
...@@ -20,8 +23,9 @@ export const solidityscanReportAverage = { ...@@ -20,8 +23,9 @@ export const solidityscanReportAverage = {
}, },
}; };
export const solidityscanReportGreat = { export const solidityscanReportGreat: SolidityscanReport = {
scan_report: { scan_report: {
contractname: 'foo',
scan_status: 'scan_done', scan_status: 'scan_done',
scan_summary: { scan_summary: {
issue_severity_distribution: { issue_severity_distribution: {
...@@ -42,8 +46,9 @@ export const solidityscanReportGreat = { ...@@ -42,8 +46,9 @@ export const solidityscanReportGreat = {
}, },
}; };
export const solidityscanReportLow = { export const solidityscanReportLow: SolidityscanReport = {
scan_report: { scan_report: {
contractname: 'foo',
scan_status: 'scan_done', scan_status: 'scan_done',
scan_summary: { scan_summary: {
issue_severity_distribution: { issue_severity_distribution: {
......
import _mapValues from 'lodash/mapValues'; import _mapValues from 'lodash/mapValues';
export const base = { import type { HomeStats } from 'types/api/stats';
export const base: HomeStats = {
average_block_time: 6212.0, average_block_time: 6212.0,
coin_price: '0.00199678', coin_price: '0.00199678',
coin_price_change_percentage: -7.42, coin_price_change_percentage: -7.42,
...@@ -42,35 +44,42 @@ export const base = { ...@@ -42,35 +44,42 @@ export const base = {
tvl: '1767425.102766552', tvl: '1767425.102766552',
}; };
export const withBtcLocked = { export const withBtcLocked: HomeStats = {
...base, ...base,
rootstock_locked_btc: '3337493406696977561374', rootstock_locked_btc: '3337493406696977561374',
}; };
export const withoutFiatPrices = { export const withoutFiatPrices: HomeStats = {
...base, ...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, fiat_price: null }) : null), gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, fiat_price: null }) : null),
}; };
export const withoutGweiPrices = { export const withoutGweiPrices: HomeStats = {
...base, ...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null }) : null), gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null }) : null),
}; };
export const withoutBothPrices = { export const withoutBothPrices: HomeStats = {
...base, ...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null, fiat_price: null }) : null), gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null, fiat_price: null }) : null),
}; };
export const withSecondaryCoin = { export const withSecondaryCoin: HomeStats = {
...base, ...base,
secondary_coin_price: '3.398', secondary_coin_price: '3.398',
}; };
export const noChartData = { export const noChartData: HomeStats = {
...base, ...base,
transactions_today: null, transactions_today: null,
coin_price: null, coin_price: null,
market_cap: null, market_cap: null,
tvl: null, tvl: null,
}; };
export const indexingStatus = {
finished_indexing_blocks: false,
indexed_blocks_ratio: '0.1',
finished_indexing: true,
indexed_internal_transactions_ratio: '1',
};
...@@ -8,7 +8,7 @@ export const tokenInfo: TokenInfo = { ...@@ -8,7 +8,7 @@ export const tokenInfo: TokenInfo = {
holders: '46554', holders: '46554',
name: 'ARIANEE', name: 'ARIANEE',
symbol: 'ARIA', symbol: 'ARIA',
type: 'ERC-20', type: 'ERC-20' as const,
total_supply: '1235', total_supply: '1235',
icon_url: 'http://localhost:3000/token-icon.png', icon_url: 'http://localhost:3000/token-icon.png',
}; };
...@@ -27,7 +27,7 @@ export const tokenInfoERC20a: TokenInfo<'ERC-20'> = { ...@@ -27,7 +27,7 @@ export const tokenInfoERC20a: TokenInfo<'ERC-20'> = {
name: 'hyfi.token', name: 'hyfi.token',
symbol: 'HyFi', symbol: 'HyFi',
total_supply: '369000000000000000000000000', total_supply: '369000000000000000000000000',
type: 'ERC-20', type: 'ERC-20' as const,
icon_url: 'http://localhost:3000/token-icon.png', icon_url: 'http://localhost:3000/token-icon.png',
}; };
...@@ -40,7 +40,7 @@ export const tokenInfoERC20b: TokenInfo<'ERC-20'> = { ...@@ -40,7 +40,7 @@ export const tokenInfoERC20b: TokenInfo<'ERC-20'> = {
name: 'USD Coin', name: 'USD Coin',
symbol: 'USDC', symbol: 'USDC',
total_supply: '900000000000000000000000000', total_supply: '900000000000000000000000000',
type: 'ERC-20', type: 'ERC-20' as const,
icon_url: null, icon_url: null,
}; };
...@@ -53,7 +53,7 @@ export const tokenInfoERC20c: TokenInfo<'ERC-20'> = { ...@@ -53,7 +53,7 @@ export const tokenInfoERC20c: TokenInfo<'ERC-20'> = {
name: 'Ethereum', name: 'Ethereum',
symbol: 'ETH', symbol: 'ETH',
total_supply: '1000000000000000000000000', total_supply: '1000000000000000000000000',
type: 'ERC-20', type: 'ERC-20' as const,
icon_url: null, icon_url: null,
}; };
...@@ -66,7 +66,7 @@ export const tokenInfoERC20d: TokenInfo<'ERC-20'> = { ...@@ -66,7 +66,7 @@ export const tokenInfoERC20d: TokenInfo<'ERC-20'> = {
name: 'Zeta', name: 'Zeta',
symbol: 'ZETA', symbol: 'ZETA',
total_supply: '2100000000000000000000000000', total_supply: '2100000000000000000000000000',
type: 'ERC-20', type: 'ERC-20' as const,
icon_url: null, icon_url: null,
}; };
...@@ -79,7 +79,7 @@ export const tokenInfoERC20LongSymbol: TokenInfo<'ERC-20'> = { ...@@ -79,7 +79,7 @@ export const tokenInfoERC20LongSymbol: TokenInfo<'ERC-20'> = {
name: 'Zeta', name: 'Zeta',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
total_supply: '2100000000000000000000000000', total_supply: '2100000000000000000000000000',
type: 'ERC-20', type: 'ERC-20' as const,
icon_url: null, icon_url: null,
}; };
...@@ -92,7 +92,7 @@ export const tokenInfoERC721a: TokenInfo<'ERC-721'> = { ...@@ -92,7 +92,7 @@ export const tokenInfoERC721a: TokenInfo<'ERC-721'> = {
name: 'HyFi Athena', name: 'HyFi Athena',
symbol: 'HYFI_ATHENA', symbol: 'HYFI_ATHENA',
total_supply: '105', total_supply: '105',
type: 'ERC-721', type: 'ERC-721' as const,
icon_url: null, icon_url: null,
}; };
...@@ -105,7 +105,7 @@ export const tokenInfoERC721b: TokenInfo<'ERC-721'> = { ...@@ -105,7 +105,7 @@ export const tokenInfoERC721b: TokenInfo<'ERC-721'> = {
name: 'World Of Women Galaxy', name: 'World Of Women Galaxy',
symbol: 'WOWG', symbol: 'WOWG',
total_supply: null, total_supply: null,
type: 'ERC-721', type: 'ERC-721' as const,
icon_url: null, icon_url: null,
}; };
...@@ -118,7 +118,7 @@ export const tokenInfoERC721c: TokenInfo<'ERC-721'> = { ...@@ -118,7 +118,7 @@ export const tokenInfoERC721c: TokenInfo<'ERC-721'> = {
name: 'Puma', name: 'Puma',
symbol: 'PUMA', symbol: 'PUMA',
total_supply: null, total_supply: null,
type: 'ERC-721', type: 'ERC-721' as const,
icon_url: null, icon_url: null,
}; };
...@@ -131,7 +131,7 @@ export const tokenInfoERC721LongSymbol: TokenInfo<'ERC-721'> = { ...@@ -131,7 +131,7 @@ export const tokenInfoERC721LongSymbol: TokenInfo<'ERC-721'> = {
name: 'Puma', name: 'Puma',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
total_supply: null, total_supply: null,
type: 'ERC-721', type: 'ERC-721' as const,
icon_url: null, icon_url: null,
}; };
...@@ -144,7 +144,7 @@ export const tokenInfoERC1155a: TokenInfo<'ERC-1155'> = { ...@@ -144,7 +144,7 @@ export const tokenInfoERC1155a: TokenInfo<'ERC-1155'> = {
name: 'HyFi Membership', name: 'HyFi Membership',
symbol: 'HYFI_MEMBERSHIP', symbol: 'HYFI_MEMBERSHIP',
total_supply: '482', total_supply: '482',
type: 'ERC-1155', type: 'ERC-1155' as const,
icon_url: null, icon_url: null,
}; };
...@@ -157,7 +157,7 @@ export const tokenInfoERC1155b: TokenInfo<'ERC-1155'> = { ...@@ -157,7 +157,7 @@ export const tokenInfoERC1155b: TokenInfo<'ERC-1155'> = {
name: 'WinkyVerse Collections', name: 'WinkyVerse Collections',
symbol: 'WVC', symbol: 'WVC',
total_supply: '4943', total_supply: '4943',
type: 'ERC-1155', type: 'ERC-1155' as const,
icon_url: null, icon_url: null,
}; };
...@@ -170,7 +170,7 @@ export const tokenInfoERC1155WithoutName: TokenInfo<'ERC-1155'> = { ...@@ -170,7 +170,7 @@ export const tokenInfoERC1155WithoutName: TokenInfo<'ERC-1155'> = {
name: null, name: null,
symbol: null, symbol: null,
total_supply: '482', total_supply: '482',
type: 'ERC-1155', type: 'ERC-1155' as const,
icon_url: null, icon_url: null,
}; };
...@@ -184,7 +184,7 @@ export const tokenInfoERC404: TokenInfo<'ERC-404'> = { ...@@ -184,7 +184,7 @@ export const tokenInfoERC404: TokenInfo<'ERC-404'> = {
name: 'OMNI404', name: 'OMNI404',
symbol: 'O404', symbol: 'O404',
total_supply: '6482275000000000000', total_supply: '6482275000000000000',
type: 'ERC-404', type: 'ERC-404' as const,
}; };
export const bridgedTokenA: TokenInfo<'ERC-20'> = { export const bridgedTokenA: TokenInfo<'ERC-20'> = {
......
import type { TxStateChange } from 'types/api/txStateChanges'; import type { TxStateChange, TxStateChanges } from 'types/api/txStateChanges';
export const mintToken: TxStateChange = { export const mintToken: TxStateChange = {
address: { address: {
...@@ -35,7 +35,7 @@ export const mintToken: TxStateChange = { ...@@ -35,7 +35,7 @@ export const mintToken: TxStateChange = {
type: 'ERC-721', type: 'ERC-721',
icon_url: null, icon_url: null,
}, },
type: 'token', type: 'token' as const,
}; };
export const receiveMintedToken: TxStateChange = { export const receiveMintedToken: TxStateChange = {
...@@ -73,7 +73,7 @@ export const receiveMintedToken: TxStateChange = { ...@@ -73,7 +73,7 @@ export const receiveMintedToken: TxStateChange = {
type: 'ERC-721', type: 'ERC-721',
icon_url: null, icon_url: null,
}, },
type: 'token', type: 'token' as const,
}; };
export const transfer1155Token: TxStateChange = { export const transfer1155Token: TxStateChange = {
...@@ -105,7 +105,7 @@ export const transfer1155Token: TxStateChange = { ...@@ -105,7 +105,7 @@ export const transfer1155Token: TxStateChange = {
type: 'ERC-1155', type: 'ERC-1155',
}, },
token_id: '1', token_id: '1',
type: 'token', type: 'token' as const,
}; };
export const receiveCoin: TxStateChange = { export const receiveCoin: TxStateChange = {
...@@ -125,7 +125,7 @@ export const receiveCoin: TxStateChange = { ...@@ -125,7 +125,7 @@ export const receiveCoin: TxStateChange = {
change: '29726406604060', change: '29726406604060',
is_miner: true, is_miner: true,
token: null, token: null,
type: 'coin', type: 'coin' as const,
}; };
export const sendCoin: TxStateChange = { export const sendCoin: TxStateChange = {
...@@ -145,12 +145,13 @@ export const sendCoin: TxStateChange = { ...@@ -145,12 +145,13 @@ export const sendCoin: TxStateChange = {
change: '-3844844822720562', change: '-3844844822720562',
is_miner: false, is_miner: false,
token: null, token: null,
type: 'coin', type: 'coin' as const,
}; };
export const sendERC20Token = { export const sendERC20Token = {
address: { address: {
hash: '0x7f6479df95Aa3036a3BE02DB6300ea201ABd9981', hash: '0x7f6479df95Aa3036a3BE02DB6300ea201ABd9981',
ens_domain_name: null,
implementation_name: null, implementation_name: null,
is_contract: false, is_contract: false,
is_verified: false, is_verified: false,
...@@ -173,13 +174,13 @@ export const sendERC20Token = { ...@@ -173,13 +174,13 @@ export const sendERC20Token = {
name: 'Tether USD', name: 'Tether USD',
symbol: 'USDT', symbol: 'USDT',
total_supply: '39030615894320966', total_supply: '39030615894320966',
type: 'ERC-20', type: 'ERC-20' as const,
token_id: null, token_id: null,
}, },
type: 'token', type: 'token' as const,
}; };
export const baseResponse = { export const baseResponse: TxStateChanges = {
items: [ items: [
mintToken, mintToken,
receiveMintedToken, receiveMintedToken,
......
...@@ -12,9 +12,10 @@ import type { Props as PageProps } from 'nextjs/getServerSideProps'; ...@@ -12,9 +12,10 @@ import type { Props as PageProps } from 'nextjs/getServerSideProps';
import config from 'configs/app'; import config from 'configs/app';
import { AppContextProvider } from 'lib/contexts/app'; import { AppContextProvider } from 'lib/contexts/app';
import { SocketProvider } from 'lib/socket/context'; import { SocketProvider } from 'lib/socket/context';
import * as app from 'playwright/utils/app';
import theme from 'theme'; import theme from 'theme';
import { port as socketPort } from './utils/socket';
export type Props = { export type Props = {
children: React.ReactNode; children: React.ReactNode;
withSocket?: boolean; withSocket?: boolean;
...@@ -74,7 +75,7 @@ const TestApp = ({ children, withSocket, withWalletClient = true, appContext = d ...@@ -74,7 +75,7 @@ const TestApp = ({ children, withSocket, withWalletClient = true, appContext = d
return ( return (
<ChakraProvider theme={ theme }> <ChakraProvider theme={ theme }>
<QueryClientProvider client={ queryClient }> <QueryClientProvider client={ queryClient }>
<SocketProvider url={ withSocket ? `ws://${ config.app.host }:${ app.socketPort }` : undefined }> <SocketProvider url={ withSocket ? `ws://${ config.app.host }:${ socketPort }` : undefined }>
<AppContextProvider { ...appContext }> <AppContextProvider { ...appContext }>
<GrowthBookProvider> <GrowthBookProvider>
<WalletClientProvider withWalletClient={ withWalletClient }> <WalletClientProvider withWalletClient={ withWalletClient }>
......
import type { test } from '@playwright/experimental-ct-react';
import createContextWithStorage from './createContextWithStorage';
interface Env {
name: string;
value: string;
}
/**
* @deprecated please use mockEnvs fixture
*
* @export
* @param {Array<Env>} envs
* @return {*} {Parameters<typeof test.extend>[0]['context']}
*/
export default function contextWithEnvsFixture(envs: Array<Env>): Parameters<typeof test.extend>[0]['context'] {
return async({ browser }, use) => {
const context = await createContextWithStorage(browser, envs);
await use(context);
await context.close();
};
}
import type { test } from '@playwright/experimental-ct-react';
import createContextWithStorage from './createContextWithStorage';
interface Feature {
id: string;
value: unknown;
}
/**
* @deprecated please use mockFeatures fixture
*
* @export
* @param {Array<Feature>} envs
* @return {*} {Parameters<typeof test.extend>[0]['context']}
*/
export default function contextWithFeaturesFixture(envs: Array<Feature>): Parameters<typeof test.extend>[0]['context'] {
return async({ browser }, use) => {
const storageItems = envs.map(({ id, value }) => ({ name: `pw_feature:${ id }`, value: JSON.stringify(value) }));
const context = await createContextWithStorage(browser, storageItems);
await use(context);
await context.close();
};
}
import type { Browser } from '@playwright/test';
import config from 'configs/app';
/**
* @deprecated please use mockEnvs or mockFeatures fixture
*
* @export
* @param {Browser} browser
* @param {Array<{ name: string; value: string }>} localStorage
* @return {*}
*/
export default async function createContextWithEnvs(browser: Browser, localStorage: Array<{ name: string; value: string }>) {
return browser.newContext({
storageState: {
origins: [
{ origin: config.app.baseUrl, localStorage },
],
cookies: [],
},
});
}
...@@ -6,6 +6,7 @@ import type { ResourceName, ResourcePayload } from 'lib/api/resources'; ...@@ -6,6 +6,7 @@ import type { ResourceName, ResourcePayload } from 'lib/api/resources';
interface Options<R extends ResourceName> { interface Options<R extends ResourceName> {
pathParams?: Parameters<typeof buildUrl<R>>[1]; pathParams?: Parameters<typeof buildUrl<R>>[1];
queryParams?: Parameters<typeof buildUrl<R>>[2]; queryParams?: Parameters<typeof buildUrl<R>>[2];
times?: number;
} }
export type MockApiResponseFixture = <R extends ResourceName>(resourceName: R, responseMock: ResourcePayload<R>, options?: Options<R>) => Promise<string>; export type MockApiResponseFixture = <R extends ResourceName>(resourceName: R, responseMock: ResourcePayload<R>, options?: Options<R>) => Promise<string>;
...@@ -17,7 +18,7 @@ const fixture: TestFixture<MockApiResponseFixture, { page: Page }> = async({ pag ...@@ -17,7 +18,7 @@ const fixture: TestFixture<MockApiResponseFixture, { page: Page }> = async({ pag
await page.route(apiUrl, (route) => route.fulfill({ await page.route(apiUrl, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(responseMock), body: JSON.stringify(responseMock),
})); }), { times: options?.times });
return apiUrl; return apiUrl;
}); });
......
/* eslint-disable no-restricted-imports */
import type { MountOptions } from '@playwright/experimental-ct-react'; import type { MountOptions } from '@playwright/experimental-ct-react';
import type { Locator, TestFixture } from '@playwright/test'; import type { Locator, TestFixture } from '@playwright/test';
import type router from 'next/router'; import type router from 'next/router';
......
...@@ -8,7 +8,7 @@ import type { SmartContractVerificationResponse } from 'types/api/contract'; ...@@ -8,7 +8,7 @@ import type { SmartContractVerificationResponse } from 'types/api/contract';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import type { Transaction } from 'types/api/transaction'; import type { Transaction } from 'types/api/transaction';
import * as app from 'playwright/utils/app'; import { port as socketPort } from '../utils/socket';
export type CreateSocketFixture = () => Promise<WebSocket>; export type CreateSocketFixture = () => Promise<WebSocket>;
...@@ -20,7 +20,7 @@ export interface SocketServerFixture { ...@@ -20,7 +20,7 @@ export interface SocketServerFixture {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const createSocket: TestFixture<CreateSocketFixture, { page: Page}> = async({ page }, use) => { export const createSocket: TestFixture<CreateSocketFixture, { page: Page}> = async({ page }, use) => {
const socketServer = new WebSocketServer({ port: app.socketPort }); const socketServer = new WebSocketServer({ port: socketPort });
const connectionPromise = new Promise<WebSocket>((resolve) => { const connectionPromise = new Promise<WebSocket>((resolve) => {
socketServer.on('connection', (socket: WebSocket) => { socketServer.on('connection', (socket: WebSocket) => {
......
export const socketPort = 3200;
import { compile } from 'path-to-regexp';
import config from 'configs/app';
import type { ResourceName, ResourcePathParams } from 'lib/api/resources';
import { RESOURCES } from 'lib/api/resources';
/**
* @deprecated please use fixture mockApiResponse from playwright/lib.tsx for rendering test suite
*
* @export
* @template R
* @param {R} resourceName
* @param {ResourcePathParams<R>} [pathParams]
* @return {*} string
*/
export default function buildApiUrl<R extends ResourceName>(resourceName: R, pathParams?: ResourcePathParams<R>) {
const resource = RESOURCES[resourceName];
const origin = 'endpoint' in resource && resource.endpoint ? resource.endpoint + (resource.basePath ?? '') : config.api.endpoint;
return origin + compile(resource.path)(pathParams);
}
/* eslint-disable max-len */
import { devices } from '@playwright/test'; import { devices } from '@playwright/test';
export const viewport = { export const viewport = {
......
export const port = 3200;
import type { AlertProps } from '@chakra-ui/react'; import type { AlertProps } from '@chakra-ui/react';
import { Alert, AlertIcon, AlertTitle } from '@chakra-ui/react'; import { Alert, AlertIcon, AlertTitle } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
test.use({ viewport: { width: 400, height: 720 } }); test.use({ viewport: { width: 400, height: 720 } });
...@@ -29,16 +28,14 @@ const TEST_CASES: Array<AlertProps> = [ ...@@ -29,16 +28,14 @@ const TEST_CASES: Array<AlertProps> = [
TEST_CASES.forEach((props) => { TEST_CASES.forEach((props) => {
const testName = Object.entries(props).map(([ key, value ]) => `${ key }=${ value }`).join(', '); const testName = Object.entries(props).map(([ key, value ]) => `${ key }=${ value }`).join(', ');
test(`${ testName } +@dark-mode`, async({ mount }) => { test(`${ testName } +@dark-mode`, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<Alert { ...props }> <Alert { ...props }>
<AlertIcon/> <AlertIcon/>
<AlertTitle> <AlertTitle>
This is alert text This is alert text
</AlertTitle> </AlertTitle>
</Alert> </Alert>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { Button } from '@chakra-ui/react'; import { Button } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
[ [
{ variant: 'solid' }, { variant: 'solid' },
...@@ -16,40 +15,24 @@ import TestApp from 'playwright/TestApp'; ...@@ -16,40 +15,24 @@ import TestApp from 'playwright/TestApp';
{ variant: 'subtle', colorScheme: 'gray', withDarkMode: true }, { variant: 'subtle', colorScheme: 'gray', withDarkMode: true },
].forEach(({ variant, colorScheme, withDarkMode }) => { ].forEach(({ variant, colorScheme, withDarkMode }) => {
test.describe(`variant ${ variant }${ colorScheme ? ` with ${ colorScheme } color scheme` : '' }${ withDarkMode ? ' +@dark-mode' : '' }`, () => { test.describe(`variant ${ variant }${ colorScheme ? ` with ${ colorScheme } color scheme` : '' }${ withDarkMode ? ' +@dark-mode' : '' }`, () => {
test('base', async({ mount }) => { test('base', async({ render }) => {
const component = await mount( const component = await render(<Button variant={ variant } colorScheme={ colorScheme }>Click me</Button>);
<TestApp>
<Button variant={ variant } colorScheme={ colorScheme }>Click me</Button>
</TestApp>,
);
await expect(component.locator('button')).toHaveScreenshot(); await expect(component.locator('button')).toHaveScreenshot();
}); });
test('disabled', async({ mount }) => { test('disabled', async({ render }) => {
const component = await mount( const component = await render(<Button variant={ variant } colorScheme={ colorScheme } isDisabled>Click me</Button>);
<TestApp>
<Button variant={ variant } colorScheme={ colorScheme } isDisabled>Click me</Button>
</TestApp>,
);
await expect(component.locator('button')).toHaveScreenshot(); await expect(component.locator('button')).toHaveScreenshot();
}); });
test('hovered', async({ mount }) => { test('hovered', async({ render }) => {
const component = await mount( const component = await render(<Button variant={ variant } colorScheme={ colorScheme }>Click me</Button>);
<TestApp>
<Button variant={ variant } colorScheme={ colorScheme }>Click me</Button>
</TestApp>,
);
await component.getByText(/click/i).hover(); await component.getByText(/click/i).hover();
await expect(component.locator('button')).toHaveScreenshot(); await expect(component.locator('button')).toHaveScreenshot();
}); });
test('active', async({ mount }) => { test('active', async({ render }) => {
const component = await mount( const component = await render(<Button variant={ variant } colorScheme={ colorScheme } isActive>Click me</Button>);
<TestApp>
<Button variant={ variant } colorScheme={ colorScheme } isActive>Click me</Button>
</TestApp>,
);
await expect(component.locator('button')).toHaveScreenshot(); await expect(component.locator('button')).toHaveScreenshot();
}); });
}); });
......
import { FormControl, Input, FormLabel } from '@chakra-ui/react'; import { FormControl, Input, FormLabel } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
test.use({ viewport: { width: 500, height: 300 } }); test.use({ viewport: { width: 500, height: 300 } });
test.describe('floating label size md +@dark-mode', () => { test.describe('floating label size md +@dark-mode', () => {
test('empty', async({ mount }) => { test('empty', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value=""/> <Input required value=""/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -23,14 +20,12 @@ test.describe('floating label size md +@dark-mode', () => { ...@@ -23,14 +20,12 @@ test.describe('floating label size md +@dark-mode', () => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('empty error', async({ mount }) => { test('empty error', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value="" isInvalid/> <Input required value="" isInvalid/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -39,53 +34,45 @@ test.describe('floating label size md +@dark-mode', () => { ...@@ -39,53 +34,45 @@ test.describe('floating label size md +@dark-mode', () => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('filled', async({ mount }) => { test('filled', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo"/> <Input required value="foo"/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('filled disabled', async({ mount }) => { test('filled disabled', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isDisabled/> <Input required value="foo" isDisabled/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('filled read-only', async({ mount }) => { test('filled read-only', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isReadOnly/> <Input required value="foo" isReadOnly/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('filled error', async({ mount }) => { test('filled error', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="md"> <FormControl variant="floating" id="name" isRequired size="md">
<Input required value="foo" isInvalid/> <Input required value="foo" isInvalid/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -93,14 +80,12 @@ test.describe('floating label size md +@dark-mode', () => { ...@@ -93,14 +80,12 @@ test.describe('floating label size md +@dark-mode', () => {
}); });
test.describe('floating label size lg +@dark-mode', () => { test.describe('floating label size lg +@dark-mode', () => {
test('empty', async({ mount }) => { test('empty', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="lg"> <FormControl variant="floating" id="name" isRequired size="lg">
<Input required value=""/> <Input required value=""/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -109,14 +94,12 @@ test.describe('floating label size lg +@dark-mode', () => { ...@@ -109,14 +94,12 @@ test.describe('floating label size lg +@dark-mode', () => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('filled', async({ mount }) => { test('filled', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FormControl variant="floating" id="name" isRequired size="lg"> <FormControl variant="floating" id="name" isRequired size="lg">
<Input required value="foo"/> <Input required value="foo"/>
<FormLabel>Smart contract / Address (0x...)</FormLabel> <FormLabel>Smart contract / Address (0x...)</FormLabel>
</FormControl> </FormControl>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { Box, Tag } from '@chakra-ui/react'; import { Box, Tag } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
[ 'blue', 'gray', 'gray-blue', 'orange', 'green', 'purple', 'cyan', 'teal' ].forEach((colorScheme) => { [ 'blue', 'gray', 'gray-blue', 'orange', 'green', 'purple', 'cyan', 'teal' ].forEach((colorScheme) => {
test(`${ colorScheme } color scheme +@dark-mode`, async({ mount }) => { test(`${ colorScheme } color scheme +@dark-mode`, async({ render }) => {
const component = await mount( const component = await render(<Tag colorScheme={ colorScheme }>content</Tag>);
<TestApp>
<Tag colorScheme={ colorScheme }>content</Tag>
</TestApp>,
);
await expect(component.getByText(/content/i)).toHaveScreenshot(); await expect(component.getByText(/content/i)).toHaveScreenshot();
}); });
}); });
test('with long text', async({ mount }) => { test('with long text', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<Box w="100px"> <Box w="100px">
<Tag>this is very looooooooooong text</Tag> <Tag>this is very looooooooooong text</Tag>
</Box> </Box>,
</TestApp>,
); );
await expect(component.getByText(/this/i)).toHaveScreenshot(); await expect(component.getByText(/this/i)).toHaveScreenshot();
}); });
import { Box, Tooltip, Icon } from '@chakra-ui/react'; import { Box, Tooltip, Icon } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
test('base view +@dark-mode', async({ mount, page }) => { test('base view +@dark-mode', async({ render, page }) => {
const component = await mount( const component = await render(
<TestApp>
<Box m={ 10 }> <Box m={ 10 }>
<Tooltip label="Tooltip content"> <Tooltip label="Tooltip content">
trigger trigger
</Tooltip> </Tooltip>
</Box> </Box>,
</TestApp>,
); );
await component.getByText(/trigger/i).hover(); await component.getByText(/trigger/i).hover();
...@@ -22,17 +19,15 @@ test('base view +@dark-mode', async({ mount, page }) => { ...@@ -22,17 +19,15 @@ test('base view +@dark-mode', async({ mount, page }) => {
// was not able to reproduce in tests issue when Icon is used as trigger for tooltip // was not able to reproduce in tests issue when Icon is used as trigger for tooltip
// https://github.com/chakra-ui/chakra-ui/issues/7107 // https://github.com/chakra-ui/chakra-ui/issues/7107
test.skip('with icon', async({ mount, page }) => { test.fixme('with icon', async({ render, page }) => {
const component = await mount( const component = await render(
<TestApp>
<Box m={ 10 }> <Box m={ 10 }>
<Tooltip label="Tooltip content"> <Tooltip label="Tooltip content">
<Icon viewBox="0 0 20 20" boxSize={ 5 } aria-label="Trigger"> <Icon viewBox="0 0 20 20" boxSize={ 5 } aria-label="Trigger">
<circle cx="10" cy="10" r="10"/> <circle cx="10" cy="10" r="10"/>
</Icon> </Icon>
</Tooltip> </Tooltip>
</Box> </Box>,
</TestApp>,
); );
const tooltip = page.getByText(/tooltip content/i); const tooltip = page.getByText(/tooltip content/i);
......
...@@ -7,13 +7,13 @@ export type HomeStats = { ...@@ -7,13 +7,13 @@ export type HomeStats = {
coin_price: string | null; coin_price: string | null;
coin_price_change_percentage: number | null; // e.g -6.22 coin_price_change_percentage: number | null; // e.g -6.22
total_gas_used: string; total_gas_used: string;
transactions_today: string; transactions_today: string | null;
gas_used_today: string; gas_used_today: string;
gas_prices: GasPrices | null; gas_prices: GasPrices | null;
gas_price_updated_at: string | null; gas_price_updated_at: string | null;
gas_prices_update_in: number; gas_prices_update_in: number;
static_gas_price: string | null; static_gas_price: string | null;
market_cap: string; market_cap: string | null;
network_utilization_percentage: number; network_utilization_percentage: number;
tvl: string | null; tvl: string | null;
rootstock_locked_btc?: string | null; rootstock_locked_btc?: string | null;
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as balanceHistoryMock from 'mocks/address/coinBalanceHistory'; import * as balanceHistoryMock from 'mocks/address/coinBalanceHistory';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressCoinBalance from './AddressCoinBalance'; import AddressCoinBalance from './AddressCoinBalance';
const addressHash = 'hash'; const addressHash = '0x1234';
const BALANCE_HISTORY_API_URL = buildApiUrl('address_coin_balance', { hash: addressHash });
const BALANCE_HISTORY_CHART_API_URL = buildApiUrl('address_coin_balance_chart', { hash: addressHash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: addressHash }, query: { hash: addressHash },
}, },
}; };
test('base view +@dark-mode +@mobile', async({ mount, page }) => { test('base view +@dark-mode +@mobile', async({ render, page, mockApiResponse }) => {
await page.route(BALANCE_HISTORY_API_URL, (route) => route.fulfill({ await mockApiResponse('address_coin_balance', balanceHistoryMock.baseResponse, { pathParams: { hash: addressHash } });
status: 200, await mockApiResponse('address_coin_balance_chart', balanceHistoryMock.chartResponse, { pathParams: { hash: addressHash } });
body: JSON.stringify(balanceHistoryMock.baseResponse), const component = await render(<AddressCoinBalance/>, { hooksConfig });
}));
await page.route(BALANCE_HISTORY_CHART_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(balanceHistoryMock.chartResponse),
}));
const component = await mount(
<TestApp>
<AddressCoinBalance/>
</TestApp>,
{ hooksConfig },
);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="chart-Balances-small"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="chart-Balances-small"]')?.getAttribute('opacity') === '1';
}); });
await page.mouse.move(240, 100); await page.mouse.move(240, 100);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { WalletProvider } from 'types/web3';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import * as countersMock from 'mocks/address/counters'; import * as countersMock from 'mocks/address/counters';
import * as tokensMock from 'mocks/address/tokens'; import * as tokensMock from 'mocks/address/tokens';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl'; import * as pwConfig from 'playwright/utils/config';
import * as configs from 'playwright/utils/configs';
import AddressDetails from './AddressDetails'; import AddressDetails from './AddressDetails';
import MockAddressPage from './testUtils/MockAddressPage'; import MockAddressPage from './testUtils/MockAddressPage';
import type { AddressQuery } from './utils/useAddressQuery'; import type { AddressQuery } from './utils/useAddressQuery';
const ADDRESS_HASH = addressMock.hash; const ADDRESS_HASH = addressMock.hash;
const API_URL_ADDRESS = buildApiUrl('address', { hash: ADDRESS_HASH });
const API_URL_COUNTERS = buildApiUrl('address_counters', { hash: ADDRESS_HASH });
const API_URL_TOKENS_ERC20 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-20';
const API_URL_TOKENS_ERC721 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-721';
const API_URL_TOKENS_ER1155 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-1155';
const API_URL_TOKENS_ERC404 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-404';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH }, query: { hash: ADDRESS_HASH },
...@@ -30,144 +20,75 @@ const hooksConfig = { ...@@ -30,144 +20,75 @@ const hooksConfig = {
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('contract', async({ mount, page }) => { test('contract', async({ render, mockApiResponse, page }) => {
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.contract, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_counters', countersMock.forContract, { pathParams: { hash: ADDRESS_HASH } });
body: JSON.stringify(addressMock.contract),
})); const component = await render(<AddressDetails addressQuery={{ data: addressMock.contract } as AddressQuery}/>, { hooksConfig });
await page.route(API_URL_COUNTERS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(countersMock.forContract),
}));
const component = await mount(
<TestApp>
<AddressDetails addressQuery={{ data: addressMock.contract } as AddressQuery}/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
test('validator', async({ mount, page }) => { test('validator', async({ render, page, mockApiResponse }) => {
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.validator, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_counters', countersMock.forValidator, { pathParams: { hash: ADDRESS_HASH } });
body: JSON.stringify(addressMock.validator),
})); const component = await render(<AddressDetails addressQuery={{ data: addressMock.validator } as AddressQuery}/>, { hooksConfig });
await page.route(API_URL_COUNTERS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(countersMock.forValidator),
}));
const component = await mount(
<TestApp>
<AddressDetails addressQuery={{ data: addressMock.validator } as AddressQuery}/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
}); });
test('contract', async({ mount, page }) => { test('contract', async({ render, page, mockApiResponse }) => {
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.contract, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_counters', countersMock.forContract, { pathParams: { hash: ADDRESS_HASH } });
body: JSON.stringify(addressMock.contract),
})); const component = await render(<AddressDetails addressQuery={{ data: addressMock.contract } as AddressQuery}/>, { hooksConfig });
await page.route(API_URL_COUNTERS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(countersMock.forContract),
}));
const component = await mount(
<TestApp>
<AddressDetails addressQuery={{ data: addressMock.contract } as AddressQuery}/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
// there's an unexpected timeout occurred in this test // there's an unexpected timeout occurred in this test
test.skip('token', async({ mount, page }) => { test.fixme('token', async({ render, mockApiResponse, injectMetaMaskProvider, page }) => {
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.token, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_counters', countersMock.forToken, { pathParams: { hash: ADDRESS_HASH } });
body: JSON.stringify(addressMock.token), await mockApiResponse('address_tokens', tokensMock.erc20List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-20' }, times: 1 });
})); await mockApiResponse('address_tokens', tokensMock.erc721List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-721' }, times: 1 });
await page.route(API_URL_COUNTERS, (route) => route.fulfill({ await mockApiResponse('address_tokens', tokensMock.erc1155List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-1155' }, times: 1 });
status: 200, await mockApiResponse('address_tokens', tokensMock.erc404List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-404' }, times: 1 });
body: JSON.stringify(countersMock.forToken), await injectMetaMaskProvider();
}));
await page.route(API_URL_TOKENS_ERC20, async(route) => route.fulfill({ const component = await render(
status: 200,
body: JSON.stringify(tokensMock.erc20List),
}), { times: 1 });
await page.route(API_URL_TOKENS_ERC721, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc721List),
}), { times: 1 });
await page.route(API_URL_TOKENS_ER1155, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc1155List),
}), { times: 1 });
await page.route(API_URL_TOKENS_ERC404, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc404List),
}), { times: 1 });
await page.evaluate(() => {
window.ethereum = {
providers: [ { isMetaMask: true, _events: {} } ],
} as WalletProvider;
});
const component = await mount(
<TestApp>
<MockAddressPage> <MockAddressPage>
<AddressDetails addressQuery={{ data: addressMock.token } as AddressQuery}/> <AddressDetails addressQuery={{ data: addressMock.token } as AddressQuery}/>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
test('validator', async({ mount, page }) => { test('validator', async({ render, mockApiResponse, page }) => {
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.validator, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_counters', countersMock.forValidator, { pathParams: { hash: ADDRESS_HASH } });
body: JSON.stringify(addressMock.validator),
})); const component = await render(<AddressDetails addressQuery={{ data: addressMock.validator } as AddressQuery}/>, { hooksConfig });
await page.route(API_URL_COUNTERS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(countersMock.forValidator),
}));
const component = await mount(
<TestApp>
<AddressDetails addressQuery={{ data: addressMock.validator } as AddressQuery}/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as internalTxsMock from 'mocks/txs/internalTxs'; import * as internalTxsMock from 'mocks/txs/internalTxs';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressInternalTxs from './AddressInternalTxs'; import AddressInternalTxs from './AddressInternalTxs';
const ADDRESS_HASH = internalTxsMock.base.from.hash; const ADDRESS_HASH = internalTxsMock.base.from.hash;
const API_URL_TX_INTERNALS = buildApiUrl('address_internal_txs', { hash: ADDRESS_HASH });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH }, query: { hash: ADDRESS_HASH },
}, },
}; };
test('base view +@mobile', async({ mount, page }) => { test('base view +@mobile', async({ render, mockApiResponse }) => {
await page.route(API_URL_TX_INTERNALS, (route) => route.fulfill({ await mockApiResponse('address_internal_txs', internalTxsMock.baseResponse, { pathParams: { hash: ADDRESS_HASH } });
status: 200, const component = await render(
body: JSON.stringify(internalTxsMock.baseResponse), <Box pt={{ base: '134px', lg: 6 }}>
}));
const component = await mount(
<TestApp>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressInternalTxs/> <AddressInternalTxs/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test as base, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import * as socketServer from 'playwright/fixtures/socketServer'; import * as socketServer from 'playwright/fixtures/socketServer';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressTokenTransfers from './AddressTokenTransfers'; import AddressTokenTransfers from './AddressTokenTransfers';
const CURRENT_ADDRESS = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859'; const CURRENT_ADDRESS = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859';
const TOKEN_HASH = '0x1189a607CEac2f0E14867de4EB15b15C9FFB5859';
const API_URL = buildApiUrl('address_token_transfers', { hash: CURRENT_ADDRESS }) +
'?token=0x1189a607CEac2f0E14867de4EB15b15C9FFB5859';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: CURRENT_ADDRESS, token: '0x1189a607CEac2f0E14867de4EB15b15C9FFB5859' }, query: { hash: CURRENT_ADDRESS, token: TOKEN_HASH },
}, },
}; };
const test = base.extend<socketServer.SocketServerFixture>({
createSocket: socketServer.createSocket,
});
// FIXME // FIXME
// test cases which use socket cannot run in parallel since the socket server always run on the same port // test cases which use socket cannot run in parallel since the socket server always run on the same port
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });
test('with token filter and pagination', async({ mount, page }) => { const tokenTransfersWithPagination = {
await page.route(API_URL, (route) => route.fulfill({ items: [ tokenTransferMock.erc1155A ],
status: 200, next_page_params: { block_number: 1, index: 1, items_count: 1 },
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }), };
})); const tokenTransfersWoPagination = {
items: [ tokenTransferMock.erc1155A ],
next_page_params: null,
};
const component = await mount( test('with token filter and pagination', async({ render, mockApiResponse }) => {
<TestApp> await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
<Box h={{ base: '134px', lg: 6 }}/> pathParams: { hash: CURRENT_ADDRESS },
queryParams: { token: TOKEN_HASH },
});
const component = await render(
<Box pt={{ base: '134px', lg: 6 }}>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with token filter and no pagination', async({ mount, page }) => { test('with token filter and no pagination', async({ render, mockApiResponse }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse('address_token_transfers', tokenTransfersWoPagination, {
status: 200, pathParams: { hash: CURRENT_ADDRESS },
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ] }), queryParams: { token: TOKEN_HASH },
})); });
const component = await render(
const component = await mount( <Box pt={{ base: '134px', lg: 6 }}>
<TestApp>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('with token filter and pagination', async({ mount, page }) => { test('with token filter and pagination', async({ render, mockApiResponse }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
status: 200, pathParams: { hash: CURRENT_ADDRESS },
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }), queryParams: { token: TOKEN_HASH },
})); });
const component = await render(
const component = await mount( <Box pt={{ base: '134px', lg: 6 }}>
<TestApp>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with token filter and no pagination', async({ mount, page }) => { test('with token filter and no pagination', async({ render, mockApiResponse }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse('address_token_transfers', tokenTransfersWoPagination, {
status: 200, pathParams: { hash: CURRENT_ADDRESS },
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ] }), queryParams: { token: TOKEN_HASH },
})); });
const component = await render(
const component = await mount( <Box pt={{ base: '134px', lg: 6 }}>
<TestApp>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
test.describe('socket', () => { test.describe('socket', () => {
test('without overload', async({ mount, page, createSocket }) => { test('without overload', async({ render, mockApiResponse, createSocket, page }) => {
const hooksConfigNoToken = { const hooksConfigNoToken = {
router: { router: {
query: { hash: CURRENT_ADDRESS }, query: { hash: CURRENT_ADDRESS },
}, },
}; };
await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
const API_URL_NO_TOKEN = buildApiUrl('address_token_transfers', { hash: CURRENT_ADDRESS }) + '?type='; pathParams: { hash: CURRENT_ADDRESS },
queryParams: { type: [] },
await page.route(API_URL_NO_TOKEN, (route) => route.fulfill({ });
status: 200, await render(
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }), <Box pt={{ base: '134px', lg: 6 }}>
}));
await mount(
<TestApp withSocket>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigNoToken }, { hooksConfig: hooksConfigNoToken },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -137,26 +121,22 @@ test.describe('socket', () => { ...@@ -137,26 +121,22 @@ test.describe('socket', () => {
expect(itemsCountNew).toBe(4); expect(itemsCountNew).toBe(4);
}); });
test('with overload', async({ mount, page, createSocket }) => { test('with overload', async({ render, mockApiResponse, page, createSocket }) => {
const hooksConfigNoToken = { const hooksConfigNoToken = {
router: { router: {
query: { hash: CURRENT_ADDRESS }, query: { hash: CURRENT_ADDRESS },
}, },
}; };
await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
const API_URL_NO_TOKEN = buildApiUrl('address_token_transfers', { hash: CURRENT_ADDRESS }) + '?type='; pathParams: { hash: CURRENT_ADDRESS },
queryParams: { type: [] },
await page.route(API_URL_NO_TOKEN, (route) => route.fulfill({ });
status: 200, await render(
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }), <Box pt={{ base: '134px', lg: 6 }}>
}));
await mount(
<TestApp withSocket>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers overloadCount={ 2 }/> <AddressTokenTransfers overloadCount={ 2 }/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigNoToken }, { hooksConfig: hooksConfigNoToken },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -176,26 +156,23 @@ test.describe('socket', () => { ...@@ -176,26 +156,23 @@ test.describe('socket', () => {
expect(counter?.startsWith('1 ')).toBe(true); expect(counter?.startsWith('1 ')).toBe(true);
}); });
test('without overload, with filters', async({ mount, page, createSocket }) => { test('without overload, with filters', async({ render, mockApiResponse, page, createSocket }) => {
const hooksConfigWithFilter = { const hooksConfigWithFilter = {
router: { router: {
query: { hash: CURRENT_ADDRESS, type: 'ERC-1155' }, query: { hash: CURRENT_ADDRESS, type: 'ERC-1155' },
}, },
}; };
await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
pathParams: { hash: CURRENT_ADDRESS },
queryParams: { type: 'ERC-1155' },
});
const API_URL_WITH_FILTER = buildApiUrl('address_token_transfers', { hash: CURRENT_ADDRESS }) + '?type=ERC-1155'; await render(
<Box pt={{ base: '134px', lg: 6 }}>
await page.route(API_URL_WITH_FILTER, (route) => route.fulfill({
status: 200,
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }),
}));
await mount(
<TestApp withSocket>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers/> <AddressTokenTransfers/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigWithFilter }, { hooksConfig: hooksConfigWithFilter },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -212,26 +189,23 @@ test.describe('socket', () => { ...@@ -212,26 +189,23 @@ test.describe('socket', () => {
expect(itemsCountNew).toBe(3); expect(itemsCountNew).toBe(3);
}); });
test('with overload, with filters', async({ mount, page, createSocket }) => { test('with overload, with filters', async({ render, mockApiResponse, page, createSocket }) => {
const hooksConfigWithFilter = { const hooksConfigWithFilter = {
router: { router: {
query: { hash: CURRENT_ADDRESS, type: 'ERC-1155' }, query: { hash: CURRENT_ADDRESS, type: 'ERC-1155' },
}, },
}; };
await mockApiResponse('address_token_transfers', tokenTransfersWithPagination, {
pathParams: { hash: CURRENT_ADDRESS },
queryParams: { type: 'ERC-1155' },
});
const API_URL_WITH_FILTER = buildApiUrl('address_token_transfers', { hash: CURRENT_ADDRESS }) + '?type=ERC-1155'; await render(
<Box pt={{ base: '134px', lg: 6 }}>
await page.route(API_URL_WITH_FILTER, (route) => route.fulfill({
status: 200,
body: JSON.stringify({ items: [ tokenTransferMock.erc1155A ], next_page_params: { block_number: 1 } }),
}));
await mount(
<TestApp withSocket>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokenTransfers overloadCount={ 2 }/> <AddressTokenTransfers overloadCount={ 2 }/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigWithFilter }, { hooksConfig: hooksConfigWithFilter },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
......
This diff is collapsed.
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test as base, expect } from '@playwright/experimental-ct-react';
import type { Locator } from '@playwright/test'; import type { Locator } from '@playwright/test';
import React from 'react'; import React from 'react';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import * as socketServer from 'playwright/fixtures/socketServer'; import * as socketServer from 'playwright/fixtures/socketServer';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl'; import * as pwConfig from 'playwright/utils/config';
import * as configs from 'playwright/utils/configs';
import AddressTxs from './AddressTxs'; import AddressTxs from './AddressTxs';
const CURRENT_ADDRESS = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859'; const CURRENT_ADDRESS = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859';
const API_URL = buildApiUrl('address_txs', { hash: CURRENT_ADDRESS });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: CURRENT_ADDRESS }, query: { hash: CURRENT_ADDRESS },
}, },
}; };
const DEFAULT_PAGINATION = { block_number: 1, index: 1, items_count: 1 };
base.describe('base view', () => { test.describe('base view', () => {
let component: Locator; let component: Locator;
base.beforeEach(async({ page, mount }) => { test.beforeEach(async({ render, mockApiResponse }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'address_txs',
body: JSON.stringify({ items: [
txMock.base,
{ {
...txMock.base, items: [
hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194', txMock.base,
{ ...txMock.base, hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194' },
],
next_page_params: DEFAULT_PAGINATION,
}, },
], next_page_params: { block: 1 } }), { pathParams: { hash: CURRENT_ADDRESS } },
})); );
component = await render(
component = await mount( <Box pt={{ base: '134px', lg: 6 }}>
<TestApp>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs/> <AddressTxs/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
}); });
base('+@mobile', async() => { test('+@mobile', async() => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
base.describe('screen xl', () => { test.describe('screen xl', () => {
base.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
base('', async() => { test('', async() => {
base.slow(); test.slow();
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
}); });
base.describe('socket', () => { test.describe('socket', () => {
const test = base.extend<socketServer.SocketServerFixture>({
createSocket: socketServer.createSocket,
});
// FIXME // FIXME
// test cases which use socket cannot run in parallel since the socket server always run on the same port // test cases which use socket cannot run in parallel since the socket server always run on the same port
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });
test('without overload', async({ mount, page, createSocket }) => { test('without overload', async({ render, mockApiResponse, page, createSocket }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'address_txs',
body: JSON.stringify({ items: [ txMock.base ], next_page_params: { block: 1 } }), { items: [ txMock.base ], next_page_params: DEFAULT_PAGINATION },
})); { pathParams: { hash: CURRENT_ADDRESS } },
);
await mount( await render(
<TestApp withSocket> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs/> <AddressTxs/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -95,18 +89,19 @@ base.describe('socket', () => { ...@@ -95,18 +89,19 @@ base.describe('socket', () => {
expect(itemsCountNew).toBe(4); expect(itemsCountNew).toBe(4);
}); });
test('with update', async({ mount, page, createSocket }) => { test('with update', async({ render, mockApiResponse, page, createSocket }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'address_txs',
body: JSON.stringify({ items: [ txMock.pending ], next_page_params: { block: 1 } }), { items: [ txMock.pending ], next_page_params: DEFAULT_PAGINATION },
})); { pathParams: { hash: CURRENT_ADDRESS } },
);
await mount( await render(
<TestApp withSocket> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs/> <AddressTxs/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -123,18 +118,19 @@ base.describe('socket', () => { ...@@ -123,18 +118,19 @@ base.describe('socket', () => {
expect(itemsCountNew).toBe(3); expect(itemsCountNew).toBe(3);
}); });
test('with overload', async({ mount, page, createSocket }) => { test('with overload', async({ render, mockApiResponse, page, createSocket }) => {
await page.route(API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'address_txs',
body: JSON.stringify({ items: [ txMock.base ], next_page_params: { block: 1 } }), { items: [ txMock.base ], next_page_params: DEFAULT_PAGINATION },
})); { pathParams: { hash: CURRENT_ADDRESS } },
);
await mount( await render(
<TestApp withSocket> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs overloadCount={ 2 }/> <AddressTxs overloadCount={ 2 }/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -154,26 +150,25 @@ base.describe('socket', () => { ...@@ -154,26 +150,25 @@ base.describe('socket', () => {
expect(counter?.startsWith('2 ')).toBe(true); expect(counter?.startsWith('2 ')).toBe(true);
}); });
test('without overload, with filters', async({ mount, page, createSocket }) => { test('without overload, with filters', async({ render, mockApiResponse, page, createSocket }) => {
const hooksConfigWithFilter = { const hooksConfigWithFilter = {
router: { router: {
query: { hash: CURRENT_ADDRESS, filter: 'from' }, query: { hash: CURRENT_ADDRESS, filter: 'from' },
}, },
}; };
const API_URL_WITH_FILTER = buildApiUrl('address_txs', { hash: CURRENT_ADDRESS }) + '?filter=from'; await mockApiResponse(
'address_txs',
await page.route(API_URL_WITH_FILTER, (route) => route.fulfill({ { items: [ txMock.base ], next_page_params: DEFAULT_PAGINATION },
status: 200, { pathParams: { hash: CURRENT_ADDRESS }, queryParams: { filter: 'from' } },
body: JSON.stringify({ items: [ txMock.base ], next_page_params: { block: 1 } }), );
}));
await mount( await render(
<TestApp withSocket> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs/> <AddressTxs/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigWithFilter }, { hooksConfig: hooksConfigWithFilter },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
...@@ -190,26 +185,25 @@ base.describe('socket', () => { ...@@ -190,26 +185,25 @@ base.describe('socket', () => {
expect(itemsCountNew).toBe(3); expect(itemsCountNew).toBe(3);
}); });
test('with overload, with filters', async({ mount, page, createSocket }) => { test('with overload, with filters', async({ render, mockApiResponse, page, createSocket }) => {
const hooksConfigWithFilter = { const hooksConfigWithFilter = {
router: { router: {
query: { hash: CURRENT_ADDRESS, filter: 'from' }, query: { hash: CURRENT_ADDRESS, filter: 'from' },
}, },
}; };
const API_URL_WITH_FILTER = buildApiUrl('address_txs', { hash: CURRENT_ADDRESS }) + '?filter=from'; await mockApiResponse(
'address_txs',
await page.route(API_URL_WITH_FILTER, (route) => route.fulfill({ { items: [ txMock.base ], next_page_params: DEFAULT_PAGINATION },
status: 200, { pathParams: { hash: CURRENT_ADDRESS }, queryParams: { filter: 'from' } },
body: JSON.stringify({ items: [ txMock.base ], next_page_params: { block: 1 } }), );
}));
await mount( await render(
<TestApp withSocket> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTxs overloadCount={ 2 }/> <AddressTxs overloadCount={ 2 }/>
</TestApp>, </Box>,
{ hooksConfig: hooksConfigWithFilter }, { hooksConfig: hooksConfigWithFilter },
{ withSocket: true },
); );
const socket = await createSocket(); const socket = await createSocket();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as solidityscanReportMock from 'mocks/contract/solidityscanReport'; import * as solidityscanReportMock from 'mocks/contract/solidityscanReport';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import SolidityscanReport from './SolidityscanReport'; import SolidityscanReport from './SolidityscanReport';
const addressHash = 'hash'; const addressHash = 'hash';
const REPORT_API_URL = buildApiUrl('contract_solidityscan_report', { hash: addressHash });
test('average report +@dark-mode +@mobile', async({ mount, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(solidityscanReportMock.solidityscanReportAverage),
}));
const component = await mount(
<TestApp>
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
);
test('average report +@dark-mode +@mobile', async({ render, mockApiResponse, page }) => {
await mockApiResponse(
'contract_solidityscan_report',
solidityscanReportMock.solidityscanReportAverage,
{ pathParams: { hash: addressHash } },
);
const component = await render(<SolidityscanReport hash={ addressHash }/>);
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });
await component.getByLabel('SolidityScan score').click(); await component.getByLabel('SolidityScan score').click();
...@@ -29,16 +21,15 @@ test('average report +@dark-mode +@mobile', async({ mount, page }) => { ...@@ -29,16 +21,15 @@ test('average report +@dark-mode +@mobile', async({ mount, page }) => {
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } });
}); });
test('great report', async({ mount, page }) => { test('great report', async({ render, mockApiResponse, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'contract_solidityscan_report',
body: JSON.stringify(solidityscanReportMock.solidityscanReportGreat), solidityscanReportMock.solidityscanReportGreat,
})); { pathParams: { hash: addressHash } },
);
const component = await mount( const component = await render(
<TestApp> <SolidityscanReport hash={ addressHash }/>,
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
); );
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });
...@@ -48,16 +39,15 @@ test('great report', async({ mount, page }) => { ...@@ -48,16 +39,15 @@ test('great report', async({ mount, page }) => {
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } });
}); });
test('low report', async({ mount, page }) => { test('low report', async({ render, mockApiResponse, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'contract_solidityscan_report',
body: JSON.stringify(solidityscanReportMock.solidityscanReportLow), solidityscanReportMock.solidityscanReportLow,
})); { pathParams: { hash: addressHash } },
);
const component = await mount( const component = await render(
<TestApp> <SolidityscanReport hash={ addressHash }/>,
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
); );
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { ContractAbiItem } from '../types'; import type { ContractAbiItem } from '../types';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import ContractMethodForm from './ContractMethodForm'; import ContractMethodForm from './ContractMethodForm';
...@@ -97,16 +96,14 @@ const data: ContractAbiItem = { ...@@ -97,16 +96,14 @@ const data: ContractAbiItem = {
constant: false, constant: false,
}; };
test('base view +@mobile +@dark-mode', async({ mount }) => { test('base view +@mobile +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<ContractMethodForm <ContractMethodForm
data={ data } data={ data }
onSubmit={ onSubmit } onSubmit={ onSubmit }
methodType="write" methodType="write"
/> />,
</TestApp>,
); );
// fill top level fields // fill top level fields
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import buildUrl from 'lib/api/buildUrl';
import * as contractMethodsMock from 'mocks/contract/methods'; import * as contractMethodsMock from 'mocks/contract/methods';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import ContractRead from './ContractRead'; import ContractRead from './ContractRead';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_READ_METHODS_API_URL = buildApiUrl('contract_methods_read', { hash: addressHash }) + '?is_custom_abi=false';
const CONTRACT_QUERY_METHOD_API_URL = buildApiUrl('contract_method_query', { hash: addressHash }) + '?is_custom_abi=false';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: addressHash }, query: { hash: addressHash },
}, },
}; };
test('base view +@mobile +@dark-mode', async({ mount, page }) => { test('base view +@mobile +@dark-mode', async({ render, mockApiResponse, page }) => {
await page.route(CONTRACT_READ_METHODS_API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'contract_methods_read',
body: JSON.stringify(contractMethodsMock.read), contractMethodsMock.read,
})); { pathParams: { hash: addressHash }, queryParams: { is_custom_abi: false } },
);
const CONTRACT_QUERY_METHOD_API_URL = buildUrl('contract_method_query', { hash: addressHash }, { is_custom_abi: false });
await page.route(CONTRACT_QUERY_METHOD_API_URL, (route) => route.fulfill({ await page.route(CONTRACT_QUERY_METHOD_API_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(contractMethodsMock.readResultSuccess), body: JSON.stringify(contractMethodsMock.readResultSuccess),
})); }));
const component = await render(<ContractRead/>, { hooksConfig });
const component = await mount(
<TestApp>
<ContractRead/>
</TestApp>,
{ hooksConfig },
);
await component.getByText(/expand all/i).click(); await component.getByText(/expand all/i).click();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as contractMethodsMock from 'mocks/contract/methods'; import * as contractMethodsMock from 'mocks/contract/methods';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import ContractWrite from './ContractWrite'; import ContractWrite from './ContractWrite';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_WRITE_METHODS_API_URL = buildApiUrl('contract_methods_write', { hash: addressHash }) + '?is_custom_abi=false';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: addressHash }, query: { hash: addressHash },
}, },
}; };
test('base view +@mobile', async({ mount, page }) => { test('base view +@mobile', async({ render, mockApiResponse }) => {
await page.route(CONTRACT_WRITE_METHODS_API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'contract_methods_write',
body: JSON.stringify(contractMethodsMock.write), contractMethodsMock.write,
})); { pathParams: { hash: addressHash }, queryParams: { is_custom_abi: false } },
const component = await mount(
<TestApp>
<ContractWrite/>
</TestApp>,
{ hooksConfig },
); );
const component = await render(<ContractWrite/>, { hooksConfig });
await component.getByText(/expand all/i).click(); await component.getByText(/expand all/i).click();
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react'; import noop from 'lodash/noop';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import ContractSubmitAuditForm from './ContractSubmitAuditForm'; import ContractSubmitAuditForm from './ContractSubmitAuditForm';
test('base view', async({ mount }) => { test('base view', async({ render }) => {
const component = await render(<ContractSubmitAuditForm address="hash" onSuccess={ noop }/>);
const component = await mount(
<TestApp>
{ /* eslint-disable-next-line react/jsx-no-bind */ }
<ContractSubmitAuditForm address="hash" onSuccess={ () => {} }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import AddressQrCode from './AddressQrCode'; import AddressQrCode from './AddressQrCode';
test('default view +@mobile +@dark-mode', async({ mount, page }) => { test('default view +@mobile +@dark-mode', async({ render, page }) => {
await mount( await render(<AddressQrCode address={ addressMock.withoutName }/>);
<TestApp>
<AddressQrCode address={ addressMock.withoutName }/>
</TestApp>,
);
await page.getByRole('button', { name: /qr code/i }).click(); await page.getByRole('button', { name: /qr code/i }).click();
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import * as ensDomainMock from 'mocks/ens/domain'; import * as ensDomainMock from 'mocks/ens/domain';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressEnsDomains from './AddressEnsDomains'; import AddressEnsDomains from './AddressEnsDomains';
const ADDRESS_HASH = ensDomainMock.ensDomainA.owner?.hash ?? ''; const ADDRESS_HASH = ensDomainMock.ensDomainA.owner?.hash as string;
const ADDRESSES_LOOKUP_API_URL = buildApiUrl('addresses_lookup', { chainId: config.chain.id }) +
`?address=${ ADDRESS_HASH }&resolved_to=true&owned_by=true&only_active=true&order=ASC`;
test('base view', async({ mount, page }) => { test('base view', async({ render, mockApiResponse, page }) => {
await page.route(ADDRESSES_LOOKUP_API_URL, (route) => route.fulfill({ await mockApiResponse(
status: 200, 'addresses_lookup',
body: JSON.stringify({ {
items: [ items: [
ensDomainMock.ensDomainA, ensDomainMock.ensDomainA,
ensDomainMock.ensDomainB, ensDomainMock.ensDomainB,
ensDomainMock.ensDomainC, ensDomainMock.ensDomainC,
ensDomainMock.ensDomainD, ensDomainMock.ensDomainD,
], ],
}), next_page_params: null,
})); },
{
const component = await mount( pathParams: { chainId: config.chain.id },
<TestApp> queryParams: {
<AddressEnsDomains addressHash={ ADDRESS_HASH } mainDomainName={ ensDomainMock.ensDomainA.name }/> address: ADDRESS_HASH,
</TestApp>, resolved_to: true,
owned_by: true,
only_active: true,
order: 'ASC',
},
},
); );
const component = await render(<AddressEnsDomains addressHash={ ADDRESS_HASH } mainDomainName={ ensDomainMock.ensDomainA.name }/>);
await component.getByText('4').click(); await component.getByText('4').click();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 550, height: 350 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 550, height: 350 } });
}); });
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { test as base, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as addressMock from 'mocks/address/address';
import * as tokensMock from 'mocks/address/tokens'; import * as tokensMock from 'mocks/address/tokens';
import { tokenInfoERC20a } from 'mocks/tokens/tokenInfo'; import { tokenInfoERC20a } from 'mocks/tokens/tokenInfo';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import MockAddressPage from 'ui/address/testUtils/MockAddressPage'; import MockAddressPage from 'ui/address/testUtils/MockAddressPage';
import TokenSelect from './TokenSelect'; import TokenSelect from './TokenSelect';
const ASSET_URL = tokenInfoERC20a.icon_url as string; const ASSET_URL = tokenInfoERC20a.icon_url as string;
const TOKENS_ERC20_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-20'; const ADDRESS_HASH = addressMock.hash;
const TOKENS_ERC721_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-721';
const TOKENS_ER1155_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-1155';
const TOKENS_ER404_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-404';
const ADDRESS_API_URL = buildApiUrl('address', { hash: '1' });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: '1' }, query: { hash: ADDRESS_HASH },
}, },
}; };
const CLIPPING_AREA = { x: 0, y: 0, width: 360, height: 500 }; const CLIPPING_AREA = { x: 0, y: 0, width: 360, height: 500 };
const test = base.extend({ test.beforeEach(async({ mockApiResponse, mockAssetResponse }) => {
page: async({ page }, use) => { await mockAssetResponse(ASSET_URL, './playwright/mocks/image_s.jpg');
await page.route(ASSET_URL, (route) => { await mockApiResponse('address', addressMock.validator, { pathParams: { hash: ADDRESS_HASH }, times: 1 });
return route.fulfill({ await mockApiResponse('address_tokens', tokensMock.erc20List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-20' }, times: 1 });
status: 200, await mockApiResponse('address_tokens', tokensMock.erc721List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-721' }, times: 1 });
path: './playwright/mocks/image_s.jpg', await mockApiResponse('address_tokens', tokensMock.erc1155List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-1155' }, times: 1 });
}); await mockApiResponse('address_tokens', tokensMock.erc404List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-404' }, times: 1 });
});
await page.route(ADDRESS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify({ hash: '1' }),
}), { times: 1 });
await page.route(TOKENS_ERC20_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc20List),
}), { times: 1 });
await page.route(TOKENS_ERC721_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc721List),
}), { times: 1 });
await page.route(TOKENS_ER1155_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc1155List),
}), { times: 1 });
await page.route(TOKENS_ER404_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc404List),
}), { times: 1 });
use(page);
},
}); });
test('base view +@dark-mode', async({ mount, page }) => { test('base view +@dark-mode', async({ render, page }) => {
await mount( await render(
<TestApp>
<MockAddressPage> <MockAddressPage>
<Flex> <Flex>
<TokenSelect/> <TokenSelect/>
</Flex> </Flex>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
...@@ -81,15 +50,13 @@ test('base view +@dark-mode', async({ mount, page }) => { ...@@ -81,15 +50,13 @@ test('base view +@dark-mode', async({ mount, page }) => {
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view', async({ mount, page }) => { test('base view', async({ render, page }) => {
await mount( await render(
<TestApp>
<MockAddressPage> <MockAddressPage>
<Flex> <Flex>
<TokenSelect/> <TokenSelect/>
</Flex> </Flex>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
...@@ -100,15 +67,13 @@ test.describe('mobile', () => { ...@@ -100,15 +67,13 @@ test.describe('mobile', () => {
}); });
}); });
test('sort', async({ mount, page }) => { test('sort', async({ render, page }) => {
await mount( await render(
<TestApp>
<MockAddressPage> <MockAddressPage>
<Flex> <Flex>
<TokenSelect/> <TokenSelect/>
</Flex> </Flex>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
await page.getByRole('button', { name: /select/i }).click(); await page.getByRole('button', { name: /select/i }).click();
...@@ -123,15 +88,13 @@ test('sort', async({ mount, page }) => { ...@@ -123,15 +88,13 @@ test('sort', async({ mount, page }) => {
await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA }); await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA });
}); });
test('filter', async({ mount, page }) => { test('filter', async({ render, page }) => {
await mount( await render(
<TestApp>
<MockAddressPage> <MockAddressPage>
<Flex> <Flex>
<TokenSelect/> <TokenSelect/>
</Flex> </Flex>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
await page.getByRole('button', { name: /select/i }).click(); await page.getByRole('button', { name: /select/i }).click();
...@@ -140,42 +103,24 @@ test('filter', async({ mount, page }) => { ...@@ -140,42 +103,24 @@ test('filter', async({ mount, page }) => {
await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA }); await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA });
}); });
base('long values', async({ mount, page }) => { test('long values', async({ render, page, mockApiResponse }) => {
await page.route(ASSET_URL, (route) => { await mockApiResponse('address_tokens', {
return route.fulfill({ items: [ tokensMock.erc20LongSymbol, tokensMock.erc20BigAmount ], next_page_params: null,
status: 200, }, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-20' }, times: 1 });
path: './playwright/mocks/image_s.jpg', await mockApiResponse('address_tokens', {
}); items: [ tokensMock.erc721LongSymbol ], next_page_params: null,
}); }, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-721' }, times: 1 });
await page.route(ADDRESS_API_URL, (route) => route.fulfill({ await mockApiResponse('address_tokens', {
status: 200, items: [ tokensMock.erc1155LongId ], next_page_params: null,
body: JSON.stringify({ hash: '1' }), }, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-1155' }, times: 1 });
}), { times: 1 }); await mockApiResponse('address_tokens', tokensMock.erc404List, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-404' }, times: 1 });
await page.route(TOKENS_ERC20_API_URL, async(route) => route.fulfill({
status: 200, await render(
body: JSON.stringify({ items: [ tokensMock.erc20LongSymbol, tokensMock.erc20BigAmount ] }),
}), { times: 1 });
await page.route(TOKENS_ERC721_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify({ items: [ tokensMock.erc721LongSymbol ] }),
}), { times: 1 });
await page.route(TOKENS_ER1155_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify({ items: [ tokensMock.erc1155LongId ] }),
}), { times: 1 });
await page.route(TOKENS_ER404_API_URL, async(route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.erc404List),
}), { times: 1 });
await mount(
<TestApp>
<MockAddressPage> <MockAddressPage>
<Flex> <Flex>
<TokenSelect/> <TokenSelect/>
</Flex> </Flex>
</MockAddressPage> </MockAddressPage>,
</TestApp>,
{ hooksConfig }, { hooksConfig },
); );
await page.getByRole('button', { name: /select/i }).click(); await page.getByRole('button', { name: /select/i }).click();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import buildUrl from 'lib/api/buildUrl';
import * as mocks from 'mocks/account/verifiedAddresses'; import * as mocks from 'mocks/account/verifiedAddresses';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressVerificationStepAddress from './AddressVerificationStepAddress'; import AddressVerificationStepAddress from './AddressVerificationStepAddress';
const CHECK_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '1', type: ':prepare' }); const CHECK_ADDRESS_URL = buildUrl('address_verification', { chainId: '1', type: ':prepare' });
test('base view', async({ mount, page }) => { test('base view', async({ render, page }) => {
await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({ await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SUCCESS), body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SUCCESS),
})); }));
const props = { const props = {
onContinue: () => {}, onContinue: () => {},
defaultAddress: mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress, defaultAddress: mocks.VERIFIED_ADDRESS.NEW_ITEM.contractAddress,
}; };
await mount( await render(<AddressVerificationStepAddress { ...props }/>);
<TestApp>
<AddressVerificationStepAddress { ...props }/>
</TestApp>,
);
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('SOURCE_CODE_NOT_VERIFIED_ERROR view +@mobile', async({ mount, page }) => { test('SOURCE_CODE_NOT_VERIFIED_ERROR view +@mobile', async({ render, page }) => {
await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({ await page.route(CHECK_ADDRESS_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SOURCE_CODE_NOT_VERIFIED_ERROR), body: JSON.stringify(mocks.ADDRESS_CHECK_RESPONSE.SOURCE_CODE_NOT_VERIFIED_ERROR),
...@@ -39,11 +32,7 @@ test('SOURCE_CODE_NOT_VERIFIED_ERROR view +@mobile', async({ mount, page }) => { ...@@ -39,11 +32,7 @@ test('SOURCE_CODE_NOT_VERIFIED_ERROR view +@mobile', async({ mount, page }) => {
onContinue: () => {}, onContinue: () => {},
}; };
await mount( await render(<AddressVerificationStepAddress { ...props }/>);
<TestApp>
<AddressVerificationStepAddress { ...props }/>
</TestApp>,
);
const addressInput = page.getByLabel(/smart contract address/i); const addressInput = page.getByLabel(/smart contract address/i);
await addressInput.focus(); await addressInput.focus();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import buildUrl from 'lib/api/buildUrl';
import * as mocks from 'mocks/account/verifiedAddresses'; import * as mocks from 'mocks/account/verifiedAddresses';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressVerificationStepSignature from './AddressVerificationStepSignature'; import AddressVerificationStepSignature from './AddressVerificationStepSignature';
const VERIFY_ADDRESS_URL = buildApiUrl('address_verification', { chainId: '1', type: ':verify' }); const VERIFY_ADDRESS_URL = buildUrl('address_verification', { chainId: '1', type: ':verify' });
test('base view', async({ mount, page }) => { test('base view', async({ render, page }) => {
await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({ await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.SUCCESS), body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.SUCCESS),
...@@ -22,16 +21,11 @@ test('base view', async({ mount, page }) => { ...@@ -22,16 +21,11 @@ test('base view', async({ mount, page }) => {
signingMessage: mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result.signingMessage, signingMessage: mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result.signingMessage,
}; };
await mount( await render(<AddressVerificationStepSignature { ...props }/>);
<TestApp>
<AddressVerificationStepSignature { ...props }/>
</TestApp>,
);
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('INVALID_SIGNER_ERROR view +@mobile', async({ mount, page }) => { test('INVALID_SIGNER_ERROR view +@mobile', async({ render, page }) => {
await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({ await page.route(VERIFY_ADDRESS_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.INVALID_SIGNER_ERROR), body: JSON.stringify(mocks.ADDRESS_VERIFY_RESPONSE.INVALID_SIGNER_ERROR),
...@@ -44,11 +38,7 @@ test('INVALID_SIGNER_ERROR view +@mobile', async({ mount, page }) => { ...@@ -44,11 +38,7 @@ test('INVALID_SIGNER_ERROR view +@mobile', async({ mount, page }) => {
...mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result, ...mocks.ADDRESS_CHECK_RESPONSE.SUCCESS.result,
}; };
await mount( await render(<AddressVerificationStepSignature { ...props }/>);
<TestApp>
<AddressVerificationStepSignature { ...props }/>
</TestApp>,
);
const signatureInput = page.getByLabel(/signature hash/i); const signatureInput = page.getByLabel(/signature hash/i);
await signatureInput.fill(mocks.SIGNATURE); await signatureInput.fill(mocks.SIGNATURE);
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import BlobData from './BlobData'; import BlobData from './BlobData';
import imageBlobWithZeroesBytes from './image_with_zeroes.blob'; import imageBlobWithZeroesBytes from './image_with_zeroes.blob';
test.use({ viewport: { width: 500, height: 300 } }); test.use({ viewport: { width: 500, height: 300 } });
test('text', async({ mount }) => { test('text', async({ render }) => {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
const data = '0xE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A280E2A3A4E2A1B6E2A0BFE2A0BFE2A0B7E2A3B6E2A384E2A080E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B0E2A1BFE2A081E2A080E2A080E2A280E2A380E2A180E2A099E2A3B7E2A180E2A080E2A080E2A0800AE2A080E2A080E2A080E2A180E2A080E2A080E2A080E2A080E2A080E2A2A0E2A3BFE2A081E2A080E2A080E2A080E2A098E2A0BFE2A083E2A080E2A2B8E2A3BFE2A3BFE2A3BFE2A3BF0AE2A080E2A3A0E2A1BFE2A09BE2A2B7E2A3A6E2A180E2A080E2A080E2A088E2A3BFE2A184E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B8E2A3BFE2A3BFE2A3BFE2A09F0AE2A2B0E2A1BFE2A081E2A080E2A080E2A099E2A2BFE2A3A6E2A3A4E2A3A4E2A3BCE2A3BFE2A384E2A080E2A080E2A080E2A080E2A080E2A2B4E2A19FE2A09BE2A08BE2A081E2A0800AE2A3BFE2A087E2A080E2A080E2A080E2A080E2A080E2A089E2A089E2A089E2A089E2A089E2A081E2A080E2A080E2A080E2A080E2A080E2A088E2A3BFE2A180E2A080E2A080E2A0800AE2A3BFE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2B9E2A187E2A080E2A080E2A0800AE2A3BFE2A186E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3BCE2A187E2A080E2A080E2A0800AE2A0B8E2A3B7E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2A0E2A1BFE2A080E2A080E2A080E2A0800AE2A080E2A0B9E2A3B7E2A3A4E2A380E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A380E2A3B0E2A1BFE2A081E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A089E2A099E2A09BE2A0BFE2A0B6E2A3B6E2A3B6E2A3B6E2A3B6E2A3B6E2A0B6E2A0BFE2A09FE2A09BE2A089E2A080E2A080E2A080E2A080E2A080E2A080'; const data = '0xE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A280E2A3A4E2A1B6E2A0BFE2A0BFE2A0B7E2A3B6E2A384E2A080E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B0E2A1BFE2A081E2A080E2A080E2A280E2A380E2A180E2A099E2A3B7E2A180E2A080E2A080E2A0800AE2A080E2A080E2A080E2A180E2A080E2A080E2A080E2A080E2A080E2A2A0E2A3BFE2A081E2A080E2A080E2A080E2A098E2A0BFE2A083E2A080E2A2B8E2A3BFE2A3BFE2A3BFE2A3BF0AE2A080E2A3A0E2A1BFE2A09BE2A2B7E2A3A6E2A180E2A080E2A080E2A088E2A3BFE2A184E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B8E2A3BFE2A3BFE2A3BFE2A09F0AE2A2B0E2A1BFE2A081E2A080E2A080E2A099E2A2BFE2A3A6E2A3A4E2A3A4E2A3BCE2A3BFE2A384E2A080E2A080E2A080E2A080E2A080E2A2B4E2A19FE2A09BE2A08BE2A081E2A0800AE2A3BFE2A087E2A080E2A080E2A080E2A080E2A080E2A089E2A089E2A089E2A089E2A089E2A081E2A080E2A080E2A080E2A080E2A080E2A088E2A3BFE2A180E2A080E2A080E2A0800AE2A3BFE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2B9E2A187E2A080E2A080E2A0800AE2A3BFE2A186E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3BCE2A187E2A080E2A080E2A0800AE2A0B8E2A3B7E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2A0E2A1BFE2A080E2A080E2A080E2A0800AE2A080E2A0B9E2A3B7E2A3A4E2A380E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A380E2A3B0E2A1BFE2A081E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A089E2A099E2A09BE2A0BFE2A0B6E2A3B6E2A3B6E2A3B6E2A3B6E2A3B6E2A0B6E2A0BFE2A09FE2A09BE2A089E2A080E2A080E2A080E2A080E2A080E2A080';
const component = await render(<BlobData hash="0x01" data={ data }/>);
const component = await mount(
<TestApp>
<BlobData hash="0x01" data={ data }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
await component.locator('select').selectOption('UTF-8'); await component.locator('select').selectOption('UTF-8');
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('image', async({ mount }) => { test('image', async({ render }) => {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
const data = '0x89504E470D0A1A0A0000000D494844520000003C0000003C0403000000C8D2C4410000000467414D410000B18F0BFC6105000000017352474200AECE1CE900000027504C54454C69712B6CB02A6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB0F4205A540000000C74524E5300ED2F788CD91B99475C09B969CFA99D0000004F7A5458745261772070726F66696C65207479706520697074630000789CE3CA2C2849E6520003230B2E630B1323134B9314031320448034C3640323B35420CBD8D4C8C4CCC41CC407CB8048A04A2E0028950EE32A226D1F0000000970485973000084DF000084DF0195C81C33000000F24944415438CB636000018E983367CE482780D90CDA40F6991D0C4820152472A60ACCE6DA03629F4E40929E03961602B39964C09C0624691B24690E88F48461215D03160903B3D962C01C07842C2758C341A80643B0B40484C3646C6C5C78E6E016171723A8E215262EEE31670E161B1B7731304C05AB155EC08002C0D172E6F80206884DBB50651938CF4003FE0CBA4390E3C56064482F53525252C329CD562A2828283A0197340B22AAB0494332C311FCD2C747A547A58996C69998D8F12745B68DA0846C85331B2CEAE8E8681A81D91F8B348C4605D0527B02A4283FA88026CD05163EAAC0900ED21EC9800EC0C2110C002BBA9FE999B920330000000049454E44AE426082'; const data = '0x89504E470D0A1A0A0000000D494844520000003C0000003C0403000000C8D2C4410000000467414D410000B18F0BFC6105000000017352474200AECE1CE900000027504C54454C69712B6CB02A6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB0F4205A540000000C74524E5300ED2F788CD91B99475C09B969CFA99D0000004F7A5458745261772070726F66696C65207479706520697074630000789CE3CA2C2849E6520003230B2E630B1323134B9314031320448034C3640323B35420CBD8D4C8C4CCC41CC407CB8048A04A2E0028950EE32A226D1F0000000970485973000084DF000084DF0195C81C33000000F24944415438CB636000018E983367CE482780D90CDA40F6991D0C4820152472A60ACCE6DA03629F4E40929E03961602B39964C09C0624691B24690E88F48461215D03160903B3D962C01C07842C2758C341A80643B0B40484C3646C6C5C78E6E016171723A8E215262EEE31670E161B1B7731304C05AB155EC08002C0D172E6F80206884DBB50651938CF4003FE0CBA4390E3C56064482F53525252C329CD562A2828283A0197340B22AAB0494332C311FCD2C747A547A58996C69998D8F12745B68DA0846C85331B2CEAE8E8681A81D91F8B348C4605D0527B02A4283FA88026CD05163EAAC0900ED21EC9800EC0C2110C002BBA9FE999B920330000000049454E44AE426082';
const component = await render(<BlobData hash="0x01" data={ data }/>);
const component = await mount(
<TestApp>
<BlobData hash="0x01" data={ data }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
await component.locator('select').selectOption('Base64'); await component.locator('select').selectOption('Base64');
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('image blob with zeroes bytes', async({ mount }) => { test('image blob with zeroes bytes', async({ render }) => {
const component = await mount( const component = await render(<BlobData hash="0x01" data={ imageBlobWithZeroesBytes }/>);
<TestApp>
<BlobData hash="0x01" data={ imageBlobWithZeroesBytes }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { SmartContractVerificationConfig } from 'types/api/contract'; import type { SmartContractVerificationConfig } from 'types/api/contract';
import * as socketServer from 'playwright/fixtures/socketServer'; import * as socketServer from 'playwright/fixtures/socketServer';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import ContractVerificationForm from './ContractVerificationForm'; import ContractVerificationForm from './ContractVerificationForm';
...@@ -72,13 +71,8 @@ const formConfig: SmartContractVerificationConfig = { ...@@ -72,13 +71,8 @@ const formConfig: SmartContractVerificationConfig = {
}, },
}; };
test('flatten source code method +@dark-mode +@mobile', async({ mount, page }) => { test('flatten source code method +@dark-mode +@mobile', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select license // select license
await component.getByLabel(/contract license/i).focus(); await component.getByLabel(/contract license/i).focus();
...@@ -96,13 +90,8 @@ test('flatten source code method +@dark-mode +@mobile', async({ mount, page }) = ...@@ -96,13 +90,8 @@ test('flatten source code method +@dark-mode +@mobile', async({ mount, page }) =
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('standard input json method', async({ mount, page }) => { test('standard input json method', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select method // select method
await component.getByLabel(/verification method/i).focus(); await component.getByLabel(/verification method/i).focus();
...@@ -113,17 +102,13 @@ test('standard input json method', async({ mount, page }) => { ...@@ -113,17 +102,13 @@ test('standard input json method', async({ mount, page }) => {
}); });
test.describe('sourcify', () => { test.describe('sourcify', () => {
const testWithSocket = test.extend<socketServer.SocketServerFixture>({ test.describe.configure({ mode: 'serial', timeout: 20_000 });
createSocket: socketServer.createSocket,
});
testWithSocket.describe.configure({ mode: 'serial', timeout: 20_000 });
testWithSocket('with multiple contracts', async({ mount, page, createSocket }) => { test('with multiple contracts', async({ render, page, createSocket }) => {
const component = await mount( const component = await render(
<TestApp withSocket> <ContractVerificationForm config={ formConfig } hash={ hash }/>,
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig }, { hooksConfig },
{ withSocket: true },
); );
// select method // select method
...@@ -163,13 +148,8 @@ test.describe('sourcify', () => { ...@@ -163,13 +148,8 @@ test.describe('sourcify', () => {
}); });
}); });
test('multi-part files method', async({ mount, page }) => { test('multi-part files method', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select method // select method
await component.getByLabel(/verification method/i).focus(); await component.getByLabel(/verification method/i).focus();
...@@ -179,13 +159,8 @@ test('multi-part files method', async({ mount, page }) => { ...@@ -179,13 +159,8 @@ test('multi-part files method', async({ mount, page }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('vyper contract method', async({ mount, page }) => { test('vyper contract method', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select method // select method
await component.getByLabel(/verification method/i).focus(); await component.getByLabel(/verification method/i).focus();
...@@ -195,13 +170,8 @@ test('vyper contract method', async({ mount, page }) => { ...@@ -195,13 +170,8 @@ test('vyper contract method', async({ mount, page }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('vyper multi-part method', async({ mount, page }) => { test('vyper multi-part method', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select method // select method
await component.getByLabel(/verification method/i).focus(); await component.getByLabel(/verification method/i).focus();
...@@ -211,13 +181,8 @@ test('vyper multi-part method', async({ mount, page }) => { ...@@ -211,13 +181,8 @@ test('vyper multi-part method', async({ mount, page }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('vyper vyper-standard-input method', async({ mount, page }) => { test('vyper vyper-standard-input method', async({ render, page }) => {
const component = await mount( const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
<TestApp>
<ContractVerificationForm config={ formConfig } hash={ hash }/>
</TestApp>,
{ hooksConfig },
);
// select method // select method
await component.getByLabel(/verification method/i).focus(); await component.getByLabel(/verification method/i).focus();
......
import React from 'react'; import React from 'react';
import type { GasPriceInfo } from 'types/api/stats';
import * as statsMock from 'mocks/stats/index'; import * as statsMock from 'mocks/stats/index';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import GasTrackerPriceSnippet from './GasTrackerPriceSnippet'; import GasTrackerPriceSnippet from './GasTrackerPriceSnippet';
test.use({ viewport: configs.viewport.md }); test.use({ viewport: pwConfig.viewport.md });
const data = statsMock.base.gas_prices.fast; const data = statsMock.base.gas_prices?.fast as GasPriceInfo;
const clip = { x: 0, y: 0, width: 334, height: 204 }; const clip = { x: 0, y: 0, width: 334, height: 204 };
test('with usd as primary unit +@dark-mode', async({ render, page }) => { test('with usd as primary unit +@dark-mode', async({ render, page }) => {
......
import { test as base, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import * as socketServer from 'playwright/fixtures/socketServer'; import * as socketServer from 'playwright/fixtures/socketServer';
import TestApp from 'playwright/TestApp'; import { test as base, expect, devices } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import LatestTxs from './LatestTxs'; import LatestTxs from './LatestTxs';
...@@ -14,44 +12,28 @@ export const test = base.extend<socketServer.SocketServerFixture>({ ...@@ -14,44 +12,28 @@ export const test = base.extend<socketServer.SocketServerFixture>({
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('default view', async({ mount, page }) => { test('default view', async({ render, mockApiResponse }) => {
await page.route(buildApiUrl('homepage_txs'), (route) => route.fulfill({ await mockApiResponse('homepage_txs', [
status: 200,
body: JSON.stringify([
txMock.base, txMock.base,
txMock.withContractCreation, txMock.withContractCreation,
txMock.withTokenTransfer, txMock.withTokenTransfer,
txMock.withWatchListNames, txMock.withWatchListNames,
]), ]);
}));
const component = await mount(
<TestApp>
<LatestTxs/>
</TestApp>,
);
const component = await render(<LatestTxs/>);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
test('default view +@dark-mode', async({ mount, page }) => { test('default view +@dark-mode', async({ render, mockApiResponse }) => {
await page.route(buildApiUrl('homepage_txs'), (route) => route.fulfill({ await mockApiResponse('homepage_txs', [
status: 200,
body: JSON.stringify([
txMock.base, txMock.base,
txMock.withContractCreation, txMock.withContractCreation,
txMock.withTokenTransfer, txMock.withTokenTransfer,
txMock.withWatchListNames, txMock.withWatchListNames,
]), ]);
}));
const component = await mount(
<TestApp>
<LatestTxs/>
</TestApp>,
);
const component = await render(<LatestTxs/>);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
...@@ -65,27 +47,17 @@ test.describe('socket', () => { ...@@ -65,27 +47,17 @@ test.describe('socket', () => {
}, },
}; };
test('new item', async({ mount, page, createSocket }) => { test('new item', async({ render, mockApiResponse, createSocket }) => {
await page.route(buildApiUrl('homepage_txs'), (route) => route.fulfill({ await mockApiResponse('homepage_txs', [
status: 200,
body: JSON.stringify([
txMock.base, txMock.base,
txMock.withContractCreation, txMock.withContractCreation,
txMock.withTokenTransfer, txMock.withTokenTransfer,
]), ]);
}));
const component = await mount(
<TestApp withSocket>
<LatestTxs/>
</TestApp>,
{ hooksConfig },
);
const component = await render(<LatestTxs/>, { hooksConfig }, { withSocket: true });
const socket = await createSocket(); const socket = await createSocket();
const channel = await socketServer.joinChannel(socket, 'transactions:new_transaction'); const channel = await socketServer.joinChannel(socket, 'transactions:new_transaction');
socketServer.sendMessage(socket, channel, 'transaction', { transaction: 1 }); socketServer.sendMessage(socket, channel, 'transaction', { transaction: 1 });
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
...@@ -3,7 +3,7 @@ import React from 'react'; ...@@ -3,7 +3,7 @@ import React from 'react';
import * as statsMock from 'mocks/stats/index'; import * as statsMock from 'mocks/stats/index';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import Stats from './Stats'; import Stats from './Stats';
...@@ -20,7 +20,7 @@ test.describe('all items', () => { ...@@ -20,7 +20,7 @@ test.describe('all items', () => {
}); });
test.describe('screen xl', () => { test.describe('screen xl', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('', async() => { test('', async() => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test as base, expect } from '@playwright/experimental-ct-react';
import type { Locator } from '@playwright/test'; import type { Locator } from '@playwright/test';
import React from 'react'; import React from 'react';
import * as dailyTxsMock from 'mocks/stats/daily_txs'; import * as dailyTxsMock from 'mocks/stats/daily_txs';
import * as statsMock from 'mocks/stats/index'; import * as statsMock from 'mocks/stats/index';
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs'; import { test, expect } from 'playwright/lib';
import TestApp from 'playwright/TestApp';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import ChainIndicators from './ChainIndicators'; import ChainIndicators from './ChainIndicators';
const STATS_API_URL = buildApiUrl('stats'); test.beforeEach(async({ mockEnvs }) => {
const TX_CHART_API_URL = buildApiUrl('stats_charts_txs'); await mockEnvs([
[ 'NEXT_PUBLIC_HOMEPAGE_CHARTS', '["daily_txs","coin_price","secondary_coin_price","market_cap","tvl"]' ],
const test = base.extend({ [ 'NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL', 'DUCK' ],
context: contextWithEnvs([ ]);
{ name: 'NEXT_PUBLIC_HOMEPAGE_CHARTS', value: '["daily_txs","coin_price","secondary_coin_price","market_cap","tvl"]' },
{ name: 'NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL', value: 'DUCK' },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
]) as any,
}); });
test.describe('daily txs chart', () => { test.describe('daily txs chart', () => {
let component: Locator; let component: Locator;
test.beforeEach(async({ page, mount }) => { test.beforeEach(async({ page, mockApiResponse, render }) => {
await page.route(STATS_API_URL, (route) => route.fulfill({ await mockApiResponse('stats', statsMock.withSecondaryCoin);
status: 200, await mockApiResponse('stats_charts_txs', dailyTxsMock.base);
body: JSON.stringify(statsMock.withSecondaryCoin), component = await render(<ChainIndicators/>);
}));
await page.route(TX_CHART_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(dailyTxsMock.base),
}));
component = await mount(
<TestApp>
<ChainIndicators/>
</TestApp>,
);
await page.hover('.ChartOverlay', { position: { x: 100, y: 100 } }); await page.hover('.ChartOverlay', { position: { x: 100, y: 100 } });
}); });
...@@ -55,43 +37,19 @@ test.describe('daily txs chart', () => { ...@@ -55,43 +37,19 @@ test.describe('daily txs chart', () => {
}); });
}); });
test('partial data', async({ page, mount }) => { test('partial data', async({ page, mockApiResponse, render }) => {
await page.route(STATS_API_URL, (route) => route.fulfill({ await mockApiResponse('stats', statsMock.base);
status: 200, await mockApiResponse('stats_charts_txs', dailyTxsMock.partialData);
body: JSON.stringify(statsMock.base), const component = await render(<ChainIndicators/>);
}));
await page.route(TX_CHART_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(dailyTxsMock.partialData),
}));
const component = await mount(
<TestApp>
<ChainIndicators/>
</TestApp>,
);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="gradient-chart-area"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="gradient-chart-area"]')?.getAttribute('opacity') === '1';
}); });
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('no data', async({ page, mount }) => { test('no data', async({ mockApiResponse, render }) => {
await page.route(STATS_API_URL, (route) => route.fulfill({ await mockApiResponse('stats', statsMock.noChartData);
status: 200, await mockApiResponse('stats_charts_txs', dailyTxsMock.noData);
body: JSON.stringify(statsMock.noChartData), const component = await render(<ChainIndicators/>);
}));
await page.route(TX_CHART_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(dailyTxsMock.noData),
}));
const component = await mount(
<TestApp>
<ChainIndicators/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import { apps as appsMock } from 'mocks/apps/apps'; import { apps as appsMock } from 'mocks/apps/apps';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import MarketplaceAppInfo from './MarketplaceAppInfo'; import MarketplaceAppInfo from './MarketplaceAppInfo';
test('base view +@dark-mode', async({ mount, page }) => { test('base view +@dark-mode', async({ render, page }) => {
await mount( await render(<MarketplaceAppInfo data={ appsMock[0] }/>);
<TestApp>
<MarketplaceAppInfo data={ appsMock[0] }/>
</TestApp>,
);
await page.getByText('Info').click(); await page.getByText('Info').click();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 500, height: 400 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 500, height: 400 } });
}); });
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view', async({ mount, page }) => { test('base view', async({ render, page }) => {
await mount( await render(<MarketplaceAppInfo data={ appsMock[0] }/>);
<TestApp>
<MarketplaceAppInfo data={ appsMock[0] }/>
</TestApp>,
);
await page.getByLabel('Show project info').click(); await page.getByLabel('Show project info').click();
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
}); });
import { test, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { MarketplaceAppWithSecurityReport } from 'types/client/marketplace'; import type { MarketplaceAppWithSecurityReport } from 'types/client/marketplace';
import { apps as appsMock } from 'mocks/apps/apps'; import { apps as appsMock } from 'mocks/apps/apps';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import MarketplaceAppModal from './MarketplaceAppModal'; import MarketplaceAppModal from './MarketplaceAppModal';
...@@ -16,20 +15,9 @@ const props = { ...@@ -16,20 +15,9 @@ const props = {
isFavorite: false, isFavorite: false,
}; };
const testFn: Parameters<typeof test>[1] = async({ mount, page }) => { const testFn: Parameters<typeof test>[1] = async({ render, page, mockAssetResponse }) => {
await page.route(appsMock[0].logo, (route) => await mockAssetResponse(appsMock[0].logo, './playwright/mocks/image_s.jpg');
route.fulfill({ await render(<MarketplaceAppModal { ...props }/>);
status: 200,
path: './playwright/mocks/image_s.jpg',
}),
);
await mount(
<TestApp>
<MarketplaceAppModal { ...props }/>
</TestApp>,
);
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}; };
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { AddressesResponse } from 'types/api/addresses'; import type { AddressesResponse } from 'types/api/addresses';
import * as addressMocks from 'mocks/address/address'; import * as addressMocks from 'mocks/address/address';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import Accounts from './Accounts'; import Accounts from './Accounts';
const ADDRESSES_API_URL = buildApiUrl('addresses');
const addresses: AddressesResponse = { const addresses: AddressesResponse = {
items: [ items: [
{ {
...@@ -32,21 +28,9 @@ const addresses: AddressesResponse = { ...@@ -32,21 +28,9 @@ const addresses: AddressesResponse = {
next_page_params: null, next_page_params: null,
}; };
test('base view +@mobile +@dark-mode', async({ mount, page }) => { test('base view +@mobile +@dark-mode', async({ render, mockTextAd, mockApiResponse }) => {
await page.route(ADDRESSES_API_URL, (route) => route.fulfill({ await mockTextAd();
status: 200, await mockApiResponse('addresses', addresses);
body: JSON.stringify(addresses), const component = await render(<Accounts/>);
}));
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
status: 200,
body: '',
}));
const component = await mount(
<TestApp>
<Accounts/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as textAdMock from 'mocks/ad/textAd';
import * as blobsMock from 'mocks/blobs/blobs'; import * as blobsMock from 'mocks/blobs/blobs';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl'; import * as pwConfig from 'playwright/utils/config';
import * as configs from 'playwright/utils/configs';
import Blob from './Blob'; import Blob from './Blob';
const BLOB_API_URL = buildApiUrl('blob', { hash: blobsMock.base1.hash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: blobsMock.base1.hash }, query: { hash: blobsMock.base1.hash },
}, },
}; };
test.beforeEach(async({ page }) => { test.beforeEach(async({ mockTextAd }) => {
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({ await mockTextAd();
status: 200,
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
}); });
test('base view +@mobile +@dark-mode', async({ mount, page }) => { test('base view +@mobile +@dark-mode', async({ render, mockApiResponse, page }) => {
await page.route(BLOB_API_URL, (route) => route.fulfill({ await mockApiResponse('blob', blobsMock.base1, { pathParams: { hash: blobsMock.base1.hash } });
status: 200, const component = await render(<Blob/>, { hooksConfig });
body: JSON.stringify(blobsMock.base1),
}));
const component = await mount(
<TestApp>
<Blob/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
test('without data', async({ mount, page }) => { test('without data', async({ render, mockApiResponse, page }) => {
await page.route(BLOB_API_URL, (route) => route.fulfill({ await mockApiResponse('blob', blobsMock.withoutData, { pathParams: { hash: blobsMock.base1.hash } });
status: 200, const component = await render(<Blob/>, { hooksConfig });
body: JSON.stringify(blobsMock.withoutData),
}));
const component = await mount(
<TestApp>
<Blob/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -4,7 +4,7 @@ import React from 'react'; ...@@ -4,7 +4,7 @@ import React from 'react';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import * as tokenMock from 'mocks/tokens/tokenInfo'; import * as tokenMock from 'mocks/tokens/tokenInfo';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import CsvExport from './CsvExport'; import CsvExport from './CsvExport';
...@@ -20,7 +20,7 @@ test('base view +@mobile +@dark-mode', async({ render, page, mockApiResponse }) ...@@ -20,7 +20,7 @@ test('base view +@mobile +@dark-mode', async({ render, page, mockApiResponse })
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator('.recaptcha') ], mask: [ page.locator('.recaptcha') ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -37,6 +37,6 @@ test('token holders', async({ render, page, mockApiResponse }) => { ...@@ -37,6 +37,6 @@ test('token holders', async({ render, page, mockApiResponse }) => {
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator('.recaptcha') ], mask: [ page.locator('.recaptcha') ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as textAdMock from 'mocks/ad/textAd';
import * as statsMock from 'mocks/stats/index'; import * as statsMock from 'mocks/stats/index';
import * as statsLineMock from 'mocks/stats/line'; import * as statsLineMock from 'mocks/stats/line';
import * as statsLinesMock from 'mocks/stats/lines'; import * as statsLinesMock from 'mocks/stats/lines';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import GasTracker from './GasTracker'; import GasTracker from './GasTracker';
const STATS_LINES_API_URL = buildApiUrl('stats_lines'); test.beforeEach(async({ mockTextAd }) => {
const GAS_PRICE_CHART_API_URL = buildApiUrl('stats_line', { id: 'averageGasPrice' }) + '?**'; await mockTextAd();
const STATS_API_URL = buildApiUrl('stats');
test.beforeEach(async({ page }) => {
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
status: 200,
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
}); });
test('base view +@dark-mode +@mobile', async({ mount, page }) => { test('base view +@dark-mode +@mobile', async({ render, mockApiResponse, page }) => {
await page.route(STATS_API_URL, (route) => route.fulfill({ await mockApiResponse('stats', { ...statsMock.base, coin_price: '2442.789' });
status: 200, await mockApiResponse('stats_lines', statsLinesMock.base);
body: JSON.stringify({ ...statsMock.base, coin_price: '2442.789' }), const chartApiUrl = await mockApiResponse(
})); 'stats_line',
await page.route(STATS_LINES_API_URL, (route) => route.fulfill({ statsLineMock.averageGasPrice,
status: 200, { pathParams: { id: 'averageGasPrice' }, queryParams: { from: '**' } },
body: JSON.stringify(statsLinesMock.base),
}));
await page.route(GAS_PRICE_CHART_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(statsLineMock.averageGasPrice),
}));
const component = await mount(
<TestApp>
<GasTracker/>
</TestApp>,
); );
await page.waitForResponse(GAS_PRICE_CHART_API_URL); const component = await render(<GasTracker/>);
await page.waitForResponse(chartApiUrl);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="chart-Averagegasprice-small"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="chart-Averagegasprice-small"]')?.getAttribute('opacity') === '1';
}); });
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
...@@ -6,16 +6,15 @@ import * as dailyTxsMock from 'mocks/stats/daily_txs'; ...@@ -6,16 +6,15 @@ import * as dailyTxsMock from 'mocks/stats/daily_txs';
import * as statsMock from 'mocks/stats/index'; import * as statsMock from 'mocks/stats/index';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import { test, expect, devices } from 'playwright/lib'; import { test, expect, devices } from 'playwright/lib';
import TestApp from 'playwright/TestApp'; import * as pwConfig from 'playwright/utils/config';
import * as configs from 'playwright/utils/configs';
import Home from './Home'; import Home from './Home';
test.describe('default view', () => { test.describe('default view', () => {
let component: Locator; let component: Locator;
test.beforeEach(async({ mount, mockApiResponse, mockAssetResponse }) => { test.beforeEach(async({ render, mockApiResponse, mockAssetResponse }) => {
await mockAssetResponse(statsMock.base.coin_image, './playwright/mocks/image_s.jpg'); await mockAssetResponse(statsMock.base.coin_image as string, './playwright/mocks/image_s.jpg');
await mockApiResponse('stats', statsMock.base); await mockApiResponse('stats', statsMock.base);
await mockApiResponse('homepage_blocks', [ await mockApiResponse('homepage_blocks', [
blockMock.base, blockMock.base,
...@@ -28,27 +27,23 @@ test.describe('default view', () => { ...@@ -28,27 +27,23 @@ test.describe('default view', () => {
]); ]);
await mockApiResponse('stats_charts_txs', dailyTxsMock.base); await mockApiResponse('stats_charts_txs', dailyTxsMock.base);
component = await mount( component = await render(<Home/>);
<TestApp>
<Home/>
</TestApp>,
);
}); });
test('-@default +@dark-mode', async({ page }) => { test('-@default +@dark-mode', async({ page }) => {
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
test.describe('screen xl', () => { test.describe('screen xl', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('', async({ page }) => { test('', async({ page }) => {
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
}); });
...@@ -62,7 +57,7 @@ test.describe('custom hero plate background', () => { ...@@ -62,7 +57,7 @@ test.describe('custom hero plate background', () => {
]); ]);
}); });
test('default view', async({ mount, page }) => { test('default view', async({ render, page }) => {
await page.route(IMAGE_URL, (route) => { await page.route(IMAGE_URL, (route) => {
return route.fulfill({ return route.fulfill({
status: 200, status: 200,
...@@ -70,17 +65,13 @@ test.describe('custom hero plate background', () => { ...@@ -70,17 +65,13 @@ test.describe('custom hero plate background', () => {
}); });
}); });
const component = await mount( const component = await render(<Home/>);
<TestApp>
<Home/>
</TestApp>,
);
const heroPlate = component.locator('div[data-label="hero plate"]'); const heroPlate = component.locator('div[data-label="hero plate"]');
await expect(heroPlate).toHaveScreenshot({ await expect(heroPlate).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
}); });
...@@ -89,8 +80,8 @@ test.describe('custom hero plate background', () => { ...@@ -89,8 +80,8 @@ test.describe('custom hero plate background', () => {
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view', async({ mount, page, mockAssetResponse, mockApiResponse }) => { test('base view', async({ render, page, mockAssetResponse, mockApiResponse }) => {
await mockAssetResponse(statsMock.base.coin_image, './playwright/mocks/image_s.jpg'); await mockAssetResponse(statsMock.base.coin_image as string, './playwright/mocks/image_s.jpg');
await mockApiResponse('stats', statsMock.base); await mockApiResponse('stats', statsMock.base);
await mockApiResponse('homepage_blocks', [ await mockApiResponse('homepage_blocks', [
blockMock.base, blockMock.base,
...@@ -103,15 +94,11 @@ test.describe('mobile', () => { ...@@ -103,15 +94,11 @@ test.describe('mobile', () => {
]); ]);
await mockApiResponse('stats_charts_txs', dailyTxsMock.base); await mockApiResponse('stats_charts_txs', dailyTxsMock.base);
const component = await mount( const component = await render(<Home/>);
<TestApp>
<Home/>
</TestApp>,
);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
}); });
import { test as base, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import contextWithFeatures from 'playwright/fixtures/contextWithFeatures'; import { test, expect } from 'playwright/lib';
import TestApp from 'playwright/TestApp';
import Login from './Login'; import Login from './Login';
const testWithFeature = base.extend({ test.fixme('has feature text', async({ render, mockFeatures }) => {
context: contextWithFeatures([ await mockFeatures([
{ id: 'test_value', value: 'kitty' }, [ 'test_value', 'kitty' ],
// eslint-disable-next-line @typescript-eslint/no-explicit-any ]);
]) as any, const component = await render(<Login/>);
});
testWithFeature('has feature text', async({ mount }) => {
const component = await mount(
<TestApp>
<Login/>
</TestApp>,
);
const featureText = component.getByText('kitty'); const featureText = component.getByText('kitty');
await expect(featureText).toBeVisible(); await expect(featureText).toBeVisible();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import * as textAdMock from 'mocks/ad/textAd';
import * as ensDomainMock from 'mocks/ens/domain'; import * as ensDomainMock from 'mocks/ens/domain';
import * as ensDomainEventsMock from 'mocks/ens/events'; import * as ensDomainEventsMock from 'mocks/ens/events';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import NameDomain from './NameDomain'; import NameDomain from './NameDomain';
const DOMAIN_API_URL = buildApiUrl('domain_info', { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name }); test('details tab', async({ render, mockTextAd, mockApiResponse }) => {
const DOMAIN_EVENTS_API_URL = buildApiUrl('domain_events', { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name }); await mockTextAd();
await mockApiResponse('domain_info', ensDomainMock.ensDomainA, {
test.beforeEach(async({ page }) => { pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
status: 200,
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
}); });
}); const component = await render(
<NameDomain/>,
test('details tab', async({ mount, page }) => {
await page.route(DOMAIN_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(ensDomainMock.ensDomainA),
}));
const component = await mount(
<TestApp>
<NameDomain/>
</TestApp>,
{ hooksConfig: { { hooksConfig: {
router: { router: {
query: { name: ensDomainMock.ensDomainA.name }, query: { name: ensDomainMock.ensDomainA.name },
...@@ -43,30 +21,24 @@ test('details tab', async({ mount, page }) => { ...@@ -43,30 +21,24 @@ test('details tab', async({ mount, page }) => {
}, },
} }, } },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('history tab +@mobile', async({ mount, page }) => { test('history tab +@mobile', async({ render, mockTextAd, mockApiResponse }) => {
await page.route(DOMAIN_API_URL, (route) => route.fulfill({ await mockTextAd();
status: 200, await mockApiResponse('domain_info', ensDomainMock.ensDomainA, {
body: JSON.stringify(ensDomainMock.ensDomainA), pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
})); });
await page.route(DOMAIN_EVENTS_API_URL, (route) => route.fulfill({ await mockApiResponse('domain_events', {
status: 200,
body: JSON.stringify({
items: [ items: [
ensDomainEventsMock.ensDomainEventA, ensDomainEventsMock.ensDomainEventA,
ensDomainEventsMock.ensDomainEventB, ensDomainEventsMock.ensDomainEventB,
], ],
totalRecords: 2, }, {
}), pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
})); });
const component = await render(
const component = await mount( <NameDomain/>,
<TestApp>
<NameDomain/>
</TestApp>,
{ hooksConfig: { { hooksConfig: {
router: { router: {
query: { name: ensDomainMock.ensDomainA.name, tab: 'history' }, query: { name: ensDomainMock.ensDomainA.name, tab: 'history' },
...@@ -74,6 +46,5 @@ test('history tab +@mobile', async({ mount, page }) => { ...@@ -74,6 +46,5 @@ test('history tab +@mobile', async({ mount, page }) => {
}, },
} }, } },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import * as textAdMock from 'mocks/ad/textAd';
import * as ensDomainMock from 'mocks/ens/domain'; import * as ensDomainMock from 'mocks/ens/domain';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import NameDomains from './NameDomains'; import NameDomains from './NameDomains';
const DOMAINS_LOOKUP_API_URL = buildApiUrl('domains_lookup', { chainId: config.chain.id }) + '?only_active=true'; test('default view +@mobile', async({ render, mockApiResponse, mockTextAd }) => {
await mockTextAd();
test.beforeEach(async({ page }) => { await mockApiResponse('domains_lookup', {
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
status: 200,
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
});
test('default view +@mobile', async({ mount, page }) => {
await page.route(DOMAINS_LOOKUP_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify({
items: [ items: [
ensDomainMock.ensDomainA, ensDomainMock.ensDomainA,
ensDomainMock.ensDomainB, ensDomainMock.ensDomainB,
...@@ -35,16 +16,14 @@ test('default view +@mobile', async({ mount, page }) => { ...@@ -35,16 +16,14 @@ test('default view +@mobile', async({ mount, page }) => {
ensDomainMock.ensDomainD, ensDomainMock.ensDomainD,
], ],
next_page_params: { next_page_params: {
token_id: '<token-id>', page_token: '<token>',
page_size: 50,
}, },
}), }, {
})); pathParams: { chainId: config.chain.id },
queryParams: { only_active: true },
const component = await mount( });
<TestApp>
<NameDomains/>
</TestApp>,
);
const component = await render(<NameDomains/>);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
...@@ -7,7 +7,7 @@ import { tokenInfo, tokenCounters, bridgedTokenA } from 'mocks/tokens/tokenInfo' ...@@ -7,7 +7,7 @@ import { tokenInfo, tokenCounters, bridgedTokenA } from 'mocks/tokens/tokenInfo'
import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; import { ENVS_MAP } from 'playwright/fixtures/mockEnvs';
import * as socketServer from 'playwright/fixtures/socketServer'; import * as socketServer from 'playwright/fixtures/socketServer';
import { test, expect, devices } from 'playwright/lib'; import { test, expect, devices } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import Token from './Token'; import Token from './Token';
...@@ -41,8 +41,8 @@ test('base view', async({ render, page, createSocket }) => { ...@@ -41,8 +41,8 @@ test('base view', async({ render, page, createSocket }) => {
socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 }); socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 });
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -59,8 +59,8 @@ test('with verified info', async({ render, page, createSocket, mockApiResponse, ...@@ -59,8 +59,8 @@ test('with verified info', async({ render, page, createSocket, mockApiResponse,
await page.getByRole('button', { name: /project info/i }).click(); await page.getByRole('button', { name: /project info/i }).click();
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -86,8 +86,8 @@ test('bridged token', async({ render, page, createSocket, mockApiResponse, mockA ...@@ -86,8 +86,8 @@ test('bridged token', async({ render, page, createSocket, mockApiResponse, mockA
socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 }); socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 });
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -101,8 +101,8 @@ test.describe('mobile', () => { ...@@ -101,8 +101,8 @@ test.describe('mobile', () => {
socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 }); socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 });
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -116,8 +116,8 @@ test.describe('mobile', () => { ...@@ -116,8 +116,8 @@ test.describe('mobile', () => {
socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 }); socketServer.sendMessage(socket, channel, 'total_supply', { total_supply: 10 ** 20 });
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as textAdMock from 'mocks/ad/textAd';
import { verifiedContractsCountersMock } from 'mocks/contracts/counters'; import { verifiedContractsCountersMock } from 'mocks/contracts/counters';
import * as verifiedContractsMock from 'mocks/contracts/index'; import * as verifiedContractsMock from 'mocks/contracts/index';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import VerifiedContracts from './VerifiedContracts'; import VerifiedContracts from './VerifiedContracts';
const VERIFIED_CONTRACTS_API_URL = buildApiUrl('verified_contracts'); test('base view +@mobile', async({ render, mockTextAd, mockApiResponse }) => {
const VERIFIED_CONTRACTS_COUNTERS_API_URL = buildApiUrl('verified_contracts_counters'); await mockTextAd();
await mockApiResponse('verified_contracts', verifiedContractsMock.baseResponse);
test.beforeEach(async({ page }) => { await mockApiResponse('verified_contracts_counters', verifiedContractsCountersMock);
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({ const component = await render(<VerifiedContracts/>);
status: 200,
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
});
test('base view +@mobile', async({ mount, page }) => {
await page.route(VERIFIED_CONTRACTS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(verifiedContractsMock.baseResponse),
}));
await page.route(VERIFIED_CONTRACTS_COUNTERS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(verifiedContractsCountersMock),
}));
const component = await mount(
<TestApp>
<VerifiedContracts/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import AppError from './AppError'; import AppError from './AppError';
test('status code 404', async({ mount }) => { test('status code 404', async({ render }) => {
const error = { message: 'Not found', cause: { status: 404 } } as Error; const error = { message: 'Not found', cause: { status: 404 } } as Error;
const component = await mount( const component = await render(<AppError error={ error }/>);
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('status code 422', async({ mount }) => { test('status code 422', async({ render }) => {
const error = { message: 'Unprocessable entry', cause: { status: 422 } } as Error; const error = { message: 'Unprocessable entry', cause: { status: 422 } } as Error;
const component = await mount( const component = await render(<AppError error={ error }/>);
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('status code 500', async({ mount }) => { test('status code 500', async({ render }) => {
const error = { message: 'Unknown error', cause: { status: 500 } } as Error; const error = { message: 'Unknown error', cause: { status: 500 } } as Error;
const component = await mount( const component = await render(<AppError error={ error }/>);
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('tx not found', async({ mount }) => { test('tx not found', async({ render }) => {
const error = { message: 'Not found', cause: { status: 404, resource: 'tx' } } as Error; const error = { message: 'Not found', cause: { status: 404, resource: 'tx' } } as Error;
const component = await mount( const component = await render(<AppError error={ error }/>);
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('block lost consensus', async({ mount }) => { test('block lost consensus', async({ render }) => {
const error = { const error = {
message: 'Not found', message: 'Not found',
cause: { payload: { message: 'Block lost consensus', hash: 'hash' } }, cause: { payload: { message: 'Block lost consensus', hash: 'hash' } },
} as Error; } as Error;
const component = await mount( const component = await render(<AppError error={ error }/>);
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('too many requests +@mobile', async({ mount, page }) => { test('too many requests +@mobile', async({ render, page }) => {
const error = { const error = {
message: 'Too many requests', message: 'Too many requests',
cause: { status: 429 }, cause: { status: 429 },
} as Error; } as Error;
const component = await render(<AppError error={ error }/>);
const component = await mount(
<TestApp>
<AppError error={ error }/>
</TestApp>,
);
await page.waitForResponse('https://www.google.com/recaptcha/api2/**'); await page.waitForResponse('https://www.google.com/recaptcha/api2/**');
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator('.recaptcha') ], mask: [ page.locator('.recaptcha') ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import _noop from 'lodash/noop'; import _noop from 'lodash/noop';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import FancySelect from './FancySelect'; import FancySelect from './FancySelect';
...@@ -24,15 +23,13 @@ const defaultProps = { ...@@ -24,15 +23,13 @@ const defaultProps = {
[ 'md' as const, 'lg' as const ].forEach((size) => { [ 'md' as const, 'lg' as const ].forEach((size) => {
test.describe(`size ${ size } +@dark-mode`, () => { test.describe(`size ${ size } +@dark-mode`, () => {
test('empty', async({ mount, page }) => { test('empty', async({ render, page }) => {
const component = await mount( const component = await render(
<TestApp>
<FancySelect <FancySelect
{ ...defaultProps } { ...defaultProps }
size={ size } size={ size }
value={ null } value={ null }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -42,23 +39,20 @@ const defaultProps = { ...@@ -42,23 +39,20 @@ const defaultProps = {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('filled', async({ mount }) => { test('filled', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FancySelect <FancySelect
{ ...defaultProps } { ...defaultProps }
size={ size } size={ size }
value={ OPTIONS[0] } value={ OPTIONS[0] }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('error', async({ mount }) => { test('error', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FancySelect <FancySelect
{ ...defaultProps } { ...defaultProps }
size={ size } size={ size }
...@@ -67,8 +61,7 @@ const defaultProps = { ...@@ -67,8 +61,7 @@ const defaultProps = {
type: 'unknown', type: 'unknown',
message: 'cannot be empty', message: 'cannot be empty',
}} }}
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -78,31 +71,27 @@ const defaultProps = { ...@@ -78,31 +71,27 @@ const defaultProps = {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('disabled', async({ mount }) => { test('disabled', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FancySelect <FancySelect
{ ...defaultProps } { ...defaultProps }
size={ size } size={ size }
value={ OPTIONS[0] } value={ OPTIONS[0] }
isDisabled isDisabled
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('read-only', async({ mount }) => { test('read-only', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<FancySelect <FancySelect
{ ...defaultProps } { ...defaultProps }
size={ size } size={ size }
value={ OPTIONS[0] } value={ OPTIONS[0] }
isReadOnly isReadOnly
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import NetworkExplorers from './NetworkExplorers'; import NetworkExplorers from './NetworkExplorers';
test('base view', async({ mount, page }) => { test('base view', async({ render, page }) => {
const component = await mount( const component = await render(<NetworkExplorers type="tx" pathParam="0x123"/>);
<TestApp>
<NetworkExplorers type="tx" pathParam="0x123"/>
</TestApp>,
);
await component.getByText('2').click(); await component.getByText('2').click();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 300, height: 150 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 300, height: 150 } });
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as textAdMock from 'mocks/ad/textAd'; import { test, expect } from 'playwright/lib';
import TestApp from 'playwright/TestApp';
import DefaultView from './specs/DefaultView'; import DefaultView from './specs/DefaultView';
import LongNameAndManyTags from './specs/LongNameAndManyTags'; import LongNameAndManyTags from './specs/LongNameAndManyTags';
import WithTextAd from './specs/WithTextAd'; import WithTextAd from './specs/WithTextAd';
test.beforeEach(async({ page }) => { test.beforeEach(async({ mockTextAd, mockAssetResponse }) => {
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({ await mockTextAd();
status: 200, await mockAssetResponse('https://example.com/logo.png', './playwright/mocks/image_s.jpg');
body: JSON.stringify(textAdMock.duck),
}));
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
await page.route('https://example.com/logo.png', (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_s.jpg',
});
});
}); });
test('default view +@mobile', async({ mount }) => { test('default view +@mobile', async({ render }) => {
const component = await mount( const component = await render(<DefaultView/>);
<TestApp>
<DefaultView/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with text ad +@mobile', async({ mount }) => { test('with text ad +@mobile', async({ render }) => {
const component = await mount( const component = await render(<WithTextAd/>);
<TestApp>
<WithTextAd/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with long name and many tags +@mobile', async({ mount }) => { test('with long name and many tags +@mobile', async({ render }) => {
const component = await mount( const component = await render(<LongNameAndManyTags/>);
<TestApp>
<LongNameAndManyTags/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import SocketNewItemsNotice from './SocketNewItemsNotice'; import SocketNewItemsNotice from './SocketNewItemsNotice';
...@@ -12,35 +11,17 @@ const hooksConfig = { ...@@ -12,35 +11,17 @@ const hooksConfig = {
}, },
}; };
test('2 new items in validated txs list +@dark-mode', async({ mount }) => { test('2 new items in validated txs list +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<SocketNewItemsNotice url="/" num={ 2 }/>, { hooksConfig });
<TestApp>
<SocketNewItemsNotice url="/" num={ 2 }/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('connection loss', async({ mount }) => { test('connection loss', async({ render }) => {
const component = await mount( const component = await render(<SocketNewItemsNotice url="/" alert="Connection is lost. Please reload the page."/>, { hooksConfig });
<TestApp>
<SocketNewItemsNotice url="/" alert="Connection is lost. Please reload the page."/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('fetching', async({ mount }) => { test('fetching', async({ render }) => {
const component = await mount( const component = await render(<SocketNewItemsNotice url="/"/>, { hooksConfig });
<TestApp>
<SocketNewItemsNotice url="/"/>
</TestApp>,
{ hooksConfig },
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { TabItem } from './types'; import type { TabItem } from './types';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TabsWithScroll from './TabsWithScroll'; import TabsWithScroll from './TabsWithScroll';
test('with counters', async({ mount }) => { test('with counters', async({ render }) => {
const tabs: Array<TabItem> = [ const tabs: Array<TabItem> = [
{ {
id: 'tab1', id: 'tab1',
...@@ -28,13 +27,7 @@ test('with counters', async({ mount }) => { ...@@ -28,13 +27,7 @@ test('with counters', async({ mount }) => {
component: null, component: null,
}, },
]; ];
const component = await mount( const component = await render(<TabsWithScroll tabs={ tabs }/>);
<TestApp>
<TabsWithScroll tabs={ tabs }/>
</TestApp>,
);
await component.getByText('Third tab').hover(); await component.getByText('Third tab').hover();
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect, devices } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import TokenTransferList from './TokenTransferList'; import TokenTransferList from './TokenTransferList';
...@@ -24,29 +23,27 @@ const data = [ ...@@ -24,29 +23,27 @@ const data = [
tokenTransferMock.erc1155D, tokenTransferMock.erc1155D,
]; ];
test('without tx info', async({ mount }) => { test('without tx info', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<TokenTransferList <TokenTransferList
data={ data } data={ data }
showTxInfo={ false } showTxInfo={ false }
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with tx info', async({ mount }) => { test('with tx info', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<TokenTransferList <TokenTransferList
data={ data } data={ data }
showTxInfo={ true } showTxInfo={ true }
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TokenTransferTable from './TokenTransferTable'; import TokenTransferTable from './TokenTransferTable';
test('without tx info', async({ mount }) => { test('without tx info', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<TokenTransferTable <TokenTransferTable
data={ tokenTransferMock.mixTokens.items } data={ tokenTransferMock.mixTokens.items }
top={ 0 } top={ 0 }
showTxInfo={ false } showTxInfo={ false }
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with tx info', async({ mount }) => { test('with tx info', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<TokenTransferTable <TokenTransferTable
data={ tokenTransferMock.mixTokens.items } data={ tokenTransferMock.mixTokens.items }
top={ 0 } top={ 0 }
showTxInfo={ true } showTxInfo={ true }
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import Utilization from './Utilization'; import Utilization from './Utilization';
test.use({ viewport: { width: 100, height: 50 } }); test.use({ viewport: { width: 100, height: 50 } });
test('green color scheme +@dark-mode', async({ mount }) => { test('green color scheme +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<Utilization value={ 0.423 }/>);
<TestApp>
<Utilization value={ 0.423 }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('gray color scheme +@dark-mode', async({ mount }) => { test('gray color scheme +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<Utilization value={ 0.423 } colorScheme="gray"/>);
<TestApp>
<Utilization value={ 0.423 } colorScheme="gray"/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import * as configs from 'playwright/utils/configs'; import * as pwConfig from 'playwright/utils/config';
import AddressFromTo from './AddressFromTo'; import AddressFromTo from './AddressFromTo';
test.use({ viewport: configs.viewport.mobile }); test.use({ viewport: pwConfig.viewport.mobile });
test('outgoing txn', async({ mount }) => { test('outgoing txn', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressFromTo <AddressFromTo
from={ addressMock.withoutName } from={ addressMock.withoutName }
to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }} to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }}
current={ addressMock.withoutName.hash } current={ addressMock.withoutName.hash }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('incoming txn', async({ mount }) => { test('incoming txn', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressFromTo <AddressFromTo
from={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }} from={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }}
to={ addressMock.withoutName } to={ addressMock.withoutName }
current={ addressMock.withoutName.hash } current={ addressMock.withoutName.hash }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('compact mode', async({ mount }) => { test('compact mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressFromTo <AddressFromTo
from={ addressMock.withoutName } from={ addressMock.withoutName }
to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }} to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }}
mode="compact" mode="compact"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('loading state', async({ mount }) => { test('loading state', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressFromTo <AddressFromTo
from={ addressMock.withoutName } from={ addressMock.withoutName }
to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }} to={{ ...addressMock.withName, hash: '0xa8FCe579a11E551635b9c9CB915BEcd873C51254' }}
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import AddressFromToIcon from './AddressFromToIcon'; import AddressFromToIcon from './AddressFromToIcon';
test.use({ viewport: { width: 36, height: 36 } }); test.use({ viewport: { width: 36, height: 36 } });
[ 'in', 'out', 'self', 'unspecified' ].forEach((type) => { [ 'in', 'out', 'self', 'unspecified' ].forEach((type) => {
test(`${ type } txn type +@dark-mode`, async({ mount }) => { test(`${ type } txn type +@dark-mode`, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<Box p={ 2 }> <Box p={ 2 }>
<AddressFromToIcon type={ type }/> <AddressFromToIcon type={ type }/>
</Box> </Box>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import BlobDataType from './BlobDataType'; import BlobDataType from './BlobDataType';
test.use({ viewport: { width: 100, height: 50 } }); test.use({ viewport: { width: 100, height: 50 } });
test('image data', async({ mount }) => { test('image data', async({ render }) => {
const component = await mount( const component = await render(<BlobDataType data="0x89504E470D0A1A0A0000000D494844520000003C0000003C0403"/>);
<TestApp>
<BlobDataType data="0x89504E470D0A1A0A0000000D494844520000003C0000003C0403"/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('raw data', async({ mount }) => { test('raw data', async({ render }) => {
const component = await mount( const component = await render(<BlobDataType data="0x010203040506"/>);
<TestApp>
<BlobDataType data="0x010203040506"/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('text data', async({ mount }) => { test('text data', async({ render }) => {
const component = await mount( const component = await render(<BlobDataType data="0x7b226e616d65223a22706963732f"/>);
<TestApp>
<BlobDataType data="0x7b226e616d65223a22706963732f"/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import type { Props } from './ChartWidget'; import type { Props } from './ChartWidget';
import ChartWidget from './ChartWidget'; import ChartWidget from './ChartWidget';
...@@ -29,12 +28,9 @@ const props: Props = { ...@@ -29,12 +28,9 @@ const props: Props = {
isError: false, isError: false,
}; };
test('base view +@dark-mode', async({ mount, page }) => { test('base view +@dark-mode', async({ render, page }) => {
const component = await mount( const component = await render(<ChartWidget { ...props }/>);
<TestApp>
<ChartWidget { ...props }/>
</TestApp>,
);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1';
}); });
...@@ -54,27 +50,17 @@ test('base view +@dark-mode', async({ mount, page }) => { ...@@ -54,27 +50,17 @@ test('base view +@dark-mode', async({ mount, page }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(<ChartWidget { ...props } isLoading minH="250px"/>);
<TestApp>
<ChartWidget { ...props } isLoading minH="250px"/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('error', async({ mount }) => { test('error', async({ render }) => {
const component = await mount( const component = await render(<ChartWidget { ...props } isError/>);
<TestApp>
<ChartWidget { ...props } isError/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('small values', async({ mount, page }) => { test('small values', async({ render, page }) => {
const modifiedProps = { const modifiedProps = {
...props, ...props,
items: [ items: [
...@@ -92,18 +78,14 @@ test('small values', async({ mount, page }) => { ...@@ -92,18 +78,14 @@ test('small values', async({ mount, page }) => {
], ],
}; };
const component = await mount( const component = await render(<ChartWidget { ...modifiedProps }/>);
<TestApp>
<ChartWidget { ...modifiedProps }/>
</TestApp>,
);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1';
}); });
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('small variations in big values', async({ mount, page }) => { test('small variations in big values', async({ render, page }) => {
const modifiedProps = { const modifiedProps = {
...props, ...props,
items: [ items: [
...@@ -121,11 +103,7 @@ test('small variations in big values', async({ mount, page }) => { ...@@ -121,11 +103,7 @@ test('small variations in big values', async({ mount, page }) => {
], ],
}; };
const component = await mount( const component = await render(<ChartWidget { ...modifiedProps }/>);
<TestApp>
<ChartWidget { ...modifiedProps }/>
</TestApp>,
);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1'; return document.querySelector('path[data-name="chart-Nativecoincirculatingsupply-small"]')?.getAttribute('opacity') === '1';
}); });
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import { AddressHighlightProvider } from 'lib/contexts/addressHighlight'; import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import AddressEntity from './AddressEntity'; import AddressEntity from './AddressEntity';
...@@ -14,14 +13,12 @@ test.use({ viewport: { width: 180, height: 140 } }); ...@@ -14,14 +13,12 @@ test.use({ viewport: { width: 180, height: 140 } });
test.describe('icon size', () => { test.describe('icon size', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -30,26 +27,22 @@ test.describe('icon size', () => { ...@@ -30,26 +27,22 @@ test.describe('icon size', () => {
}); });
test.describe('contract', () => { test.describe('contract', () => {
test('unverified', async({ mount, page }) => { test('unverified', async({ render, page }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={{ ...addressMock.contract, is_verified: false }} address={{ ...addressMock.contract, is_verified: false }}
/> />,
</TestApp>,
); );
await component.getByText(/eternal/i).hover(); await component.getByText(/eternal/i).hover();
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('verified', async({ mount }) => { test('verified', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={{ ...addressMock.contract, is_verified: true }} address={{ ...addressMock.contract, is_verified: true }}
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -57,27 +50,23 @@ test.describe('contract', () => { ...@@ -57,27 +50,23 @@ test.describe('contract', () => {
}); });
test.describe('loading', () => { test.describe('loading', () => {
test('without alias', async({ mount }) => { test('without alias', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with alias', async({ mount }) => { test('with alias', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withName } address={ addressMock.withName }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -85,83 +74,71 @@ test.describe('loading', () => { ...@@ -85,83 +74,71 @@ test.describe('loading', () => {
}); });
test('with ENS', async({ mount }) => { test('with ENS', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withEns } address={ addressMock.withEns }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with name tag', async({ mount }) => { test('with name tag', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withNameTag } address={ addressMock.withNameTag }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('external link', async({ mount }) => { test('external link', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
isExternal isExternal
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('no link', async({ mount }) => { test('no link', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
noLink noLink
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
truncation="constant" truncation="constant"
p={ 3 } p={ 3 }
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('hover', async({ page, mount }) => { test('hover', async({ page, render }) => {
const component = await mount( const component = await render(
<TestApp>
<AddressHighlightProvider> <AddressHighlightProvider>
<Box p={ 3 }> <Box p={ 3 }>
<AddressEntity <AddressEntity
address={ addressMock.withoutName } address={ addressMock.withoutName }
/> />
</Box> </Box>
</AddressHighlightProvider> </AddressHighlightProvider>,
</TestApp>,
); );
await component.getByText(addressMock.hash.slice(0, 4)).hover(); await component.getByText(addressMock.hash.slice(0, 4)).hover();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import BlockEntity from './BlockEntity'; import BlockEntity from './BlockEntity';
...@@ -11,14 +10,12 @@ test.use({ viewport: { width: 180, height: 30 } }); ...@@ -11,14 +10,12 @@ test.use({ viewport: { width: 180, height: 30 } });
test.describe('icon sizes', () => { test.describe('icon sizes', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<BlockEntity <BlockEntity
number={ 17943507 } number={ 17943507 }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -26,27 +23,23 @@ test.describe('icon sizes', () => { ...@@ -26,27 +23,23 @@ test.describe('icon sizes', () => {
}); });
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<BlockEntity <BlockEntity
number={ 17943507 } number={ 17943507 }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('external link +@dark-mode', async({ mount }) => { test('external link +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<BlockEntity <BlockEntity
number={ 17943507 } number={ 17943507 }
isExternal isExternal
/> />,
</TestApp>,
); );
await component.getByText('17943507').hover(); await component.getByText('17943507').hover();
...@@ -54,28 +47,24 @@ test('external link +@dark-mode', async({ mount }) => { ...@@ -54,28 +47,24 @@ test('external link +@dark-mode', async({ mount }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('long number', async({ mount }) => { test('long number', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<BlockEntity <BlockEntity
number={ 1794350723452223 } number={ 1794350723452223 }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<BlockEntity <BlockEntity
number={ 17943507 } number={ 17943507 }
p={ 3 } p={ 3 }
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import EnsEntity from './EnsEntity'; import EnsEntity from './EnsEntity';
...@@ -12,14 +11,12 @@ test.use({ viewport: { width: 180, height: 30 } }); ...@@ -12,14 +11,12 @@ test.use({ viewport: { width: 180, height: 30 } });
test.describe('icon size', () => { test.describe('icon size', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<EnsEntity <EnsEntity
name={ name } name={ name }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -27,26 +24,22 @@ test.describe('icon size', () => { ...@@ -27,26 +24,22 @@ test.describe('icon size', () => {
}); });
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<EnsEntity <EnsEntity
name={ name } name={ name }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with long name', async({ mount }) => { test('with long name', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<EnsEntity <EnsEntity
name="kitty.kitty.kitty.cat.eth" name="kitty.kitty.kitty.cat.eth"
/> />,
</TestApp>,
); );
await component.getByText(name.slice(0, 4)).hover(); await component.getByText(name.slice(0, 4)).hover();
...@@ -54,16 +47,14 @@ test('with long name', async({ mount }) => { ...@@ -54,16 +47,14 @@ test('with long name', async({ mount }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<EnsEntity <EnsEntity
name={ name } name={ name }
p={ 3 } p={ 3 }
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import NftEntity from './NftEntity'; import NftEntity from './NftEntity';
...@@ -12,15 +11,13 @@ test.use({ viewport: { width: 180, height: 30 } }); ...@@ -12,15 +11,13 @@ test.use({ viewport: { width: 180, height: 30 } });
test.describe('icon sizes', () => { test.describe('icon sizes', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<NftEntity <NftEntity
hash={ hash } hash={ hash }
id={ 1042 } id={ 1042 }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -28,44 +25,38 @@ test.describe('icon sizes', () => { ...@@ -28,44 +25,38 @@ test.describe('icon sizes', () => {
}); });
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<NftEntity <NftEntity
hash={ hash } hash={ hash }
id={ 1042 } id={ 1042 }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('long id', async({ mount }) => { test('long id', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<NftEntity <NftEntity
hash={ hash } hash={ hash }
id={ 1794350723452223 } id={ 1794350723452223 }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<NftEntity <NftEntity
hash={ hash } hash={ hash }
id={ 1042 } id={ 1042 }
p={ 3 } p={ 3 }
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as tokenMock from 'mocks/tokens/tokenInfo'; import * as tokenMock from 'mocks/tokens/tokenInfo';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TokenEntity from './TokenEntity'; import TokenEntity from './TokenEntity';
...@@ -13,14 +12,12 @@ test.use({ viewport: { width: 300, height: 100 } }); ...@@ -13,14 +12,12 @@ test.use({ viewport: { width: 300, height: 100 } });
test.describe('icon size', () => { test.describe('icon size', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TokenEntity <TokenEntity
token={ tokenMock.tokenInfo } token={ tokenMock.tokenInfo }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -28,7 +25,7 @@ test.describe('icon size', () => { ...@@ -28,7 +25,7 @@ test.describe('icon size', () => {
}); });
}); });
test('with logo, long name and symbol', async({ page, mount }) => { test('with logo, long name and symbol', async({ page, render }) => {
const LOGO_URL = 'https://example.com/logo.png'; const LOGO_URL = 'https://example.com/logo.png';
await page.route(LOGO_URL, (route) => { await page.route(LOGO_URL, (route) => {
return route.fulfill({ return route.fulfill({
...@@ -37,8 +34,7 @@ test('with logo, long name and symbol', async({ page, mount }) => { ...@@ -37,8 +34,7 @@ test('with logo, long name and symbol', async({ page, mount }) => {
}); });
}); });
await mount( await render(
<TestApp>
<TokenEntity <TokenEntity
token={{ token={{
name: 'This token is the best token ever', name: 'This token is the best token ever',
...@@ -46,8 +42,7 @@ test('with logo, long name and symbol', async({ page, mount }) => { ...@@ -46,8 +42,7 @@ test('with logo, long name and symbol', async({ page, mount }) => {
address: tokenMock.tokenInfo.address, address: tokenMock.tokenInfo.address,
icon_url: LOGO_URL, icon_url: LOGO_URL,
}} }}
/> />,
</TestApp>,
); );
await page.getByText(/this/i).hover(); await page.getByText(/this/i).hover();
...@@ -57,22 +52,19 @@ test('with logo, long name and symbol', async({ page, mount }) => { ...@@ -57,22 +52,19 @@ test('with logo, long name and symbol', async({ page, mount }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TokenEntity <TokenEntity
token={ tokenMock.tokenInfo } token={ tokenMock.tokenInfo }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<Box <Box
borderWidth="1px" borderWidth="1px"
borderColor="orange.500" borderColor="orange.500"
...@@ -84,8 +76,7 @@ test('customization', async({ mount }) => { ...@@ -84,8 +76,7 @@ test('customization', async({ mount }) => {
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />
</Box> </Box>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TxEntity from './TxEntity'; import TxEntity from './TxEntity';
...@@ -12,14 +11,12 @@ test.use({ viewport: { width: 180, height: 30 } }); ...@@ -12,14 +11,12 @@ test.use({ viewport: { width: 180, height: 30 } });
test.describe('icon size', () => { test.describe('icon size', () => {
iconSizes.forEach((size) => { iconSizes.forEach((size) => {
test(size, async({ mount }) => { test(size, async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TxEntity <TxEntity
hash={ hash } hash={ hash }
iconSize={ size } iconSize={ size }
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -27,40 +24,34 @@ test.describe('icon size', () => { ...@@ -27,40 +24,34 @@ test.describe('icon size', () => {
}); });
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TxEntity <TxEntity
hash={ hash } hash={ hash }
isLoading isLoading
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('external link', async({ mount }) => { test('external link', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TxEntity <TxEntity
hash={ hash } hash={ hash }
isExternal isExternal
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with copy +@dark-mode', async({ mount }) => { test('with copy +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TxEntity <TxEntity
hash={ hash } hash={ hash }
noCopy={ false } noCopy={ false }
/> />,
</TestApp>,
); );
await component.getByText(hash.slice(0, 4)).hover(); await component.getByText(hash.slice(0, 4)).hover();
...@@ -68,17 +59,15 @@ test('with copy +@dark-mode', async({ mount }) => { ...@@ -68,17 +59,15 @@ test('with copy +@dark-mode', async({ mount }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('customization', async({ mount }) => { test('customization', async({ render }) => {
const component = await mount( const component = await render(
<TestApp>
<TxEntity <TxEntity
hash={ hash } hash={ hash }
truncation="constant" truncation="constant"
p={ 3 } p={ 3 }
borderWidth="1px" borderWidth="1px"
borderColor="blue.700" borderColor="blue.700"
/> />,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
This diff is collapsed.
This diff is collapsed.
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { indexingStatus } from 'mocks/stats/index';
import buildApiUrl from 'playwright/utils/buildApiUrl'; import { test, expect } from 'playwright/lib';
import LayoutHome from './LayoutHome'; import LayoutHome from './LayoutHome';
const API_URL = buildApiUrl('homepage_indexing_status'); test('base view +@mobile', async({ render, mockApiResponse }) => {
await mockApiResponse('homepage_indexing_status', indexingStatus);
test('base view +@mobile', async({ mount, page }) => { const component = await render(
await page.route(API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify({ finished_indexing_blocks: false, indexed_blocks_ratio: 0.1 }),
}));
const component = await mount(
<TestApp>
<LayoutHome> <LayoutHome>
<Box pt={ 10 }>Error</Box> <Box pt={ 10 }>Error</Box>
</LayoutHome> </LayoutHome>,
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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