Skip to content

Commit

Permalink
test: add e2e for imported account being removed and then reimported (#…
Browse files Browse the repository at this point in the history
…10380)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
This PR adds an e2e that uses a fixture to start with the imported
account present. The imported account is removed, and then imported
again by private key.

## **Related issues**

Fixes: [494](https://github.com/MetaMask/accounts-planning/issues/494)

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
plasmacorral authored Jul 26, 2024
1 parent 35ae0b4 commit 234738a
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import PickerBase from '../PickerBase';
import { PickerAccountProps } from './PickerAccount.types';
import styleSheet from './PickerAccount.styles';
import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';
import { AccountListViewSelectorsIDs } from '../../../../../e2e/selectors/AccountListView.selectors';

const PickerAccount: React.ForwardRefRenderFunction<
TouchableOpacity,
Expand Down Expand Up @@ -59,6 +60,7 @@ const PickerAccount: React.ForwardRefRenderFunction<
<Text
variant={TextVariant.BodySM}
style={styles.accountNameLabelText}
testID={AccountListViewSelectorsIDs.ACCOUNT_TYPE_LABEL}
>
{strings(accountTypeLabel)}
</Text>
Expand Down
18 changes: 18 additions & 0 deletions e2e/fixtures/fixture-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,24 @@ class FixtureBuilder {
return this;
}

withImportedAccountKeyringController() {
merge(this.fixture.state.engine.backgroundState.KeyringController, {
keyrings: [
{
type: 'HD Key Tree',
accounts: ['0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3'],
},
{
type: 'Simple Key Pair',
accounts: ['0xDDFFa077069E1d4d478c5967809f31294E24E674'],
},
],
vault:
'{"cipher":"vxFqPMlClX2xjUidoCTiwazr43W59dKIBp6ihT2lX66q8qPTeBRwv7xgBaGDIwDfk4DpJ3r5FBety1kFpS9ni3HtcoNQsDN60Pa80L94gta0Fp4b1jVeP8EJ7Ho71mJ360aDFyIgxPBSCcHWs+l27L3WqF2VpEuaQonK1UTF7c3WQ4pyio4jMAH9x2WQtB11uzyOYiXWmiD3FMmWizqYZY4tHuRlzJZTWrgE7njJLaGMlMmw86+ZVkMf55jryaDtrBVAoqVzPsK0bvo1cSsonxpTa6B15A5N2ANyEjDAP1YVl17roouuVGVWZk0FgDpP82i0YqkSI9tMtOTwthi7/+muDPl7Oc7ppj9LU91JYH6uHGomU/pYj9ufrjWBfnEH/+ZDvPoXl00H1SmX8FWs9NvOg7DZDB6ULs4vAi2/5KGs7b+Td2PLmDf75NKqt03YS2XeRGbajZQ/jjmRt4AhnWgnwRzsSavzyjySWTWiAgn9Vp/kWpd70IgXWdCOakVf2TtKQ6cFQcAf4JzP+vqC0EzgkfbOPRetrovD8FHEFXQ+crNUJ7s41qRw2sketk7FtYUDCz/Junpy5YnYgkfcOTRBHAoOy6BfDFSncuY+08E6eiRHzXsXtbmVXenor15pfbEp/wtfV9/vZVN7ngMpkho3eGQjiTJbwIeA9apIZ+BtC5b7TXWLtGuxSZPhomVkKvNx/GNntjD7ieLHvzCWYmDt6BA9hdfOt1T3UKTN4yLWG0v+IsnngRnhB6G3BGjJHUvdR6Zp5SzZraRse8B3z5ixgVl2hBxOS8+Uvr6LlfImaUcZLMMzkRdKeowS/htAACLowVJe3pU544IJ2CGTsnjwk9y3b5bUJKO3jXukWjDYtrLNKfdNuQjg+kqvIHaCQW40t+vfXGhC5IDBWC5kuev4DJAIFEcvJfJgRrm8ua6LrzEfH0GuhjLwYb+pnQ/eg8dmcXwzzggJF7xK56kxgnA4qLtOqKV4NgjVR0QsCqOBKb3l5LQMlSktdfgp9hlW","iv":"b09c32a79ed33844285c0f1b1b4d1feb","keyMetadata":{"algorithm":"PBKDF2","params":{"iterations":5000}},"lib":"original","salt":"GYNFQCSCigu8wNp8cS8C3w=="}',
});
return this;
}

/**
* Build and return the fixture object.
* @returns {Object} - The built fixture object.
Expand Down
42 changes: 41 additions & 1 deletion e2e/pages/AccountListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@ import {
ACCOUNT_LIST_ADD_BUTTON_ID,
} from '../../wdio/screen-objects/testIDs/Components/AccountListComponent.testIds';
import { CellModalSelectorsIDs } from '../selectors/Modals/CellModal.selectors';
import { AccountListViewSelectorsText } from '../selectors/AccountListView.selectors';
import {
AccountListViewSelectorsIDs,
AccountListViewSelectorsText,
} from '../selectors/AccountListView.selectors';
import { ConnectAccountModalSelectorsIDs } from '../selectors/Modals/ConnectAccountModal.selectors';
import Matchers from '../utils/Matchers';

export default class AccountListView {
static async accountTypeLabel() {
return await Matchers.getElementByID(
AccountListViewSelectorsIDs.ACCOUNT_TYPE_LABEL,
);
}

static async tapAccountIndex(index) {
await TestHelpers.tapItemAtIndex(CellModalSelectorsIDs.MULTISELECT, index);
}
Expand All @@ -28,6 +38,7 @@ export default class AccountListView {
static async longPressImportedAccount() {
await TestHelpers.tapAndLongPressAtIndex(CellModalSelectorsIDs.SELECT, 1);
}

static async swipeToDimssAccountsModal() {
if (device.getPlatform() === 'android') {
await TestHelpers.swipe(ACCOUNT_LIST_ID, 'down', 'fast', 0.6);
Expand Down Expand Up @@ -56,6 +67,35 @@ export default class AccountListView {
await TestHelpers.checkIfElementWithTextIsNotVisible('Account 2');
}

static async checkAccountVisibilityAtIndex(index, shouldBeVisible) {
const expectedAccountElement = element(
by.id(CellModalSelectorsIDs.BASE_TITLE),
).atIndex(index);

const expectedAccountNameText = `Account ${index + 1}`;

try {
if (shouldBeVisible) {
await expect(expectedAccountElement).toHaveText(
expectedAccountNameText,
);
} else {
await expect(expectedAccountElement).not.toHaveText(
expectedAccountNameText,
);
}
} catch (error) {
if (shouldBeVisible) {
throw new Error(
`Expected element at index ${index} to be visible, but it does not exist.`,
);
} else {
// If the element should not be visible and it doesn't exist, the test passes.
return;
}
}
}

static async connectAccountsButton() {
await TestHelpers.waitAndTap(
ConnectAccountModalSelectorsIDs.SELECT_MULTI_BUTTON,
Expand Down
5 changes: 5 additions & 0 deletions e2e/selectors/AccountListView.selectors.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import enContent from '../../locales/languages/en.json';

export const AccountListViewSelectorsIDs = {
ACCOUNT_TYPE_LABEL: 'account-type-label',
};

// eslint-disable-next-line import/prefer-default-export
export const AccountListViewSelectorsText = {
REMOVE_IMPORTED_ACCOUNT: enContent.accounts.yes_remove_it,
IMPORT_ACCOUNT: enContent.account_actions.import_account,
CREATE_ACCOUNT: enContent.account_actions.add_new_account,
ACCOUNT_TYPE_LABEL_TEXT: enContent.accounts.imported,
};
72 changes: 72 additions & 0 deletions e2e/specs/accounts/imported-account-remove-and-import.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';

import { Regression } from '../../tags.js';
import TestHelpers from '../../helpers.js';
import FixtureBuilder from '../../fixtures/fixture-builder';
import {
loadFixture,
startFixtureServer,
stopFixtureServer,
} from '../../fixtures/fixture-helper';
import FixtureServer from '../../fixtures/fixture-server';
import { getFixturesServerPort } from '../../fixtures/utils';
import { loginToApp } from '../../viewHelper.js';
import WalletView from '../../pages/wallet/WalletView.js';
import AccountListView from '../../pages/AccountListView.js';
import ImportAccountView from '../../pages/ImportAccountView.js';
import Assertions from '../../utils/Assertions.js';
import { AccountListViewSelectorsText } from '../../selectors/AccountListView.selectors.js';

const fixtureServer = new FixtureServer();
// This key is for testing private key import only
// It should NEVER hold any eth or token
const TEST_PRIVATE_KEY =
'cbfd798afcfd1fd8ecc48cbecb6dc7e876543395640b758a90e11d986e758ad1';

describe(
Regression('removes and reimports an account using a private key'),
() => {
beforeAll(async () => {
await TestHelpers.reverseServerPort();
const fixture = new FixtureBuilder()
.withImportedAccountKeyringController()
.build();
await startFixtureServer(fixtureServer);
await loadFixture(fixtureServer, { fixture });
await device.launchApp({
launchArgs: { fixtureServerPort: `${getFixturesServerPort()}` },
});
await loginToApp();
});

afterAll(async () => {
await stopFixtureServer(fixtureServer);
});

it('removes an imported account and imports it again using a private key', async () => {
// Ensure imported account is present
await WalletView.tapIdenticon();
await AccountListView.isVisible();
await AccountListView.checkAccountVisibilityAtIndex(1, true);

// Remove the imported account
await AccountListView.longPressImportedAccount();
await AccountListView.tapYesToRemoveImportedAccountAlertButton();
await AccountListView.checkAccountVisibilityAtIndex(1, false);
await Assertions.checkIfNotVisible(AccountListView.accountTypeLabel());

// Import account again
await AccountListView.tapAddAccountButton();
await AccountListView.tapImportAccountButton();
await ImportAccountView.isVisible();
await ImportAccountView.enterPrivateKey(TEST_PRIVATE_KEY);
await ImportAccountView.isImportSuccessSreenVisible();
await ImportAccountView.tapCloseButtonOnImportSuccess();
await AccountListView.checkAccountVisibilityAtIndex(1, true);
await Assertions.checkIfElementToHaveText(
AccountListView.accountTypeLabel(),
AccountListViewSelectorsText.ACCOUNT_TYPE_LABEL_TEXT,
);
});
},
);

0 comments on commit 234738a

Please sign in to comment.