Skip to content

Commit fdc8b80

Browse files
authored
fix flaky tests (blockscout#1871)
* try to fix flaky tests * wagmi test config * update zk evm test
1 parent 232e179 commit fdc8b80

13 files changed

+78
-28
lines changed

playwright/TestApp.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { ChakraProvider } from '@chakra-ui/react';
22
import { GrowthBookProvider } from '@growthbook/growthbook-react';
33
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
44
import React from 'react';
5-
import { WagmiProvider } from 'wagmi';
5+
import { http } from 'viem';
6+
import { WagmiProvider, createConfig } from 'wagmi';
7+
import { sepolia } from 'wagmi/chains';
8+
import { mock } from 'wagmi/connectors';
69

710
import type { Props as PageProps } from 'nextjs/getServerSideProps';
811

912
import config from 'configs/app';
1013
import { AppContextProvider } from 'lib/contexts/app';
1114
import { SocketProvider } from 'lib/socket/context';
12-
import wagmiConfig from 'lib/web3/wagmiConfig';
1315
import * as app from 'playwright/utils/app';
1416
import theme from 'theme';
1517

@@ -31,6 +33,20 @@ const defaultAppContext = {
3133
},
3234
};
3335

36+
const wagmiConfig = createConfig({
37+
chains: [ sepolia ],
38+
connectors: [
39+
mock({
40+
accounts: [
41+
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
42+
],
43+
}),
44+
],
45+
transports: {
46+
[sepolia.id]: http(),
47+
},
48+
});
49+
3450
const TestApp = ({ children, withSocket, appContext = defaultAppContext }: Props) => {
3551
const [ queryClient ] = React.useState(() => new QueryClient({
3652
defaultOptions: {
@@ -47,7 +63,7 @@ const TestApp = ({ children, withSocket, appContext = defaultAppContext }: Props
4763
<SocketProvider url={ withSocket ? `ws://${ config.app.host }:${ app.socketPort }` : undefined }>
4864
<AppContextProvider { ...appContext }>
4965
<GrowthBookProvider>
50-
<WagmiProvider config={ wagmiConfig! }>
66+
<WagmiProvider config={ wagmiConfig }>
5167
{ children }
5268
</WagmiProvider>
5369
</GrowthBookProvider>

playwright/fixtures/mockEnvs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
3434
hasContractAuditReports: [
3535
[ 'NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS', 'true' ],
3636
],
37+
blockHiddenFields: [
38+
[ 'NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS', '["burnt_fees", "total_reward", "nonce"]' ],
39+
],
3740
};

playwright/fixtures/mockTextAd.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { TestFixture, Page } from '@playwright/test';
2+
3+
import * as textAdMock from 'mocks/ad/textAd';
4+
5+
export type MockTextAdFixture = () => Promise<void>;
6+
7+
const fixture: TestFixture<MockTextAdFixture, { page: Page }> = async({ page }, use) => {
8+
await use(async() => {
9+
10+
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
11+
status: 200,
12+
body: JSON.stringify(textAdMock.duck),
13+
}));
14+
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
15+
return route.fulfill({
16+
status: 200,
17+
path: './playwright/mocks/image_s.jpg',
18+
});
19+
});
20+
});
21+
};
22+
23+
export default fixture;

playwright/lib.tsx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
/* eslint-disable no-console */
22
import { test as base } from '@playwright/experimental-ct-react';
33

4-
import * as textAdMock from 'mocks/ad/textAd';
5-
64
import * as injectMetaMaskProvider from './fixtures/injectMetaMaskProvider';
75
import * as mockApiResponse from './fixtures/mockApiResponse';
86
import * as mockAssetResponse from './fixtures/mockAssetResponse';
97
import * as mockConfigResponse from './fixtures/mockConfigResponse';
108
import * as mockEnvs from './fixtures/mockEnvs';
119
import * as mockFeatures from './fixtures/mockFeatures';
10+
import * as mockTextAd from './fixtures/mockTextAd';
1211
import * as render from './fixtures/render';
1312
import * as socketServer from './fixtures/socketServer';
1413

@@ -21,6 +20,7 @@ interface Fixtures {
2120
mockFeatures: mockFeatures.MockFeaturesFixture;
2221
createSocket: socketServer.CreateSocketFixture;
2322
injectMetaMaskProvider: injectMetaMaskProvider.InjectMetaMaskProvider;
23+
mockTextAd: mockTextAd.MockTextAdFixture;
2424
}
2525

2626
const test = base.extend<Fixtures>({
@@ -30,11 +30,15 @@ const test = base.extend<Fixtures>({
3030
mockConfigResponse: mockConfigResponse.default,
3131
mockEnvs: mockEnvs.default,
3232
mockFeatures: mockFeatures.default,
33+
// FIXME: for some reason Playwright does not intercept requests to text ad provider when running multiple tests in parallel
34+
// even if we have a global request interceptor (maybe it is related to service worker issue, maybe not)
35+
// so we have to inject mockTextAd fixture in each test and mock the response where it is needed
36+
mockTextAd: mockTextAd.default,
3337
createSocket: socketServer.createSocket,
3438
injectMetaMaskProvider: injectMetaMaskProvider.default,
3539
});
3640

37-
test.beforeEach(async({ page }) => {
41+
test.beforeEach(async({ page, mockTextAd }) => {
3842
// debug
3943
const isDebug = process.env.PWDEBUG === '1';
4044

@@ -56,16 +60,7 @@ test.beforeEach(async({ page }) => {
5660

5761
// with few exceptions:
5862
// 1. mock text AD requests
59-
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
60-
status: 200,
61-
body: JSON.stringify(textAdMock.duck),
62-
}));
63-
await page.route(textAdMock.duck.ad.thumbnail, (route) => {
64-
return route.fulfill({
65-
status: 200,
66-
path: './playwright/mocks/image_s.jpg',
67-
});
68-
});
63+
await mockTextAd();
6964
});
7065

7166
export * from '@playwright/experimental-ct-react';

ui/pages/Blocks.pw.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import * as blockMock from 'mocks/blocks/block';
55
import * as statsMock from 'mocks/stats/index';
66
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs';
7+
import { ENVS_MAP } from 'playwright/fixtures/mockEnvs';
78
import * as socketServer from 'playwright/fixtures/socketServer';
89
import { test, expect, devices } from 'playwright/lib';
910
import * as configs from 'playwright/utils/configs';
@@ -21,6 +22,10 @@ const hooksConfig = {
2122
// test cases which use socket cannot run in parallel since the socket server always run on the same port
2223
test.describe.configure({ mode: 'serial' });
2324

25+
test.beforeEach(async({ mockTextAd }) => {
26+
await mockTextAd();
27+
});
28+
2429
test('base view +@dark-mode', async({ render, mockApiResponse }) => {
2530
await mockApiResponse('blocks', blockMock.baseListResponse, { queryParams: { type: 'block' } });
2631
await mockApiResponse('stats', statsMock.base);
@@ -30,11 +35,8 @@ test('base view +@dark-mode', async({ render, mockApiResponse }) => {
3035
await expect(component).toHaveScreenshot();
3136
});
3237

33-
const hiddenFieldsTest = test.extend<{ context: BrowserContext }>({
34-
context: contextWithEnvs(configs.viewsEnvs.block.hiddenFields),
35-
});
36-
37-
hiddenFieldsTest('hidden fields', async({ render, mockApiResponse }) => {
38+
test('hidden fields', async({ render, mockApiResponse, mockEnvs }) => {
39+
await mockEnvs(ENVS_MAP.blockHiddenFields);
3840
await mockApiResponse('blocks', blockMock.baseListResponse, { queryParams: { type: 'block' } });
3941
await mockApiResponse('stats', statsMock.base);
4042

ui/pages/ShibariumDeposits.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib';
66

77
import ShibariumDeposits from './ShibariumDeposits';
88

9-
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => {
9+
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
10+
await mockTextAd();
1011
await mockEnvs(ENVS_MAP.shibariumRollup);
1112
await mockApiResponse('shibarium_deposits', depositsData);
1213
await mockApiResponse('shibarium_deposits_count', 3971111);

ui/pages/ShibariumWithdrawals.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import { test, expect } from 'playwright/lib';
66

77
import ShibariumWithdrawals from './ShibariumWithdrawals';
88

9-
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => {
9+
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
1010
// test on mobile is flaky
1111
// my assumption is there is not enough time to calculate hashes truncation so component is unstable
1212
// so I raised the test timeout to check if it helps
1313
test.slow();
1414

15+
await mockTextAd();
1516
await mockEnvs(ENVS_MAP.shibariumRollup);
1617
await mockApiResponse('shibarium_withdrawals', withdrawalsData);
1718
await mockApiResponse('shibarium_withdrawals_count', 397);

ui/pages/Token.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ const hooksConfig = {
2525
// test cases which use socket cannot run in parallel since the socket server always run on the same port
2626
test.describe.configure({ mode: 'serial' });
2727

28-
test.beforeEach(async({ mockApiResponse }) => {
28+
test.beforeEach(async({ mockApiResponse, mockTextAd }) => {
2929
await mockApiResponse('token', tokenInfo, { pathParams: { hash } });
3030
await mockApiResponse('address', contract, { pathParams: { hash } });
3131
await mockApiResponse('token_counters', tokenCounters, { pathParams: { hash } });
3232
await mockApiResponse('token_transfers', { items: [], next_page_params: null }, { pathParams: { hash } });
33+
await mockTextAd();
3334
});
3435

3536
test('base view', async({ render, page, createSocket }) => {

ui/pages/Tokens.pw.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { test, expect } from 'playwright/lib';
77

88
import Tokens from './Tokens';
99

10+
test.beforeEach(async({ mockTextAd }) => {
11+
await mockTextAd();
12+
});
13+
1014
test('base view +@mobile +@dark-mode', async({ render, mockApiResponse }) => {
1115
const allTokens = {
1216
items: [

ui/pages/Validators.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import Validators from './Validators';
77

88
const chainType = 'stability';
99

10-
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => {
10+
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
1111
await mockEnvs([
1212
[ 'NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE', chainType ],
1313
]);
1414
await mockApiResponse('validators', validatorsMock.validatorsResponse, { pathParams: { chainType } });
1515
await mockApiResponse('validators_counters', validatorsMock.validatorsCountersResponse, { pathParams: { chainType } });
16+
await mockTextAd();
1617

1718
const component = await render(<Validators/>);
1819

ui/pages/ZkEvmL2Deposits.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib';
66

77
import ZkEvmL2Deposits from './ZkEvmL2Deposits';
88

9-
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => {
9+
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
10+
await mockTextAd();
1011
await mockEnvs(ENVS_MAP.zkEvmRollup);
1112
await mockApiResponse('zkevm_l2_deposits', depositsMock.baseResponse);
1213
await mockApiResponse('zkevm_l2_deposits_count', 3971111);

ui/pages/ZkEvmL2Withdrawals.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib';
66

77
import ZkEvmL2Withdrawals from './ZkEvmL2Withdrawals';
88

9-
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs }) => {
9+
test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => {
10+
await mockTextAd();
1011
await mockEnvs(ENVS_MAP.zkEvmRollup);
1112
await mockApiResponse('zkevm_l2_withdrawals', withdrawalsMock.baseResponse);
1213
await mockApiResponse('zkevm_l2_withdrawals_count', 3971111);

ui/snippets/searchBar/SearchBar.pw.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { test, expect } from 'playwright/lib';
66

77
import SearchBar from './SearchBar';
88

9-
test.beforeEach(async({ mockAssetResponse, mockEnvs }) => {
9+
test.beforeEach(async({ mockAssetResponse, mockEnvs, mockTextAd }) => {
10+
await mockTextAd();
1011
await mockAssetResponse(searchMock.token1.icon_url as string, './playwright/mocks/image_s.jpg');
1112
await mockEnvs([
1213
[ 'NEXT_PUBLIC_MARKETPLACE_ENABLED', 'false' ],

0 commit comments

Comments
 (0)