Skip to content

Commit aa99bb3

Browse files
authored
test: add e2e tests for adding new BTC wallet (#2077)
1 parent 4e1a26d commit aa99bb3

20 files changed

Lines changed: 500 additions & 23 deletions

packages/core/src/ui/components/WalletSetupRevamp/WalletSetupEnterPasswordStep.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const WalletSetupEnterPasswordStep = ({
5454
label={t('core.walletSetupReuseRecoveryPhrase.insertPassword')}
5555
onSubmit={() => handleOnNext()}
5656
onChange={(target) => setPassword(target)}
57-
data-testid="wallet-setup-enter-password-input"
57+
testId="wallet-setup-enter-password-input"
5858
errorMessage={errorMessage}
5959
autoFocus
6060
/>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import OnboardingCommonAssert from './onboardingCommonAssert';
2+
import ConfirmPasswordPage from '../../elements/onboarding/ConfirmPasswordPage';
3+
import { t } from '../../utils/translationService';
4+
import { expect } from 'chai';
5+
6+
class ConfirmPasswordPageAssert extends OnboardingCommonAssert {
7+
async assertSeeConfirmPasswordPage(walletName: string) {
8+
await ConfirmPasswordPage.stepTitle.waitForDisplayed();
9+
expect(await ConfirmPasswordPage.stepTitle.getText()).to.equal(
10+
await t('core.walletSetupReuseRecoveryPhrase.confirmPassword')
11+
);
12+
await ConfirmPasswordPage.stepSubtitle.waitForDisplayed();
13+
const expectedSubtitle = (await t('core.walletSetupReuseRecoveryPhrase.confirmPasswordDescription'))
14+
.replace('<b>', '')
15+
.replace('</b>', '')
16+
.replace('{{walletName}}', walletName);
17+
expect(await ConfirmPasswordPage.stepSubtitle.getText()).to.equal(expectedSubtitle);
18+
await ConfirmPasswordPage.passwordInput.waitForDisplayed();
19+
20+
await this.assertSeeBackButton();
21+
22+
await ConfirmPasswordPage.nextButton.waitForDisplayed();
23+
expect(await ConfirmPasswordPage.nextButton.getText()).to.equal(
24+
await t('core.walletSetupReuseRecoveryPhrase.confirm')
25+
);
26+
}
27+
28+
async assertConfirmButtonIsEnabled(shouldBeEnabled: boolean) {
29+
await ConfirmPasswordPage.nextButton.waitForEnabled({ reverse: !shouldBeEnabled });
30+
}
31+
32+
async assertSeePasswordError() {
33+
await ConfirmPasswordPage.passwordError.waitForDisplayed();
34+
expect(await ConfirmPasswordPage.passwordError.getText()).to.equal(await t('general.errors.invalidPassword'));
35+
}
36+
}
37+
38+
export default new ConfirmPasswordPageAssert();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import OnboardingCommonAssert from './onboardingCommonAssert';
2+
import IncompatibleRecoveryPhraseErrorPage from '../../elements/onboarding/IncompatibleRecoveryPhraseErrorPage';
3+
import { t } from '../../utils/translationService';
4+
import { expect } from 'chai';
5+
6+
class IncompatibleRecoveryPhraseErrorPageAssert extends OnboardingCommonAssert {
7+
async assertSeeIncompatibleRecoveryPhraseErrorPage() {
8+
await IncompatibleRecoveryPhraseErrorPage.sadFaceIcon.waitForDisplayed();
9+
await IncompatibleRecoveryPhraseErrorPage.errorMessage.waitForDisplayed();
10+
11+
const errorText = await IncompatibleRecoveryPhraseErrorPage.errorMessage.getText();
12+
expect(errorText).to.include(await t('core.walletSetupReuseRecoveryPhrase.error'));
13+
expect(errorText).to.include(await t('core.walletSetupReuseRecoveryPhrase.createNewRecoveryPhrase'));
14+
expect(errorText).to.include(await t('core.walletSetupReuseRecoveryPhrase.supportedRecoveryPhrase'));
15+
16+
await IncompatibleRecoveryPhraseErrorPage.backButton.waitForDisplayed();
17+
expect(await IncompatibleRecoveryPhraseErrorPage.backButton.getText()).to.equal(
18+
await t('core.walletSetupReuseRecoveryPhrase.selectAnotherWallet')
19+
);
20+
21+
await IncompatibleRecoveryPhraseErrorPage.nextButton.waitForDisplayed();
22+
expect(await IncompatibleRecoveryPhraseErrorPage.nextButton.getText()).to.equal(
23+
await t('core.walletSetupReuseRecoveryPhrase.createNewOne')
24+
);
25+
}
26+
}
27+
28+
export default new IncompatibleRecoveryPhraseErrorPageAssert();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import OnboardingCommonAssert from './onboardingCommonAssert';
2+
import ReuseRecoveryPhrasePage from '../../elements/onboarding/ReuseRecoveryPhrasePage';
3+
import { t } from '../../utils/translationService';
4+
import { expect } from 'chai';
5+
6+
class ReuseRecoveryPhrasePageAssert extends OnboardingCommonAssert {
7+
async assertSeeReuseRecoveryPhrasePage() {
8+
await ReuseRecoveryPhrasePage.stepTitle.waitForDisplayed();
9+
expect(await ReuseRecoveryPhrasePage.stepTitle.getText()).to.equal(
10+
await t('core.walletSetupReuseRecoveryPhrase.title')
11+
);
12+
await ReuseRecoveryPhrasePage.stepSubtitle.waitForDisplayed();
13+
expect(await ReuseRecoveryPhrasePage.stepSubtitle.getText()).to.equal(
14+
await t('core.walletSetupReuseRecoveryPhrase.description')
15+
);
16+
await ReuseRecoveryPhrasePage.walletSelectInput.waitForDisplayed();
17+
18+
await ReuseRecoveryPhrasePage.backButton.waitForDisplayed();
19+
expect(await ReuseRecoveryPhrasePage.backButton.getText()).to.equal(
20+
await t('core.walletSetupReuseRecoveryPhrase.createNewOne')
21+
);
22+
23+
await ReuseRecoveryPhrasePage.nextButton.waitForDisplayed();
24+
expect(await ReuseRecoveryPhrasePage.nextButton.getText()).to.equal(
25+
await t('core.walletSetupReuseRecoveryPhrase.useSameRecoveryPhrase')
26+
);
27+
}
28+
29+
async assertWalletIsSelected(walletName: string) {
30+
await ReuseRecoveryPhrasePage.walletSelectInput.waitForDisplayed();
31+
const selectedValue = await ReuseRecoveryPhrasePage.walletSelectInput.getText();
32+
expect(selectedValue).to.include(walletName);
33+
}
34+
}
35+
36+
export default new ReuseRecoveryPhrasePageAssert();

packages/e2e-tests/src/assert/walletAddressPageAssert.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,34 @@ class WalletAddressPageAssert {
173173
}
174174
}
175175

176+
async waitUntilWalletNameIsNotEmpty() {
177+
await browser.waitUntil(async () => (await WalletAddressPage.walletName.getText()) !== '', {
178+
timeout: 3000,
179+
timeoutMsg: 'failed while waiting for wallet name'
180+
});
181+
}
182+
176183
async assertSeeWalletNameAndAddress(wallet: WalletRepositoryConfig, mode: 'extended' | 'popup') {
184+
await this.waitUntilWalletNameIsNotEmpty();
177185
expect(await WalletAddressPage.walletName.getText()).to.equal(wallet.name);
178186
const address = String(extensionUtils.isMainnet() ? wallet.accounts[0].mainnetAddress : wallet.accounts[0].address);
179187
const expectedAddress = mode === 'extended' ? address : `${address.slice(0, 7)}...${address.slice(-8)}`;
180188
expect(await WalletAddressPage.walletAddress.getText()).to.equal(expectedAddress);
181189
}
182190

191+
async assertSeeBitcoinWalletNameAndAddress(wallet: WalletRepositoryConfig, addressShouldMatch: boolean) {
192+
await this.waitUntilWalletNameIsNotEmpty();
193+
expect(await WalletAddressPage.walletName.getText()).to.equal(wallet.name);
194+
const expectedAddress = String(
195+
extensionUtils.isMainnet() ? wallet.bitCoinMainnetAddress : wallet.bitCoinTestnetAddress
196+
);
197+
if (addressShouldMatch) {
198+
expect(await WalletAddressPage.walletAddress.getText()).to.equal(expectedAddress);
199+
} else {
200+
expect(await WalletAddressPage.walletAddress.getText()).to.not.equal(expectedAddress);
201+
}
202+
}
203+
183204
async assertSeeWalletNameAccountAndAddress(
184205
wallet: WalletRepositoryConfig,
185206
accountNumber: number,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* global WebdriverIO */
2+
import CommonOnboardingElements from './commonOnboardingElements';
3+
import type { ChainablePromiseElement } from 'webdriverio';
4+
import { setInputFieldValue } from '../../utils/inputFieldUtils';
5+
6+
class ConfirmPasswordPage extends CommonOnboardingElements {
7+
private PASSWORD_INPUT = '[data-testid="wallet-setup-enter-password-input"]';
8+
private PASSWORD_ERROR = '[data-testid="wallet-setup-enter-password-input-error"]';
9+
10+
get passwordInput(): ChainablePromiseElement<WebdriverIO.Element> {
11+
return $(this.PASSWORD_INPUT);
12+
}
13+
14+
get passwordError(): ChainablePromiseElement<WebdriverIO.Element> {
15+
return $(this.PASSWORD_ERROR);
16+
}
17+
18+
async setPasswordInput(value: string): Promise<void> {
19+
await setInputFieldValue(await this.passwordInput, value);
20+
}
21+
22+
async clickConfirmButton(): Promise<void> {
23+
await this.nextButton.waitForClickable();
24+
await this.nextButton.click();
25+
}
26+
}
27+
28+
export default new ConfirmPasswordPage();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* global WebdriverIO */
2+
import CommonOnboardingElements from './commonOnboardingElements';
3+
import type { ChainablePromiseElement } from 'webdriverio';
4+
5+
class IncompatibleRecoveryPhraseErrorPage extends CommonOnboardingElements {
6+
private SAD_FACE_ICON = '[data-testid="sad-face-icon"]';
7+
private ERROR_MESSAGE = '[data-testid="asset-list-empty-state-message"]';
8+
9+
get sadFaceIcon(): ChainablePromiseElement<WebdriverIO.Element> {
10+
return $(this.SAD_FACE_ICON);
11+
}
12+
13+
get errorMessage(): ChainablePromiseElement<WebdriverIO.Element> {
14+
return $(this.ERROR_MESSAGE);
15+
}
16+
17+
async clickSelectAnotherWalletButton(): Promise<void> {
18+
await this.backButton.waitForClickable();
19+
await this.backButton.click();
20+
}
21+
22+
async clickCreateNewButton(): Promise<void> {
23+
await this.nextButton.waitForClickable();
24+
await this.nextButton.click();
25+
}
26+
}
27+
28+
export default new IncompatibleRecoveryPhraseErrorPage();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* global WebdriverIO */
2+
import CommonOnboardingElements from './commonOnboardingElements';
3+
import type { ChainablePromiseElement } from 'webdriverio';
4+
5+
class ReuseRecoveryPhrasePage extends CommonOnboardingElements {
6+
private WALLET_SELECT_INPUT = '[data-testid="wallet-setup-select-input"]';
7+
8+
get walletSelectInput(): ChainablePromiseElement<WebdriverIO.Element> {
9+
return $(this.WALLET_SELECT_INPUT);
10+
}
11+
12+
async clickUseSamePhraseButton(): Promise<void> {
13+
await this.nextButton.waitForClickable();
14+
await this.nextButton.click();
15+
}
16+
17+
async clickCreateNewButton(): Promise<void> {
18+
await this.backButton.waitForClickable();
19+
await this.backButton.click();
20+
}
21+
22+
async selectWallet(walletName: string): Promise<void> {
23+
await this.walletSelectInput.waitForClickable();
24+
await this.walletSelectInput.click();
25+
const walletOptionSelector = `//div[@role="option"][contains(.,"${walletName}")]`;
26+
const walletOption = $(walletOptionSelector);
27+
await walletOption.waitForClickable();
28+
await walletOption.click();
29+
}
30+
}
31+
32+
export default new ReuseRecoveryPhrasePage();

packages/e2e-tests/src/features/AddNewWalletCreate.part2.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Feature: Add new wallet - Create wallet
8787
Then password value is hidden for "Password" input field
8888
And password value is hidden for "Confirm password" input field
8989

90-
@LW-9357 @memory-snapshot
90+
@LW-9357 @LW-13744 @memory-snapshot
9191
Scenario: Extended-view - Multi-wallet - Create - Add new wallet - happy path
9292
Given I opened "Create" flow via "Add new wallet" feature
9393
When I go to "Wallet setup" page from "Create" wallet flow for Cardano chain
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
@AddNewWalletCreateBitcoin @Testnet @Mainnet
2+
Feature: Add new wallet - Create Bitcoin wallet
3+
4+
Background:
5+
Given Lace is ready for test
6+
7+
@LW-13739 @Smoke
8+
Scenario: Extended-view - Multi-wallet - Create Bitcoin Wallet - Use same recovery phrase
9+
When I opened "Create" flow via "Add new wallet" feature
10+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
11+
And I click "Next" button during wallet setup
12+
And I click "Understood" button on "Bitcoin warning" modal
13+
Then "Choose recovery method" page is displayed on "Create" flow for Bitcoin chain
14+
And "Recovery phrase" is selected as a recovery method for Bitcoin chain
15+
When I click "Next" button during wallet setup
16+
Then "Reuse your Recovery Phrase" page is displayed
17+
When I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
18+
Then "Confirm your password" page is displayed for wallet "MultiWallet2"
19+
When I enter valid password for wallet "MultiWallet2" on "Confirm your password" page
20+
And I click "Confirm" button on "Confirm your password" page
21+
Then "Wallet setup" page is displayed
22+
When I enter wallet name: "MultiWallet2", password: "N_8J@bne87A" and password confirmation: "N_8J@bne87A"
23+
And I click "Enter wallet" button
24+
Then I see LW homepage
25+
When I click "Receive" button on page header
26+
Then I see Bitcoin wallet name and address for wallet "MultiWallet2" in the Receive drawer
27+
28+
@LW-13742
29+
Scenario: Extended-view - Multi-wallet - Create Bitcoin Wallet - Create new recovery phrase
30+
When I opened "Create" flow via "Add new wallet" feature
31+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
32+
And I click "Next" button during wallet setup
33+
And I click "Understood" button on "Bitcoin warning" modal
34+
Then "Choose recovery method" page is displayed on "Create" flow for Bitcoin chain
35+
And "Recovery phrase" is selected as a recovery method for Bitcoin chain
36+
When I click "Next" button during wallet setup
37+
Then "Reuse your Recovery Phrase" page is displayed
38+
When I click "Create a new one" button on "Reuse your Recovery Phrase" page
39+
Then "Mnemonic writedown" page is displayed with 24 words
40+
When I save mnemonic words
41+
And I click "Next" button during wallet setup
42+
Then "Mnemonic verification" page is displayed from "Create wallet" flow with 24 words
43+
When I enter saved mnemonic words
44+
And I click "Next" button during wallet setup
45+
Then "Wallet setup" page is displayed
46+
When I enter wallet name: "MultiWallet2", password: "N_8J@bne87A" and password confirmation: "N_8J@bne87A"
47+
And I click "Enter wallet" button
48+
Then I see LW homepage
49+
When I click "Receive" button on page header
50+
Then I see Bitcoin wallet name but no address for wallet "MultiWallet2" in the Receive drawer
51+
52+
@LW-13746 @LW-13747
53+
Scenario: Extended-view - Multi-wallet - Create Bitcoin Wallet - Only 24 words allowed - Select another wallet
54+
Given I open wallet: "TwelveWordsMnemonic" in: extended mode
55+
When I opened "Create" flow via "Add new wallet" feature
56+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
57+
And I click "Next" button during wallet setup
58+
And I click "Understood" button on "Bitcoin warning" modal
59+
Then "Choose recovery method" page is displayed on "Create" flow for Bitcoin chain
60+
And "Recovery phrase" is selected as a recovery method for Bitcoin chain
61+
When I click "Next" button during wallet setup
62+
Then "Reuse your Recovery Phrase" page is displayed
63+
When I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
64+
Then "Confirm your password" page is displayed for wallet "TwelveWordsMnemonic"
65+
When I enter valid password for wallet "TwelveWordsMnemonic" on "Confirm your password" page
66+
And I click "Confirm" button on "Confirm your password" page
67+
Then I see incompatible recovery phrase error page
68+
When I click "Select another wallet" button on incompatible recovery phrase error page
69+
Then "Reuse your Recovery Phrase" page is displayed
70+
71+
@LW-13747
72+
Scenario: Extended-view - Multi-wallet - Create Bitcoin Wallet - Only 24 words allowed - Create new recovery phrase
73+
Given I open wallet: "TwelveWordsMnemonic" in: extended mode
74+
When I opened "Create" flow via "Add new wallet" feature
75+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
76+
And I click "Next" button during wallet setup
77+
And I click "Understood" button on "Bitcoin warning" modal
78+
Then "Choose recovery method" page is displayed on "Create" flow for Bitcoin chain
79+
And "Recovery phrase" is selected as a recovery method for Bitcoin chain
80+
When I click "Next" button during wallet setup
81+
Then "Reuse your Recovery Phrase" page is displayed
82+
When I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
83+
Then "Confirm your password" page is displayed for wallet "TwelveWordsMnemonic"
84+
When I enter valid password for wallet "TwelveWordsMnemonic" on "Confirm your password" page
85+
And I click "Confirm" button on "Confirm your password" page
86+
Then I see incompatible recovery phrase error page
87+
When I click "Create a new one" button on incompatible recovery phrase error page
88+
Then "Mnemonic writedown" page is displayed with 24 words
89+
When I save mnemonic words
90+
And I click "Next" button during wallet setup
91+
Then "Mnemonic verification" page is displayed from "Create wallet" flow with 24 words
92+
When I enter saved mnemonic words
93+
And I click "Next" button during wallet setup
94+
Then "Wallet setup" page is displayed
95+
When I enter wallet name: "AddNewWallet", password: "N_8J@bne87A" and password confirmation: "N_8J@bne87A"
96+
And I click "Enter wallet" button
97+
Then I see LW homepage
98+
99+
@LW-13743
100+
Scenario: Extended-view - Multi-wallet - Create Bitcoin Wallet - Use same recovery phrase - Invalid password
101+
When I opened "Create" flow via "Add new wallet" feature
102+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
103+
And I click "Next" button during wallet setup
104+
And I click "Understood" button on "Bitcoin warning" modal
105+
Then "Choose recovery method" page is displayed on "Create" flow for Bitcoin chain
106+
And "Recovery phrase" is selected as a recovery method for Bitcoin chain
107+
When I click "Next" button during wallet setup
108+
Then "Reuse your Recovery Phrase" page is displayed
109+
And "MultiWallet2" wallet name is selected on "Reuse your Recovery Phrase" page
110+
When I select "MultiWallet1" wallet name on "Reuse your Recovery Phrase" page
111+
Then "MultiWallet1" wallet name is selected on "Reuse your Recovery Phrase" page
112+
When I select "MultiWallet2" wallet name on "Reuse your Recovery Phrase" page
113+
Then "MultiWallet2" wallet name is selected on "Reuse your Recovery Phrase" page
114+
When I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
115+
Then "Confirm your password" page is displayed for wallet "MultiWallet2"
116+
When I enter invalid password for wallet "MultiWallet2" on "Confirm your password" page
117+
And I click "Confirm" button on "Confirm your password" page
118+
Then I see password error on "Confirm your password" page
119+
And "Confirm" button is disabled on "Confirm your password" page
120+
121+
@LW-13741
122+
Scenario: Extended-view - Multi-wallet - Trying to reuse the same mnemonic
123+
When I opened "Create" flow via "Add new wallet" feature
124+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
125+
And I click "Next" button during wallet setup
126+
And I click "Understood" button on "Bitcoin warning" modal
127+
And I click "Next" button during wallet setup
128+
And I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
129+
And I enter valid password for wallet "MultiWallet2" on "Confirm your password" page
130+
And I click "Confirm" button on "Confirm your password" page
131+
And I enter wallet name: "MultiWallet2", password: "N_8J@bne87A" and password confirmation: "N_8J@bne87A"
132+
And I click "Enter wallet" button
133+
Then I see LW homepage
134+
When I click "Receive" button on page header
135+
Then I see Bitcoin wallet name and address for wallet "MultiWallet2" in the Receive drawer
136+
When I close the drawer by clicking close button
137+
And I opened "Create" flow via "Add new wallet" feature
138+
And I select "Bitcoin" blockchain on the "Select a blockchain" page
139+
And I click "Next" button during wallet setup
140+
And I click "Understood" button on "Bitcoin warning" modal
141+
And I click "Next" button during wallet setup
142+
And I click "Use same recovery phrase" button on "Reuse your Recovery Phrase" page
143+
And I enter valid password for wallet "MultiWallet2" on "Confirm your password" page
144+
And I click "Confirm" button on "Confirm your password" page
145+
And I enter wallet name: "MultiWallet2", password: "N_8J@bne87A" and password confirmation: "N_8J@bne87A"
146+
And I click "Enter wallet" button
147+
Then I see LW homepage
148+
And I see a toast with text: "Wallet already exists"
149+
When I click "Receive" button on page header
150+
Then I see Bitcoin wallet name and address for wallet "MultiWallet2" in the Receive drawer

0 commit comments

Comments
 (0)