From 1724f3542ccfe3c17af9e14b93da72a2f65d959e Mon Sep 17 00:00:00 2001 From: Kris <605420+krzysu@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:14:43 +0100 Subject: [PATCH] fix: correctly close ws connection in web3-eth-contract integration tests (#7338) --- lerna.json | 10 +- packages/web3-eth-contract/package.json | 4 +- .../integration/contract_accesslist.test.ts | 17 +- .../test/integration/contract_clone.test.ts | 13 +- .../integration/contract_defaults.test.ts | 22 +- .../contract_defaults_extra.test.ts | 145 ++++----- .../test/integration/contract_deploy.test.ts | 77 +++-- .../integration/contract_empty_string.test.ts | 13 +- .../test/integration/contract_erc20.test.ts | 43 ++- .../test/integration/contract_erc721.test.ts | 76 ++--- .../contract_estimateGas_without_0x.test.ts | 10 +- .../test/integration/contract_events.test.ts | 279 +++++++++--------- .../contract_filter_events.test.ts | 10 + .../test/integration/contract_methods.test.ts | 9 + .../contract_methods_errors.test.ts | 5 +- .../contract_negative_numbers.test.ts | 15 +- .../contract_simple_overloaded.test.ts | 12 +- .../local_account/contract_deploy.test.ts | 15 +- .../local_account/contract_erc20.test.ts | 10 +- .../local_account/contract_erc721.test.ts | 17 +- .../contract_overloaded_methods.test.ts | 10 +- scripts/system_tests_utils.ts | 22 +- 22 files changed, 487 insertions(+), 347 deletions(-) diff --git a/lerna.json b/lerna.json index b5104ac58aa..e45823a46f8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,7 +1,7 @@ { - "lerna": "4.0.0", - "npmClient": "yarn", - "useWorkspaces": true, - "version": "independent", - "packages": ["packages/*", "tools/*"] + "lerna": "4.0.0", + "npmClient": "yarn", + "useWorkspaces": true, + "version": "independent", + "packages": ["packages/*", "tools/*"] } diff --git a/packages/web3-eth-contract/package.json b/packages/web3-eth-contract/package.json index 4d780091c80..30db5ffc723 100644 --- a/packages/web3-eth-contract/package.json +++ b/packages/web3-eth-contract/package.json @@ -35,11 +35,11 @@ "format": "prettier --write '**/*'", "test": "jest --config=./test/unit/jest.config.js", "test:coverage:unit": "jest --config=./test/unit/jest.config.js --coverage=true --coverage-reporters=text", - "test:coverage:integration": "jest --config=./test/integration/jest.config.js --runInBand --forceExit --coverage=true --coverage-reporters=text", + "test:coverage:integration": "jest --config=./test/integration/jest.config.js --runInBand --coverage=true --coverage-reporters=text", "test:ci": "jest --coverage=true --coverage-reporters=json --verbose", "test:watch": "npm test -- --watch", "test:unit": "jest --config=./test/unit/jest.config.js", - "test:integration": "jest --config=./test/integration/jest.config.js --runInBand --forceExit", + "test:integration": "jest --config=./test/integration/jest.config.js --runInBand", "test:e2e:electron": "npx cypress run --headless --browser electron --env grep='ignore',invert=true", "test:e2e:chrome": "npx cypress run --headless --browser chrome --env grep='ignore',invert=true", "test:e2e:firefox": "npx cypress run --headless --browser firefox --env grep='ignore',invert=true" diff --git a/packages/web3-eth-contract/test/integration/contract_accesslist.test.ts b/packages/web3-eth-contract/test/integration/contract_accesslist.test.ts index 3173f452c33..9c1aff2af36 100644 --- a/packages/web3-eth-contract/test/integration/contract_accesslist.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_accesslist.test.ts @@ -23,16 +23,18 @@ import { describeIf, getSystemTestBackend, BACKEND, + closeOpenConnection, } from '../fixtures/system_test_utils'; describe('contract', () => { describeIf(getSystemTestBackend() === BACKEND.GETH)('createAccessList', () => { let contract: Contract; + let deployedContract: Contract; let deployOptions: Record; let sendOptions: Record; let acc: { address: string; privateKey: string }; - beforeEach(async () => { + beforeAll(async () => { contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), }); @@ -46,10 +48,16 @@ describe('contract', () => { sendOptions = { from: acc.address, gas: '1000000' }; }); - it('create access list for setter', async () => { - const deployedContract = await contract.deploy(deployOptions).send(sendOptions); + afterAll(async () => { + await closeOpenConnection(contract); + }); + + beforeEach(async () => { + deployedContract = await contract.deploy(deployOptions).send(sendOptions); deployedContract.defaultAccount = acc.address; + }); + it('create access list for setter', async () => { const receipt = await deployedContract.methods .setGreeting('New Greeting') .send({ gas: '1000000' }); @@ -75,9 +83,6 @@ describe('contract', () => { }); it('create access list for getter', async () => { - const deployedContract = await contract.deploy(deployOptions).send(sendOptions); - deployedContract.defaultAccount = acc.address; - const receipt = await deployedContract.methods .setGreeting('New Greeting') .send({ gas: '1000000' }); diff --git a/packages/web3-eth-contract/test/integration/contract_clone.test.ts b/packages/web3-eth-contract/test/integration/contract_clone.test.ts index 873ac0658ea..e27b0be402f 100644 --- a/packages/web3-eth-contract/test/integration/contract_clone.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_clone.test.ts @@ -16,13 +16,18 @@ along with web3.js. If not, see . */ import { Contract } from '../../src'; import { GreeterBytecode, GreeterAbi } from '../shared_fixtures/build/Greeter'; -import { getSystemTestProvider, createTempAccount } from '../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createTempAccount, + closeOpenConnection, +} from '../fixtures/system_test_utils'; describe('contract', () => { describe('clone', () => { let contract: Contract; let deployOptions: Record; let sendOptions: Record; + beforeAll(async () => { contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), @@ -34,7 +39,11 @@ describe('contract', () => { arguments: ['My Greeting'], }; - sendOptions = { from: acc.address, gas: '1000000' }; + sendOptions = { from: acc.address }; + }); + + afterAll(async () => { + await closeOpenConnection(contract); }); it('should clone the contract but with same address', async () => { diff --git a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts index b481237c739..0f28e31269b 100644 --- a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts @@ -20,7 +20,11 @@ import { Web3Context } from 'web3-core'; import { Contract } from '../../src'; import { GreeterBytecode, GreeterAbi } from '../shared_fixtures/build/Greeter'; -import { getSystemTestProvider, createTempAccount } from '../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createTempAccount, + closeOpenConnection, +} from '../fixtures/system_test_utils'; describe('contract', () => { describe('defaults', () => { @@ -43,6 +47,10 @@ describe('contract', () => { sendOptions = { from: acc.address, gas: '1000000' }; }); + afterEach(async () => { + await closeOpenConnection(contract); + }); + it('should use "defaultAccount" on "instance" level instead of "from"', async () => { const deployedContract = await contract.deploy(deployOptions).send(sendOptions); // eslint-disable-next-line prefer-destructuring @@ -63,23 +71,27 @@ describe('contract', () => { }); it('should set syncWithContext from init options', async () => { - contract = new Contract(GreeterAbi, { + const testContract = new Contract(GreeterAbi, { provider: getSystemTestProvider(), syncWithContext: true, }); - contract = await contract.deploy(deployOptions).send(sendOptions); + const deployedContract = await testContract.deploy(deployOptions).send(sendOptions); - expect(contract.syncWithContext).toBeTruthy(); + expect(deployedContract.syncWithContext).toBeTruthy(); + + await closeOpenConnection(testContract); }); - it('should subscribe to provided context upon instantiation', () => { + it('should subscribe to provided context upon instantiation', async () => { const web3Context = new Web3Context('http://127.0.0.1:8545'); const _contract = new Contract([], { syncWithContext: true }, web3Context); expect(_contract.defaultBlock).toBe('latest'); web3Context.defaultBlock = 'earliest'; expect(_contract.defaultBlock).toBe('earliest'); + + await closeOpenConnection(_contract); }); describe('defaultBlock', () => { diff --git a/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts b/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts index 206b10ee709..ce4f126a539 100644 --- a/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts @@ -48,7 +48,11 @@ describe('contract defaults (extra)', () => { let sendOptions: Record; let acc: { address: string; privateKey: string }; - beforeEach(async () => { + beforeAll(async () => { + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + acc = await createTempAccount(); deployOptions = { @@ -59,27 +63,23 @@ describe('contract defaults (extra)', () => { sendOptions = { from: acc.address, gas: '1000000' }; }); - afterEach(async () => { + afterAll(async () => { await closeOpenConnection(contract); }); it('should use "defaultHardfork" on "instance" level', async () => { const hardfork = 'berlin'; - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); - contract.defaultHardfork = hardfork; + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); + deployedContract.defaultHardfork = hardfork; - await contract.methods.setGreeting('New Greeting').send(sendOptions); - await contract.methods.greet().send(sendOptions); + await deployedContract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods.greet().send(sendOptions); - expect(contract.defaultHardfork).toBe(hardfork); + expect(deployedContract.defaultHardfork).toBe(hardfork); const callSpy = jest.spyOn(Web3Eth, 'call'); - await contract.methods.greet().call(); + await deployedContract.methods.greet().call(); expect(callSpy).toHaveBeenLastCalledWith( expect.objectContaining({ @@ -93,24 +93,20 @@ describe('contract defaults (extra)', () => { describe('defaultChain', () => { it('should use "defaultChain" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); - contract = await contract.deploy(deployOptions).send(sendOptions); - - expect(contract.defaultChain).toBe('mainnet'); + expect(deployedContract.defaultChain).toBe('mainnet'); const defaultChain = 'ropsten'; - contract.defaultChain = defaultChain; + deployedContract.defaultChain = defaultChain; - expect(contract.defaultChain).toBe(defaultChain); + expect(deployedContract.defaultChain).toBe(defaultChain); - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods.setGreeting('New Greeting').send(sendOptions); const callSpy = jest.spyOn(Web3Eth, 'call'); - await contract.methods.greet().call(); + await deployedContract.methods.greet().call(); expect(callSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -131,27 +127,12 @@ describe('contract defaults (extra)', () => { hardfork: 'london' as Hardfork, }; - beforeEach(async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - acc = await createTempAccount(); - - deployOptions = { - data: GreeterBytecode, - arguments: ['My Greeting'], - }; - - sendOptions = { from: acc.address, gas: '1000000' }; - - contract = await contract.deploy(deployOptions).send(sendOptions); - }); - it('should use "defaultCommon" on "instance" level', async () => { - contract.defaultCommon = common; + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); + deployedContract.defaultCommon = common; const callSpy = jest.spyOn(Web3Eth, 'call'); - await contract.methods.greet().call(); + await deployedContract.methods.greet().call(); expect(callSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -166,19 +147,16 @@ describe('contract defaults (extra)', () => { describeIf(isWs)('transactionBlockTimeout', () => { it('should use "transactionBlockTimeout" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - contract = await contract.deploy(deployOptions).send(sendOptions); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); - expect(contract.transactionBlockTimeout).toBe(50); + expect(deployedContract.transactionBlockTimeout).toBe(50); - contract.transactionBlockTimeout = 32; - expect(contract.transactionBlockTimeout).toBe(32); + deployedContract.transactionBlockTimeout = 32; + expect(deployedContract.transactionBlockTimeout).toBe(32); // eslint-disable-next-line @typescript-eslint/no-unsafe-call - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods.setGreeting('New Greeting').send(sendOptions); expect(sendTransactionSpy).toHaveBeenLastCalledWith( expect.objectContaining({ @@ -191,38 +169,41 @@ describe('contract defaults (extra)', () => { }); it('should fail if transaction was not mined within `transactionBlockTimeout` blocks', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - contract = await contract.deploy(deployOptions).send(sendOptions); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); // Make the test run faster by casing the polling to start after 2 blocks - contract.transactionBlockTimeout = 1; + deployedContract.transactionBlockTimeout = 1; // Prevent transaction from stucking for a long time if the provider (like Ganache v7.4.0) // does not respond, when raising the nonce - contract.transactionSendTimeout = MAX_32_SIGNED_INTEGER; + deployedContract.transactionSendTimeout = MAX_32_SIGNED_INTEGER; // Increase other timeouts - contract.transactionPollingTimeout = MAX_32_SIGNED_INTEGER; + deployedContract.transactionPollingTimeout = MAX_32_SIGNED_INTEGER; // Setting a high `nonce` when sending a transaction, to cause the RPC call to stuck at the Node // The previous test has the nonce set to Number.MAX_SAFE_INTEGER. // So, just decrease 1 from it here to not fall into another error. - const sentTx = contract.methods.setGreeting('New Greeting with high nonce').send({ - ...sendOptions, - nonce: (Number.MAX_SAFE_INTEGER - 1).toString(), - }); + const sentTx = deployedContract.methods + .setGreeting('New Greeting with high nonce') + .send({ + ...sendOptions, + nonce: (Number.MAX_SAFE_INTEGER - 1).toString(), + }); // Some providers (mostly used for development) will make blocks only when there are new transactions // So, send 2 transactions because in this test `transactionBlockTimeout = 2`. And do nothing if an error happens. setTimeout(() => { (async () => { try { - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods + .setGreeting('New Greeting') + .send(sendOptions); } catch (error) { // Nothing needed to be done. } try { - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods + .setGreeting('New Greeting') + .send(sendOptions); } catch (error) { // Nothing needed to be done. } @@ -237,20 +218,16 @@ describe('contract defaults (extra)', () => { describeIf(isWs)('blockHeaderTimeout', () => { it('should use "blockHeaderTimeout" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); - contract = await contract.deploy(deployOptions).send(sendOptions); - - expect(contract.blockHeaderTimeout).toBe(10); + expect(deployedContract.blockHeaderTimeout).toBe(10); const blockHeaderTimeout = 1; - contract.blockHeaderTimeout = blockHeaderTimeout; + deployedContract.blockHeaderTimeout = blockHeaderTimeout; - expect(contract.blockHeaderTimeout).toBe(blockHeaderTimeout); + expect(deployedContract.blockHeaderTimeout).toBe(blockHeaderTimeout); - const sentTx = contract.methods.setGreeting('New Greeting').send(sendOptions); + const sentTx = deployedContract.methods.setGreeting('New Greeting').send(sendOptions); const confirmationPromise = new Promise((resolve: Resolve) => { // Tx promise is handled separately @@ -262,7 +239,9 @@ describe('contract defaults (extra)', () => { resolve(); } else { // Send a transaction to cause dev providers creating new blocks to fire the 'confirmation' event again. - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods + .setGreeting('New Greeting') + .send(sendOptions); } }, ); @@ -284,36 +263,28 @@ describe('contract defaults (extra)', () => { describeIf(isHttp)('transactionPollingInterval', () => { it('should use "transactionPollingTimeout" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); const transactionPollingInterval = 500; - contract.transactionPollingInterval = transactionPollingInterval; + deployedContract.transactionPollingInterval = transactionPollingInterval; - expect(contract.transactionPollingInterval).toBe(transactionPollingInterval); + expect(deployedContract.transactionPollingInterval).toBe(transactionPollingInterval); }); }); it('should use "handleRevert" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); + const deployedContract = await contract.deploy(deployOptions).send(sendOptions); - expect(contract.handleRevert).toBeFalsy(); + expect(deployedContract.handleRevert).toBeFalsy(); const handleRevert = true; - contract.handleRevert = handleRevert; + deployedContract.handleRevert = handleRevert; - expect(contract.handleRevert).toBe(handleRevert); + expect(deployedContract.handleRevert).toBe(handleRevert); const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); - await contract.methods.setGreeting('New Greeting').send(sendOptions); + await deployedContract.methods.setGreeting('New Greeting').send(sendOptions); expect(sendTransactionSpy).toHaveBeenCalled(); }); diff --git a/packages/web3-eth-contract/test/integration/contract_deploy.test.ts b/packages/web3-eth-contract/test/integration/contract_deploy.test.ts index b54ed63b41d..e4833882e94 100644 --- a/packages/web3-eth-contract/test/integration/contract_deploy.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_deploy.test.ts @@ -17,13 +17,11 @@ along with web3.js. If not, see . import { Web3Eth } from 'web3-eth'; import { FMT_BYTES, FMT_NUMBER } from 'web3-types'; import { Contract, createContractAddress } from '../../src'; -import { sleep } from '../shared_fixtures/utils'; import { ERC721TokenAbi, ERC721TokenBytecode } from '../shared_fixtures/build/ERC721Token'; import { GreeterBytecode, GreeterAbi } from '../shared_fixtures/build/Greeter'; import { DeployRevertAbi, DeployRevertBytecode } from '../shared_fixtures/build/DeployRevert'; import { getSystemTestProvider, - isWs, createTempAccount, createNewAccount, signTxAndSendEIP2930, @@ -46,16 +44,22 @@ describe('contract', () => { beforeAll(() => { web3Eth = new Web3Eth(getSystemTestProvider()); + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); deployOptions = { data: GreeterBytecode, arguments: ['My Greeting'], }; }); + + afterAll(async () => { + await closeOpenConnection(web3Eth); + await closeOpenConnection(contract); + }); + beforeEach(async () => { acc = await createTempAccount(); - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); sendOptions = { from: acc.address, gas: '1000000' }; }); @@ -71,9 +75,6 @@ describe('contract', () => { expect(deployedContract.options.address).toEqual(address); }); - afterAll(async () => { - await closeOpenConnection(web3Eth); - }); describe('local account', () => { it.each([signTxAndSendEIP1559, signTxAndSendEIP2930])( 'should deploy the contract %p', @@ -112,9 +113,11 @@ describe('contract', () => { ); it('should return estimated gas of contract constructor %p', async () => { - const estimatedGas = await new Contract(GreeterAbi, undefined, { + const testContract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), - }) + }); + + const estimatedGas = await testContract .deploy({ data: GreeterBytecode, arguments: ['My Greeting'], @@ -123,21 +126,27 @@ describe('contract', () => { from: acc.address, gas: '1000000', }); + expect(typeof estimatedGas).toBe('bigint'); expect(Number(estimatedGas)).toBeGreaterThan(0); + + await closeOpenConnection(testContract); }); + it.each(Object.values(FMT_NUMBER))( 'should return estimated gas of contract constructor %p with correct type', async format => { const returnFormat = { number: format as FMT_NUMBER, bytes: FMT_BYTES.HEX }; - const estimatedGas = await new Contract( + const testContract = new Contract( GreeterAbi, { provider: getSystemTestProvider(), }, returnFormat, - ) + ); + + const estimatedGas = await testContract .deploy({ data: GreeterBytecode, arguments: ['My Greeting'], @@ -146,14 +155,20 @@ describe('contract', () => { from: acc.address, gas: '1000000', }); + expect(typeof estimatedGas).toBe(mapFormatToType[format as string]); expect(Number(estimatedGas)).toBeGreaterThan(0); + + await closeOpenConnection(testContract); }, ); + it('should return estimated gas of contract constructor without arguments', async () => { - const estimatedGas = await new Contract(ERC721TokenAbi, undefined, { + const testContract = new Contract(ERC721TokenAbi, undefined, { provider: getSystemTestProvider(), - }) + }); + + const estimatedGas = await testContract .deploy({ data: ERC721TokenBytecode, arguments: [], @@ -162,8 +177,12 @@ describe('contract', () => { from: acc.address, gas: '10000000', }); + expect(Number(estimatedGas)).toBeGreaterThan(0); + + await closeOpenConnection(testContract); }); + it('should return estimated gas of contract method', async () => { const contractDeployed = await contract.deploy(deployOptions).send(sendOptions); @@ -173,8 +192,10 @@ describe('contract', () => { gas: '1000000', from: acc.address, }); + expect(Number(estimatedGas)).toBeGreaterThan(0); }); + it('should return estimated gas of contract method without arguments', async () => { const contractDeployed = await contract.deploy(deployOptions).send(sendOptions); @@ -193,15 +214,19 @@ describe('contract', () => { }); it('should deploy the contract if data is provided at initiation', async () => { - contract = new Contract(GreeterAbi, { + const testContract = new Contract(GreeterAbi, { provider: getSystemTestProvider(), data: GreeterBytecode, from: acc.address, gas: '1000000', }); - const deployedContract = await contract.deploy({ arguments: ['Hello World'] }).send(); + const deployedContract = await testContract + .deploy({ arguments: ['Hello World'] }) + .send(); expect(deployedContract).toBeDefined(); + + await closeOpenConnection(testContract); }); it('should return instance of the contract', async () => { @@ -218,26 +243,18 @@ describe('contract', () => { it('should emit the "confirmation" event', async () => { const confirmationHandler = jest.fn(); - contract.setConfig({ transactionConfirmationBlocks: 1 }); - await contract + contract.setConfig({ transactionConfirmationBlocks: 2 }); + + const promiEvent = contract .deploy(deployOptions) .send(sendOptions) .on('confirmation', confirmationHandler); - // Wait for some time to allow the transaction to be processed - await sleep(500); - - // Deploy once again to trigger block mining to trigger confirmation - // We can send any other transaction as well - await contract.deploy(deployOptions).send(sendOptions); + // Deploy the contract + await promiEvent; await sendFewSampleTxs(3); - // Wait for some fraction of time to trigger the handler - // On http we use polling to get confirmation, so wait a bit longer - await sleep(isWs ? 500 : 2000); - - // eslint-disable-next-line jest/no-standalone-expect expect(confirmationHandler).toHaveBeenCalled(); }); @@ -345,6 +362,8 @@ describe('contract', () => { 'Error happened while trying to execute a function inside a smart contract', ); } + + await closeOpenConnection(revert); }); }); }); diff --git a/packages/web3-eth-contract/test/integration/contract_empty_string.test.ts b/packages/web3-eth-contract/test/integration/contract_empty_string.test.ts index 25540c2ebf4..ceba0aa6c61 100644 --- a/packages/web3-eth-contract/test/integration/contract_empty_string.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_empty_string.test.ts @@ -16,13 +16,18 @@ along with web3.js. If not, see . */ import { Contract } from '../../src'; -import { getSystemTestProvider, createTempAccount } from '../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createTempAccount, + closeOpenConnection, +} from '../fixtures/system_test_utils'; import { MyContractAbi, MyContractBytecode } from '../fixtures/MyContract'; describe('request empty string from contract', () => { let contract: Contract; let deployOptions: Record; let sendOptions: Record; + beforeAll(async () => { contract = new Contract(MyContractAbi, undefined, { provider: getSystemTestProvider(), @@ -34,7 +39,11 @@ describe('request empty string from contract', () => { arguments: [], }; - sendOptions = { from: acc.address, gas: '1000000' }; + sendOptions = { from: acc.address }; + }); + + afterAll(async () => { + await closeOpenConnection(contract); }); it('should fetch empty string', async () => { diff --git a/packages/web3-eth-contract/test/integration/contract_erc20.test.ts b/packages/web3-eth-contract/test/integration/contract_erc20.test.ts index 5e268691aa5..c18582a4f8e 100644 --- a/packages/web3-eth-contract/test/integration/contract_erc20.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_erc20.test.ts @@ -27,8 +27,9 @@ import { refillAccount, signAndSendContractMethodEIP1559, signAndSendContractMethodEIP2930, + closeOpenConnection, } from '../fixtures/system_test_utils'; -import { processAsync, toUpperCaseHex } from '../shared_fixtures/utils'; +import { toUpperCaseHex } from '../shared_fixtures/utils'; const initialSupply = BigInt('5000000000'); @@ -49,6 +50,10 @@ describe('contract', () => { }; }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should deploy the contract', async () => { const acc = await createTempAccount(); const sendOptionsLocal = { from: acc.address, gas: '10000000' }; @@ -61,6 +66,7 @@ describe('contract', () => { let contractDeployed: Contract; let pkAccount: { address: string; privateKey: string }; let mainAcc: { address: string; privateKey: string }; + const prepareForTransfer = async (value: string) => { const tempAccount = await createTempAccount(); await contractDeployed.methods.transfer(pkAccount.address, value).send(sendOptions); @@ -74,6 +80,11 @@ describe('contract', () => { sendOptions = { from: mainAcc.address, gas: '10000000' }; contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); + + afterAll(async () => { + await closeOpenConnection(contractDeployed); + }); + describe('methods', () => { it('should return the name', async () => { expect(await contractDeployed.methods.name().call()).toBe('Gold'); @@ -150,6 +161,7 @@ describe('contract', () => { expect(await catchErrorPromise).toBeDefined(); expect(catchError).toBe(true); }); + it('send tokens from the account that does not have tokens', async () => { const tempAccount = await createTempAccount(); const test = await createNewAccount({ @@ -186,7 +198,7 @@ describe('contract', () => { const value = BigInt(10); const tempAccount = await prepareForTransfer(value.toString()); await signAndSendContractMethod( - contract.provider, + contractDeployed.provider, contractDeployed.options.address as string, contractDeployed.methods.transfer(tempAccount.address, value), pkAccount.privateKey, @@ -291,22 +303,21 @@ describe('contract', () => { describeIf(isWs)('events', () => { it('should emit transfer event', async () => { const acc2 = await createTempAccount(); - await expect( - processAsync(async resolve => { - const event = contractDeployed.events.Transfer(); - event.on('data', data => { - resolve({ - from: toUpperCaseHex(data.returnValues.from as string), - to: toUpperCaseHex(data.returnValues.to as string), - value: data.returnValues.value, - }); + const event = contractDeployed.events.Transfer(); + const eventPromise = new Promise((resolve, reject) => { + event.on('data', data => { + resolve({ + from: toUpperCaseHex(data.returnValues.from as string), + to: toUpperCaseHex(data.returnValues.to as string), + value: data.returnValues.value, }); + }); + event.on('error', reject); + }); - await contractDeployed.methods - .transfer(acc2.address, '100') - .send(sendOptions); - }), - ).resolves.toEqual({ + await contractDeployed.methods.transfer(acc2.address, '100').send(sendOptions); + + await expect(eventPromise).resolves.toEqual({ from: toUpperCaseHex(sendOptions.from as string), to: toUpperCaseHex(acc2.address), value: BigInt(100), diff --git a/packages/web3-eth-contract/test/integration/contract_erc721.test.ts b/packages/web3-eth-contract/test/integration/contract_erc721.test.ts index 9463a636930..f979e1d396a 100644 --- a/packages/web3-eth-contract/test/integration/contract_erc721.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_erc721.test.ts @@ -27,8 +27,9 @@ import { signAndSendContractMethodEIP2930, createNewAccount, refillAccount, + closeOpenConnection, } from '../fixtures/system_test_utils'; -import { processAsync, toUpperCaseHex } from '../shared_fixtures/utils'; +import { toUpperCaseHex } from '../shared_fixtures/utils'; describe('contract', () => { describe('erc721', () => { @@ -51,21 +52,25 @@ describe('contract', () => { sendOptions = { from: acc.address, gas: '10000000' }; }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should deploy the contract', async () => { await expect(contract.deploy(deployOptions).send(sendOptions)).resolves.toBeDefined(); }); describe('contract instance', () => { let acc: { address: string; privateKey: string }; - let acc2: { address: string; privateKey: string }; let pkAccount: { address: string; privateKey: string }; + beforeAll(async () => { acc = await createTempAccount(); pkAccount = await createNewAccount(); await refillAccount(acc.address, pkAccount.address, '20000000000000000'); }); + beforeEach(async () => { - acc2 = await createTempAccount(); sendOptions = { from: acc.address, gas: '10000000' }; contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); @@ -293,42 +298,47 @@ describe('contract', () => { describeIf(isWs)('events', () => { it('should emit transfer event', async () => { - await expect( - processAsync(async resolve => { - const event = contractDeployed.events.Transfer(); - event.on('data', data => { - resolve({ - from: toUpperCaseHex(data.returnValues.from as string), - to: toUpperCaseHex(data.returnValues.to as string), - tokenId: data.returnValues.tokenId, - }); + const acc2 = await createTempAccount(); + const event = contractDeployed.events.Transfer(); + + const eventPromise = new Promise((resolve, reject) => { + event.on('data', data => { + resolve({ + from: toUpperCaseHex(data.returnValues.from as string), + to: toUpperCaseHex(data.returnValues.to as string), + tokenId: data.returnValues.tokenId, }); + }); + event.on('error', reject); + }); + + const receipt = await contractDeployed.methods + .awardItem(acc2.address, 'http://my-nft-uri') + .send(sendOptions); - const receipt = await contractDeployed.methods - .awardItem(acc2.address, 'http://my-nft-uri') - .send(sendOptions); - - expect(receipt.events).toBeDefined(); - expect(receipt.events?.Transfer).toBeDefined(); - expect(receipt.events?.Transfer.event).toBe('Transfer'); - expect( - String(receipt.events?.Transfer.returnValues.from).toLowerCase(), - ).toBe('0x0000000000000000000000000000000000000000'); - expect( - String(receipt.events?.Transfer.returnValues[0]).toLowerCase(), - ).toBe('0x0000000000000000000000000000000000000000'); - expect( - String(receipt.events?.Transfer.returnValues.to).toLowerCase(), - ).toBe(acc2.address.toLowerCase()); - expect( - String(receipt.events?.Transfer.returnValues[1]).toLowerCase(), - ).toBe(acc2.address.toLowerCase()); - }), - ).resolves.toEqual({ + expect(receipt.events).toBeDefined(); + expect(receipt.events?.Transfer).toBeDefined(); + expect(receipt.events?.Transfer.event).toBe('Transfer'); + expect(String(receipt.events?.Transfer.returnValues.from).toLowerCase()).toBe( + '0x0000000000000000000000000000000000000000', + ); + expect(String(receipt.events?.Transfer.returnValues[0]).toLowerCase()).toBe( + '0x0000000000000000000000000000000000000000', + ); + expect(String(receipt.events?.Transfer.returnValues.to).toLowerCase()).toBe( + acc2.address.toLowerCase(), + ); + expect(String(receipt.events?.Transfer.returnValues[1]).toLowerCase()).toBe( + acc2.address.toLowerCase(), + ); + + await expect(eventPromise).resolves.toEqual({ from: '0x0000000000000000000000000000000000000000', to: toUpperCaseHex(acc2.address), tokenId: BigInt(0), }); + + event.removeAllListeners(); }); }); }); diff --git a/packages/web3-eth-contract/test/integration/contract_estimateGas_without_0x.test.ts b/packages/web3-eth-contract/test/integration/contract_estimateGas_without_0x.test.ts index d74a901e265..7212060bac5 100644 --- a/packages/web3-eth-contract/test/integration/contract_estimateGas_without_0x.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_estimateGas_without_0x.test.ts @@ -17,7 +17,11 @@ along with web3.js. If not, see . import { ETH_DATA_FORMAT } from 'web3-types'; import { Contract } from '../../src'; -import { getSystemTestProvider, createTempAccount } from '../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createTempAccount, + closeOpenConnection, +} from '../fixtures/system_test_utils'; describe('contract', () => { // Create a new contract object using the ABI and bytecode @@ -49,6 +53,10 @@ describe('contract', () => { acc = await createTempAccount(); }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should be able to add `data` input without `0x` prefix', async () => { contract = new Contract(abi, undefined, { provider: getSystemTestProvider(), diff --git a/packages/web3-eth-contract/test/integration/contract_events.test.ts b/packages/web3-eth-contract/test/integration/contract_events.test.ts index b84a875d173..0e13a68f366 100644 --- a/packages/web3-eth-contract/test/integration/contract_events.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_events.test.ts @@ -15,10 +15,8 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { EventLog } from 'web3-types'; -import { Contract } from '../../src'; +import { Contract, EventLog } from '../../src'; import { BasicAbi, BasicBytecode } from '../shared_fixtures/build/Basic'; -import { processAsync } from '../shared_fixtures/utils'; import { getSystemTestProvider, describeIf, @@ -26,6 +24,8 @@ import { itIf, isHttp, createTempAccount, + closeOpenConnection, + sendFewSampleTxs, } from '../fixtures/system_test_utils'; describe('contract', () => { @@ -34,12 +34,11 @@ describe('contract', () => { let deployOptions: Record; let sendOptions: Record; - beforeAll(() => { + beforeAll(async () => { contract = new Contract(BasicAbi, undefined, { provider: getSystemTestProvider(), }); - }); - beforeEach(async () => { + const acc = await createTempAccount(); deployOptions = { @@ -47,123 +46,127 @@ describe('contract', () => { arguments: [10, 'string init value'], }; - sendOptions = { from: acc.address, gas: '1000000' }; + sendOptions = { from: acc.address }; + }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + + beforeEach(async () => { contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); - describe('events', () => { - itIf(isWs)('should trigger the "contract.events."', async () => { - // eslint-disable-next-line jest/no-standalone-expect - return expect( - processAsync(async (resolve, reject) => { - const event = contractDeployed.events.MultiValueEvent(); + describeIf(isWs)('events', () => { + it('should trigger the "contract.events."', async () => { + const event = contractDeployed.events.MultiValueEvent(); + + const eventPromise = new Promise((resolve, reject) => { + event.on('data', resolve); + event.on('error', reject); + }); - event.on('data', resolve); - event.on('error', reject); + await contractDeployed.methods + .firesMultiValueEvent('value', 12, true) + .send(sendOptions); - // trigger event - await contractDeployed.methods - .firesMultiValueEvent('value', 12, true) - .send(sendOptions); + await expect(eventPromise).resolves.toEqual( + expect.objectContaining({ + event: 'MultiValueEvent', }), - ).resolves.toEqual( + ); + + event.removeAllListeners(); + }); + + it('should trigger the "contract.events." for indexed parameters', async () => { + const event = contractDeployed.events.MultiValueIndexedEvent({ + filter: { val: 100 }, + }); + + const eventPromise = new Promise((resolve, reject) => { + event.on('data', resolve); + event.on('error', reject); + }); + + await contractDeployed.methods + .firesMultiValueIndexedEvent('value', 12, true) + .send(sendOptions); + await contractDeployed.methods + .firesMultiValueIndexedEvent('value', 100, true) + .send(sendOptions); + + await expect(eventPromise).resolves.toEqual( + expect.objectContaining({ + event: 'MultiValueIndexedEvent', + returnValues: expect.objectContaining({ + val: BigInt(100), + }), + }), + ); + + event.removeAllListeners(); + }); + + it('should trigger when "fromBlock" is passed to contract.events.', async () => { + const event = contractDeployed.events.MultiValueEvent({ + fromBlock: 'latest', + }); + + const eventPromise = new Promise((resolve, reject) => { + event.on('data', resolve); + event.on('error', reject); + }); + + await contractDeployed.methods + .firesMultiValueEvent('Event Value', 11, false) + .send(sendOptions); + + await expect(eventPromise).resolves.toEqual( expect.objectContaining({ event: 'MultiValueEvent', }), ); + + event.removeAllListeners(); }); - itIf(isWs)( - 'should trigger the "contract.events." for indexed parameters', - async () => { - const res = await processAsync(async (resolve, reject) => { - const event = contractDeployed.events.MultiValueIndexedEvent({ - filter: { val: 100 }, - }); - - event.on('data', resolve); - event.on('error', reject); - - // trigger event - await contractDeployed.methods - .firesMultiValueIndexedEvent('value', 12, true) - .send(sendOptions); - await contractDeployed.methods - .firesMultiValueIndexedEvent('value', 100, true) - .send(sendOptions); + it('should fetch past events when "fromBlock" is passed to contract.events.', async () => { + const eventValues = [11, 12, 13, 14]; + const event = contractDeployed.events.MultiValueEvent({ + fromBlock: 'earliest', + }); + + const eventPromise = new Promise((resolve, reject) => { + const pastEvents: EventLog[] = []; + event.on('data', d => { + pastEvents.push(d); + if (pastEvents.length === eventValues.length) { + resolve(pastEvents); + } }); - // eslint-disable-next-line jest/no-standalone-expect - expect((res as any)?.event).toBe('MultiValueIndexedEvent'); - // eslint-disable-next-line jest/no-standalone-expect - expect((res as any)?.returnValues.val).toBe(BigInt(100)); - }, - ); - - itIf(isWs)( - 'should trigger when "fromBlock" is passed to contract.events.', - async () => { - // eslint-disable-next-line jest/no-standalone-expect - return expect( - processAsync(async (resolve, reject) => { - const event = contractDeployed.events.MultiValueEvent({ - fromBlock: 'latest', - }); - - event.on('data', resolve); - event.on('error', reject); - - // trigger event - await contractDeployed.methods - .firesMultiValueEvent('Event Value', 11, false) - .send(sendOptions); - }), - ).resolves.toEqual( - expect.objectContaining({ - event: 'MultiValueEvent', - }), - ); - }, - ); - - itIf(isWs)( - 'should fetch past events when "fromBlock" is passed to contract.events.', - async () => { - const eventValues = [11, 12, 13, 14]; - // eslint-disable-next-line jest/no-standalone-expect - return expect( - processAsync(async resolve => { - // trigger multiple events - for (const eventValue of eventValues) { - // Wait for every transaction, before firing the next one, to prevent a possible nonce duplication. - // eslint-disable-next-line no-await-in-loop - await contractDeployed.methods - .firesMultiValueEvent('Event Value', eventValue, false) - .send(sendOptions); - } - - const event = contractDeployed.events.MultiValueEvent({ - fromBlock: 'earliest', - }); - - const pastEvents: EventLog[] = []; - event.on('data', d => { - pastEvents.push(d); - if (pastEvents.length === eventValues.length) { - resolve(pastEvents); - } - }); - }), - ).resolves.toEqual( - expect.arrayContaining([ - expect.objectContaining({ event: 'MultiValueEvent' }), - expect.objectContaining({ event: 'MultiValueEvent' }), - expect.objectContaining({ event: 'MultiValueEvent' }), - expect.objectContaining({ event: 'MultiValueEvent' }), - ]), - ); - }, - ); + event.on('error', reject); + }); + + for (const eventValue of eventValues) { + // Wait for every transaction, before firing the next one, to prevent a possible nonce duplication. + // eslint-disable-next-line no-await-in-loop + await contractDeployed.methods + .firesMultiValueEvent('Event Value', eventValue, false) + .send(sendOptions); + } + + await expect(eventPromise).resolves.toEqual( + expect.arrayContaining([ + expect.objectContaining({ event: 'MultiValueEvent' }), + expect.objectContaining({ event: 'MultiValueEvent' }), + expect.objectContaining({ event: 'MultiValueEvent' }), + expect.objectContaining({ event: 'MultiValueEvent' }), + ]), + ); + + event.removeAllListeners(); + }); }); describe('events subscription with HTTP', () => { @@ -186,7 +189,6 @@ describe('contract', () => { }); describeIf(isWs)('getPastEvents', () => { - // TODO: Debug why this tests is hanging the websocket it('should return all past events using earliest and latest options', async () => { await contractDeployed.methods .firesMultiValueEvent('New Greeting 1', 11, true) @@ -195,6 +197,8 @@ describe('contract', () => { .firesMultiValueEvent('New Greeting 2', 12, true) .send(sendOptions); + await sendFewSampleTxs(2); + expect( await contractDeployed.getPastEvents('MultiValueEvent', { fromBlock: 'earliest', @@ -202,6 +206,7 @@ describe('contract', () => { }), ).toHaveLength(2); }); + it('should return all past events using number options', async () => { await contractDeployed.methods .firesMultiValueEvent('New Greeting 1', 11, true) @@ -210,6 +215,8 @@ describe('contract', () => { .firesMultiValueEvent('New Greeting 2', 12, true) .send(sendOptions); + await sendFewSampleTxs(2); + expect( await contractDeployed.getPastEvents('MultiValueEvent', { fromBlock: 0, @@ -217,6 +224,7 @@ describe('contract', () => { }), ).toHaveLength(2); }); + it('should return all past events using string options', async () => { await contractDeployed.methods .firesMultiValueEvent('New Greeting 1', 11, true) @@ -225,6 +233,8 @@ describe('contract', () => { .firesMultiValueEvent('New Greeting 2', 12, true) .send(sendOptions); + await sendFewSampleTxs(2); + expect( await contractDeployed.getPastEvents('MultiValueEvent', { fromBlock: '0', @@ -232,6 +242,7 @@ describe('contract', () => { }), ).toHaveLength(2); }); + it('should return all past events using bigint options', async () => { await contractDeployed.methods .firesMultiValueEvent('New Greeting 1', 11, true) @@ -240,6 +251,8 @@ describe('contract', () => { .firesMultiValueEvent('New Greeting 2', 12, true) .send(sendOptions); + await sendFewSampleTxs(2); + expect( await contractDeployed.getPastEvents('MultiValueEvent', { fromBlock: BigInt(0), @@ -251,45 +264,43 @@ describe('contract', () => { describeIf(isWs)('allEvents', () => { it('should sub and get event using earliest options with allEvents()', async () => { - // eslint-disable-next-line jest/no-standalone-expect - return expect( - processAsync(async (resolve, reject) => { - const event = contractDeployed.events.allEvents({ fromBlock: 'earliest' }); + const event = contractDeployed.events.allEvents({ fromBlock: 'earliest' }); - event.on('data', resolve); - event.on('error', reject); + const eventPromise = new Promise((resolve, reject) => { + event.on('data', resolve); + event.on('error', reject); + }); - // trigger event - await contractDeployed.methods - .firesMultiValueEvent('val test', 12, true) - .send(sendOptions); - }), - ).resolves.toEqual( + await contractDeployed.methods + .firesMultiValueEvent('val test', 12, true) + .send(sendOptions); + + await expect(eventPromise).resolves.toEqual( expect.objectContaining({ event: 'MultiValueEvent', }), ); + + event.removeAllListeners(); }); it('should sub allEvents()', async () => { - // eslint-disable-next-line jest/no-standalone-expect - return expect( - processAsync(async (resolve, reject) => { - const event = contractDeployed.events.allEvents(); + const event = contractDeployed.events.allEvents(); - event.on('data', resolve); - event.on('error', reject); + const eventPromise = new Promise((resolve, reject) => { + event.on('data', resolve); + event.on('error', reject); + }); - // trigger event - await contractDeployed.methods - .firesMultiValueEvent('Pak1', 12, true) - .send(sendOptions); - }), - ).resolves.toEqual( + await contractDeployed.methods.firesMultiValueEvent('Pak1', 12, true).send(sendOptions); + + await expect(eventPromise).resolves.toEqual( expect.objectContaining({ event: 'MultiValueEvent', }), ); + + event.removeAllListeners(); }); }); }); diff --git a/packages/web3-eth-contract/test/integration/contract_filter_events.test.ts b/packages/web3-eth-contract/test/integration/contract_filter_events.test.ts index 338cd448c12..000a305eb72 100644 --- a/packages/web3-eth-contract/test/integration/contract_filter_events.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_filter_events.test.ts @@ -24,6 +24,7 @@ import { getSystemTestProvider, createTempAccount, createNewAccount, + closeOpenConnection, } from '../fixtures/system_test_utils'; const initialSupply = BigInt('5000000000'); @@ -60,6 +61,10 @@ describe('contract getPastEvent filter', () => { await contractDeployed.methods.transfer(toAcc3.address, value).send(sendOptions); }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should filter one event by address with event name and filter param', async () => { const res: EventLog[] = (await contractDeployed.getPastEvents('Transfer', { fromBlock: 'earliest', @@ -155,6 +160,7 @@ describe('contract getPastEvent filter', () => { ); }); }); + describe('basic', () => { let contract: Contract; let contractDeployed: Contract; @@ -188,6 +194,10 @@ describe('contract getPastEvent filter', () => { .send(sendOptions); }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should filter one event by address with event name and filter param', async () => { const res: EventLog[] = (await contractDeployed.getPastEvents( 'MultiValueIndexedEvent', diff --git a/packages/web3-eth-contract/test/integration/contract_methods.test.ts b/packages/web3-eth-contract/test/integration/contract_methods.test.ts index 152c3feec8a..7048fe121d6 100644 --- a/packages/web3-eth-contract/test/integration/contract_methods.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_methods.test.ts @@ -22,6 +22,7 @@ import { createTempAccount, getSystemTestBackend, BACKEND, + closeOpenConnection, } from '../fixtures/system_test_utils'; describe('contract', () => { @@ -47,6 +48,10 @@ describe('contract', () => { contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + describe('methods', () => { describe('call', () => { it('should retrieve the values', async () => { @@ -72,6 +77,8 @@ describe('contract', () => { .send(); const res = await deployedTempContract.methods.getStringValue().call(); expect(res).toBe('string init value'); + + await closeOpenConnection(tempContract); }); describe('revert handling', () => { @@ -191,6 +198,8 @@ describe('contract', () => { await deployedTempContract.methods.setValues(10, 'TEST', true).send(); expect(await deployedTempContract.methods.getStringValue().call()).toBe('TEST'); + + await closeOpenConnection(tempContract); }); it('should returns errors on reverts', async () => { diff --git a/packages/web3-eth-contract/test/integration/contract_methods_errors.test.ts b/packages/web3-eth-contract/test/integration/contract_methods_errors.test.ts index 7c07ee5af8d..276bb23b992 100644 --- a/packages/web3-eth-contract/test/integration/contract_methods_errors.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_methods_errors.test.ts @@ -24,6 +24,7 @@ import { getSystemTestBackend, describeIf, BACKEND, + closeOpenConnection, } from '../fixtures/system_test_utils'; describe('contract errors', () => { @@ -47,8 +48,10 @@ describe('contract errors', () => { const sendOptionsLocal = { from: acc.address, gas: '10000000' }; deployedContract = await contract.deploy(deployOptions).send(sendOptionsLocal); + }); - contract.setProvider(getSystemTestProvider()); + afterAll(async () => { + await closeOpenConnection(contract); }); describeIf(getSystemTestBackend() === BACKEND.GETH)('Test EIP-838 Error Codes', () => { diff --git a/packages/web3-eth-contract/test/integration/contract_negative_numbers.test.ts b/packages/web3-eth-contract/test/integration/contract_negative_numbers.test.ts index bf9283d5a4f..9e29824c2c6 100644 --- a/packages/web3-eth-contract/test/integration/contract_negative_numbers.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_negative_numbers.test.ts @@ -15,7 +15,11 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ import Contract from '../../src'; -import { createTempAccount, getSystemTestProvider } from '../fixtures/system_test_utils'; +import { + closeOpenConnection, + createTempAccount, + getSystemTestProvider, +} from '../fixtures/system_test_utils'; import { NegativeNumbersAbi, NegativeNumbersBytecode, @@ -39,14 +43,15 @@ describe('Contract - NegativeNumbers.sol', () => { data: NegativeNumbersBytecode, arguments: [storedNegativeNumber], }; - sendOptions = { - from: account.address, - gas: '1000000', - }; + sendOptions = { from: account.address }; contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); + afterAll(async () => { + await closeOpenConnection(contract); + }); + it('should retrieve storedNegativeNumber', async () => { const response = await contractDeployed.methods.storedNegativeNumber().call(); expect(response).toBe(BigInt(storedNegativeNumber)); diff --git a/packages/web3-eth-contract/test/integration/contract_simple_overloaded.test.ts b/packages/web3-eth-contract/test/integration/contract_simple_overloaded.test.ts index 0e786b77428..fd71aff487a 100644 --- a/packages/web3-eth-contract/test/integration/contract_simple_overloaded.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_simple_overloaded.test.ts @@ -16,7 +16,11 @@ along with web3.js. If not, see . */ import Contract from '../../src'; import { SimpleOverloadedAbi, SimpleOverloadedBytecode } from '../fixtures/SimpleOverloaded'; -import { createTempAccount, getSystemTestProvider } from '../fixtures/system_test_utils'; +import { + closeOpenConnection, + createTempAccount, + getSystemTestProvider, +} from '../fixtures/system_test_utils'; describe('SimpleOverloaded', () => { let contract: Contract; @@ -32,7 +36,11 @@ describe('SimpleOverloaded', () => { .deploy({ data: SimpleOverloadedBytecode, }) - .send({ from: mainAcc.address, gas: '10000000' }); + .send({ from: mainAcc.address }); + }); + + afterAll(async () => { + await closeOpenConnection(contract); }); it('should call getSecret with no args', async () => { diff --git a/packages/web3-eth-contract/test/integration/local_account/contract_deploy.test.ts b/packages/web3-eth-contract/test/integration/local_account/contract_deploy.test.ts index 821101ca225..cb24ad22fca 100644 --- a/packages/web3-eth-contract/test/integration/local_account/contract_deploy.test.ts +++ b/packages/web3-eth-contract/test/integration/local_account/contract_deploy.test.ts @@ -20,7 +20,11 @@ import Web3 from 'web3'; // eslint-disable-next-line import/no-extraneous-dependencies import { Web3Account } from 'web3-eth-accounts'; import { GreeterBytecode, GreeterAbi } from '../../shared_fixtures/build/Greeter'; -import { getSystemTestProvider, createLocalAccount } from '../../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createLocalAccount, + closeOpenConnection, +} from '../../fixtures/system_test_utils'; import { Contract } from '../../../src'; describe('contract', () => { @@ -31,13 +35,20 @@ describe('contract', () => { let localAccount: Web3Account; let web3: Web3; - beforeEach(async () => { + beforeAll(async () => { web3 = new Web3(getSystemTestProvider()); contract = new web3.eth.Contract(GreeterAbi) as unknown as Contract; deployOptions = { data: GreeterBytecode, arguments: ['My Greeting'], }; + }); + + afterAll(async () => { + await closeOpenConnection(web3); + }); + + beforeEach(async () => { localAccount = await createLocalAccount(web3); sendOptions = { from: localAccount.address, diff --git a/packages/web3-eth-contract/test/integration/local_account/contract_erc20.test.ts b/packages/web3-eth-contract/test/integration/local_account/contract_erc20.test.ts index edff03fe598..35ebc29cc46 100644 --- a/packages/web3-eth-contract/test/integration/local_account/contract_erc20.test.ts +++ b/packages/web3-eth-contract/test/integration/local_account/contract_erc20.test.ts @@ -21,7 +21,11 @@ import Web3 from 'web3'; import { Web3Account } from 'web3-eth-accounts'; import { Contract } from '../../../src'; import { ERC20TokenAbi, ERC20TokenBytecode } from '../../shared_fixtures/build/ERC20Token'; -import { getSystemTestProvider, createLocalAccount } from '../../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createLocalAccount, + closeOpenConnection, +} from '../../fixtures/system_test_utils'; const initialSupply = BigInt('5000000000'); @@ -53,6 +57,10 @@ describe('contract', () => { contractDeployed = await contract.deploy(deployOptions).send(sendOptions); }); + afterAll(async () => { + await closeOpenConnection(web3); + }); + it('should deploy the contract', () => { expect(contractDeployed.options.address).toBeDefined(); }); diff --git a/packages/web3-eth-contract/test/integration/local_account/contract_erc721.test.ts b/packages/web3-eth-contract/test/integration/local_account/contract_erc721.test.ts index d9226c580f1..4ea801ee686 100644 --- a/packages/web3-eth-contract/test/integration/local_account/contract_erc721.test.ts +++ b/packages/web3-eth-contract/test/integration/local_account/contract_erc721.test.ts @@ -21,7 +21,11 @@ import Web3 from 'web3'; import { Web3Account } from 'web3-eth-accounts'; import { Contract } from '../../../src'; import { ERC721TokenAbi, ERC721TokenBytecode } from '../../shared_fixtures/build/ERC721Token'; -import { getSystemTestProvider, createLocalAccount } from '../../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createLocalAccount, + closeOpenConnection, +} from '../../fixtures/system_test_utils'; import { toUpperCaseHex } from '../../shared_fixtures/utils'; describe('contract', () => { @@ -32,6 +36,7 @@ describe('contract', () => { let localAccount: Web3Account; let web3: Web3; let contractDeployed: Contract; + beforeAll(async () => { web3 = new Web3(getSystemTestProvider()); localAccount = await createLocalAccount(web3); @@ -46,11 +51,13 @@ describe('contract', () => { sendOptions = { from: localAccount.address, - gas: '1000000', }; - contractDeployed = await contract - .deploy(deployOptions) - .send({ ...sendOptions, gas: '3000000' }); + contractDeployed = await contract.deploy(deployOptions).send({ ...sendOptions }); + }); + + afterAll(async () => { + await closeOpenConnection(web3); + await closeOpenConnection(contract); }); it('should deploy the contract', () => { diff --git a/packages/web3-eth-contract/test/integration/local_account/contract_overloaded_methods.test.ts b/packages/web3-eth-contract/test/integration/local_account/contract_overloaded_methods.test.ts index 0c905e8ece2..5593e905b3a 100644 --- a/packages/web3-eth-contract/test/integration/local_account/contract_overloaded_methods.test.ts +++ b/packages/web3-eth-contract/test/integration/local_account/contract_overloaded_methods.test.ts @@ -23,7 +23,11 @@ import { utf8ToHex } from 'web3-utils'; import { EventLog } from 'web3-types'; import { Contract } from '../../../src'; import { ERC721TokenAbi, ERC721TokenBytecode } from '../../shared_fixtures/build/ERC721Token'; -import { getSystemTestProvider, createLocalAccount } from '../../fixtures/system_test_utils'; +import { + getSystemTestProvider, + createLocalAccount, + closeOpenConnection, +} from '../../fixtures/system_test_utils'; import { toUpperCaseHex } from '../../shared_fixtures/utils'; describe('contract ERC721 overloaded functions', () => { @@ -55,6 +59,10 @@ describe('contract ERC721 overloaded functions', () => { .send({ ...sendOptions, gas: '3000000' }); }); + afterAll(async () => { + await closeOpenConnection(web3); + }); + it('transferFrom with 4 arguments', async () => { const tempAccount = await createLocalAccount(web3); const toAccount = await createLocalAccount(web3); diff --git a/scripts/system_tests_utils.ts b/scripts/system_tests_utils.ts index e634b98a35b..db460e8229c 100644 --- a/scripts/system_tests_utils.ts +++ b/scripts/system_tests_utils.ts @@ -165,7 +165,8 @@ export const closeOpenConnection = async (web3Context: Web3Context) => { (web3Context.provider as unknown as Web3BaseProvider).disconnect(); await new Promise(resolve => { - setTimeout(resolve, 1000); + const timer = setTimeout(resolve, 1); + timer.unref(); }); } }; @@ -250,8 +251,9 @@ export const createNewAccount = async (config?: { const url = getSystemTestProviderUrl(); const web3 = new Web3(url); web3.registerPlugin(new HardhatPlugin()); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await web3.hardhat.impersonateAccount(acc.address); - // await impersonateAccount(acc.address); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await web3.hardhat.setBalance(acc.address, web3.utils.toHex('100000000')); await closeOpenConnection(web3); } else { @@ -275,6 +277,7 @@ export const createNewAccount = async (config?: { const url = getSystemTestProviderUrl(); const web3 = new Web3(url); web3.registerPlugin(new HardhatPlugin()); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await web3.hardhat.setBalance(acc.address, web3.utils.toHex('100000000')); await closeOpenConnection(web3); } else { @@ -365,7 +368,9 @@ export const signTxAndSendEIP1559 = async ( from: acc.address, }; - return web3.eth.sendTransaction(txObj, undefined, { checkRevertBeforeSending: false }); + return web3.eth.sendTransaction(txObj, undefined, { + checkRevertBeforeSending: false, + }); }; export const signTxAndSendEIP2930 = async ( @@ -383,7 +388,9 @@ export const signTxAndSendEIP2930 = async ( from: acc.address, }; - return web3.eth.sendTransaction(txObj, undefined, { checkRevertBeforeSending: false }); + return web3.eth.sendTransaction(txObj, undefined, { + checkRevertBeforeSending: false, + }); }; export const signAndSendContractMethodEIP1559 = async ( @@ -418,7 +425,7 @@ export const signAndSendContractMethodEIP2930 = async ( export const createLocalAccount = async (web3: Web3) => { const account = web3.eth.accounts.create(); - await refillAccount((await createTempAccount()).address, account.address, '10000000000000000'); + await refillAccount((await createTempAccount()).address, account.address, '100000000000000000'); web3.eth.accounts.wallet.add(account); return account; }; @@ -515,8 +522,8 @@ export const waitForCondition = async ( logicFunc: () => Promise | void, maxIterations = 10, // 10 times duration = 8000, // check after each 8 seconds -): Promise => { - return new Promise((resolve, reject) => { +): Promise => + new Promise((resolve, reject) => { let iterations = 0; // eslint-disable-next-line @typescript-eslint/no-misused-promises const interval = setInterval(async () => { @@ -540,4 +547,3 @@ export const waitForCondition = async ( } }, duration); }); -};