From 0e82a3c35c228cca6ea069bedafd2ce2135dcf14 Mon Sep 17 00:00:00 2001 From: rabi-siddique Date: Wed, 28 Feb 2024 17:37:47 +0500 Subject: [PATCH 1/3] feature: adding keplr interaction for creating an account using private key --- commands/keplr.js | 77 +++++++++++++++++++++-------- commands/playwright-keplr.js | 30 ++++++++--- pages/keplr/first-time-flow-page.js | 2 + plugins/keplr-plugin.js | 1 + support/commands.js | 4 ++ tests/e2e/specs/keplr/keplr-spec.js | 39 ++++++++------- 6 files changed, 108 insertions(+), 45 deletions(-) diff --git a/commands/keplr.js b/commands/keplr.js index 1f7dca9a8..ae7dddda5 100644 --- a/commands/keplr.js +++ b/commands/keplr.js @@ -48,6 +48,43 @@ const keplr = { onboardingElements.useRecoveryPhraseButton, await playwright.keplrWindow(), ); + + if (secretWords.includes(' ')) { + await module.exports.importWalletWithPhrase(secretWords, password); + } else { + await module.exports.importWalletWithPrivateKey(secretWords, password); + } + + await playwright.waitAndClick( + onboardingElements.submitWalletDataButton, + await playwright.keplrWindow(), + { number: 1 }, + ); + + await playwright.waitForByText( + onboardingElements.phraseSelectChain, + await playwright.keplrWindow(), + ); + + await playwright.waitAndClick( + onboardingElements.submitChainButton, + await playwright.keplrWindow(), + ); + + await playwright.waitForByText( + onboardingElements.phraseAccountCreated, + await playwright.keplrWindow(), + ); + + await playwright.waitAndClick( + onboardingElements.finishButton, + await playwright.keplrWindow(), + { dontWait: true }, + ); + + return true; + }, + async importWalletWithPhrase(secretWords, password) { await playwright.waitAndClickByText( onboardingElements.phraseCount24, await playwright.keplrWindow(), @@ -75,37 +112,37 @@ const keplr = { onboardingElements.confirmPasswordInput, password, ); + }, + async importWalletWithPrivateKey(privateKey, password) { + await playwright.clickByText(onboardingElements.phrasePrivateKey); - await playwright.waitAndClick( - onboardingElements.submitWalletDataButton, - await playwright.keplrWindow(), - { number: 1 }, - ); - - await playwright.waitForByText( - onboardingElements.phraseSelectChain, - await playwright.keplrWindow(), + await playwright.waitAndTypeByLocator( + onboardingElements.textAreaSelector, + privateKey, ); await playwright.waitAndClick( - onboardingElements.submitChainButton, + onboardingElements.submitPhraseButton, await playwright.keplrWindow(), ); - await playwright.waitForByText( - onboardingElements.phraseAccountCreated, - await playwright.keplrWindow(), + await playwright.waitAndType( + onboardingElements.walletInput, + onboardingElements.walletName, ); - await playwright.waitAndClick( - onboardingElements.finishButton, - await playwright.keplrWindow(), - { dontWait: true }, + const passwordFieldExists = await playwright.doesElementExist( + onboardingElements.passwordInput, ); - return true; + if (passwordFieldExists) { + await playwright.waitAndType(onboardingElements.passwordInput, password); + await playwright.waitAndType( + onboardingElements.confirmPasswordInput, + password, + ); + } }, - async acceptAccess() { const notificationPage = await playwright.switchToKeplrNotification(); await playwright.waitAndClick( @@ -143,4 +180,4 @@ const keplr = { }, }; -module.exports = keplr; \ No newline at end of file +module.exports = keplr; diff --git a/commands/playwright-keplr.js b/commands/playwright-keplr.js index c7fc975c6..722bc90e2 100644 --- a/commands/playwright-keplr.js +++ b/commands/playwright-keplr.js @@ -7,6 +7,7 @@ let browser; let mainWindow; let keplrWindow; let keplrNotificationWindow; +let keplrRegistrationWindow; let activeTabName; let extensionsData = {}; let retries = 0; @@ -19,6 +20,7 @@ module.exports = { keplrWindow = undefined; activeTabName = undefined; keplrNotificationWindow = undefined; + keplrRegistrationWindow = undefined; retries = 0; extensionsData = {}; }, @@ -77,6 +79,10 @@ module.exports = { return keplrNotificationWindow; }, + async clickByText(text, page = keplrWindow) { + await page.click(`text="${text}"`); + }, + async waitAndClickByText(text, page = keplrWindow) { await module.exports.waitForByText(text, page); const element = `:is(:text-is("${text}"), :text("${text}"))`; @@ -170,16 +176,13 @@ module.exports = { }, async waitUntilStable(page) { - const keplrExtensionData = (await module.exports.getExtensionsData()) - .keplr; + const keplrExtensionData = (await module.exports.getExtensionsData()).keplr; if ( page && page .url() - .includes( - `chrome-extension://${keplrExtensionData.id}/register.html`, - ) + .includes(`chrome-extension://${keplrExtensionData.id}/register.html`) ) { await page.waitForLoadState('load'); await page.waitForLoadState('domcontentloaded'); @@ -216,6 +219,14 @@ module.exports = { } return element; }, + async doesElementExist(selector, timeout = 1000, page = keplrWindow) { + try { + await page.waitForSelector(selector, { timeout }); + return true; + } catch (error) { + return false; + } + }, async waitForByText(text, page = keplrWindow) { await module.exports.waitUntilStable(page); // await page.waitForSelector(selector, { strict: false }); @@ -347,6 +358,13 @@ module.exports = { return extensionsData; }, + async switchToKeplrRegistrationWindow() { + const keplrExtensionData = (await module.exports.getExtensionsData()).keplr; + const browserContext = await browser.contexts()[0]; + keplrRegistrationWindow = await browserContext.newPage(); + await keplrRegistrationWindow.goto(`chrome-extension://${keplrExtensionData.id}/register.html`); + return true; + }, async switchToKeplrNotification() { const keplrExtensionData = (await module.exports.getExtensionsData()).keplr; @@ -375,4 +393,4 @@ module.exports = { ); } }, -}; \ No newline at end of file +}; diff --git a/pages/keplr/first-time-flow-page.js b/pages/keplr/first-time-flow-page.js index d79d6e7f9..786d5c428 100644 --- a/pages/keplr/first-time-flow-page.js +++ b/pages/keplr/first-time-flow-page.js @@ -2,6 +2,7 @@ const createWalletButton = 'Create a new wallet'; const importRecoveryPhraseButton = 'Import existing recovery phrase'; const useRecoveryPhraseButton = 'Use recovery phrase or private key'; const phraseCount24 = '24 words'; +const phrasePrivateKey = 'Private key'; const walletInput = 'input[name="name"]:focus'; const passwordInput = 'input[name="password"]'; const confirmPasswordInput = 'input[name="confirmPassword"]'; @@ -19,6 +20,7 @@ module.exports.onboardingElements = { importRecoveryPhraseButton, useRecoveryPhraseButton, phraseCount24, + phrasePrivateKey, walletInput, walletName, passwordInput, diff --git a/plugins/keplr-plugin.js b/plugins/keplr-plugin.js index 99ef9be15..96d07b169 100644 --- a/plugins/keplr-plugin.js +++ b/plugins/keplr-plugin.js @@ -59,6 +59,7 @@ module.exports = (on, config) => { clearWindows: playwright.clearWindows, isCypressWindowActive: playwright.isCypressWindowActive, switchToExtensionWindow: playwright.switchToKeplrWindow, + switchToExtensionRegistrationWindow: playwright.switchToKeplrRegistrationWindow, // keplr commands importWallet: keplr.importWallet, diff --git a/support/commands.js b/support/commands.js index 1c5363a62..d357a6748 100644 --- a/support/commands.js +++ b/support/commands.js @@ -437,4 +437,8 @@ Cypress.Commands.add('isExtensionWindowActive', () => { Cypress.Commands.add('switchToExtensionWindow', () => { return cy.task('switchToExtensionWindow'); +}); + +Cypress.Commands.add('switchToExtensionRegistrationWindow', () => { + return cy.task('switchToExtensionRegistrationWindow'); }); \ No newline at end of file diff --git a/tests/e2e/specs/keplr/keplr-spec.js b/tests/e2e/specs/keplr/keplr-spec.js index 28e5b3049..5c11b5b56 100644 --- a/tests/e2e/specs/keplr/keplr-spec.js +++ b/tests/e2e/specs/keplr/keplr-spec.js @@ -1,30 +1,31 @@ /* eslint-disable ui-testing/no-disabled-tests */ describe('Keplr', () => { - context('Test commands', () => { - it(`setupWallet should finish Keplr setup using secret words`, () => { - cy.setupWallet().then(setupFinished => { - expect(setupFinished).to.be.true; - }); - }); - - it(`acceptAccess should accept connection request to Keplr`, () => { + context('Test commands', () => { + it(`should complete Keplr connect with wallet, and confirm transaction after importing a wallet using 24 word phrase`, () => { + cy.setupWallet().then(setupFinished => { + expect(setupFinished).to.be.true; + cy.visit('/'); cy.contains('Connect Wallet').click(); cy.acceptAccess().then(taskCompleted => { expect(taskCompleted).to.be.true; + + cy.contains('Make an Offer').click(); + cy.confirmTransaction().then(taskCompleted => { + expect(taskCompleted).to.be.true; + }); }); - cy.get('.card') - .contains('My Wallet') - .then(p => console.log(p)); - - cy.contains('agoric1p2aqakv3ulz4qfy2nut86j9gx0dx0yw09h96md'); }); - - it(`confirmTransaction should confirm transaction for token creation (contract deployment) and check tx data`, () => { - cy.contains('Make an Offer').click(); - cy.confirmTransaction().then(taskCompleted => { - expect(taskCompleted).to.be.true; + }); + + it(`should complete Keplr setup by importing the wallet using private key`, () => { + cy.switchToExtensionRegistrationWindow().then(() => { + cy.setupWallet( + 'A9C09B6E4AF70DE1F1B621CB1AA66CFD0B4AA977E4C18497C49132DD9E579485', + ).then(setupFinished => { + expect(setupFinished).to.be.true; }); }); }); - }); \ No newline at end of file + }); +}); From e48a42b4a9a10de27b896f9998b0a4fa81fd4c40 Mon Sep 17 00:00:00 2001 From: rabi-siddique Date: Wed, 28 Feb 2024 22:09:11 +0500 Subject: [PATCH 2/3] feature: keplr interaction for importing an existing wallet and creating a new wallet --- commands/keplr.js | 77 +++++++++++++++-------------- pages/keplr/first-time-flow-page.js | 4 +- plugins/keplr-plugin.js | 8 +-- support/commands.js | 4 +- tests/e2e/specs/keplr/keplr-spec.js | 25 +++++++++- 5 files changed, 71 insertions(+), 47 deletions(-) diff --git a/commands/keplr.js b/commands/keplr.js index ae7dddda5..978703747 100644 --- a/commands/keplr.js +++ b/commands/keplr.js @@ -35,26 +35,50 @@ const keplr = { }; }, - async importWallet(secretWords, password) { + async importWallet(secretWords, password, newAccount) { await playwright.waitAndClickByText( - onboardingElements.createWalletButton, - await playwright.keplrWindow(), - ); - await playwright.waitAndClickByText( - onboardingElements.importRecoveryPhraseButton, + newAccount + ? onboardingElements.createWalletButton + : onboardingElements.existingWalletButton, await playwright.keplrWindow(), ); + await playwright.waitAndClickByText( - onboardingElements.useRecoveryPhraseButton, + newAccount + ? onboardingElements.importRecoveryPhraseButton + : onboardingElements.useRecoveryPhraseButton, await playwright.keplrWindow(), ); + newAccount && + (await playwright.waitAndClickByText( + onboardingElements.useRecoveryPhraseButton, + await playwright.keplrWindow(), + )); + if (secretWords.includes(' ')) { await module.exports.importWalletWithPhrase(secretWords, password); } else { await module.exports.importWalletWithPrivateKey(secretWords, password); } + await playwright.waitAndType( + onboardingElements.walletInput, + onboardingElements.walletName, + ); + + const passwordFieldExists = await playwright.doesElementExist( + onboardingElements.passwordInput, + ); + + if (passwordFieldExists) { + await playwright.waitAndType(onboardingElements.passwordInput, password); + await playwright.waitAndType( + onboardingElements.confirmPasswordInput, + password, + ); + } + await playwright.waitAndClick( onboardingElements.submitWalletDataButton, await playwright.keplrWindow(), @@ -84,7 +108,7 @@ const keplr = { return true; }, - async importWalletWithPhrase(secretWords, password) { + async importWalletWithPhrase(secretWords) { await playwright.waitAndClickByText( onboardingElements.phraseCount24, await playwright.keplrWindow(), @@ -102,18 +126,8 @@ const keplr = { onboardingElements.submitPhraseButton, await playwright.keplrWindow(), ); - - await playwright.waitAndType( - onboardingElements.walletInput, - onboardingElements.walletName, - ); - await playwright.waitAndType(onboardingElements.passwordInput, password); - await playwright.waitAndType( - onboardingElements.confirmPasswordInput, - password, - ); }, - async importWalletWithPrivateKey(privateKey, password) { + async importWalletWithPrivateKey(privateKey) { await playwright.clickByText(onboardingElements.phrasePrivateKey); await playwright.waitAndTypeByLocator( @@ -125,23 +139,6 @@ const keplr = { onboardingElements.submitPhraseButton, await playwright.keplrWindow(), ); - - await playwright.waitAndType( - onboardingElements.walletInput, - onboardingElements.walletName, - ); - - const passwordFieldExists = await playwright.doesElementExist( - onboardingElements.passwordInput, - ); - - if (passwordFieldExists) { - await playwright.waitAndType(onboardingElements.passwordInput, password); - await playwright.waitAndType( - onboardingElements.confirmPasswordInput, - password, - ); - } }, async acceptAccess() { const notificationPage = await playwright.switchToKeplrNotification(); @@ -165,7 +162,7 @@ const keplr = { async initialSetup( playwrightInstance, - { secretWordsOrPrivateKey, password }, + { secretWordsOrPrivateKey, password, newAccount }, ) { if (playwrightInstance) { await playwright.init(playwrightInstance); @@ -176,7 +173,11 @@ const keplr = { await playwright.assignWindows(); await playwright.assignActiveTabName('keplr'); await module.exports.getExtensionDetails(); - await module.exports.importWallet(secretWordsOrPrivateKey, password); + await module.exports.importWallet( + secretWordsOrPrivateKey, + password, + newAccount, + ); }, }; diff --git a/pages/keplr/first-time-flow-page.js b/pages/keplr/first-time-flow-page.js index 786d5c428..7bfc1bf52 100644 --- a/pages/keplr/first-time-flow-page.js +++ b/pages/keplr/first-time-flow-page.js @@ -1,5 +1,6 @@ const createWalletButton = 'Create a new wallet'; -const importRecoveryPhraseButton = 'Import existing recovery phrase'; +const existingWalletButton = 'Import an existing wallet'; +const importRecoveryPhraseButton = 'Import existing recovery phrase'; const useRecoveryPhraseButton = 'Use recovery phrase or private key'; const phraseCount24 = '24 words'; const phrasePrivateKey = 'Private key'; @@ -16,6 +17,7 @@ const textAreaSelector = 'textbox'; const submitPhraseButton = 'button[type="submit"]'; module.exports.onboardingElements = { + existingWalletButton, createWalletButton, importRecoveryPhraseButton, useRecoveryPhraseButton, diff --git a/plugins/keplr-plugin.js b/plugins/keplr-plugin.js index 96d07b169..2d018276c 100644 --- a/plugins/keplr-plugin.js +++ b/plugins/keplr-plugin.js @@ -67,17 +67,13 @@ module.exports = (on, config) => { confirmTransaction: keplr.confirmTransaction, setupWallet: async ({ secretWordsOrPrivateKey, - network, password, - enableAdvancedSettings, - enableExperimentalSettings, + newAccount, }) => { await keplr.initialSetup(null, { secretWordsOrPrivateKey, - network, password, - enableAdvancedSettings, - enableExperimentalSettings, + newAccount }); return true; }, diff --git a/support/commands.js b/support/commands.js index d357a6748..0dac7f6a2 100644 --- a/support/commands.js +++ b/support/commands.js @@ -415,10 +415,12 @@ Cypress.Commands.add( ( secretWordsOrPrivateKey = 'orbit bench unit task food shock brand bracket domain regular warfare company announce wheel grape trust sphere boy doctor half guard ritual three ecology', password = 'Test1234', + newAccount = false ) => { return cy.task('setupWallet', { secretWordsOrPrivateKey, - password + password, + newAccount }); }, ); diff --git a/tests/e2e/specs/keplr/keplr-spec.js b/tests/e2e/specs/keplr/keplr-spec.js index 5c11b5b56..fb7588bb6 100644 --- a/tests/e2e/specs/keplr/keplr-spec.js +++ b/tests/e2e/specs/keplr/keplr-spec.js @@ -1,7 +1,7 @@ /* eslint-disable ui-testing/no-disabled-tests */ describe('Keplr', () => { context('Test commands', () => { - it(`should complete Keplr connect with wallet, and confirm transaction after importing a wallet using 24 word phrase`, () => { + it(`should complete Keplr connect with wallet, and confirm transaction after importing an existing wallet using 24 word phrase`, () => { cy.setupWallet().then(setupFinished => { expect(setupFinished).to.be.true; @@ -18,6 +18,29 @@ describe('Keplr', () => { }); }); + it(`should complete Keplr connect with wallet, and confirm transaction after creating a new wallet using 24 word phrase`, () => { + cy.switchToExtensionRegistrationWindow().then(() => { + cy.setupWallet( + 'orbit bench unit task food shock brand bracket domain regular warfare company announce wheel grape trust sphere boy doctor half guard ritual three ecology', + 'Test1234', + true, + ).then(setupFinished => { + expect(setupFinished).to.be.true; + + cy.visit('/'); + cy.contains('Connect Wallet').click(); + cy.acceptAccess().then(taskCompleted => { + expect(taskCompleted).to.be.true; + + cy.contains('Make an Offer').click(); + cy.confirmTransaction().then(taskCompleted => { + expect(taskCompleted).to.be.true; + }); + }); + }); + }); + }); + it(`should complete Keplr setup by importing the wallet using private key`, () => { cy.switchToExtensionRegistrationWindow().then(() => { cy.setupWallet( From d3be1b997a5dbc1826a4e3a0fb49ed8b6fc8456b Mon Sep 17 00:00:00 2001 From: Fraz Arshad Date: Fri, 1 Mar 2024 14:04:42 +0500 Subject: [PATCH 3/3] fix: fixed implementation of waitAndClickByText to perform exact matching --- commands/keplr.js | 20 +++++++++++++++----- commands/playwright-keplr.js | 12 +++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/commands/keplr.js b/commands/keplr.js index 978703747..891293fa5 100644 --- a/commands/keplr.js +++ b/commands/keplr.js @@ -35,7 +35,7 @@ const keplr = { }; }, - async importWallet(secretWords, password, newAccount) { + async importWallet(secretWordsOrPrivateKey, password, newAccount) { await playwright.waitAndClickByText( newAccount ? onboardingElements.createWalletButton @@ -56,10 +56,16 @@ const keplr = { await playwright.keplrWindow(), )); - if (secretWords.includes(' ')) { - await module.exports.importWalletWithPhrase(secretWords, password); + if (secretWordsOrPrivateKey.includes(' ')) { + await module.exports.importWalletWithPhrase( + secretWordsOrPrivateKey, + password, + ); } else { - await module.exports.importWalletWithPrivateKey(secretWords, password); + await module.exports.importWalletWithPrivateKey( + secretWordsOrPrivateKey, + password, + ); } await playwright.waitAndType( @@ -128,7 +134,11 @@ const keplr = { ); }, async importWalletWithPrivateKey(privateKey) { - await playwright.clickByText(onboardingElements.phrasePrivateKey); + await playwright.waitAndClickByText( + onboardingElements.phrasePrivateKey, + await playwright.keplrWindow(), + true, + ); await playwright.waitAndTypeByLocator( onboardingElements.textAreaSelector, diff --git a/commands/playwright-keplr.js b/commands/playwright-keplr.js index 722bc90e2..0d953b3db 100644 --- a/commands/playwright-keplr.js +++ b/commands/playwright-keplr.js @@ -79,13 +79,9 @@ module.exports = { return keplrNotificationWindow; }, - async clickByText(text, page = keplrWindow) { - await page.click(`text="${text}"`); - }, - - async waitAndClickByText(text, page = keplrWindow) { + async waitAndClickByText(text, page = keplrWindow, exact = false) { await module.exports.waitForByText(text, page); - const element = `:is(:text-is("${text}"), :text("${text}"))`; + const element = `:is(:text-is("${text}")${exact ? '' : `, :text("${text}")`})`; await page.click(element); await module.exports.waitUntilStable(); }, @@ -362,7 +358,9 @@ module.exports = { const keplrExtensionData = (await module.exports.getExtensionsData()).keplr; const browserContext = await browser.contexts()[0]; keplrRegistrationWindow = await browserContext.newPage(); - await keplrRegistrationWindow.goto(`chrome-extension://${keplrExtensionData.id}/register.html`); + await keplrRegistrationWindow.goto( + `chrome-extension://${keplrExtensionData.id}/register.html`, + ); return true; }, async switchToKeplrNotification() {