From 0fca0e354238c15a43d513cb997c0bb3f33c649e Mon Sep 17 00:00:00 2001 From: Peter <53189696+PeterYinusa@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:31:14 +0000 Subject: [PATCH] Use deployed contracts in fixtures (#18107) * substitute smart contact address in fixtures * add smart contract fixtures * rename fixture * leverage fixture to import erc1155 * leverage fixture to import erc721 * fix flaky test --- test/e2e/fixture-builder.js | 105 ++++++++++++++++++---- test/e2e/fixture-server.js | 26 ++++-- test/e2e/helpers.js | 2 +- test/e2e/nft/erc1155-interaction.spec.js | 9 ++ test/e2e/nft/remove-erc1155.spec.js | 15 +--- test/e2e/nft/remove-nft.spec.js | 15 +--- test/e2e/nft/send-nft.spec.js | 15 +--- test/e2e/nft/view-erc1155-details.spec.js | 15 +--- test/e2e/nft/view-nft-details.spec.js | 15 +--- test/e2e/tests/send-eth.spec.js | 2 +- 10 files changed, 131 insertions(+), 88 deletions(-) diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index 1c45d4992..4dcaa6ccb 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -4,6 +4,7 @@ const { } = require('@metamask/snaps-utils'); const { merge } = require('lodash'); const { CHAIN_IDS } = require('../../shared/constants/network'); +const { SMART_CONTRACTS } = require('./seeder/smart-contracts'); function defaultFixture() { return { @@ -419,16 +420,6 @@ class FixtureBuilder { return this; } - withNftsController(data) { - merge( - this.fixture.data.NftController - ? this.fixture.data.NftController - : (this.fixture.data.NftController = {}), - data, - ); - return this; - } - withCurrencyController(data) { merge(this.fixture.data.CurrencyController, data); return this; @@ -495,6 +486,91 @@ class FixtureBuilder { return this; } + withNetworkControllerSupportEIP1559() { + merge(this.fixture.data.NetworkController, { + networkDetails: { + EIPS: { 1559: true }, + }, + }); + return this; + } + + withNftController(data) { + merge( + this.fixture.data.NftController + ? this.fixture.data.NftController + : (this.fixture.data.NftController = {}), + data, + ); + return this; + } + + withNftControllerERC1155() { + return this.withNftController({ + allNftContracts: { + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1': { + 1337: [ + { + address: `__FIXTURE_SUBSTITUTION__CONTRACT${SMART_CONTRACTS.ERC1155}`, + }, + ], + }, + }, + allNfts: { + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1': { + 1337: [ + { + address: `__FIXTURE_SUBSTITUTION__CONTRACT${SMART_CONTRACTS.ERC1155}`, + tokenId: '1', + favorite: false, + isCurrentlyOwned: true, + name: 'Rocks', + description: 'This is a collection of Rock NFTs.', + image: + 'ipfs://bafkreifvhjdf6ve4jfv6qytqtux5nd4nwnelioeiqx5x2ez5yrgrzk7ypi', + standard: 'ERC1155', + }, + ], + }, + }, + ignoredNfts: [], + }); + } + + withNftControllerERC721() { + return this.withNftController({ + allNftContracts: { + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1': { + 1337: [ + { + address: `__FIXTURE_SUBSTITUTION__CONTRACT${SMART_CONTRACTS.NFTS}`, + name: 'TestDappCollectibles', + symbol: 'TDC', + }, + ], + }, + }, + allNfts: { + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1': { + 1337: [ + { + address: `__FIXTURE_SUBSTITUTION__CONTRACT${SMART_CONTRACTS.NFTS}`, + description: 'Test Dapp Collectibles for testing.', + favorite: false, + image: + 'data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjM1MCIgd2lkdGg9IjM1MCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdGggaWQ9Ik15UGF0aCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZWQiIGQ9Ik0xMCw5MCBROTAsOTAgOTAsNDUgUTkwLDEwIDUwLDEwIFExMCwxMCAxMCw0MCBRMTAsNzAgNDUsNzAgUTcwLDcwIDc1LDUwIiAvPjwvZGVmcz48dGV4dD48dGV4dFBhdGggaHJlZj0iI015UGF0aCI+UXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgdGhlIGxhenkgZG9nLjwvdGV4dFBhdGg+PC90ZXh0Pjwvc3ZnPg==', + isCurrentlyOwned: true, + name: 'Test Dapp Collectibles #1', + standard: 'ERC721', + tokenId: '1', + }, + ], + }, + }, + ignoredNfts: [], + }); + } + withOnboardingController(data) { merge(this.fixture.data.OnboardingController, data); return this; @@ -1321,15 +1397,6 @@ class FixtureBuilder { }); } - withNetworkSupportEIP1559() { - merge(this.fixture.data.NetworkController, { - networkDetails: { - EIPS: { 1559: true }, - }, - }); - return this; - } - build() { this.fixture.meta = { version: 74, diff --git a/test/e2e/fixture-server.js b/test/e2e/fixture-server.js index bad4bc165..0ef8cd854 100644 --- a/test/e2e/fixture-server.js +++ b/test/e2e/fixture-server.js @@ -8,6 +8,7 @@ const FIXTURE_SERVER_HOST = 'localhost'; const FIXTURE_SERVER_PORT = 12345; const fixtureSubstitutionPrefix = '__FIXTURE_SUBSTITUTION__'; +const CONTRACT_KEY = 'CONTRACT'; const fixtureSubstitutionCommands = { currentDateInMilliseconds: 'currentDateInMilliseconds', }; @@ -16,13 +17,18 @@ const fixtureSubstitutionCommands = { * Perform substitutions on a single piece of state. * * @param {unknown} partialState - The piece of state to perform substitutions on. + * @param {object} contractRegistry - The smart contract registry. * @returns {unknown} The partial state with substititions performed. */ -function performSubstitution(partialState) { +function performSubstitution(partialState, contractRegistry) { if (Array.isArray(partialState)) { - return partialState.map(performSubstitution); + return partialState.map((item) => + performSubstitution(item, contractRegistry), + ); } else if (isObject(partialState)) { - return mapValues(partialState, performSubstitution); + return mapValues(partialState, (item) => + performSubstitution(item, contractRegistry), + ); } else if ( typeof partialState === 'string' && partialState.startsWith(fixtureSubstitutionPrefix) @@ -35,6 +41,9 @@ function performSubstitution(partialState) { fixtureSubstitutionCommands.currentDateInMilliseconds ) { return new Date().getTime(); + } else if (partialState.includes(CONTRACT_KEY)) { + const contract = partialState.split(CONTRACT_KEY).pop(); + return contractRegistry.getContractAddress(contract); } throw new Error(`Unknown substitution command: ${substitutionCommand}`); } @@ -45,10 +54,13 @@ function performSubstitution(partialState) { * Substitute values in the state fixture. * * @param {object} rawState - The state fixture. + * @param {object} contractRegistry - The smart contract registry. * @returns {object} The state fixture with substitutions performed. */ -function performStateSubstitutions(rawState) { - return mapValues(rawState, performSubstitution); +function performStateSubstitutions(rawState, contractRegistry) { + return mapValues(rawState, (item) => { + return performSubstitution(item, contractRegistry); + }); } class FixtureServer { @@ -91,8 +103,8 @@ class FixtureServer { }); } - loadJsonState(rawState) { - const state = performStateSubstitutions(rawState); + loadJsonState(rawState, contractRegistry) { + const state = performStateSubstitutions(rawState, contractRegistry); this._stateMap.set(CURRENT_STATE_KEY, state); } diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 31aa705d9..4efd0ba1b 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -75,7 +75,7 @@ async function withFixtures(options, testSuite) { }); } await fixtureServer.start(); - fixtureServer.loadJsonState(fixtures); + fixtureServer.loadJsonState(fixtures, contractRegistry); await phishingPageServer.start(); if (dapp) { if (dappOptions?.numberOfDapps) { diff --git a/test/e2e/nft/erc1155-interaction.spec.js b/test/e2e/nft/erc1155-interaction.spec.js index a1dcde156..5dcc75203 100644 --- a/test/e2e/nft/erc1155-interaction.spec.js +++ b/test/e2e/nft/erc1155-interaction.spec.js @@ -52,6 +52,10 @@ describe('ERC1155 NFTs testdapp interaction', function () { ); // Confirm Mint + await driver.waitForSelector({ + css: '.confirm-page-container-summary__action__name', + text: 'Deposit', + }); await driver.clickElement({ text: 'Confirm', tag: 'button' }); await driver.waitUntilXWindowHandles(2); await driver.switchToWindow(extension); @@ -101,6 +105,11 @@ describe('ERC1155 NFTs testdapp interaction', function () { windowHandles, ); + // Confirm Transfer + await driver.waitForSelector({ + css: '.confirm-page-container-summary__action__name', + text: 'Deposit', + }); await driver.clickElement({ text: 'Confirm', tag: 'button' }); await driver.waitUntilXWindowHandles(2); await driver.switchToWindow(extension); diff --git a/test/e2e/nft/remove-erc1155.spec.js b/test/e2e/nft/remove-erc1155.spec.js index e03832694..b2b52812c 100644 --- a/test/e2e/nft/remove-erc1155.spec.js +++ b/test/e2e/nft/remove-erc1155.spec.js @@ -19,27 +19,18 @@ describe('Remove ERC1155 NFT', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder().withNftControllerERC1155().build(), ganacheOptions, smartContract, title: this.test.title, }, - async ({ driver, _, contractRegistry }) => { - const contractAddress = - contractRegistry.getContractAddress(smartContract); + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // After login, go to NFTs tab and import an ERC1155 NFT - await driver.clickElement('[data-testid="home__nfts-tab"]'); - await driver.clickElement({ text: 'Import NFTs', tag: 'a' }); - - await driver.fill('[data-testid="address"]', contractAddress); - await driver.fill('[data-testid="token-id"]', '1'); - await driver.clickElement({ text: 'Add', tag: 'button' }); - // Open the details page and click remove nft button + await driver.clickElement('[data-testid="home__nfts-tab"]'); const importedNftImage = await driver.findVisibleElement( '.nfts-items__item img', ); diff --git a/test/e2e/nft/remove-nft.spec.js b/test/e2e/nft/remove-nft.spec.js index 80f6499da..3999d16fb 100644 --- a/test/e2e/nft/remove-nft.spec.js +++ b/test/e2e/nft/remove-nft.spec.js @@ -19,27 +19,18 @@ describe('Remove NFT', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder().withNftControllerERC721().build(), ganacheOptions, smartContract, title: this.test.title, }, - async ({ driver, _, contractRegistry }) => { - const contractAddress = - contractRegistry.getContractAddress(smartContract); + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // After login, go to NFTs tab and import an NFT - await driver.clickElement('[data-testid="home__nfts-tab"]'); - await driver.clickElement({ text: 'Import NFTs', tag: 'a' }); - - await driver.fill('[data-testid="address"]', contractAddress); - await driver.fill('[data-testid="token-id"]', '1'); - await driver.clickElement({ text: 'Add', tag: 'button' }); - // Open the details and click remove nft button + await driver.clickElement('[data-testid="home__nfts-tab"]'); await driver.clickElement('.nfts-items__item-image'); await driver.clickElement('[data-testid="nft-options__button"]'); await driver.clickElement('[data-testid="nft-item-remove"]'); diff --git a/test/e2e/nft/send-nft.spec.js b/test/e2e/nft/send-nft.spec.js index 264557751..2c58af6c5 100644 --- a/test/e2e/nft/send-nft.spec.js +++ b/test/e2e/nft/send-nft.spec.js @@ -19,27 +19,18 @@ describe('Send NFT', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder().withNftControllerERC721().build(), ganacheOptions, smartContract, title: this.test.title, }, - async ({ driver, _, contractRegistry }) => { - const contractAddress = - contractRegistry.getContractAddress(smartContract); + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // After login, go to NFTs tab and import an NFT - await driver.clickElement('[data-testid="home__nfts-tab"]'); - await driver.clickElement({ text: 'Import NFTs', tag: 'a' }); - - await driver.fill('[data-testid="address"]', contractAddress); - await driver.fill('[data-testid="token-id"]', '1'); - await driver.clickElement({ text: 'Add', tag: 'button' }); - // Fill the send NFT form and confirm the transaction + await driver.clickElement('[data-testid="home__nfts-tab"]'); await driver.clickElement('.nfts-items__item-image'); await driver.clickElement({ text: 'Send', tag: 'button' }); await driver.fill( diff --git a/test/e2e/nft/view-erc1155-details.spec.js b/test/e2e/nft/view-erc1155-details.spec.js index 7c035af8b..3a1167728 100644 --- a/test/e2e/nft/view-erc1155-details.spec.js +++ b/test/e2e/nft/view-erc1155-details.spec.js @@ -21,27 +21,18 @@ describe('View ERC1155 NFT details', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder().withNftControllerERC1155().build(), ganacheOptions, smartContract, title: this.test.title, }, - async ({ driver, _, contractRegistry }) => { - const contractAddress = - contractRegistry.getContractAddress(smartContract); + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // After login, go to NFTs tab and import an ERC1155 NFT - await driver.clickElement('[data-testid="home__nfts-tab"]'); - await driver.clickElement({ text: 'Import NFTs', tag: 'a' }); - - await driver.fill('[data-testid="address"]', contractAddress); - await driver.fill('[data-testid="token-id"]', '1'); - await driver.clickElement({ text: 'Add', tag: 'button' }); - // Click to open the NFT details page and check displayed account + await driver.clickElement('[data-testid="home__nfts-tab"]'); const importedNftImage = await driver.findVisibleElement( '.nfts-items__item img', ); diff --git a/test/e2e/nft/view-nft-details.spec.js b/test/e2e/nft/view-nft-details.spec.js index d48e34cdc..7ca84b14b 100644 --- a/test/e2e/nft/view-nft-details.spec.js +++ b/test/e2e/nft/view-nft-details.spec.js @@ -21,27 +21,18 @@ describe('View NFT details', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder().withNftControllerERC721().build(), ganacheOptions, smartContract, title: this.test.title, }, - async ({ driver, _, contractRegistry }) => { - const contractAddress = - contractRegistry.getContractAddress(smartContract); + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // After login, go to NFTs tab and import an NFT - await driver.clickElement('[data-testid="home__nfts-tab"]'); - await driver.clickElement({ text: 'Import NFTs', tag: 'a' }); - - await driver.fill('[data-testid="address"]', contractAddress); - await driver.fill('[data-testid="token-id"]', '1'); - await driver.clickElement({ text: 'Add', tag: 'button' }); - // Click to open the NFT details page and check title + await driver.clickElement('[data-testid="home__nfts-tab"]'); await driver.clickElement('.nfts-items__item-image'); const detailsPageTitle = await driver.findElement('.asset-breadcrumb'); diff --git a/test/e2e/tests/send-eth.spec.js b/test/e2e/tests/send-eth.spec.js index 9e8ec1594..d5005dcf3 100644 --- a/test/e2e/tests/send-eth.spec.js +++ b/test/e2e/tests/send-eth.spec.js @@ -302,7 +302,7 @@ describe('Send ETH from dapp using advanced gas controls', function () { dapp: true, fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() - .withNetworkSupportEIP1559() + .withNetworkControllerSupportEIP1559() .build(), ganacheOptions, title: this.test.title,