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, <MockAddressPage>
body: JSON.stringify(tokensMock.erc20List), <AddressDetails addressQuery={{ data: addressMock.token } as AddressQuery}/>
}), { times: 1 }); </MockAddressPage>,
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>
<AddressDetails addressQuery={{ data: addressMock.token } as AddressQuery}/>
</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();
......
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 type { AddressTokensResponse } from 'types/api/address';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import * as tokensMock from 'mocks/address/tokens'; import * as tokensMock from 'mocks/address/tokens';
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 AddressTokens from './AddressTokens'; import AddressTokens from './AddressTokens';
const ADDRESS_HASH = addressMock.withName.hash; const ADDRESS_HASH = addressMock.validator.hash;
const API_URL_ADDRESS = buildApiUrl('address', { hash: ADDRESS_HASH });
const API_URL_TOKENS = buildApiUrl('address_tokens', { hash: ADDRESS_HASH });
const API_URL_NFT = buildApiUrl('address_nfts', { hash: ADDRESS_HASH }) + '?type=';
const API_URL_COLLECTIONS = buildApiUrl('address_collections', { hash: ADDRESS_HASH }) + '?type=';
const nextPageParams = { const nextPageParams = {
items_count: 50, items_count: 50,
token_name: 'aaa', token_name: 'aaa',
token_type: '123', token_type: 'ERC-20' as const,
value: 1, value: 1,
fiat_value: '1',
}; };
const test = base.extend({ test.beforeEach(async({ mockApiResponse }) => {
page: async({ page }, use) => { const response20: AddressTokensResponse = {
const response20 = { items: [ tokensMock.erc20a, tokensMock.erc20b, tokensMock.erc20c, tokensMock.erc20d ],
items: [ tokensMock.erc20a, tokensMock.erc20b, tokensMock.erc20c, tokensMock.erc20d ], next_page_params: nextPageParams,
next_page_params: nextPageParams, };
}; const response721: AddressTokensResponse = {
const response721 = { items: [ tokensMock.erc721a, tokensMock.erc721b, tokensMock.erc721c ],
items: [ tokensMock.erc721a, tokensMock.erc721b, tokensMock.erc721c ], next_page_params: nextPageParams,
next_page_params: nextPageParams, };
}; const response1155: AddressTokensResponse = {
const response1155 = { items: [ tokensMock.erc1155a, tokensMock.erc1155b ],
items: [ tokensMock.erc1155a, tokensMock.erc1155b ], next_page_params: nextPageParams,
next_page_params: nextPageParams, };
}; const response404: AddressTokensResponse = {
const response404 = { items: [ tokensMock.erc404a, tokensMock.erc404b ],
items: [ tokensMock.erc404a, tokensMock.erc404b ], next_page_params: nextPageParams,
next_page_params: nextPageParams, };
};
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ await mockApiResponse('address', addressMock.validator, { pathParams: { hash: ADDRESS_HASH } });
status: 200, await mockApiResponse('address_tokens', response20, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-20' } });
body: JSON.stringify(addressMock.withName), await mockApiResponse('address_tokens', response721, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-721' } });
})); await mockApiResponse('address_tokens', response1155, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-1155' } });
await page.route(API_URL_TOKENS + '?type=ERC-20', (route) => route.fulfill({ await mockApiResponse('address_tokens', response404, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-404' } });
status: 200, await mockApiResponse('address_nfts', tokensMock.nfts, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: [] } });
body: JSON.stringify(response20), await mockApiResponse('address_collections', tokensMock.collections, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: [] } });
}));
await page.route(API_URL_TOKENS + '?type=ERC-721', (route) => route.fulfill({
status: 200,
body: JSON.stringify(response721),
}));
await page.route(API_URL_TOKENS + '?type=ERC-1155', (route) => route.fulfill({
status: 200,
body: JSON.stringify(response1155),
}));
await page.route(API_URL_TOKENS + '?type=ERC-404', (route) => route.fulfill({
status: 200,
body: JSON.stringify(response404),
}));
await page.route(API_URL_NFT, (route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.nfts),
}));
await page.route(API_URL_COLLECTIONS, (route) => route.fulfill({
status: 200,
body: JSON.stringify(tokensMock.collections),
}));
use(page);
},
}); });
test('erc20 +@dark-mode', async({ mount }) => { test('erc20 +@dark-mode', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' }, query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' },
...@@ -83,18 +55,17 @@ test('erc20 +@dark-mode', async({ mount }) => { ...@@ -83,18 +55,17 @@ test('erc20 +@dark-mode', async({ mount }) => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('collections +@dark-mode', async({ mount }) => { test('collections +@dark-mode', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' }, query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
...@@ -102,18 +73,17 @@ test('collections +@dark-mode', async({ mount }) => { ...@@ -102,18 +73,17 @@ test('collections +@dark-mode', async({ mount }) => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('nfts +@dark-mode', async({ mount }) => { test('nfts +@dark-mode', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' }, query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
...@@ -121,11 +91,10 @@ test('nfts +@dark-mode', async({ mount }) => { ...@@ -121,11 +91,10 @@ test('nfts +@dark-mode', async({ mount }) => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
...@@ -137,7 +106,7 @@ test('nfts +@dark-mode', async({ mount }) => { ...@@ -137,7 +106,7 @@ test('nfts +@dark-mode', async({ mount }) => {
test.describe('mobile', () => { test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('erc20', async({ mount }) => { test('erc20', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' }, query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' },
...@@ -145,18 +114,17 @@ test.describe('mobile', () => { ...@@ -145,18 +114,17 @@ test.describe('mobile', () => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('nfts', async({ mount }) => { test('nfts', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' }, query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
...@@ -164,11 +132,10 @@ test.describe('mobile', () => { ...@@ -164,11 +132,10 @@ test.describe('mobile', () => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
...@@ -177,7 +144,7 @@ test.describe('mobile', () => { ...@@ -177,7 +144,7 @@ test.describe('mobile', () => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('collections', async({ mount }) => { test('collections', async({ render }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' }, query: { hash: ADDRESS_HASH, tab: 'tokens_nfts' },
...@@ -185,11 +152,10 @@ test.describe('mobile', () => { ...@@ -185,11 +152,10 @@ test.describe('mobile', () => {
}, },
}; };
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/> <AddressTokens/>
</TestApp>, </Box>,
{ hooksConfig }, { hooksConfig },
); );
...@@ -197,13 +163,10 @@ test.describe('mobile', () => { ...@@ -197,13 +163,10 @@ test.describe('mobile', () => {
}); });
}); });
base.describe('update balances via socket', () => { test.describe('update balances via socket', () => {
const test = base.extend<socketServer.SocketServerFixture>({
createSocket: socketServer.createSocket,
});
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });
test('', async({ mount, page, createSocket }) => { test('', async({ render, page, createSocket, mockApiResponse }) => {
test.slow(); test.slow();
const hooksConfig = { const hooksConfig = {
...@@ -230,41 +193,23 @@ base.describe('update balances via socket', () => { ...@@ -230,41 +193,23 @@ base.describe('update balances via socket', () => {
next_page_params: null, next_page_params: null,
}; };
await page.route(API_URL_ADDRESS, (route) => route.fulfill({ const erc20ApiUrl = await mockApiResponse('address_tokens', response20, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-20' } });
status: 200, const erc721ApiUrl = await mockApiResponse('address_tokens', response721, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-721' } });
body: JSON.stringify(addressMock.validator), const erc1155ApiUrl = await mockApiResponse('address_tokens', response1155, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-1155' } });
})); const erc404ApiUrl = await mockApiResponse('address_tokens', response404, { pathParams: { hash: ADDRESS_HASH }, queryParams: { type: 'ERC-404' } });
await page.route(API_URL_TOKENS + '?type=ERC-20', (route) => route.fulfill({
status: 200, const component = await render(
body: JSON.stringify(response20), <Box pt={{ base: '134px', lg: 6 }}>
})); <AddressTokens/>
await page.route(API_URL_TOKENS + '?type=ERC-721', (route) => route.fulfill({ </Box>,
status: 200,
body: JSON.stringify(response721),
}));
await page.route(API_URL_TOKENS + '?type=ERC-1155', (route) => route.fulfill({
status: 200,
body: JSON.stringify(response1155),
}));
await page.route(API_URL_TOKENS + '?type=ERC-404', (route) => route.fulfill({
status: 200,
body: JSON.stringify(response404),
}));
const component = await mount(
<TestApp withSocket>
<Box>
<Box h={{ base: '134px', lg: 6 }}/>
<AddressTokens/>
</Box>
</TestApp>,
{ hooksConfig }, { hooksConfig },
{ withSocket: true },
); );
await page.waitForResponse(API_URL_TOKENS + '?type=ERC-20'); await page.waitForResponse(erc20ApiUrl);
await page.waitForResponse(API_URL_TOKENS + '?type=ERC-721'); await page.waitForResponse(erc721ApiUrl);
await page.waitForResponse(API_URL_TOKENS + '?type=ERC-1155'); await page.waitForResponse(erc1155ApiUrl);
await page.waitForResponse(API_URL_TOKENS + '?type=ERC-404'); await page.waitForResponse(erc404ApiUrl);
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 } 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, items: [
{ txMock.base,
...txMock.base, { ...txMock.base, hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194' },
hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194', ],
}, next_page_params: DEFAULT_PAGINATION,
], next_page_params: { block: 1 } }), },
})); { pathParams: { hash: CURRENT_ADDRESS } },
);
component = await mount( component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 6 }}>
<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 ] }), <MockAddressPage>
}), { times: 1 }); <Flex>
await page.route(TOKENS_ERC721_API_URL, async(route) => route.fulfill({ <TokenSelect/>
status: 200, </Flex>
body: JSON.stringify({ items: [ tokensMock.erc721LongSymbol ] }), </MockAddressPage>,
}), { 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>
<Flex>
<TokenSelect/>
</Flex>
</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.withContractCreation,
txMock.withTokenTransfer,
txMock.withWatchListNames,
]),
}));
const component = await mount(
<TestApp>
<LatestTxs/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
});
test('default view +@dark-mode', async({ mount, page }) => {
await page.route(buildApiUrl('homepage_txs'), (route) => route.fulfill({
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( const component = await render(<LatestTxs/>);
<TestApp> await expect(component).toHaveScreenshot();
<LatestTxs/> });
</TestApp>, });
);
test('default view +@dark-mode', async({ render, mockApiResponse }) => {
await mockApiResponse('homepage_txs', [
txMock.base,
txMock.withContractCreation,
txMock.withTokenTransfer,
txMock.withWatchListNames,
]);
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, txMock.base,
body: JSON.stringify([ txMock.withContractCreation,
txMock.base, txMock.withTokenTransfer,
txMock.withContractCreation, ]);
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, items: [
body: JSON.stringify({ ensDomainEventsMock.ensDomainEventA,
items: [ ensDomainEventsMock.ensDomainEventB,
ensDomainEventsMock.ensDomainEventA, ],
ensDomainEventsMock.ensDomainEventB, }, {
], pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
totalRecords: 2, });
}), const component = await render(
})); <NameDomain/>,
const component = await mount(
<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({ items: [
status: 200, ensDomainMock.ensDomainA,
body: JSON.stringify(textAdMock.duck), ensDomainMock.ensDomainB,
})); ensDomainMock.ensDomainC,
await page.route(textAdMock.duck.ad.thumbnail, (route) => { ensDomainMock.ensDomainD,
return route.fulfill({ ],
status: 200, next_page_params: {
path: './playwright/mocks/image_s.jpg', page_token: '<token>',
}); page_size: 50,
},
}, {
pathParams: { chainId: config.chain.id },
queryParams: { only_active: true },
}); });
});
test('default view +@mobile', async({ mount, page }) => {
await page.route(DOMAINS_LOOKUP_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify({
items: [
ensDomainMock.ensDomainA,
ensDomainMock.ensDomainB,
ensDomainMock.ensDomainC,
ensDomainMock.ensDomainD,
],
next_page_params: {
token_id: '<token-id>',
},
}),
}));
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,33 +39,29 @@ const defaultProps = { ...@@ -42,33 +39,29 @@ 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 } value={ null }
value={ null } error={{
error={{ 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,17 +34,15 @@ test('with logo, long name and symbol', async({ page, mount }) => { ...@@ -37,17 +34,15 @@ 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', symbol: 'DUCK DUCK DUCK',
symbol: 'DUCK DUCK DUCK', 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,35 +52,31 @@ test('with logo, long name and symbol', async({ page, mount }) => { ...@@ -57,35 +52,31 @@ 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"
borderColor="orange.500"
>
<TokenEntity
token={ tokenMock.tokenInfo }
p={ 2 }
maxW="200px"
borderWidth="1px" borderWidth="1px"
borderColor="orange.500" borderColor="blue.700"
> />
<TokenEntity </Box>,
token={ tokenMock.tokenInfo }
p={ 2 }
maxW="200px"
borderWidth="1px"
borderColor="blue.700"
/>
</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();
......
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 UserOpEntity from './UserOpEntity'; import UserOpEntity from './UserOpEntity';
...@@ -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> <UserOpEntity
<UserOpEntity hash={ hash }
hash={ hash } iconSize={ size }
iconSize={ size } />,
/>
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -27,27 +24,23 @@ test.describe('icon size', () => { ...@@ -27,27 +24,23 @@ test.describe('icon size', () => {
}); });
}); });
test('loading', async({ mount }) => { test('loading', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <UserOpEntity
<UserOpEntity hash={ hash }
hash={ hash } isLoading
isLoading />,
/>
</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> <UserOpEntity
<UserOpEntity 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();
...@@ -55,17 +48,15 @@ test('with copy +@dark-mode', async({ mount }) => { ...@@ -55,17 +48,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> <UserOpEntity
<UserOpEntity 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();
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import type { GasPriceInfo } from 'types/api/stats';
import { SECOND } from 'lib/consts'; import { SECOND } from 'lib/consts';
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 GasInfoTooltip from './GasInfoTooltip'; import GasInfoTooltip from './GasInfoTooltip';
import GasPrice from './GasPrice'; import GasPrice from './GasPrice';
...@@ -13,13 +13,11 @@ const dataUpdatedAt = Date.now() - 30 * SECOND; ...@@ -13,13 +13,11 @@ const dataUpdatedAt = Date.now() - 30 * SECOND;
test.use({ viewport: { width: 300, height: 300 } }); test.use({ viewport: { width: 300, height: 300 } });
test('all data', async({ mount, page }) => { test('all data', async({ render, page }) => {
await mount( await render(
<TestApp> <GasInfoTooltip data={ statsMock.base } dataUpdatedAt={ dataUpdatedAt } isOpen>
<GasInfoTooltip data={ statsMock.base } dataUpdatedAt={ dataUpdatedAt } isOpen> <span>Gas <GasPrice data={ statsMock.base.gas_prices?.average as GasPriceInfo }/></span>
<span>Gas <GasPrice data={ statsMock.base.gas_prices.average }/></span> </GasInfoTooltip>,
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
...@@ -27,13 +25,11 @@ test('all data', async({ mount, page }) => { ...@@ -27,13 +25,11 @@ test('all data', async({ mount, page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('without primary unit price', async({ mount, page }) => { test('without primary unit price', async({ render, page }) => {
await mount( await render(
<TestApp> <GasInfoTooltip data={ statsMock.withoutFiatPrices } dataUpdatedAt={ dataUpdatedAt } isOpen>
<GasInfoTooltip data={ statsMock.withoutFiatPrices } dataUpdatedAt={ dataUpdatedAt } isOpen> <span>Gas: <GasPrice data={ statsMock.withoutFiatPrices.gas_prices?.average as GasPriceInfo }/></span>
<span>Gas: <GasPrice data={ statsMock.withoutFiatPrices.gas_prices.average }/></span> </GasInfoTooltip>,
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
...@@ -41,13 +37,11 @@ test('without primary unit price', async({ mount, page }) => { ...@@ -41,13 +37,11 @@ test('without primary unit price', async({ mount, page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('without secondary unit price', async({ mount, page }) => { test('without secondary unit price', async({ render, page }) => {
await mount( await render(
<TestApp> <GasInfoTooltip data={ statsMock.withoutGweiPrices } dataUpdatedAt={ dataUpdatedAt } isOpen>
<GasInfoTooltip data={ statsMock.withoutGweiPrices } dataUpdatedAt={ dataUpdatedAt } isOpen> <span>Gas: <GasPrice data={ statsMock.withoutGweiPrices.gas_prices?.average as GasPriceInfo }/></span>
<span>Gas: <GasPrice data={ statsMock.withoutGweiPrices.gas_prices.average }/></span> </GasInfoTooltip>,
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
...@@ -55,13 +49,11 @@ test('without secondary unit price', async({ mount, page }) => { ...@@ -55,13 +49,11 @@ test('without secondary unit price', async({ mount, page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('no data', async({ mount, page }) => { test('no data', async({ render, page }) => {
await mount( await render(
<TestApp> <GasInfoTooltip data={ statsMock.withoutBothPrices } dataUpdatedAt={ dataUpdatedAt } isOpen>
<GasInfoTooltip data={ statsMock.withoutBothPrices } dataUpdatedAt={ dataUpdatedAt } isOpen> <span>Gas: <GasPrice data={ statsMock.withoutBothPrices.gas_prices?.average as GasPriceInfo }/></span>
<span>Gas: <GasPrice data={ statsMock.withoutBothPrices.gas_prices.average }/></span> </GasInfoTooltip>,
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
...@@ -69,21 +61,18 @@ test('no data', async({ mount, page }) => { ...@@ -69,21 +61,18 @@ test('no data', async({ mount, page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
const oneUnitTest = test.extend({ test.describe('one unit', () => {
context: contextWithEnvs([ test.beforeEach(async({ mockEnvs }) => {
{ name: 'NEXT_PUBLIC_GAS_TRACKER_UNITS', value: '["gwei"]' }, await mockEnvs([
// eslint-disable-next-line @typescript-eslint/no-explicit-any [ 'NEXT_PUBLIC_GAS_TRACKER_UNITS', '["gwei"]' ],
]) as any, ]);
}); });
oneUnitTest.describe('one unit', () => { test('with data', async({ render, page }) => {
oneUnitTest('with data', async({ mount, page }) => { await render(
await mount( <GasInfoTooltip data={ statsMock.withoutFiatPrices } dataUpdatedAt={ dataUpdatedAt } isOpen>
<TestApp> <span>Gas: <GasPrice data={ statsMock.withoutFiatPrices.gas_prices?.average as GasPriceInfo }/></span>
<GasInfoTooltip data={ statsMock.withoutFiatPrices } dataUpdatedAt={ dataUpdatedAt } isOpen> </GasInfoTooltip>,
<span>Gas: <GasPrice data={ statsMock.withoutFiatPrices.gas_prices.average }/></span>
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
...@@ -91,13 +80,11 @@ oneUnitTest.describe('one unit', () => { ...@@ -91,13 +80,11 @@ oneUnitTest.describe('one unit', () => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
oneUnitTest('without data', async({ mount, page }) => { test('without data', async({ render, page }) => {
await mount( await render(
<TestApp> <GasInfoTooltip data={ statsMock.withoutGweiPrices } dataUpdatedAt={ dataUpdatedAt } isOpen>
<GasInfoTooltip data={ statsMock.withoutGweiPrices } dataUpdatedAt={ dataUpdatedAt } isOpen> <span>Gas: <GasPrice data={ statsMock.withoutGweiPrices.gas_prices?.average as GasPriceInfo }/></span>
<span>Gas: <GasPrice data={ statsMock.withoutGweiPrices.gas_prices.average }/></span> </GasInfoTooltip>,
</GasInfoTooltip>
</TestApp>,
); );
// await page.getByText(/gas/i).hover(); // await page.getByText(/gas/i).hover();
......
import { test as base, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs'; import { indexingStatus } from 'mocks/stats/index';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import Layout from './Layout'; import Layout from './Layout';
const API_URL = buildApiUrl('homepage_indexing_status'); test('base view +@mobile', async({ render, mockEnvs, mockApiResponse }) => {
await mockEnvs([
const test = base.extend({ [
context: contextWithEnvs([ 'NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE',
{ 'We are currently lacking pictures of <i>ducks</i>. Please <a href="mailto:duck@blockscout.com">send</a> us one.',
name: 'NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE', ],
value: 'We are currently lacking pictures of <i>ducks</i>. Please <a href="mailto:duck@blockscout.com">send</a> us one.', ]);
}, await mockApiResponse('homepage_indexing_status', indexingStatus);
// eslint-disable-next-line @typescript-eslint/no-explicit-any const component = await render(<Layout>Page Content</Layout>);
]) as any,
});
test('base view +@mobile', async({ mount, page }) => {
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>
<Layout>Page Content</Layout>
</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 { 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({ <LayoutHome>
status: 200, <Box pt={ 10 }>Error</Box>
body: JSON.stringify({ finished_indexing_blocks: false, indexed_blocks_ratio: 0.1 }), </LayoutHome>,
}));
const component = await mount(
<TestApp>
<LayoutHome>
<Box pt={ 10 }>Error</Box>
</LayoutHome>
</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 { 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(<LayoutHome>Page Content</LayoutHome>);
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>Page Content</LayoutHome>
</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 mocks from 'mocks/txs/decodedInputData'; import * as mocks from 'mocks/txs/decodedInputData';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import LogDecodedInputData from './LogDecodedInputData'; import LogDecodedInputData from './LogDecodedInputData';
test('with indexed fields +@mobile +@dark-mode', async({ mount }) => { test('with indexed fields +@mobile +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<LogDecodedInputData data={ mocks.withIndexedFields }/>);
<TestApp>
<LogDecodedInputData data={ mocks.withIndexedFields }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('without indexed fields +@mobile', async({ mount }) => { test('without indexed fields +@mobile', async({ render }) => {
const component = await mount( const component = await render(<LogDecodedInputData data={ mocks.withoutIndexedFields }/>);
<TestApp>
<LogDecodedInputData data={ mocks.withoutIndexedFields }/>
</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 addressMocks from 'mocks/address/address'; import * as addressMocks from 'mocks/address/address';
import * as inputDataMocks from 'mocks/txs/decodedInputData'; import * as inputDataMocks from 'mocks/txs/decodedInputData';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import LogItem from './LogItem'; import LogItem from './LogItem';
...@@ -15,36 +14,32 @@ const TOPICS = [ ...@@ -15,36 +14,32 @@ const TOPICS = [
]; ];
const DATA = '0x0000000000000000000000000000000000000000000000000070265bf0112cee'; const DATA = '0x0000000000000000000000000000000000000000000000000070265bf0112cee';
test('with decoded input data +@mobile +@dark-mode', async({ mount }) => { test('with decoded input data +@mobile +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <LogItem
<LogItem index={ 42 }
index={ 42 } decoded={ inputDataMocks.withIndexedFields }
decoded={ inputDataMocks.withIndexedFields } address={{ ...addressMocks.withName, is_verified: true }}
address={{ ...addressMocks.withName, is_verified: true }} topics={ TOPICS }
topics={ TOPICS } data={ DATA }
data={ DATA } type="transaction"
type="transaction" tx_hash={ null }
tx_hash={ null } />,
/>
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('without decoded input data +@mobile', async({ mount }) => { test('without decoded input data +@mobile', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <LogItem
<LogItem index={ 42 }
index={ 42 } decoded={ null }
decoded={ null } address={ addressMocks.withoutName }
address={ addressMocks.withoutName } topics={ TOPICS }
topics={ TOPICS } data={ DATA }
data={ DATA } type="transaction"
type="transaction" tx_hash={ null }
tx_hash={ null } />,
/>
</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 LogTopic from './LogTopic'; import LogTopic from './LogTopic';
test('address view +@mobile -@default', async({ mount }) => { test('address view +@mobile -@default', async({ render }) => {
const component = await mount( const component = await render(<LogTopic hex="0x000000000000000000000000d789a607ceac2f0e14867de4eb15b15c9ffb5859" index={ 42 }/>);
<TestApp>
<LogTopic hex="0x000000000000000000000000d789a607ceac2f0e14867de4eb15b15c9ffb5859" index={ 42 }/>
</TestApp>,
);
await component.locator('select[aria-label="Data type"]').selectOption('address'); await component.locator('select[aria-label="Data type"]').selectOption('address');
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('hex view +@mobile -@default', async({ mount }) => { test('hex view +@mobile -@default', async({ render }) => {
const component = await mount( const component = await render(<LogTopic hex="0x000000000000000000000000d789a607ceac2f0e14867de4eb15b15c9ffb5859" index={ 42 }/>);
<TestApp>
<LogTopic hex="0x000000000000000000000000d789a607ceac2f0e14867de4eb15b15c9ffb5859" index={ 42 }/>
</TestApp>,
);
await component.locator('select[aria-label="Data type"]').selectOption('hex'); await component.locator('select[aria-label="Data type"]').selectOption('hex');
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
......
import { test, expect } from '@playwright/experimental-ct-react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import NftMedia from './NftMedia'; import NftMedia from './NftMedia';
test.describe('no url', () => { test.describe('no url', () => {
test.use({ viewport: { width: 250, height: 250 } }); test.use({ viewport: { width: 250, height: 250 } });
test('preview +@dark-mode', async({ mount }) => { test('preview +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<NftMedia animationUrl={ null } imageUrl={ null }/>);
<TestApp>
<NftMedia animationUrl={ null } imageUrl={ null }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with fallback', async({ mount, page }) => { test('with fallback', async({ render, mockAssetResponse }) => {
const IMAGE_URL = 'https://localhost:3000/my-image.jpg'; const IMAGE_URL = 'https://localhost:3000/my-image.jpg';
await mockAssetResponse(IMAGE_URL, './playwright/mocks/image_long.jpg');
await page.route(IMAGE_URL, (route) => { const component = await render(<NftMedia animationUrl={ null } imageUrl={ IMAGE_URL }/>);
return route.fulfill({
status: 200,
path: './playwright/mocks/image_long.jpg',
});
});
const component = await mount(
<TestApp>
<NftMedia animationUrl={ null } imageUrl={ IMAGE_URL }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('non-media url and fallback', async({ mount, page }) => { test('non-media url and fallback', async({ render, page, mockAssetResponse }) => {
const ANIMATION_URL = 'https://localhost:3000/my-animation.m3u8'; const ANIMATION_URL = 'https://localhost:3000/my-animation.m3u8';
const ANIMATION_MEDIA_TYPE_API_URL = `/node-api/media-type?url=${ encodeURIComponent(ANIMATION_URL) }`; const ANIMATION_MEDIA_TYPE_API_URL = `/node-api/media-type?url=${ encodeURIComponent(ANIMATION_URL) }`;
const IMAGE_URL = 'https://localhost:3000/my-image.jpg'; const IMAGE_URL = 'https://localhost:3000/my-image.jpg';
...@@ -47,88 +30,40 @@ test.describe('no url', () => { ...@@ -47,88 +30,40 @@ test.describe('no url', () => {
body: JSON.stringify({ type: undefined }), body: JSON.stringify({ type: undefined }),
}); });
}); });
await mockAssetResponse(IMAGE_URL, './playwright/mocks/image_long.jpg');
await page.route(IMAGE_URL, (route) => { const component = await render(<NftMedia animationUrl={ ANIMATION_URL } imageUrl={ IMAGE_URL }/>);
return route.fulfill({
status: 200,
path: './playwright/mocks/image_long.jpg',
});
});
const component = await mount(
<TestApp>
<NftMedia animationUrl={ ANIMATION_URL } imageUrl={ IMAGE_URL }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
test.describe('image', () => { test.describe('image', () => {
test.use({ viewport: { width: 250, height: 250 } });
const MEDIA_URL = 'https://localhost:3000/my-image.jpg'; const MEDIA_URL = 'https://localhost:3000/my-image.jpg';
test.beforeEach(async({ page }) => { test.beforeEach(async({ mockAssetResponse }) => {
await page.route(MEDIA_URL, (route) => { await mockAssetResponse(MEDIA_URL, './playwright/mocks/image_long.jpg');
return route.fulfill({
status: 200,
path: './playwright/mocks/image_long.jpg',
});
});
}); });
test('preview +@dark-mode', async({ mount }) => { test('preview +@dark-mode', async({ render, page }) => {
const component = await mount( await render(
<TestApp> <Box boxSize="250px">
<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null }/> <NftMedia animationUrl={ MEDIA_URL } imageUrl={ null }/>
</TestApp>, </Box>,
); );
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
await expect(component).toHaveScreenshot();
}); });
});
test('image preview hover', async({ mount, page }) => {
const MEDIA_URL = 'https://localhost:3000/my-image.jpg';
await page.route(MEDIA_URL, (route) => { test('preview hover', async({ render, page }) => {
return route.fulfill({ const component = await render(<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null } w="250px"/>);
status: 200, await component.getByAltText('Token instance image').hover();
path: './playwright/mocks/image_long.jpg', await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
});
}); });
const component = await mount( test('fullscreen +@dark-mode +@mobile', async({ render, page }) => {
<TestApp> const component = await render(<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null } withFullscreen w="250px"/>);
<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null } w="250px"/> await component.getByAltText('Token instance image').click();
</TestApp>, await expect(page).toHaveScreenshot();
);
await component.getByAltText('Token instance image').hover();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
});
test('image fullscreen +@dark-mode +@mobile', async({ mount, page }) => {
const MEDIA_URL = 'https://localhost:3000/my-image.jpg';
await page.route(MEDIA_URL, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_long.jpg',
});
}); });
const component = await mount(
<TestApp>
<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null } withFullscreen w="250px"/>
</TestApp>,
);
await component.getByAltText('Token instance image').click();
await expect(page).toHaveScreenshot();
}); });
test.describe('page', () => { test.describe('page', () => {
...@@ -137,27 +72,16 @@ test.describe('page', () => { ...@@ -137,27 +72,16 @@ test.describe('page', () => {
const MEDIA_URL = 'https://localhost:3000/page.html'; const MEDIA_URL = 'https://localhost:3000/page.html';
const MEDIA_TYPE_API_URL = `/node-api/media-type?url=${ encodeURIComponent(MEDIA_URL) }`; const MEDIA_TYPE_API_URL = `/node-api/media-type?url=${ encodeURIComponent(MEDIA_URL) }`;
test.beforeEach(async({ page }) => { test.beforeEach(async({ page, mockAssetResponse }) => {
await mockAssetResponse(MEDIA_URL, './playwright/mocks/page.html');
await page.route(MEDIA_URL, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/page.html',
});
});
await page.route(MEDIA_TYPE_API_URL, (route) => route.fulfill({ await page.route(MEDIA_TYPE_API_URL, (route) => route.fulfill({
status: 200, status: 200,
body: JSON.stringify({ type: 'html' }), body: JSON.stringify({ type: 'html' }),
})); }));
}); });
test('preview +@dark-mode', async({ mount }) => { test('preview +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null }/>);
<TestApp>
<NftMedia animationUrl={ MEDIA_URL } imageUrl={ null }/>
</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 { PaginationParams } from './types'; import type { PaginationParams } from './types';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import Pagination from './Pagination'; import Pagination from './Pagination';
test.use({ viewport: { width: 250, height: 50 } }); test.use({ viewport: { width: 250, height: 50 } });
test('default view', async({ mount }) => { test('default view', async({ render }) => {
const props: PaginationParams = { const props: PaginationParams = {
page: 2, page: 2,
isVisible: true, isVisible: true,
...@@ -21,11 +20,6 @@ test('default view', async({ mount }) => { ...@@ -21,11 +20,6 @@ test('default view', async({ mount }) => {
onPrevPageClick: () => {}, onPrevPageClick: () => {},
resetPage: () => {}, resetPage: () => {},
}; };
const component = await mount( const component = await render(<Pagination { ...props } w="fit-content"/>);
<TestApp>
<Pagination { ...props } w="fit-content"/>
</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 RadioButtonGroupTest from './specs/RadioButtonGroupTest'; import RadioButtonGroupTest from './specs/RadioButtonGroupTest';
test('radio button group', async({ mount }) => { test('radio button group', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box w="400px" p="10px">
<Box w="400px" p="10px"> <RadioButtonGroupTest/>
<RadioButtonGroupTest/> </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 StatusTag from './StatusTag'; import StatusTag from './StatusTag';
test('ok status', async({ page, mount }) => { test('ok status', async({ page, render }) => {
await mount( await render(<StatusTag type="ok" text="Test"/>);
<TestApp>
<StatusTag type="ok" text="Test"/>
</TestApp>,
);
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } });
}); });
test('error status', async({ page, mount }) => { test('error status', async({ page, render }) => {
await mount( await render(<StatusTag type="error" text="Test"/>);
<TestApp>
<StatusTag type="error" text="Test"/>
</TestApp>,
);
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } });
}); });
test('pending status', async({ page, mount }) => { test('pending status', async({ page, render }) => {
await mount( await render(<StatusTag type="pending" text="Test"/>);
<TestApp>
<StatusTag type="pending" text="Test"/>
</TestApp>,
);
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 75, height: 30 } });
}); });
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 { ZKEVM_L2_TX_STATUSES } from 'types/api/transaction'; import { ZKEVM_L2_TX_STATUSES } from 'types/api/transaction';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import VerificationSteps from './VerificationSteps'; import VerificationSteps from './VerificationSteps';
test('first step +@mobile +@dark-mode', async({ mount }) => { test('first step +@mobile +@dark-mode', async({ render }) => {
const component = await render(
const component = await mount( <Box p={ 10 }>
<TestApp> <VerificationSteps currentStep={ ZKEVM_L2_TX_STATUSES[0] } steps={ ZKEVM_L2_TX_STATUSES }/>
<Box p={ 10 }> </Box>,
<VerificationSteps currentStep={ ZKEVM_L2_TX_STATUSES[0] } steps={ ZKEVM_L2_TX_STATUSES }/>
</Box>
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('second status', async({ mount }) => { test('second status', async({ render }) => {
const component = await render(
const component = await mount( <VerificationSteps currentStep={ ZKEVM_L2_TX_STATUSES[1] } steps={ ZKEVM_L2_TX_STATUSES }/>,
<TestApp>
<VerificationSteps currentStep={ ZKEVM_L2_TX_STATUSES[1] } steps={ ZKEVM_L2_TX_STATUSES }/>
</TestApp>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import { FOOTER_LINKS } from 'mocks/config/footerLinks'; import { FOOTER_LINKS } from 'mocks/config/footerLinks';
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 Footer from './Footer'; import Footer from './Footer';
...@@ -30,7 +30,7 @@ test.describe('with custom links, max cols', () => { ...@@ -30,7 +30,7 @@ test.describe('with custom links, max cols', () => {
}); });
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(page).toHaveScreenshot(); await expect(page).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 HeaderDesktop from './HeaderDesktop'; import HeaderDesktop from './HeaderDesktop';
test('default view +@dark-mode', async({ mount }) => { test('default view +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<HeaderDesktop/>);
<TestApp>
<HeaderDesktop/>
</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 TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import HeaderMobile from './HeaderMobile'; import HeaderMobile from './HeaderMobile';
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('default view +@dark-mode', async({ mount, page }) => { test('default view +@dark-mode', async({ render, page }) => {
await mount( await render(<HeaderMobile/>);
<TestApp>
<HeaderMobile/>
</TestApp>,
);
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1500, height: 150 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1500, height: 150 } });
}); });
...@@ -7,7 +7,7 @@ import * as cookies from 'lib/cookies'; ...@@ -7,7 +7,7 @@ import * as cookies from 'lib/cookies';
import { FEATURED_NETWORKS_MOCK } from 'mocks/config/network'; import { FEATURED_NETWORKS_MOCK } from 'mocks/config/network';
import { contextWithAuth } from 'playwright/fixtures/auth'; import { contextWithAuth } from 'playwright/fixtures/auth';
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 NavigationDesktop from './NavigationDesktop'; import NavigationDesktop from './NavigationDesktop';
...@@ -46,7 +46,7 @@ test.describe('no auth', () => { ...@@ -46,7 +46,7 @@ test.describe('no auth', () => {
}); });
test.describe('xl screen', () => { test.describe('xl screen', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('+@dark-mode', async() => { test('+@dark-mode', async() => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -76,7 +76,7 @@ authTest.describe('auth', () => { ...@@ -76,7 +76,7 @@ authTest.describe('auth', () => {
}); });
authTest.describe('xl screen', () => { authTest.describe('xl screen', () => {
authTest.use({ viewport: configs.viewport.xl }); authTest.use({ viewport: pwConfig.viewport.xl });
authTest('+@dark-mode', async() => { authTest('+@dark-mode', async() => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -85,7 +85,7 @@ authTest.describe('auth', () => { ...@@ -85,7 +85,7 @@ authTest.describe('auth', () => {
}); });
test.describe('with tooltips', () => { test.describe('with tooltips', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('', async({ render, page }) => { test('', async({ render, page }) => {
const component = await render( const component = await render(
...@@ -123,7 +123,7 @@ test.describe('with submenu', () => { ...@@ -123,7 +123,7 @@ test.describe('with submenu', () => {
}); });
test.describe('xl screen', () => { test.describe('xl screen', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('', async() => { test('', async() => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
...@@ -157,7 +157,7 @@ noSideBarCookieTest.describe('cookie set to false', () => { ...@@ -157,7 +157,7 @@ noSideBarCookieTest.describe('cookie set to false', () => {
}); });
noSideBarCookieTest.describe('xl screen', () => { noSideBarCookieTest.describe('xl screen', () => {
noSideBarCookieTest.use({ viewport: configs.viewport.xl }); noSideBarCookieTest.use({ viewport: pwConfig.viewport.xl });
noSideBarCookieTest('', async() => { noSideBarCookieTest('', async() => {
const networkMenu = component.locator('button[aria-label="Network menu"]'); const networkMenu = component.locator('button[aria-label="Network menu"]');
...@@ -202,7 +202,7 @@ test('hover +@dark-mode', async({ render }) => { ...@@ -202,7 +202,7 @@ test('hover +@dark-mode', async({ render }) => {
}); });
test.describe('hover xl screen', () => { test.describe('hover xl screen', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('+@dark-mode', async({ render }) => { test('+@dark-mode', async({ render }) => {
const component = await render( const component = await render(
......
...@@ -2,7 +2,7 @@ import type { Locator } from '@playwright/test'; ...@@ -2,7 +2,7 @@ import type { Locator } from '@playwright/test';
import React from 'react'; import React from 'react';
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 NetworkLogo from './NetworkLogo'; import NetworkLogo from './NetworkLogo';
...@@ -24,7 +24,7 @@ test.describe('placeholder logo', () => { ...@@ -24,7 +24,7 @@ test.describe('placeholder logo', () => {
}); });
test.describe('screen xl', () => { test.describe('screen xl', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('+@dark-mode', async({ render }) => { test('+@dark-mode', async({ render }) => {
const component = await render(<NetworkLogo/>); const component = await render(<NetworkLogo/>);
...@@ -52,7 +52,7 @@ test.describe('custom logo', () => { ...@@ -52,7 +52,7 @@ test.describe('custom logo', () => {
}); });
test.describe('screen xl', () => { test.describe('screen xl', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('+@dark-mode', async() => { test('+@dark-mode', async() => {
await expect(component.locator('a')).toHaveScreenshot(); await expect(component.locator('a')).toHaveScreenshot();
...@@ -83,7 +83,7 @@ test.describe('custom logo with dark option -@default +@dark-mode', () => { ...@@ -83,7 +83,7 @@ test.describe('custom logo with dark option -@default +@dark-mode', () => {
}); });
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.locator('a')).toHaveScreenshot(); await expect(component.locator('a')).toHaveScreenshot();
......
import { LightMode } from '@chakra-ui/react'; import { LightMode } 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 SearchBarInput from './SearchBarInput'; import SearchBarInput from './SearchBarInput';
...@@ -13,26 +12,18 @@ const props = { ...@@ -13,26 +12,18 @@ const props = {
value: 'duck duck', value: 'duck duck',
}; };
test('input on regular page +@mobile +@dark-mode', async({ mount, page }) => { test('input on regular page +@mobile +@dark-mode', async({ render, page }) => {
await mount( await render(<SearchBarInput { ...props }/>);
<TestApp>
<SearchBarInput { ...props }/>
</TestApp>,
);
const input = page.getByPlaceholder(/search by/i); const input = page.getByPlaceholder(/search by/i);
await expect(input).toHaveScreenshot(); await expect(input).toHaveScreenshot();
}); });
test('input on home page +@mobile +@dark-mode', async({ mount, page }) => { test('input on home page +@mobile +@dark-mode', async({ render, page }) => {
await mount( await render(
<TestApp> <LightMode>
<LightMode> <SearchBarInput { ...props } isHomepage/>
<SearchBarInput { ...props } isHomepage/> </LightMode>,
</LightMode>
</TestApp>,
); );
const input = page.getByPlaceholder(/search by/i); const input = page.getByPlaceholder(/search by/i);
await expect(input).toHaveScreenshot(); await expect(input).toHaveScreenshot();
}); });
import { test as base, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
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 TopBar from './TopBar'; import TopBar from './TopBar';
const test = base.extend({ test.beforeEach(async({ mockEnvs }) => {
context: contextWithEnvs([ await mockEnvs([
{ name: 'NEXT_PUBLIC_SWAP_BUTTON_URL', value: 'uniswap' }, [ 'NEXT_PUBLIC_SWAP_BUTTON_URL', 'uniswap' ],
{ name: 'NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL', value: 'DUCK' }, [ 'NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL', 'DUCK' ],
// eslint-disable-next-line @typescript-eslint/no-explicit-any ]);
]) as any,
}); });
test('default view +@dark-mode +@mobile', async({ mount, page }) => { test('default view +@dark-mode +@mobile', async({ render, mockApiResponse, page }) => {
await page.route(buildApiUrl('stats'), (route) => route.fulfill({ await mockApiResponse('stats', statsMock.base);
status: 200, const component = await render(<TopBar/>);
body: JSON.stringify(statsMock.base),
}));
const component = await mount(
<TestApp>
<TopBar/>
</TestApp>,
);
await component.getByText(/\$1\.39/).click(); await component.getByText(/\$1\.39/).click();
await expect(page.getByText(/last update/i)).toBeVisible(); await expect(page.getByText(/last update/i)).toBeVisible();
...@@ -36,17 +24,8 @@ test('default view +@dark-mode +@mobile', async({ mount, page }) => { ...@@ -36,17 +24,8 @@ test('default view +@dark-mode +@mobile', async({ mount, page }) => {
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1500, height: 400 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 1500, height: 400 } });
}); });
test('with secondary coin price +@mobile', async({ mount, page }) => { test('with secondary coin price +@mobile', async({ render, mockApiResponse }) => {
await page.route(buildApiUrl('stats'), (route) => route.fulfill({ await mockApiResponse('stats', statsMock.withSecondaryCoin);
status: 200, const component = await render(<TopBar/>);
body: JSON.stringify(statsMock.withSecondaryCoin),
}));
const component = await mount(
<TestApp>
<TopBar/>
</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 { tokenHoldersERC20, tokenHoldersERC1155 } from 'mocks/tokens/tokenHolders'; import { tokenHoldersERC20, tokenHoldersERC1155 } from 'mocks/tokens/tokenHolders';
import { tokenInfo, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo'; import { tokenInfo, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo';
import TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import TokenHoldersList from './TokenHoldersList'; import TokenHoldersList from './TokenHoldersList';
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view without IDs', async({ mount }) => { test('base view without IDs', async({ render }) => {
const component = await mount( const component = await render(<TokenHoldersList data={ tokenHoldersERC20.items } token={ tokenInfo }/>);
<TestApp>
<TokenHoldersList data={ tokenHoldersERC20.items } token={ tokenInfo }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('base view with IDs', async({ mount }) => { test('base view with IDs', async({ render }) => {
const component = await mount( const component = await render(<TokenHoldersList data={ tokenHoldersERC1155.items } token={ tokenInfoERC1155a }/>);
<TestApp>
<TokenHoldersList data={ tokenHoldersERC1155.items } token={ tokenInfoERC1155a }/>
</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 { tokenHoldersERC20, tokenHoldersERC1155 } from 'mocks/tokens/tokenHolders'; import { tokenHoldersERC20, tokenHoldersERC1155 } from 'mocks/tokens/tokenHolders';
import { tokenInfo, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo'; import { tokenInfo, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TokenHoldersTable from './TokenHoldersTable'; import TokenHoldersTable from './TokenHoldersTable';
test('base view without IDs', async({ mount }) => { test('base view without IDs', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt="128px">
<Box h="128px"/>
<TokenHoldersTable data={ tokenHoldersERC20.items } token={ tokenInfo } top={ 76 }/> <TokenHoldersTable data={ tokenHoldersERC20.items } token={ tokenInfo } top={ 76 }/>
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('base view with IDs', async({ mount }) => { test('base view with IDs', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt="128px">
<Box h="128px"/>
<TokenHoldersTable data={ tokenHoldersERC1155.items } token={ tokenInfoERC1155a } top={ 76 }/> <TokenHoldersTable data={ tokenHoldersERC1155.items } token={ tokenInfoERC1155a } top={ 76 }/>
</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 { tokenInfoERC721a } from 'mocks/tokens/tokenInfo'; import { tokenInfoERC721a } from 'mocks/tokens/tokenInfo';
import { base as tokenInstanse } from 'mocks/tokens/tokenInstance'; import { base as tokenInstanse } from 'mocks/tokens/tokenInstance';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TokenInventory from './TokenInventory'; import TokenInventory from './TokenInventory';
test('base view +@mobile', async({ mount }) => { test('base view +@mobile', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: 0 }}>
<Box h={{ base: '134px', lg: 0 }}/>
<TokenInventory <TokenInventory
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: // @ts-ignore:
...@@ -30,7 +28,7 @@ test('base view +@mobile', async({ mount }) => { ...@@ -30,7 +28,7 @@ test('base view +@mobile', async({ mount }) => {
data: tokenInfoERC721a, data: tokenInfoERC721a,
}} }}
/> />
</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 TokenTransfer from './TokenTransfer'; import TokenTransfer from './TokenTransfer';
test('erc20 +@mobile', async({ mount }) => { test('erc20 +@mobile', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: '100px' }}>
<Box h={{ base: '134px', lg: '100px' }}/>
<TokenTransfer <TokenTransfer
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: // @ts-ignore:
...@@ -24,16 +22,15 @@ test('erc20 +@mobile', async({ mount }) => { ...@@ -24,16 +22,15 @@ test('erc20 +@mobile', async({ mount }) => {
pagination: { page: 1, isVisible: true }, pagination: { page: 1, isVisible: true },
}} }}
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('erc721 +@mobile', async({ mount }) => { test('erc721 +@mobile', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: '100px' }}>
<Box h={{ base: '134px', lg: '100px' }}/>
<TokenTransfer <TokenTransfer
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: // @ts-ignore:
...@@ -47,16 +44,15 @@ test('erc721 +@mobile', async({ mount }) => { ...@@ -47,16 +44,15 @@ test('erc721 +@mobile', async({ mount }) => {
pagination: { page: 1, isVisible: true }, pagination: { page: 1, isVisible: true },
}} }}
/> />
</TestApp>, </Box>,
); );
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('erc1155 +@mobile', async({ mount }) => { test('erc1155 +@mobile', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <Box pt={{ base: '134px', lg: '100px' }}>
<Box h={{ base: '134px', lg: '100px' }}/>
<TokenTransfer <TokenTransfer
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: // @ts-ignore:
...@@ -75,7 +71,7 @@ test('erc1155 +@mobile', async({ mount }) => { ...@@ -75,7 +71,7 @@ test('erc1155 +@mobile', async({ mount }) => {
pagination: { page: 1, isVisible: true }, pagination: { page: 1, isVisible: 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 * 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 TokenInfoForm from './TokenInfoForm'; import TokenInfoForm from './TokenInfoForm';
const FORM_CONFIG_URL = buildApiUrl('token_info_applications_config', { chainId: '1' }); test.beforeEach(async({ mockApiResponse, mockAssetResponse }) => {
await mockApiResponse('token_info_applications_config', mocks.TOKEN_INFO_FORM_CONFIG, { pathParams: { chainId: '1' } });
test('base view +@mobile +@dark-mode', async({ mount, page }) => { await mockAssetResponse(mocks.TOKEN_INFO_APPLICATION_BASE.iconUrl, './playwright/mocks/image_md.jpg');
await page.route(mocks.TOKEN_INFO_APPLICATION_BASE.iconUrl, (route) => { });
return route.fulfill({
status: 200,
path: './playwright/mocks/image_md.jpg',
});
});
await page.route(FORM_CONFIG_URL, (route) => route.fulfill({
body: JSON.stringify(mocks.TOKEN_INFO_FORM_CONFIG),
}));
test('base view +@mobile +@dark-mode', async({ render }) => {
const props = { const props = {
address: mocks.VERIFIED_ADDRESS.ITEM_1.contractAddress, address: mocks.VERIFIED_ADDRESS.ITEM_1.contractAddress,
tokenName: 'Test Token (TT)', tokenName: 'Test Token (TT)',
application: mocks.TOKEN_INFO_APPLICATION.APPROVED, application: mocks.TOKEN_INFO_APPLICATION.APPROVED,
onSubmit: () => {}, onSubmit: () => {},
}; };
const component = await render(<TokenInfoForm { ...props }/>);
const component = await mount(
<TestApp>
<TokenInfoForm { ...props }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('status IN_PROCESS', async({ mount, page }) => { test('status IN_PROCESS', async({ render }) => {
await page.route(mocks.TOKEN_INFO_APPLICATION_BASE.iconUrl, (route) => {
return route.fulfill({
status: 200,
path: './playwright/mocks/image_md.jpg',
});
});
await page.route(FORM_CONFIG_URL, (route) => route.fulfill({
body: JSON.stringify(mocks.TOKEN_INFO_FORM_CONFIG),
}));
const props = { const props = {
address: mocks.VERIFIED_ADDRESS.ITEM_1.contractAddress, address: mocks.VERIFIED_ADDRESS.ITEM_1.contractAddress,
tokenName: 'Test Token (TT)', tokenName: 'Test Token (TT)',
application: mocks.TOKEN_INFO_APPLICATION.IN_PROCESS, application: mocks.TOKEN_INFO_APPLICATION.IN_PROCESS,
onSubmit: () => {}, onSubmit: () => {},
}; };
const component = await render(<TokenInfoForm { ...props }/>);
const component = await mount(
<TestApp>
<TokenInfoForm { ...props }/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
...@@ -9,8 +9,7 @@ import { tokenInfoERC721a } from 'mocks/tokens/tokenInfo'; ...@@ -9,8 +9,7 @@ import { tokenInfoERC721a } from 'mocks/tokens/tokenInfo';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance'; import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; import { ENVS_MAP } from 'playwright/fixtures/mockEnvs';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import TestApp from 'playwright/TestApp'; import * as pwConfig from 'playwright/utils/config';
import * as configs from 'playwright/utils/configs';
import TokenInstanceDetails from './TokenInstanceDetails'; import TokenInstanceDetails from './TokenInstanceDetails';
...@@ -42,15 +41,10 @@ test.beforeEach(async({ mockApiResponse, mockAssetResponse }) => { ...@@ -42,15 +41,10 @@ test.beforeEach(async({ mockApiResponse, mockAssetResponse }) => {
}); });
test('base view +@dark-mode +@mobile', async({ render, page }) => { test('base view +@dark-mode +@mobile', async({ render, page }) => {
const component = await render( const component = await render(<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>);
<TestApp>
<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>
</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,
}); });
}); });
...@@ -63,30 +57,19 @@ test.describe('action button', () => { ...@@ -63,30 +57,19 @@ test.describe('action button', () => {
}); });
test('base view +@dark-mode +@mobile', async({ render, page }) => { test('base view +@dark-mode +@mobile', async({ render, page }) => {
const component = await render( const component = await render(<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>);
<TestApp>
<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>
</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,
}); });
}); });
test('without marketplaces +@dark-mode +@mobile', async({ render, page, mockEnvs }) => { test('without marketplaces +@dark-mode +@mobile', async({ render, page, mockEnvs }) => {
mockEnvs(ENVS_MAP.noNftMarketplaces); mockEnvs(ENVS_MAP.noNftMarketplaces);
const component = await render(<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>);
const component = await render(
<TestApp>
<TokenInstanceDetails data={ tokenInstanceMock.unique } token={ tokenInfoERC721a }/>
</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, expect } from '@playwright/experimental-ct-react';
import React from 'react'; import React from 'react';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance'; import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TokenInstanceMetadata from './TokenInstanceMetadata'; import TokenInstanceMetadata from './TokenInstanceMetadata';
test('base view +@mobile', async({ mount }) => { test('base view +@mobile', async({ render }) => {
const component = await mount( const component = await render(<TokenInstanceMetadata data={ tokenInstanceMock.withRichMetadata.metadata }/>);
<TestApp>
<TokenInstanceMetadata data={ tokenInstanceMock.withRichMetadata.metadata }/>
</TestApp>,
);
await component.getByRole('button', { name: /png/i }).click(); await component.getByRole('button', { name: /png/i }).click();
await component.getByRole('button', { name: /primary/i }).click(); await component.getByRole('button', { name: /primary/i }).click();
...@@ -26,14 +21,8 @@ test('base view +@mobile', async({ mount }) => { ...@@ -26,14 +21,8 @@ test('base view +@mobile', async({ mount }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('raw view', async({ mount }) => { test('raw view', async({ render }) => {
const component = await mount( const component = await render(<TokenInstanceMetadata data={ tokenInstanceMock.withRichMetadata.metadata }/>);
<TestApp>
<TokenInstanceMetadata data={ tokenInstanceMock.withRichMetadata.metadata }/>
</TestApp>,
);
await component.locator('select').selectOption('JSON'); await component.locator('select').selectOption('JSON');
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 blobsMock from 'mocks/blobs/blobs'; import * as blobsMock from 'mocks/blobs/blobs';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import TxBlobs from './TxBlobs'; import TxBlobs from './TxBlobs';
import type { TxQuery } from './useTxQuery'; import type { TxQuery } from './useTxQuery';
const TX_BLOBS_API_URL = buildApiUrl('tx_blobs', { hash: txMock.base.hash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: txMock.base.hash }, query: { hash: txMock.base.hash },
}, },
}; };
test('base view +@mobile', async({ mount, page }) => { test('base view +@mobile', async({ render, mockApiResponse }) => {
await page.route(TX_BLOBS_API_URL, (route) => route.fulfill({ await mockApiResponse('tx_blobs', blobsMock.txBlobs, { pathParams: { hash: txMock.base.hash } });
status: 200,
body: JSON.stringify(blobsMock.txBlobs),
}));
const txQuery = { const txQuery = {
data: txMock.base, data: txMock.base,
isPlaceholderData: false, isPlaceholderData: false,
isError: false, isError: false,
} as TxQuery; } as TxQuery;
const component = await render(<TxBlobs txQuery={ txQuery }/>, { hooksConfig });
const component = await mount(
<TestApp>
<TxBlobs txQuery={ txQuery }/>
</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 * as internalTxsMock from 'mocks/txs/internalTxs'; import * as internalTxsMock from 'mocks/txs/internalTxs';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import TxInternals from './TxInternals'; import TxInternals from './TxInternals';
import type { TxQuery } from './useTxQuery'; import type { TxQuery } from './useTxQuery';
const TX_HASH = txMock.base.hash; const TX_HASH = txMock.base.hash;
const API_URL_TX_INTERNALS = buildApiUrl('tx_internal_txs', { hash: TX_HASH });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: TX_HASH }, query: { hash: TX_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('tx_internal_txs', internalTxsMock.baseResponse, { pathParams: { hash: TX_HASH } });
status: 200,
body: JSON.stringify(internalTxsMock.baseResponse),
}));
const txQuery = { const txQuery = {
data: txMock.base, data: txMock.base,
isPlaceholderData: false, isPlaceholderData: false,
isError: false, isError: false,
} as TxQuery; } as TxQuery;
const component = await render(<TxInternals txQuery={ txQuery }/>, { hooksConfig });
const component = await mount(
<TestApp>
<TxInternals txQuery={ txQuery }/>
</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 * as txStateMock from 'mocks/txs/state'; import * as txStateMock from 'mocks/txs/state';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import TxState from './TxState'; import TxState from './TxState';
import type { TxQuery } from './useTxQuery'; import type { TxQuery } from './useTxQuery';
const TX_STATE_API_URL = buildApiUrl('tx_state_changes', { hash: txMock.base.hash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: txMock.base.hash }, query: { hash: txMock.base.hash },
}, },
}; };
test('base view +@mobile', async({ mount, page }) => { test('base view +@mobile', async({ render, mockApiResponse }) => {
await page.route(TX_STATE_API_URL, (route) => route.fulfill({ await mockApiResponse('tx_state_changes', txStateMock.baseResponse, { pathParams: { hash: txMock.base.hash } });
status: 200,
body: JSON.stringify(txStateMock.baseResponse),
}));
const txQuery = { const txQuery = {
data: txMock.base, data: txMock.base,
isPlaceholderData: false, isPlaceholderData: false,
isError: false, isError: false,
} as TxQuery; } as TxQuery;
const component = await render(<TxState txQuery={ txQuery }/>, { hooksConfig });
const component = await mount(
<TestApp>
<TxState txQuery={ txQuery }/>
</TestApp>,
{ hooksConfig },
);
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 txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; import { ENVS_MAP } from 'playwright/fixtures/mockEnvs';
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 TxInfo from './TxInfo'; import TxInfo from './TxInfo';
...@@ -13,8 +13,8 @@ test('between addresses +@mobile +@dark-mode', async({ render, page }) => { ...@@ -13,8 +13,8 @@ test('between addresses +@mobile +@dark-mode', async({ render, page }) => {
await page.getByText('View details').click(); await page.getByText('View details').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,
}); });
}); });
...@@ -22,8 +22,8 @@ test('creating contact', async({ render, page }) => { ...@@ -22,8 +22,8 @@ test('creating contact', async({ render, page }) => {
const component = await render(<TxInfo data={ txMock.withContractCreation } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withContractCreation } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -31,8 +31,8 @@ test('with token transfer +@mobile', async({ render, page }) => { ...@@ -31,8 +31,8 @@ test('with token transfer +@mobile', async({ render, page }) => {
const component = await render(<TxInfo data={ txMock.withTokenTransfer } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withTokenTransfer } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -40,8 +40,8 @@ test('with decoded revert reason', async({ render, page }) => { ...@@ -40,8 +40,8 @@ test('with decoded revert reason', async({ render, page }) => {
const component = await render(<TxInfo data={ txMock.withDecodedRevertReason } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withDecodedRevertReason } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -49,8 +49,8 @@ test('with decoded raw reason', async({ render, page }) => { ...@@ -49,8 +49,8 @@ test('with decoded raw reason', async({ render, page }) => {
const component = await render(<TxInfo data={ txMock.withRawRevertReason } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withRawRevertReason } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -60,8 +60,8 @@ test('pending', async({ render, page }) => { ...@@ -60,8 +60,8 @@ test('pending', async({ render, page }) => {
await page.getByText('View details').click(); await page.getByText('View details').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,
}); });
}); });
...@@ -69,8 +69,8 @@ test('with actions uniswap +@mobile +@dark-mode', async({ render, page }) => { ...@@ -69,8 +69,8 @@ test('with actions uniswap +@mobile +@dark-mode', async({ render, page }) => {
const component = await render(<TxInfo data={ txMock.withActionsUniswap } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withActionsUniswap } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -80,8 +80,8 @@ test('with blob', async({ render, page }) => { ...@@ -80,8 +80,8 @@ test('with blob', async({ render, page }) => {
await page.getByText('View details').click(); await page.getByText('View details').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,
}); });
}); });
...@@ -89,8 +89,8 @@ test('l2', async({ render, page, mockEnvs }) => { ...@@ -89,8 +89,8 @@ test('l2', async({ render, page, mockEnvs }) => {
await mockEnvs(ENVS_MAP.optimisticRollup); await mockEnvs(ENVS_MAP.optimisticRollup);
const component = await render(<TxInfo data={ txMock.l2tx } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.l2tx } isLoading={ false }/>);
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('without testnet warning', async({ render, page, mockEnvs }) => { ...@@ -101,8 +101,8 @@ test('without testnet warning', async({ render, page, mockEnvs }) => {
const component = await render(<TxInfo data={ txMock.l2tx } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.l2tx } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
mask: [ page.locator(configs.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: configs.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
...@@ -111,7 +111,7 @@ test('stability customization', async({ render, page, mockEnvs }) => { ...@@ -111,7 +111,7 @@ test('stability customization', async({ render, page, mockEnvs }) => {
const component = await render(<TxInfo data={ txMock.stabilityTx } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.stabilityTx } isLoading={ false }/>);
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 txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import TxAdditionalInfo from './TxAdditionalInfo'; import TxAdditionalInfo from './TxAdditionalInfo';
test('regular transaction +@dark-mode', async({ mount, page }) => { test('regular transaction +@dark-mode', async({ render, page }) => {
const component = await mount( const component = await render(<TxAdditionalInfo tx={ txMock.base }/>);
<TestApp>
<TxAdditionalInfo tx={ txMock.base }/>
</TestApp>,
);
await component.getByLabel('Transaction info').click(); await component.getByLabel('Transaction info').click();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 600 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 600 } });
}); });
test('regular transaction +@mobile -@default', async({ mount, page }) => { test('regular transaction +@mobile -@default', async({ render, page }) => {
const component = await mount( const component = await render(<TxAdditionalInfo tx={ txMock.base } isMobile/>);
<TestApp>
<TxAdditionalInfo tx={ txMock.base } isMobile/>
</TestApp>,
);
await component.getByLabel('Transaction info').click(); await component.getByLabel('Transaction info').click();
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
test('blob transaction', async({ mount, page }) => { test('blob transaction', async({ render, page }) => {
const component = await mount( const component = await render(<TxAdditionalInfo tx={ txMock.withBlob }/>);
<TestApp>
<TxAdditionalInfo tx={ txMock.withBlob }/>
</TestApp>,
);
await component.getByLabel('Transaction info').click(); await component.getByLabel('Transaction info').click();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 600 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 600 } });
}); });
import { test, 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 TestApp from 'playwright/TestApp'; import { test, expect, devices } from 'playwright/lib';
import TxsListItem from './TxsListItem'; import TxsListItem from './TxsListItem';
test.use({ viewport: devices['iPhone 13 Pro'].viewport }); test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view +@dark-mode', async({ mount }) => { test('base view +@dark-mode', async({ render }) => {
const component = await mount( const component = await render(<TxsListItem tx={ txMock.withWatchListNames } showBlockInfo/>);
<TestApp>
<TxsListItem tx={ txMock.withWatchListNames } showBlockInfo/>
</TestApp>,
);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with base address', async({ mount }) => { test('with base address', async({ render }) => {
const component = await mount( const component = await render(<TxsListItem tx={ txMock.withWatchListNames } showBlockInfo currentAddress={ txMock.base.from.hash }/>);
<TestApp>
<TxsListItem tx={ txMock.withWatchListNames } showBlockInfo currentAddress={ txMock.base.from.hash }/>
</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 statsMock from 'mocks/stats'; import * as statsMock from 'mocks/stats';
import * as txsStatsMock from 'mocks/txs/stats'; import * as txsStatsMock from 'mocks/txs/stats';
import TestApp from 'playwright/TestApp'; import { test, expect } from 'playwright/lib';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import TxsStats from './TxsStats'; import TxsStats from './TxsStats';
const TXS_STATS_API_URL = buildApiUrl('txs_stats'); test('base view +@mobile', async({ render, mockApiResponse }) => {
const STATS_API_URL = buildApiUrl('stats'); await mockApiResponse('stats', statsMock.base);
await mockApiResponse('txs_stats', txsStatsMock.base);
test('base view +@mobile', async({ mount, page }) => { const component = await render(<TxsStats/>);
await page.route(STATS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(statsMock.base),
}));
await page.route(TXS_STATS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(txsStatsMock.base),
}));
const component = await mount(
<TestApp>
<TxsStats/>
</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 txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
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 TxsTable from './TxsTable'; import TxsTable from './TxsTable';
test.describe('base view', () => { test.describe('base view', () => {
test('+@dark-mode', async({ mount }) => { test('+@dark-mode', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <TxsTable
{ /* eslint-disable-next-line react/jsx-no-bind */ } txs={ [ txMock.base, txMock.withWatchListNames ] }
<TxsTable txs={ [ txMock.base, txMock.withWatchListNames ] } sort={ () => () => {} } top={ 0 } showBlockInfo showSocketInfo={ false }/> // eslint-disable-next-line react/jsx-no-bind
</TestApp>, sort={ () => () => {} }
top={ 0 }
showBlockInfo
showSocketInfo={ false }
/>,
); );
await component.getByText('kitty').first().hover(); await component.getByText('kitty').first().hover();
...@@ -23,14 +26,18 @@ test.describe('base view', () => { ...@@ -23,14 +26,18 @@ test.describe('base view', () => {
}); });
test.describe('screen xl', () => { test.describe('screen xl', () => {
test.use({ viewport: configs.viewport.xl }); test.use({ viewport: pwConfig.viewport.xl });
test('', async({ mount }) => { test('', async({ render }) => {
const component = await mount( const component = await render(
<TestApp> <TxsTable
{ /* eslint-disable-next-line react/jsx-no-bind */ } txs={ [ txMock.base, txMock.withWatchListNames ] }
<TxsTable txs={ [ txMock.base, txMock.withWatchListNames ] } sort={ () => () => {} } top={ 0 } showBlockInfo showSocketInfo={ false }/> // eslint-disable-next-line react/jsx-no-bind
</TestApp>, sort={ () => () => {} }
top={ 0 }
showBlockInfo
showSocketInfo={ false }
/>,
); );
await component.getByText('kitty').first().hover(); await component.getByText('kitty').first().hover();
......
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