-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat(metamask): Add support for importing seed phrase
- Loading branch information
1 parent
e4dc605
commit cf32332
Showing
17 changed files
with
225 additions
and
40 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
wallets/metamask/src/pages/OnboardingPage/actions/helpers/confirmSecretRecoveryPhrase.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { Page } from '@playwright/test' | ||
import { SecretRecoveryPhrasePageSelectors } from '../../../../selectors' | ||
|
||
const StepSelectors = SecretRecoveryPhrasePageSelectors.recoveryStep | ||
|
||
export async function confirmSecretRecoveryPhrase(page: Page, seedPhrase: string) { | ||
const seedPhraseWords = seedPhrase.split(' ') | ||
const seedPhraseLength = seedPhraseWords.length | ||
|
||
// TODO: This should be validated! | ||
await page | ||
.locator(StepSelectors.selectNumberOfWordsDropdown) | ||
.selectOption(StepSelectors.selectNumberOfWordsOption(seedPhraseLength)) | ||
|
||
for (const [index, word] of seedPhraseWords.entries()) { | ||
await page.locator(StepSelectors.secretRecoveryPhraseWord(index)).fill(word) | ||
} | ||
|
||
const confirmSRPButton = page.locator(StepSelectors.confirmSecretRecoveryPhraseButton) | ||
|
||
if (await confirmSRPButton.isDisabled()) { | ||
const errorText = await page.locator(StepSelectors.error).textContent({ | ||
timeout: 1000 | ||
}) | ||
|
||
throw new Error(`[ConfirmSecretRecoveryPhrase] Invalid seed phrase. Error from MetaMask: ${errorText}`) | ||
} | ||
|
||
await confirmSRPButton.click() | ||
} |
24 changes: 24 additions & 0 deletions
24
wallets/metamask/src/pages/OnboardingPage/actions/helpers/createPassword.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { Page } from '@playwright/test' | ||
import { SecretRecoveryPhrasePageSelectors } from '../../../../selectors' | ||
|
||
const StepSelectors = SecretRecoveryPhrasePageSelectors.passwordStep | ||
|
||
export async function createPassword(page: Page, password: string) { | ||
await page.locator(StepSelectors.passwordInput).fill(password) | ||
await page.locator(StepSelectors.confirmPasswordInput).fill(password) | ||
|
||
// Using `locator.click()` instead of `locator.check()` as a workaround due to dynamically appearing elements. | ||
await page.locator(StepSelectors.acceptTermsCheckbox).click() | ||
|
||
const importWalletButton = page.locator(StepSelectors.importWalletButton) | ||
|
||
if (await importWalletButton.isDisabled()) { | ||
const errorText = await page.locator(StepSelectors.error).textContent({ | ||
timeout: 1000 | ||
}) | ||
|
||
throw new Error(`[CreatePassword] Invalid password. Error from MetaMask: ${errorText}`) | ||
} | ||
|
||
await importWalletButton.click() | ||
} |
2 changes: 2 additions & 0 deletions
2
wallets/metamask/src/pages/OnboardingPage/actions/helpers/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './confirmSecretRecoveryPhrase' | ||
export * from './createPassword' |
23 changes: 23 additions & 0 deletions
23
wallets/metamask/src/pages/OnboardingPage/actions/importWallet.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { Page } from '@playwright/test' | ||
import { | ||
AnalyticsPageSelectors, | ||
GetStartedPageSelectors, | ||
PinExtensionPageSelectors, | ||
WalletCreationSuccessPageSelectors | ||
} from '../../../selectors' | ||
import { confirmSecretRecoveryPhrase, createPassword } from './helpers' | ||
|
||
export async function importWallet(page: Page, seedPhrase: string, password: string) { | ||
await page.locator(GetStartedPageSelectors.importWallet).click() | ||
|
||
await page.locator(AnalyticsPageSelectors.optOut).click() | ||
|
||
// Secret Recovery Phrase Page | ||
await confirmSecretRecoveryPhrase(page, seedPhrase) | ||
await createPassword(page, password) | ||
|
||
await page.locator(WalletCreationSuccessPageSelectors.confirmButton).click() | ||
|
||
await page.locator(PinExtensionPageSelectors.nextButton).click() | ||
await page.locator(PinExtensionPageSelectors.confirmButton).click() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './importWallet' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { Page } from '@playwright/test' | ||
import { importWallet } from './actions' | ||
|
||
export class OnboardingPage { | ||
readonly page: Page | ||
|
||
constructor(page: Page) { | ||
this.page = page | ||
} | ||
|
||
async importWallet(seedPhrase: string, password: string) { | ||
return importWallet(this.page, seedPhrase, password) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './OnboardingPage/page' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './onboarding' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { createDataTestSelector } from '../../utils/selectors/createDataTestSelector' | ||
|
||
export default { | ||
optIn: createDataTestSelector('metametrics-i-agree'), | ||
optOut: createDataTestSelector('metametrics-no-thanks') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { createDataTestSelector } from '../../utils/selectors/createDataTestSelector' | ||
|
||
export default { | ||
createNewWallet: createDataTestSelector('onboarding-create-wallet'), | ||
importWallet: createDataTestSelector('onboarding-import-wallet') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import AnalyticsPageSelectors from './analyticsPage' | ||
import GetStartedPageSelectors from './getStartedPage' | ||
import PinExtensionPageSelectors from './pinExtensionPage' | ||
import SecretRecoveryPhrasePageSelectors from './secretRecoveryPhrasePage' | ||
import WalletCreationSuccessPageSelectors from './walletCreationSuccessPage' | ||
|
||
// biome-ignore format: empty lines should be preserved | ||
export { | ||
// Initial Welcome Page | ||
GetStartedPageSelectors, | ||
|
||
// 2nd Page | ||
AnalyticsPageSelectors, | ||
|
||
// 3rd Page with two steps: | ||
// - Input Secret Recovery Phrase | ||
// - Create Password | ||
SecretRecoveryPhrasePageSelectors, | ||
|
||
// 4th Page | ||
WalletCreationSuccessPageSelectors, | ||
|
||
// 5th Page | ||
PinExtensionPageSelectors | ||
} |
6 changes: 6 additions & 0 deletions
6
wallets/metamask/src/selectors/onboarding/pinExtensionPage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { createDataTestSelector } from '../../utils/selectors/createDataTestSelector' | ||
|
||
export default { | ||
nextButton: createDataTestSelector('pin-extension-next'), | ||
confirmButton: createDataTestSelector('pin-extension-done') | ||
} |
22 changes: 22 additions & 0 deletions
22
wallets/metamask/src/selectors/onboarding/secretRecoveryPhrasePage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { createDataTestSelector } from '../../utils/selectors/createDataTestSelector' | ||
|
||
const recoveryStep = { | ||
selectNumberOfWordsDropdown: '.import-srp__number-of-words-dropdown > .dropdown__select', | ||
selectNumberOfWordsOption: (option: number | string) => `${option}`, | ||
secretRecoveryPhraseWord: (index: number) => createDataTestSelector(`import-srp__srp-word-${index}`), | ||
confirmSecretRecoveryPhraseButton: createDataTestSelector('import-srp-confirm'), | ||
error: '.actionable-message.actionable-message--danger.import-srp__srp-error > .actionable-message__message' | ||
} | ||
|
||
const passwordStep = { | ||
passwordInput: createDataTestSelector('create-password-new'), | ||
confirmPasswordInput: createDataTestSelector('create-password-confirm'), | ||
acceptTermsCheckbox: createDataTestSelector('create-password-terms'), | ||
importWalletButton: createDataTestSelector('create-password-import'), | ||
error: `${createDataTestSelector('create-password-confirm')} + h6` | ||
} | ||
|
||
export default { | ||
recoveryStep, | ||
passwordStep | ||
} |
5 changes: 5 additions & 0 deletions
5
wallets/metamask/src/selectors/onboarding/walletCreationSuccessPage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { createDataTestSelector } from '../../utils/selectors/createDataTestSelector' | ||
|
||
export default { | ||
confirmButton: createDataTestSelector('onboarding-complete-done') | ||
} |
3 changes: 3 additions & 0 deletions
3
wallets/metamask/src/utils/selectors/createDataTestSelector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const createDataTestSelector = (dataTestId: string) => { | ||
return `[data-testid="${dataTestId}"]` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { type Page, chromium, test as base } from '@playwright/test' | ||
import { OnboardingPage } from '../../src/pages' | ||
import { prepareExtension } from '../../src/prepareExtension' | ||
|
||
const DEFAULT_SEED_PHRASE = 'test test test test test test test test test test test junk' | ||
const DEFAULT_PASSWORD = 'Tester@1234' | ||
|
||
// Fixture for the test. | ||
const test = base.extend({ | ||
context: async ({ context: _ }, use) => { | ||
const metamaskPath = await prepareExtension() | ||
|
||
// biome-ignore format: the array should not be formatted | ||
const browserArgs = [ | ||
`--disable-extensions-except=${metamaskPath}`, | ||
`--load-extension=${metamaskPath}` | ||
] | ||
|
||
if (process.env.HEADLESS) { | ||
browserArgs.push('--headless=new') | ||
} | ||
|
||
const context = await chromium.launchPersistentContext('', { | ||
headless: false, | ||
args: browserArgs | ||
}) | ||
|
||
try { | ||
await context.waitForEvent('page', { timeout: 5000 }) | ||
} catch { | ||
throw new Error('[FIXTURE] MetaMask extension did not load in time') | ||
} | ||
|
||
await use(context) | ||
}, | ||
page: async ({ context }, use) => { | ||
const metamaskOnboardingPage = context.pages()[1] as Page | ||
await use(metamaskOnboardingPage) | ||
} | ||
}) | ||
|
||
const { describe, expect } = test | ||
|
||
// Currently testing only happy paths until we have proper setup for parallel tests. | ||
describe('MetaMask', () => { | ||
describe('importWallet', () => { | ||
test('should go through the onboarding flow and import wallet from seed phrase', async ({ page }) => { | ||
const onboardingPage = new OnboardingPage(page) | ||
|
||
await onboardingPage.importWallet(DEFAULT_SEED_PHRASE, DEFAULT_PASSWORD) | ||
|
||
await expect(page.getByText('Account 1')).toBeVisible() | ||
await expect(page.getByText('0xf39...2266')).toBeVisible() | ||
}) | ||
}) | ||
}) |
This file was deleted.
Oops, something went wrong.