diff --git a/playwright/TestApp.tsx b/playwright/TestApp.tsx index 51c03e1c14..d8ef52ca2c 100644 --- a/playwright/TestApp.tsx +++ b/playwright/TestApp.tsx @@ -2,14 +2,16 @@ import { ChakraProvider } from '@chakra-ui/react'; import { GrowthBookProvider } from '@growthbook/growthbook-react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import React from 'react'; -import { WagmiProvider } from 'wagmi'; +import { http } from 'viem'; +import { WagmiProvider, createConfig } from 'wagmi'; +import { sepolia } from 'wagmi/chains'; +import { mock } from 'wagmi/connectors'; import type { Props as PageProps } from 'nextjs/getServerSideProps'; import config from 'configs/app'; import { AppContextProvider } from 'lib/contexts/app'; import { SocketProvider } from 'lib/socket/context'; -import wagmiConfig from 'lib/web3/wagmiConfig'; import * as app from 'playwright/utils/app'; import theme from 'theme'; @@ -31,6 +33,20 @@ const defaultAppContext = { }, }; +const wagmiConfig = createConfig({ + chains: [ sepolia ], + connectors: [ + mock({ + accounts: [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + ], + }), + ], + transports: { + [sepolia.id]: http(), + }, +}); + const TestApp = ({ children, withSocket, appContext = defaultAppContext }: Props) => { const [ queryClient ] = React.useState(() => new QueryClient({ defaultOptions: { @@ -47,7 +63,7 @@ const TestApp = ({ children, withSocket, appContext = defaultAppContext }: Props - + { children } diff --git a/playwright/fixtures/mockEnvs.ts b/playwright/fixtures/mockEnvs.ts index ce18100857..69353ead37 100644 --- a/playwright/fixtures/mockEnvs.ts +++ b/playwright/fixtures/mockEnvs.ts @@ -34,4 +34,7 @@ export const ENVS_MAP: Record> = { hasContractAuditReports: [ [ 'NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS', 'true' ], ], + blockHiddenFields: [ + [ 'NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS', '["burnt_fees", "total_reward", "nonce"]' ], + ], }; diff --git a/playwright/fixtures/mockTextAd.ts b/playwright/fixtures/mockTextAd.ts new file mode 100644 index 0000000000..5ad764fe60 --- /dev/null +++ b/playwright/fixtures/mockTextAd.ts @@ -0,0 +1,23 @@ +import type { TestFixture, Page } from '@playwright/test'; + +import * as textAdMock from 'mocks/ad/textAd'; + +export type MockTextAdFixture = () => Promise; + +const fixture: TestFixture = async({ page }, use) => { + await use(async() => { + + 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', + }); + }); + }); +}; + +export default fixture; diff --git a/playwright/lib.tsx b/playwright/lib.tsx index 40a4bc4ea3..7313a5a980 100644 --- a/playwright/lib.tsx +++ b/playwright/lib.tsx @@ -1,14 +1,13 @@ /* eslint-disable no-console */ import { test as base } from '@playwright/experimental-ct-react'; -import * as textAdMock from 'mocks/ad/textAd'; - import * as injectMetaMaskProvider from './fixtures/injectMetaMaskProvider'; import * as mockApiResponse from './fixtures/mockApiResponse'; import * as mockAssetResponse from './fixtures/mockAssetResponse'; import * as mockConfigResponse from './fixtures/mockConfigResponse'; import * as mockEnvs from './fixtures/mockEnvs'; import * as mockFeatures from './fixtures/mockFeatures'; +import * as mockTextAd from './fixtures/mockTextAd'; import * as render from './fixtures/render'; import * as socketServer from './fixtures/socketServer'; @@ -21,6 +20,7 @@ interface Fixtures { mockFeatures: mockFeatures.MockFeaturesFixture; createSocket: socketServer.CreateSocketFixture; injectMetaMaskProvider: injectMetaMaskProvider.InjectMetaMaskProvider; + mockTextAd: mockTextAd.MockTextAdFixture; } const test = base.extend({ @@ -30,11 +30,15 @@ const test = base.extend({ mockConfigResponse: mockConfigResponse.default, mockEnvs: mockEnvs.default, mockFeatures: mockFeatures.default, + // FIXME: for some reason Playwright does not intercept requests to text ad provider when running multiple tests in parallel + // even if we have a global request interceptor (maybe it is related to service worker issue, maybe not) + // so we have to inject mockTextAd fixture in each test and mock the response where it is needed + mockTextAd: mockTextAd.default, createSocket: socketServer.createSocket, injectMetaMaskProvider: injectMetaMaskProvider.default, }); -test.beforeEach(async({ page }) => { +test.beforeEach(async({ page, mockTextAd }) => { // debug const isDebug = process.env.PWDEBUG === '1'; @@ -56,16 +60,7 @@ test.beforeEach(async({ page }) => { // with few exceptions: // 1. mock text AD requests - 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', - }); - }); + await mockTextAd(); }); export * from '@playwright/experimental-ct-react'; diff --git a/ui/pages/Blocks.pw.tsx b/ui/pages/Blocks.pw.tsx index 95e0bc452a..07395a1656 100644 --- a/ui/pages/Blocks.pw.tsx +++ b/ui/pages/Blocks.pw.tsx @@ -4,6 +4,7 @@ import React from 'react'; import * as blockMock from 'mocks/blocks/block'; import * as statsMock from 'mocks/stats/index'; import contextWithEnvs from 'playwright/fixtures/contextWithEnvs'; +import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; import * as socketServer from 'playwright/fixtures/socketServer'; import { test, expect, devices } from 'playwright/lib'; import * as configs from 'playwright/utils/configs'; @@ -21,6 +22,10 @@ const hooksConfig = { // 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.beforeEach(async({ mockTextAd }) => { + await mockTextAd(); +}); + test('base view +@dark-mode', async({ render, mockApiResponse }) => { await mockApiResponse('blocks', blockMock.baseListResponse, { queryParams: { type: 'block' } }); await mockApiResponse('stats', statsMock.base); @@ -30,11 +35,8 @@ test('base view +@dark-mode', async({ render, mockApiResponse }) => { await expect(component).toHaveScreenshot(); }); -const hiddenFieldsTest = test.extend<{ context: BrowserContext }>({ - context: contextWithEnvs(configs.viewsEnvs.block.hiddenFields), -}); - -hiddenFieldsTest('hidden fields', async({ render, mockApiResponse }) => { +test('hidden fields', async({ render, mockApiResponse, mockEnvs }) => { + await mockEnvs(ENVS_MAP.blockHiddenFields); await mockApiResponse('blocks', blockMock.baseListResponse, { queryParams: { type: 'block' } }); await mockApiResponse('stats', statsMock.base); diff --git a/ui/pages/ShibariumDeposits.pw.tsx b/ui/pages/ShibariumDeposits.pw.tsx index d4b532aac4..a52dfb557e 100644 --- a/ui/pages/ShibariumDeposits.pw.tsx +++ b/ui/pages/ShibariumDeposits.pw.tsx @@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib'; import ShibariumDeposits from './ShibariumDeposits'; -test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => { +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { + await mockTextAd(); await mockEnvs(ENVS_MAP.shibariumRollup); await mockApiResponse('shibarium_deposits', depositsData); await mockApiResponse('shibarium_deposits_count', 3971111); diff --git a/ui/pages/ShibariumWithdrawals.pw.tsx b/ui/pages/ShibariumWithdrawals.pw.tsx index ff7ecb24d1..9310892bd8 100644 --- a/ui/pages/ShibariumWithdrawals.pw.tsx +++ b/ui/pages/ShibariumWithdrawals.pw.tsx @@ -6,12 +6,13 @@ import { test, expect } from 'playwright/lib'; import ShibariumWithdrawals from './ShibariumWithdrawals'; -test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => { +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { // test on mobile is flaky // my assumption is there is not enough time to calculate hashes truncation so component is unstable // so I raised the test timeout to check if it helps test.slow(); + await mockTextAd(); await mockEnvs(ENVS_MAP.shibariumRollup); await mockApiResponse('shibarium_withdrawals', withdrawalsData); await mockApiResponse('shibarium_withdrawals_count', 397); diff --git a/ui/pages/Token.pw.tsx b/ui/pages/Token.pw.tsx index 2720da63ef..676f606133 100644 --- a/ui/pages/Token.pw.tsx +++ b/ui/pages/Token.pw.tsx @@ -25,11 +25,12 @@ const hooksConfig = { // 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.beforeEach(async({ mockApiResponse }) => { +test.beforeEach(async({ mockApiResponse, mockTextAd }) => { await mockApiResponse('token', tokenInfo, { pathParams: { hash } }); await mockApiResponse('address', contract, { pathParams: { hash } }); await mockApiResponse('token_counters', tokenCounters, { pathParams: { hash } }); await mockApiResponse('token_transfers', { items: [], next_page_params: null }, { pathParams: { hash } }); + await mockTextAd(); }); test('base view', async({ render, page, createSocket }) => { diff --git a/ui/pages/Tokens.pw.tsx b/ui/pages/Tokens.pw.tsx index 149571d2ab..22f62bd3bb 100644 --- a/ui/pages/Tokens.pw.tsx +++ b/ui/pages/Tokens.pw.tsx @@ -7,6 +7,10 @@ import { test, expect } from 'playwright/lib'; import Tokens from './Tokens'; +test.beforeEach(async({ mockTextAd }) => { + await mockTextAd(); +}); + test('base view +@mobile +@dark-mode', async({ render, mockApiResponse }) => { const allTokens = { items: [ diff --git a/ui/pages/Validators.pw.tsx b/ui/pages/Validators.pw.tsx index d492f8d457..605328b313 100644 --- a/ui/pages/Validators.pw.tsx +++ b/ui/pages/Validators.pw.tsx @@ -7,12 +7,13 @@ import Validators from './Validators'; const chainType = 'stability'; -test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => { +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { await mockEnvs([ [ 'NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE', chainType ], ]); await mockApiResponse('validators', validatorsMock.validatorsResponse, { pathParams: { chainType } }); await mockApiResponse('validators_counters', validatorsMock.validatorsCountersResponse, { pathParams: { chainType } }); + await mockTextAd(); const component = await render(); diff --git a/ui/pages/ZkEvmL2Deposits.pw.tsx b/ui/pages/ZkEvmL2Deposits.pw.tsx index fca3893dfb..b1ae7c8f93 100644 --- a/ui/pages/ZkEvmL2Deposits.pw.tsx +++ b/ui/pages/ZkEvmL2Deposits.pw.tsx @@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib'; import ZkEvmL2Deposits from './ZkEvmL2Deposits'; -test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => { +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { + await mockTextAd(); await mockEnvs(ENVS_MAP.zkEvmRollup); await mockApiResponse('zkevm_l2_deposits', depositsMock.baseResponse); await mockApiResponse('zkevm_l2_deposits_count', 3971111); diff --git a/ui/pages/ZkEvmL2Withdrawals.pw.tsx b/ui/pages/ZkEvmL2Withdrawals.pw.tsx index 0327d33c87..92a9fbf88a 100644 --- a/ui/pages/ZkEvmL2Withdrawals.pw.tsx +++ b/ui/pages/ZkEvmL2Withdrawals.pw.tsx @@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib'; import ZkEvmL2Withdrawals from './ZkEvmL2Withdrawals'; -test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => { +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { + await mockTextAd(); await mockEnvs(ENVS_MAP.zkEvmRollup); await mockApiResponse('zkevm_l2_withdrawals', withdrawalsMock.baseResponse); await mockApiResponse('zkevm_l2_withdrawals_count', 3971111); diff --git a/ui/snippets/searchBar/SearchBar.pw.tsx b/ui/snippets/searchBar/SearchBar.pw.tsx index 6ae9cbe3a8..895b948153 100644 --- a/ui/snippets/searchBar/SearchBar.pw.tsx +++ b/ui/snippets/searchBar/SearchBar.pw.tsx @@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib'; import SearchBar from './SearchBar'; -test.beforeEach(async({ mockAssetResponse, mockEnvs }) => { +test.beforeEach(async({ mockAssetResponse, mockEnvs, mockTextAd }) => { + await mockTextAd(); await mockAssetResponse(searchMock.token1.icon_url as string, './playwright/mocks/image_s.jpg'); await mockEnvs([ [ 'NEXT_PUBLIC_MARKETPLACE_ENABLED', 'false' ],