diff --git a/old-ui/app/components/account-dropdowns.js b/old-ui/app/components/account-dropdowns.js index 44f8e46cfdd7..41cefd0c450a 100644 --- a/old-ui/app/components/account-dropdowns.js +++ b/old-ui/app/components/account-dropdowns.js @@ -288,6 +288,19 @@ class AccountDropdowns extends Component { }, 'Copy address to clipboard', ), + ifContractAcc(keyring) ? h( + DropdownMenuItem, + { + closeMenu: () => {}, + onClick: async () => { + const { selected } = this.props + const contractProps = await this.props.actions.getContract(selected) + const abi = contractProps && contractProps.abi + copyToClipboard(JSON.stringify(abi)) + }, + }, + 'Copy ABI to clipboard', + ) : null, (!this.ifHardwareAcc(keyring) && !(ifContractAcc(keyring))) ? h( DropdownMenuItem, { @@ -391,6 +404,7 @@ const mapDispatchToProps = (dispatch) => { showConnectHWWalletPage: () => dispatch(actions.showConnectHWWalletPage()), showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), showDeleteImportedAccount: (identity) => dispatch(actions.showDeleteImportedAccount(identity)), + getContract: (addr) => dispatch(actions.getContract(addr)), }, } } diff --git a/package-lock.json b/package-lock.json index 8f636ff3ffe6..0cc5421dcd1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10543,6 +10543,16 @@ "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereum-common": { @@ -10966,6 +10976,16 @@ "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereum-common": { diff --git a/test/e2e/elements.js b/test/e2e/elements.js index 071977d49f7d..a0d327b5a097 100644 --- a/test/e2e/elements.js +++ b/test/e2e/elements.js @@ -42,7 +42,7 @@ module.exports = { menu: By.className('account-dropdown'), showQRcode: By.css('#app-content > div > div.app-primary.from-right > div > div > div:nth-child(1) > flex-column > div.name-label > div > span > div > div > div > li:nth-child(3)'), exportPR: By.css('#app-content > div > div.app-primary.from-right > div > div > div:nth-child(1) > flex-column > div.name-label > div > span > div > div > div > li:nth-child(5)'), - + item: By.className('dropdown-menu-item'), }, networks: { addedCustomRpc: By.className('span custom-rpc'), @@ -60,7 +60,7 @@ module.exports = { }, executeMethod: { - + copy: By.className('clipboard cursor-pointer'), title: By.className('flex-center send-header'), titleText: 'Execute Method', selectArrow: By.className('Select-arrow-zone'), diff --git a/test/e2e/metamask.spec.js b/test/e2e/metamask.spec.js index 6fbccc5e4783..6ab4c50d9904 100644 --- a/test/e2e/metamask.spec.js +++ b/test/e2e/metamask.spec.js @@ -4,6 +4,7 @@ const mkdirp = require('mkdirp') const path = require('path') const assert = require('assert') const pify = require('pify') +const clipboardy = require('clipboardy') const webdriver = require('selenium-webdriver') const { By, Key } = webdriver const { delay, buildChromeWebDriver, buildFirefoxWebdriver, installWebExt, getExtensionIdChrome, getExtensionIdFirefox } = require('./func') @@ -16,6 +17,7 @@ const eventsEmitter = 'https://vbaranov.github.io/event-listener-dapp/' describe('Metamask popup page', async function () { let driver, accountAddress, tokenAddress, extensionId let password = '123456789' + let abiClipboard const newPassword = { correct: 'abcDEF123!@#', short: '123', @@ -140,6 +142,11 @@ describe('Metamask popup page', async function () { assert.notEqual(field, false, 'copy icon doesn\'t present') }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.length, 42, "address account wasn't copied to clipboard") + }) + it('open \'Account name\' change dialog', async () => { const menu = await waitUntilShowUp(menus.dot.menu) await menu.click() @@ -222,6 +229,11 @@ describe('Metamask popup page', async function () { assert.notEqual(field, false, 'copy icon doesn\'t present') }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.length, 42, "address account wasn't copied to clipboard") + }) + it('close QR code screen by clicking button arrow', async () => { const button = await waitUntilShowUp(screens.QRcode.buttonArrow) await click(button) @@ -245,7 +257,6 @@ describe('Metamask popup page', async function () { }) describe('Import Contract account', async () => { - // const poaContract = '0xc6468767214c577013a904900ada0a0dd6653bc3' const contractSokol = '0x215b2ab35749e5a9f3efe890de602fb9844e842f' console.log('Contract ' + contractSokol + ' , Sokol') const wrongAddress = '0xB87b6077D59B01Ab9fa8cd5A1A21D02a4d60D35' @@ -267,6 +278,7 @@ describe('Metamask popup page', async function () { }) it("Select type 'Contract'", async function () { + await delay(1000) const field = await waitUntilShowUp(screens.importAccounts.selectArrow) await field.click() const item = await waitUntilShowUp(screens.importAccounts.itemContract) @@ -296,12 +308,7 @@ describe('Metamask popup page', async function () { assert.notEqual(field, false, "field 'ABI' isn't displayed") }) - it('icon copy is displayed for ABI ', async function () { - const field = await waitUntilShowUp(screens.importAccounts.iconCopy) - assert.notEqual(field, false, "icon copy isn't displayed") - }) - - it("Field 'ABI' is empty if contract isn't verified in current network", async function () { + it("Field 'ABI' is empty if contract isn't verified in current network", async function () { const field = await waitUntilShowUp(screens.importAccounts.contractABI) assert.equal(await field.getText(), '', "field 'ABI' isn't displayed") }) @@ -331,8 +338,19 @@ describe('Metamask popup page', async function () { it('ABI is fetched ', async function () { const field = await waitUntilShowUp(screens.importAccounts.contractABI) - const abi = await field.getText() - assert.equal(abi.length, 4457, "ABI isn't fetched") + abiClipboard = await field.getText() + assert.equal(abiClipboard.length, 4457, "ABI isn't fetched") + }) + + it('icon copy is displayed for ABI ', async function () { + const field = await waitUntilShowUp(screens.importAccounts.iconCopy) + assert.notEqual(field, false, "icon copy isn't displayed") + await field.click() + }) + + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text, abiClipboard, "address account wasn't copied to clipboard") }) it("Click button 'Import', main screen opens", async function () { @@ -341,8 +359,36 @@ describe('Metamask popup page', async function () { const ident = await waitUntilShowUp(screens.main.identicon, 20) assert.notEqual(ident, false, "main screen isn't opened") }) + }) + describe("Check 3dot menu for 'Contract' account", () => { + it('open 3dot menu', async function () { + const menu = await waitUntilShowUp(menus.dot.menu) + await menu.click() + await waitUntilShowUp(menus.dot.item) + const items = await driver.findElements(menus.dot.item) + assert.equal(items.length, 4, '3dot menu has incorrect number of items') + }) + it('Check text of items', async function () { + const items = await driver.findElements(menus.dot.item) + assert.equal(await items[0].getText(), 'View on block explorer', '1st item has incorrect text') + assert.equal(await items[1].getText(), 'Show QR Code', '2st item has incorrect text') + assert.equal(await items[2].getText(), 'Copy address to clipboard', '3st item has incorrect text') + assert.equal(await items[3].getText(), 'Copy ABI to clipboard', '4st item has incorrect text') + }) + it("Click 'Copy ABI'", async function () { + const items = await driver.findElements(menus.dot.item) + await items[3].click() + const menu = await waitUntilShowUp(menus.dot.item, 20) + assert.equal(menu, false, "3dot menu wasn't closed") + }) + + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text, abiClipboard, "ABI wasn't copied to clipboard") + }) }) + describe('Execute Method screen', () => { const notContractAddress = '0x56B2e3C3cFf7f3921Dc2e0F8B8e20d1eEc29216b' describe("Check UI and button's functionality", () => { @@ -419,6 +465,16 @@ describe('Metamask popup page', async function () { assert.equal(text.toLowerCase(), address.toLowerCase(), 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), address.toLowerCase(), "output wasn't copied to clipboard") + }) + it("2nd call doesn't throw the error", async function () { const button = await waitUntilShowUp(screens.executeMethod.buttonCall) assert.notEqual(button, false, "button 'Call data' isn't displayed") @@ -434,6 +490,7 @@ describe('Metamask popup page', async function () { const stringValue = 'POA network' it("Select method 'returnString'", async function () { + await delay(3000) const field = await waitUntilShowUp(screens.executeMethod.selectArrow) await field.click() await waitUntilShowUp(screens.executeMethod.items) @@ -464,6 +521,15 @@ describe('Metamask popup page', async function () { const text = await waitUntilHasValue(fields[1]) assert.equal(text, stringValue, 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), stringValue.toLowerCase(), "output wasn't copied to clipboard") + }) }) describe('Check output for data type : BOOLEAN', () => { @@ -521,6 +587,15 @@ describe('Metamask popup page', async function () { const text = await waitUntilHasValue(fields[1]) assert.equal(text, 'false', 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), 'false', "output wasn't copied to clipboard") + }) }) describe('Check output for data type : BYTES', () => { @@ -558,6 +633,16 @@ describe('Metamask popup page', async function () { const text = await waitUntilHasValue(fields[1]) assert.equal(text, bytesValue, 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), bytesValue.toLowerCase(), "output wasn't copied to clipboard") + }) + }) describe('Check output for data type : UINT256', () => { @@ -595,6 +680,16 @@ describe('Metamask popup page', async function () { assert.equal(text, uint256Value, 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), uint256Value.toLowerCase(), "output wasn't copied to clipboard") + }) + }) describe('Check output for data type : INT256', () => { @@ -631,6 +726,16 @@ describe('Metamask popup page', async function () { const text = await waitUntilHasValue(fields[1]) assert.equal(text, int256Value, 'incorrect value was returned') }) + it('icon copy cliboard is displayed and clickable', async function () { + const icon = await waitUntilShowUp(screens.executeMethod.copy) + assert.notEqual(icon, false, 'icon copy isn\'t displayed') + await icon.click() + }) + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.toLowerCase(), int256Value.toLowerCase(), "output wasn't copied to clipboard") + }) + }) describe('Check executed method', () => { @@ -1020,8 +1125,15 @@ describe('Metamask popup page', async function () { }) it('icon copy cliboard is displayed and clickable', async function () { - const field = await waitUntilShowUp(screens.yourPR.copy) - assert.notEqual(field, false, 'icon copy isn\'t displayed') + await waitUntilShowUp(screens.yourPR.copy) + const icons = await driver.findElements(screens.yourPR.copy) + assert.notEqual(icons[1], false, 'icon copy isn\'t displayed') + await icons[1].click() + }) + + it('Check clipboard buffer', async function () { + const text = clipboardy.readSync() + assert.equal(text.length, 64, "private key wasn't copied to clipboard") }) it('file loaded if click button \'Save\' ', async function () {