Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: account watcher e2e #26524

Merged
merged 57 commits into from
Aug 21, 2024
Merged
Changes from 54 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
51a5320
feat: added AccountWatcher as preinstalled snap and added to menu list
k-g-j Aug 13, 2024
9293af3
feat: put 'Watch Ethereum account (Beta)' behind experimental setting…
k-g-j Aug 13, 2024
0497284
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 13, 2024
6169fe0
feat: renamed metric to 'WatchEthereumAccountsToggled'
k-g-j Aug 13, 2024
9aca5a6
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 13, 2024
9efcdff
fix: setupSentry state
k-g-j Aug 13, 2024
03a01d9
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 14, 2024
64c5b1c
feat: updated copy and changed to eye icon
k-g-j Aug 14, 2024
b14b0b0
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 14, 2024
d0aab2f
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 14, 2024
5789263
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 14, 2024
e08a9b1
feat: updated account-watcher to 4.0.3
k-g-j Aug 14, 2024
0c4d02b
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 15, 2024
0f3e0e3
feat: added width styling to the create-named-snap-account component
k-g-j Aug 15, 2024
263d596
chore: updated snapshots
k-g-j Aug 15, 2024
9192883
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 15, 2024
d3238c4
Merge remote-tracking branch 'origin/develop' into feat/add-account-w…
k-g-j Aug 15, 2024
ef465ff
fix: merge conflicts with develop
k-g-j Aug 15, 2024
bdd38c8
feat: redirect to default route from back button on snap homepage for…
k-g-j Aug 15, 2024
fd8a1c3
chore: yarn dedupe
k-g-j Aug 15, 2024
4d963aa
feat: useCallback for 'handleAddWatchAccount'
k-g-j Aug 15, 2024
d89ac15
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 16, 2024
217b60d
feat: added not removable to conditional in back button
k-g-j Aug 16, 2024
38961fd
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 16, 2024
e6c625e
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 16, 2024
3296f93
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 16, 2024
35c1736
feat: updated account-watcher to 4.1.0 with hidden flag
k-g-j Aug 16, 2024
db054fd
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 19, 2024
9674570
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 19, 2024
1bd6ac0
chore: update lavamoat
k-g-j Aug 19, 2024
4ff4fc0
feat: added start of create-watch-account.spec.ts
k-g-j Aug 19, 2024
6051869
Merge branch 'develop' into feat/add-account-watcher-snap
k-g-j Aug 19, 2024
bacdef4
feat: updated lavamoat policy to match develop
k-g-j Aug 19, 2024
283416e
Merge remote-tracking branch 'origin/feat/add-account-watcher-snap' i…
k-g-j Aug 19, 2024
8d2feb8
feat: updated preferences controller fixtures
k-g-j Aug 19, 2024
e56f8c2
feat: updated fixtures
k-g-j Aug 19, 2024
e647d43
fix: yarn.lock
k-g-j Aug 19, 2024
0626bb2
Merge remote-tracking branch 'origin/feat/add-account-watcher-snap' i…
k-g-j Aug 19, 2024
43479d3
fix: yarn dedupe
k-g-j Aug 19, 2024
96f81e7
feat: updated lavamoat policies
k-g-j Aug 19, 2024
9f79954
Revert "feat: updated lavamoat policies"
k-g-j Aug 19, 2024
1b07172
Merge remote-tracking branch 'origin/feat/add-account-watcher-snap' i…
k-g-j Aug 19, 2024
0efea14
Update LavaMoat policies
metamaskbot Aug 19, 2024
8ffcf7f
Merge remote-tracking branch 'origin/feat/add-account-watcher-snap' i…
k-g-j Aug 19, 2024
37c825e
feat: updated tests for putting extension on mainnet
k-g-j Aug 19, 2024
cb5db1b
fix: changes in create-snap-account.spec
k-g-j Aug 19, 2024
386face
feat: updated test fixture builder
k-g-j Aug 19, 2024
ef452c9
feat: added failure comments
k-g-j Aug 19, 2024
74b62a1
feat: finished adding e2e test cases for account-watcher
k-g-j Aug 20, 2024
52c35be
feat: updated test descriptions and comments
k-g-j Aug 20, 2024
bfdeca3
fix: ACCOUNT_1 address format
k-g-j Aug 20, 2024
166e2fb
feat: updated test names to proper format
k-g-j Aug 20, 2024
e1b1b48
fix: lint
k-g-j Aug 20, 2024
390483c
Merge branch 'develop' into feat/account-watcher-e2e
k-g-j Aug 20, 2024
16dfd85
feat: added experimental settings tests
k-g-j Aug 21, 2024
d2e17e4
Merge branch 'develop' into feat/account-watcher-e2e
k-g-j Aug 21, 2024
8ea6344
feat: updated test descriptions
k-g-j Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 348 additions & 0 deletions test/e2e/accounts/create-watch-account.spec.ts
k-g-j marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
import { Suite } from 'mocha';

import FixtureBuilder from '../fixture-builder';
import { defaultGanacheOptions, unlockWallet, withFixtures } from '../helpers';
import { Driver } from '../webdriver/driver';

const ACCOUNT_1 = '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1';
const EOA_ADDRESS = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';
const SHORTENED_EOA_ADDRESS = '0xd8dA6...96045';
const DEFAULT_WATCHED_ACCOUNT_NAME = 'Watched Account 1';

/**
* Start the flow to create a watch account by clicking the account menu and selecting the option to add a watch account.
*
* @param driver - The WebDriver instance used to control the browser.
* @param unlockWalletFirst - Whether to unlock the wallet before starting the flow.
*/
async function startCreateWatchAccountFlow(
driver: Driver,
unlockWalletFirst: boolean = true,
): Promise<void> {
if (unlockWalletFirst) {
await unlockWallet(driver);
}

await driver.clickElement('[data-testid="account-menu-icon"]');
await driver.clickElement(
'[data-testid="multichain-account-menu-popover-action-button"]',
);
await driver.clickElement(
'[data-testid="multichain-account-menu-popover-add-watch-only-account"]',
);
}

/**
* Watches an EOA address.
*
* @param driver - The WebDriver instance used to control the browser.
* @param unlockWalletFirst - Whether to unlock the wallet before watching the address.
* @param address - The EOA address to watch.
*/
async function watchEoaAddress(
driver: Driver,
unlockWalletFirst: boolean = true,
address: string = EOA_ADDRESS,
): Promise<void> {
await startCreateWatchAccountFlow(driver, unlockWalletFirst);
await driver.fill(
'[placeholder="Enter a public address or ENS name"]',
address,
);
await driver.clickElement({ text: 'Watch account', tag: 'button' });
await driver.clickElement('[data-testid="submit-add-account-with-name"]');
}

/**
* Removes the selected account.
*
* @param driver - The WebDriver instance used to control the browser.
*/
async function removeSelectedAccount(driver: Driver): Promise<void> {
await driver.clickElement('[data-testid="account-menu-icon"]');
await driver.clickElement(
'.multichain-account-list-item--selected [data-testid="account-list-item-menu-button"]',
);
await driver.clickElement('[data-testid="account-list-menu-remove"]');
await driver.clickElement({ text: 'Remove', tag: 'button' });
}

describe('Account-watcher snap', function (this: Suite) {
it('adds watch account with valid EOA address', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver);

// new account should be displayed in the account list
await driver.findElement({
css: '[data-testid="account-menu-icon"]',
text: DEFAULT_WATCHED_ACCOUNT_NAME,
});
await driver.findElement({
css: '.mm-text--ellipsis',
text: SHORTENED_EOA_ADDRESS,
});
},
);
});

it("disables 'Send' 'Swap' and 'Bridge' buttons for watch accounts", async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver);

// 'Send' button should be disabled
await driver.findElement('[data-testid="eth-overview-send"][disabled]');
await driver.findElement(
'[data-testid="eth-overview-send"].icon-button--disabled',
);

// 'Swap' button should be disabled
await driver.findElement(
'[data-testid="token-overview-button-swap"][disabled]',
);
await driver.findElement(
'[data-testid="token-overview-button-swap"].icon-button--disabled',
);

// 'Bridge' button should be disabled
await driver.findElement(
'[data-testid="eth-overview-bridge"][disabled]',
);
await driver.findElement(
'[data-testid="eth-overview-bridge"].icon-button--disabled',
);

// check tooltips for disabled buttons
await driver.findElement(
'.icon-button--disabled [data-tooltipped][data-original-title="Not supported with this account."]',
);
},
);
});

const invalidInputTests = [
{
input: 'd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
message: 'Invalid input',
description: 'address missing 0x prefix',
},
{
input: '0x123ABC',
message: 'Invalid address',
description: 'invalid address',
},
{
input: 'invalid.eth',
message: 'Invalid ENS name',
description: 'invalid ENS name',
},
{
input: ACCOUNT_1,
message: `Unknown snap error: Account address '${ACCOUNT_1}' already exists`,
description: 'existing address',
},
];

invalidInputTests.forEach(({ input, message, description }) => {
it(`handles invalid input: ${description}`, async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
await startCreateWatchAccountFlow(driver);

await driver.fill(
'[placeholder="Enter a public address or ENS name"]',
input,
);
await driver.clickElement({ text: 'Watch account', tag: 'button' });

// error message should be displayed by the snap
await driver.findElement({
css: '.snap-ui-renderer__text',
text: message,
});
},
);
});
});

it('does not allow user to import private key of watched address', async function () {
const PRIVATE_KEY_TWO =
'0xf444f52ea41e3a39586d7069cb8e8233e9f6b9dea9cbb700cce69ae860661cc8';
const ACCOUNT_2 = '0x09781764c08de8ca82e156bbf156a3ca217c7950';

await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver, true, ACCOUNT_2);

// import private key of account 2
await driver.clickElement('[data-testid="account-menu-icon"]');
await driver.clickElement(
'[data-testid="multichain-account-menu-popover-action-button"]',
);
await driver.clickElement({ text: 'Import account', tag: 'button' });
await driver.findClickableElement('#private-key-box');
await driver.fill('#private-key-box', PRIVATE_KEY_TWO);
await driver.clickElement(
'[data-testid="import-account-confirm-button"]',
);

// error message should be displayed
await driver.findElement({
css: '.mm-box--color-error-default',
text: 'KeyringController - The account you are trying to import is a duplicate',
});
},
);
});

it("does not display 'Show private key' button for watch accounts", async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver);

// click to view account details
await driver.clickElement(
'[data-testid="account-options-menu-button"]',
);
await driver.clickElement('[data-testid="account-list-menu-details"]');
// 'Show private key' button should not be displayed
await driver.assertElementNotPresent({
css: 'button',
text: 'Show private key',
});
},
);
});

it('removes a watched account', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver);

// remove the selected watch account
await removeSelectedAccount(driver);

// account should be removed from the account list
await driver.assertElementNotPresent({
css: '[data-testid="account-menu-icon"]',
text: DEFAULT_WATCHED_ACCOUNT_NAME,
});
await driver.assertElementNotPresent({
css: '.mm-text--ellipsis',
text: SHORTENED_EOA_ADDRESS,
});
},
);
});

it('can remove and recreate a watched account', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withPreferencesControllerAndFeatureFlag({
watchEthereumAccountEnabled: true,
})
.withNetworkControllerOnMainnet()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test?.fullTitle(),
},
async ({ driver }: { driver: Driver }) => {
// watch EOA address
await watchEoaAddress(driver);

// remove the selected watch account
await removeSelectedAccount(driver);

// account should be removed from the account list
await driver.assertElementNotPresent({
css: '[data-testid="account-menu-icon"]',
text: DEFAULT_WATCHED_ACCOUNT_NAME,
});
await driver.assertElementNotPresent({
css: '.mm-text--ellipsis',
text: SHORTENED_EOA_ADDRESS,
});

// re-add the same watch account
await watchEoaAddress(driver, false);

// same account should be displayed in the account list
await driver.findElement({
css: '[data-testid="account-menu-icon"]',
text: DEFAULT_WATCHED_ACCOUNT_NAME,
});
await driver.findElement({
css: '.mm-text--ellipsis',
text: SHORTENED_EOA_ADDRESS,
});
},
);
});
});