From 994a71d30e9210ce63eb2f1590ed75d38f93814a Mon Sep 17 00:00:00 2001 From: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com> Date: Wed, 28 Jun 2023 08:21:02 +0100 Subject: [PATCH] Add e2e tests for queuing multiple signing operations (#19446) --- test/e2e/tests/eth-sign.spec.js | 122 ++++++- test/e2e/tests/personal-sign.spec.js | 102 +++++- test/e2e/tests/signature-request.spec.js | 436 +++++++++++------------ 3 files changed, 410 insertions(+), 250 deletions(-) diff --git a/test/e2e/tests/eth-sign.spec.js b/test/e2e/tests/eth-sign.spec.js index ce8da87bb..26d585ea5 100644 --- a/test/e2e/tests/eth-sign.spec.js +++ b/test/e2e/tests/eth-sign.spec.js @@ -5,6 +5,7 @@ const { DAPP_URL, defaultGanacheOptions, unlockWallet, + regularDelayMs, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); @@ -36,7 +37,7 @@ describe('Eth sign', function () { }); it('can initiate and confirm a eth sign', async function () { - const expectedPersonalMessage = + const expectedEthSignMessage = '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0'; const expectedEthSignResult = '"0x816ab6c5d5356548cc4e004ef35a37fdfab916742a2bbeda756cd064c3d3789a6557d41d49549be1de249e1937a8d048996dfcc70d0552111605dc7cc471e8531b"'; @@ -69,23 +70,11 @@ describe('Eth sign', function () { windowHandles, ); - await driver.findElement({ - css: '.request-signature__content__title', - text: 'Signature request', - }); + await verifyAndAssertEthSign(driver, DAPP_URL, expectedEthSignMessage); - await driver.findElement({ - css: '.request-signature__origin', - text: DAPP_URL, - }); - - await driver.findElement({ - css: '.request-signature__row-value', - text: expectedPersonalMessage, - }); - - await driver.clickElement('[data-testid="page-container-footer-next"]'); - await driver.clickElement( + await approveEthSign( + driver, + '[data-testid="page-container-footer-next"]', '.signature-request-warning__footer__sign-button', ); // Switch to the Dapp @@ -101,4 +90,103 @@ describe('Eth sign', function () { }, ); }); + + it('can queue multiple eth sign and confirm', async function () { + const expectedEthSignMessage = + '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0'; + const expectedEthSignResult = + '"0x816ab6c5d5356548cc4e004ef35a37fdfab916742a2bbeda756cd064c3d3789a6557d41d49549be1de249e1937a8d048996dfcc70d0552111605dc7cc471e8531b"'; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPreferencesController({ + disabledRpcMethodPreferences: { + eth_sign: true, + }, + }) + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + await openDapp(driver); + // Create eth sign + await driver.clickElement('#ethSign'); + + // Wait for Signature request popup + await driver.waitUntilXWindowHandles(3); + let windowHandles = await driver.getAllWindowHandles(); + + // Switch to Dapp + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + + // Create second eth sign + await driver.clickElement('#ethSign'); + + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + + await driver.waitForSelector({ + text: 'Reject 2 requests', + tag: 'a', + }); + + await verifyAndAssertEthSign(driver, DAPP_URL, expectedEthSignMessage); + + // Confirm first eth sign + await approveEthSign( + driver, + '[data-testid="page-container-footer-next"]', + '.signature-request-warning__footer__sign-button', + ); + + // Confirm second eth sign + await approveEthSign( + driver, + '[data-testid="page-container-footer-next"]', + '.signature-request-warning__footer__sign-button', + ); + + // Switch to the Dapp + await driver.waitUntilXWindowHandles(2); + windowHandles = await driver.getAllWindowHandles(); + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + + // Verify last confirmed request + const result = await driver.findElement('#ethSignResult'); + assert.equal(await result.getText(), expectedEthSignResult); + }, + ); + }); }); + +async function verifyAndAssertEthSign(driver, dappUrl, expectedMessage) { + await driver.findElement({ + css: '.request-signature__content__title', + text: 'Signature request', + }); + + await driver.findElement({ + css: '.request-signature__origin', + text: dappUrl, + }); + + await driver.findElement({ + css: '.request-signature__row-value', + text: expectedMessage, + }); +} + +async function approveEthSign(driver, buttonTestId, signButtonClass) { + await driver.clickElement(buttonTestId); + await driver.clickElement(signButtonClass); + await driver.delay(regularDelayMs); +} diff --git a/test/e2e/tests/personal-sign.spec.js b/test/e2e/tests/personal-sign.spec.js index 9ecd04f52..10e37a7c7 100644 --- a/test/e2e/tests/personal-sign.spec.js +++ b/test/e2e/tests/personal-sign.spec.js @@ -1,5 +1,10 @@ const { strict: assert } = require('assert'); -const { convertToHexValue, withFixtures, openDapp } = require('../helpers'); +const { + convertToHexValue, + withFixtures, + openDapp, + regularDelayMs, +} = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); describe('Personal sign', function () { @@ -33,7 +38,7 @@ describe('Personal sign', function () { await driver.clickElement('#personalSign'); await driver.waitUntilXWindowHandles(3); - let windowHandles = await driver.getAllWindowHandles(); + const windowHandles = await driver.getAllWindowHandles(); await driver.switchToWindowWithTitle( 'MetaMask Notification', windowHandles, @@ -47,23 +52,92 @@ describe('Personal sign', function () { await driver.clickElement('[data-testid="page-container-footer-next"]'); - // Switch to the Dapp - await driver.waitUntilXWindowHandles(2); - windowHandles = await driver.getAllWindowHandles(); + await verifyAndAssertPersonalMessage(driver, publicAddress); + }, + ); + }); + it('can queue multiple personal signs and confirm', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + }; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions, + title: this.test.title, + }, + async ({ driver, ganacheServer }) => { + const addresses = await ganacheServer.getAccounts(); + const publicAddress = addresses[0]; + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + await openDapp(driver); + // Create personal sign + await driver.clickElement('#personalSign'); + + await driver.waitUntilXWindowHandles(3); + const windowHandles = await driver.getAllWindowHandles(); + + // Switch to Dapp await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); - // Verify - await driver.clickElement('#personalSignVerify'); - const verifySigUtil = await driver.findElement( - '#personalSignVerifySigUtilResult', + // Create second personal sign + await driver.clickElement('#personalSign'); + + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, ); - const verifyECRecover = await driver.waitForSelector({ - css: '#personalSignVerifyECRecoverResult', - text: publicAddress, + + await driver.waitForSelector({ + text: 'Reject 2 requests', + tag: 'a', }); - assert.equal(await verifySigUtil.getText(), publicAddress); - assert.equal(await verifyECRecover.getText(), publicAddress); + + const personalMessageRow = await driver.findElement( + '.request-signature__row-value', + ); + const personalMessage = await personalMessageRow.getText(); + assert.equal(personalMessage, 'Example `personal_sign` message'); + + // Confirm first personal sign + await driver.clickElement('[data-testid="page-container-footer-next"]'); + await driver.delay(regularDelayMs); + // Confirm second personal sign + await driver.clickElement('[data-testid="page-container-footer-next"]'); + + await verifyAndAssertPersonalMessage(driver, publicAddress); }, ); }); }); + +async function verifyAndAssertPersonalMessage(driver, publicAddress) { + // Switch to the Dapp + await driver.waitUntilXWindowHandles(2); + const windowHandles = await driver.getAllWindowHandles(); + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + + // Verify last confirmed personal sign + await driver.clickElement('#personalSignVerify'); + const verifySigUtil = await driver.findElement( + '#personalSignVerifySigUtilResult', + ); + const verifyECRecover = await driver.waitForSelector({ + css: '#personalSignVerifyECRecoverResult', + text: publicAddress, + }); + assert.equal(await verifySigUtil.getText(), publicAddress); + assert.equal(await verifyECRecover.getText(), publicAddress); +} diff --git a/test/e2e/tests/signature-request.spec.js b/test/e2e/tests/signature-request.spec.js index f16bdf4ff..9ef703389 100644 --- a/test/e2e/tests/signature-request.spec.js +++ b/test/e2e/tests/signature-request.spec.js @@ -1,240 +1,238 @@ const { strict: assert } = require('assert'); const { - convertToHexValue, withFixtures, regularDelayMs, openDapp, DAPP_URL, + convertToHexValue, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); -describe('Sign Typed Data V4 Signature Request', function () { - it('can initiate and confirm a Signature Request', async function () { - const ganacheOptions = { - accounts: [ - { - secretKey: - '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', - balance: convertToHexValue(25000000000000000000), - }, - ], - }; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions, - title: this.test.title, - }, - async ({ driver, ganacheServer }) => { - const addresses = await ganacheServer.getAccounts(); - const publicAddress = addresses[0]; - await driver.navigate(); - await driver.fill('#password', 'correct horse battery staple'); - await driver.press('#password', driver.Key.ENTER); - - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#signTypedDataV4'); - - await driver.waitUntilXWindowHandles(3); - let windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - 'MetaMask Notification', - windowHandles, - ); - - const title = await driver.findElement( - '.signature-request__content__title', - ); - const origin = await driver.findElement('.signature-request__origin'); - const verifyContractDetailsButton = await driver.findElement( - '.signature-request-content__verify-contract-details', - ); - const message = await driver.findElement( - '.signature-request-data__node__value', - ); - - assert.equal(await title.getText(), 'Signature request'); - assert.equal(await origin.getText(), DAPP_URL); - - verifyContractDetailsButton.click(); - await driver.findElement({ text: 'Third-party details', tag: 'h5' }); - await driver.findElement('[data-testid="recipient"]'); - await driver.clickElement({ text: 'Got it', tag: 'button' }); - - assert.equal(await message.getText(), 'Hello, Bob!'); - // Approve signing typed data - await driver.clickElement( - '[data-testid="signature-request-scroll-button"]', - ); - await driver.delay(regularDelayMs); - await driver.clickElement({ text: 'Sign', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - windowHandles = await driver.getAllWindowHandles(); - - // switch to the Dapp and verify the signed addressed - await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); - await driver.clickElement('#signTypedDataV4Verify'); - const recoveredAddress = await driver.findElement( - '#signTypedDataV4VerifyResult', - ); - assert.equal(await recoveredAddress.getText(), publicAddress); - }, - ); - }); -}); - -/* eslint-disable-next-line mocha/max-top-level-suites */ -describe('Sign Typed Data V3 Signature Request', function () { - it('can initiate and confirm a Signature Request', async function () { - const ganacheOptions = { - accounts: [ - { - secretKey: - '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', - balance: convertToHexValue(25000000000000000000), - }, - ], - }; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions, - title: this.test.title, - }, - async ({ driver, ganacheServer }) => { - const addresses = await ganacheServer.getAccounts(); - const publicAddress = addresses[0]; - await driver.navigate(); - await driver.fill('#password', 'correct horse battery staple'); - await driver.press('#password', driver.Key.ENTER); - - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#signTypedDataV3'); - - await driver.waitUntilXWindowHandles(3); - let windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - 'MetaMask Notification', - windowHandles, - ); - - const title = await driver.findElement( - '.signature-request__content__title', - ); - const origin = await driver.findElement('.signature-request__origin'); - const verifyContractDetailsButton = await driver.findElement( - '.signature-request-content__verify-contract-details', - ); - - const messages = await driver.findElements( - '.signature-request-data__node__value', - ); - - assert.equal(await title.getText(), 'Signature request'); - assert.equal(await origin.getText(), DAPP_URL); - - verifyContractDetailsButton.click(); - await driver.findElement({ text: 'Third-party details', tag: 'h5' }); - await driver.findElement('[data-testid="recipient"]'); - await driver.clickElement({ text: 'Got it', tag: 'button' }); - - assert.equal(await messages[4].getText(), 'Hello, Bob!'); - - // Approve signing typed data - await driver.clickElement( - '[data-testid="signature-request-scroll-button"]', - ); - await driver.delay(regularDelayMs); - await driver.clickElement({ text: 'Sign', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - windowHandles = await driver.getAllWindowHandles(); - - // switch to the Dapp and verify the signed addressed - await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); - await driver.clickElement('#signTypedDataV3Verify'); - const recoveredAddress = await driver.findElement( - '#signTypedDataV3VerifyResult', - ); - assert.equal(await recoveredAddress.getText(), publicAddress); - }, - ); - }); -}); +const signatureRequestType = { + signTypedData: 'Sign Typed Data', + signTypedDataV3: 'Sign Typed Data V3', + signTypedDataV4: 'Sign Typed Data V4', +}; +const testData = [ + { + type: signatureRequestType.signTypedData, + buttonId: '#signTypedData', + verifyId: '#signTypedDataVerify', + verifyResultId: '#signTypedDataVerifyResult', + expectedMessage: 'Hi, Alice!', + verifyAndAssertMessage: { + titleClass: '.request-signature__content__title', + originClass: '.request-signature__origin', + messageClass: '.request-signature__row-value', + }, + }, + { + type: signatureRequestType.signTypedDataV3, + buttonId: '#signTypedDataV3', + verifyId: '#signTypedDataV3Verify', + verifyResultId: '#signTypedDataV3VerifyResult', + expectedMessage: 'Hello, Bob!', + verifyAndAssertMessage: { + titleClass: '.signature-request__content__title', + originClass: '.signature-request__origin', + messageClass: '.signature-request-data__node__value', + }, + }, + { + type: signatureRequestType.signTypedDataV4, + buttonId: '#signTypedDataV4', + verifyId: '#signTypedDataV4Verify', + verifyResultId: '#signTypedDataV4VerifyResult', + expectedMessage: 'Hello, Bob!', + verifyAndAssertMessage: { + titleClass: '.signature-request__content__title', + originClass: '.signature-request__origin', + messageClass: '.signature-request-data__node__value', + }, + }, +]; +const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], +}; describe('Sign Typed Data Signature Request', function () { - it('can initiate and confirm a Signature Request', async function () { - const ganacheOptions = { - accounts: [ + testData.forEach((data) => { + it(`can initiate and confirm a Signature Request of ${data.type}`, async function () { + await withFixtures( { - secretKey: - '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', - balance: convertToHexValue(25000000000000000000), + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions, + title: this.test.title, }, - ], - }; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions, - title: this.test.title, - }, - async ({ driver, ganacheServer }) => { - const addresses = await ganacheServer.getAccounts(); - const publicAddress = addresses[0]; - await driver.navigate(); - await driver.fill('#password', 'correct horse battery staple'); - await driver.press('#password', driver.Key.ENTER); + async ({ driver, ganacheServer }) => { + const addresses = await ganacheServer.getAccounts(); + const publicAddress = addresses[0]; + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); - await openDapp(driver); + await openDapp(driver); - // creates a sign typed data signature request - await driver.clickElement('#signTypedData'); + // creates a sign typed data signature request + await driver.clickElement(data.buttonId); - await driver.waitUntilXWindowHandles(3); - let windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - 'MetaMask Notification', - windowHandles, - ); + await driver.waitUntilXWindowHandles(3); + let windowHandles = await driver.getAllWindowHandles(); + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); - const title = await driver.findElement( - '.request-signature__content__title', - ); - const origin = await driver.findElement('.request-signature__origin'); - const message = await driver.findElements( - '.request-signature__row-value', - ); - assert.equal(await title.getText(), 'Signature request'); - assert.equal(await origin.getText(), DAPP_URL); - assert.equal(await message[0].getText(), 'Hi, Alice!'); - assert.equal(await message[1].getText(), '1337'); + await verifyAndAssertSignTypedData( + driver, + data.type, + data.verifyAndAssertMessage.titleClass, + data.verifyAndAssertMessage.originClass, + data.verifyAndAssertMessage.messageClass, + data.expectedMessage, + ); - // Approve signing typed data - await driver.clickElement({ text: 'Sign', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - windowHandles = await driver.getAllWindowHandles(); + // Approve signing typed data + await approveSignatureRequest( + driver, + data.type, + '[data-testid="signature-request-scroll-button"]', + ); + await driver.waitUntilXWindowHandles(2); + windowHandles = await driver.getAllWindowHandles(); - // switch to the Dapp and verify the signed addressed - await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); - await driver.clickElement('#signTypedDataVerify'); - const recoveredAddress = await driver.findElement( - '#signTypedDataVerifyResult', - ); - assert.equal(await recoveredAddress.getText(), publicAddress); - }, - ); + // switch to the Dapp and verify the signed address + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + await driver.clickElement(data.verifyId); + const recoveredAddress = await driver.findElement( + data.verifyResultId, + ); + + assert.equal(await recoveredAddress.getText(), publicAddress); + }, + ); + }); + }); + + testData.forEach((data) => { + it(`can queue multiple Signature Requests of ${data.type} and confirm`, async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions, + title: this.test.title, + }, + async ({ driver, ganacheServer }) => { + const addresses = await ganacheServer.getAccounts(); + const publicAddress = addresses[0]; + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + await openDapp(driver); + + // creates multiple sign typed data signature requests + await driver.clickElement(data.buttonId); + + await driver.waitUntilXWindowHandles(3); + const windowHandles = await driver.getAllWindowHandles(); + // switches to Dapp + await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); + // creates second sign typed data signature request + await driver.clickElement(data.buttonId); + + await driver.switchToWindowWithTitle( + 'MetaMask Notification', + windowHandles, + ); + + await driver.waitForSelector({ + text: 'Reject 2 requests', + tag: 'a', + }); + + await verifyAndAssertSignTypedData( + driver, + data.type, + data.verifyAndAssertMessage.titleClass, + data.verifyAndAssertMessage.originClass, + data.verifyAndAssertMessage.messageClass, + data.expectedMessage, + ); + + // approve first signature request + await approveSignatureRequest( + driver, + data.type, + '[data-testid="signature-request-scroll-button"]', + ); + await driver.waitUntilXWindowHandles(3); + + // approve second signature request + await approveSignatureRequest( + driver, + data.type, + '[data-testid="signature-request-scroll-button"]', + ); + await driver.waitUntilXWindowHandles(2); + + // switch to the Dapp and verify the signed address for each request + await driver.switchToWindowWithTitle('E2E Test Dapp'); + await driver.clickElement(data.verifyId); + const recoveredAddress = await driver.findElement( + data.verifyResultId, + ); + assert.equal(await recoveredAddress.getText(), publicAddress); + }, + ); + }); }); }); + +async function verifyAndAssertSignTypedData( + driver, + type, + titleClass, + originClass, + messageClass, + expectedMessage, +) { + const title = await driver.findElement(titleClass); + const origin = await driver.findElement(originClass); + + assert.equal(await title.getText(), 'Signature request'); + assert.equal(await origin.getText(), DAPP_URL); + + const messages = await driver.findElements(messageClass); + if (type !== signatureRequestType.signTypedData) { + const verifyContractDetailsButton = await driver.findElement( + '.signature-request-content__verify-contract-details', + ); + verifyContractDetailsButton.click(); + await driver.findElement({ text: 'Third-party details', tag: 'h5' }); + await driver.findElement('[data-testid="recipient"]'); + await driver.clickElement({ text: 'Got it', tag: 'button' }); + } + const messageNumber = type === signatureRequestType.signTypedDataV3 ? 4 : 0; + assert.equal(await messages[messageNumber].getText(), expectedMessage); +} + +async function approveSignatureRequest(driver, type, buttonElementId) { + if (type !== signatureRequestType.signTypedData) { + await driver.clickElement(buttonElementId); + } + await driver.delay(regularDelayMs); + await driver.clickElement({ text: 'Sign', tag: 'button' }); +}