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

Multichain API E2E Test: handling when MetaMask is password locked #29724

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
4 changes: 2 additions & 2 deletions test/e2e/fixture-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ class FixtureBuilder {
});
}

withPermissionControllerConnectedToTestDappMultichain({
withPermissionControllerConnectedToMultichainTestDapp({
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
account = '',
useLocalhostHostname = false,
} = {}) {
Expand Down Expand Up @@ -541,7 +541,7 @@ class FixtureBuilder {
});
}

withPermissionControllerConnectedToTestDappMultichainWithTwoAccounts({
withPermissionControllerConnectedToMultichainTestDappWithTwoAccounts({
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
scopes = ['eip155:1337'],
}) {
const optionalScopes = scopes
Expand Down
10 changes: 2 additions & 8 deletions test/e2e/flask/multichain-api/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
WINDOW_TITLES,
withFixtures,
} from '../../helpers';
import { Driver } from '../../webdriver/driver';

import FixtureBuilder from '../../fixture-builder';
import type { FixtureCallbackArgs } from './testHelpers';

describe('Multichain API', function () {
it('should connect the wallet to the multichain test dapp via `externally_connectable` and successfully create a session with the requested chains', async function () {
Expand All @@ -30,13 +30,7 @@ describe('Multichain API', function () {
fixtures: new FixtureBuilder().withPopularNetworks().build(),
title: this.test?.fullTitle(),
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await unlockWallet(driver);

await openDapp(driver, undefined, DAPP_URL);
Expand Down
146 changes: 146 additions & 0 deletions test/e2e/flask/multichain-api/password-locked.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { strict as assert } from 'assert';
import { ACCOUNT_1, WINDOW_TITLES, withFixtures } from '../../helpers';
import { Driver } from '../../webdriver/driver';
import FixtureBuilder from '../../fixture-builder';
import {
DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
escapeColon,
type FixtureCallbackArgs,
getExpectedSessionScope,
getSessionScopes,
openMultichainDappAndConnectWalletWithExternallyConnectable,
passwordLockMetamaskExtension,
} from './testHelpers';

describe("A dapp is connected with account and chain permissions previously granted via `wallet_createSession`, user's extension becomes password locked", function () {
describe('the dapp sends a request through the Multichain API that requires user confirmation on the permitted account', function () {
it('should prompts the user to unlock MetaMask before returning an RPC response to the dapp', async function () {
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
await withFixtures(
{
title: this.test?.fullTitle(),
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.withPermissionControllerConnectedToMultichainTestDapp()
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({

Check failure on line 27 in test/e2e/flask/multichain-api/password-locked.spec.ts

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

Replace `⏎··········driver,⏎··········extensionId,⏎·······` with `·driver,·extensionId`
driver,
extensionId,
}: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
);
await passwordLockMetamaskExtension(driver);
await driver.switchToWindowWithTitle(
WINDOW_TITLES.MultichainTestDApp,
);

await driver.clickElementSafe(
'[data-testid="eip155:1337-eth_sendTransaction-option"]',
);
await driver.clickElement(
'[data-testid="invoke-method-eip155:1337-btn"]',
);

await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);

const unlockExtensionPageWebElement0 = await driver.findElement(
'[data-testid="unlock-page"]',
);

assert.ok(
unlockExtensionPageWebElement0,
'Should prompt user to unlock Metamask Extension',
);

await driver.switchToWindowWithTitle(
WINDOW_TITLES.MultichainTestDApp,
);

await driver.clickElementSafe(
'[data-testid="wallet:eip155-wallet_addEthereumChain-option"]',
);
await driver.clickElement(
'[data-testid="invoke-method-wallet:eip155-btn"]',
);
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved

await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);

const unlockExtensionPageWebElement1 = await driver.findElement(
'[data-testid="unlock-page"]',
);

assert.ok(
unlockExtensionPageWebElement1,
'Should prompt user to unlock Metamask Extension',
);
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
},
);
});
});

describe('the dapp sends requests through the Multichain API that do NOT require user confirmation', function () {
const SCOPE = 'eip155:1337';
const CHAIN_ID = '0x539';
it('should handle the requests without prompting the user to unlock the wallet', async function () {
await withFixtures(
{
title: this.test?.fullTitle(),
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.withPermissionControllerConnectedToMultichainTestDapp()
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
);
await passwordLockMetamaskExtension(driver);

await driver.switchToWindowWithTitle(
WINDOW_TITLES.MultichainTestDApp,
);

const parsedResult = await getSessionScopes(driver);
const sessionScope = parsedResult.sessionScopes[SCOPE];
const expectedSessionScope = getExpectedSessionScope(SCOPE, [
ACCOUNT_1,
]);

ffmcgee725 marked this conversation as resolved.
Show resolved Hide resolved
await driver.clickElementSafe(
`[data-testid="${SCOPE}-eth_chainId-option"]`,
);
await driver.clickElementSafe(
`[data-testid="invoke-method-${SCOPE}-btn"]`,
);
const chainIdResultWebElement = await driver.findElement(
`#invoke-method-${escapeColon(SCOPE)}-eth_chainId-result-0`,
);
const chainId = await chainIdResultWebElement.getText();

assert.deepStrictEqual(
sessionScope,
expectedSessionScope,
`Should receive result that specifies expected session scopes for ${SCOPE}`,
);

assert.deepStrictEqual(
chainId,
`"${CHAIN_ID}"`,
'Should get expected result from calling eth_chainId',
);
},
);
});
});
});
15 changes: 15 additions & 0 deletions test/e2e/flask/multichain-api/testHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
} from '../../helpers';
import { Driver } from '../../webdriver/driver';

export type FixtureCallbackArgs = { driver: Driver; extensionId: string };

/**
* Default options for setting up Multichain E2E test environment
*/
Expand Down Expand Up @@ -83,7 +85,7 @@

// @ts-expect-error Driver.findNestedElement injects `fill` method onto returned element, but typescript compiler will not let us access this method without a complaint, so we override it.
scopeInput.fill(scope);
await driver.clickElement(`#add-custom-scope-button-${i}`);

Check warning on line 88 in test/e2e/flask/multichain-api/testHelpers.ts

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'#add' Hex color values are not allowed. Consider using design tokens instead. For support reach out to the design system team #metamask-design-system on Slack
}

for (const [i, account] of accounts.entries()) {
Expand All @@ -93,7 +95,7 @@

// @ts-expect-error Driver.findNestedElement injects `fill` method onto returned element, but typescript compiler will not let us access this method without a complaint, so we override it.
accountInput.fill(account);
await driver.clickElement(`#add-custom-address-button-${i}`);

Check warning on line 98 in test/e2e/flask/multichain-api/testHelpers.ts

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'#add' Hex color values are not allowed. Consider using design tokens instead. For support reach out to the design system team #metamask-design-system on Slack
}

await driver.clickElement({ text: 'wallet_createSession', tag: 'span' });
Expand Down Expand Up @@ -197,6 +199,19 @@
await driver.clickElement({ text: 'Update', tag: 'button' });
};

/**
* Password locks user's metamask extension.
*
* @param driver - E2E test driver {@link Driver}, wrapping the Selenium WebDriver.
*/
export const passwordLockMetamaskExtension = async (
driver: Driver,
): Promise<void> => {
await driver.switchToWindowWithTitle(WINDOW_TITLES.ExtensionInFullScreenView);
await driver.clickElementSafe('[data-testid="account-options-menu-button"]');
await driver.clickElementSafe('[data-testid="global-menu-lock"]');
};

/**
* Sometimes we need to escape colon character when using {@link Driver.findElement}, otherwise selenium will treat this as an invalid selector.
*
Expand Down
68 changes: 10 additions & 58 deletions test/e2e/flask/multichain-api/wallet_createSession.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
ACCOUNT_1,
ACCOUNT_2,
} from '../../helpers';
import { Driver } from '../../webdriver/driver';
import FixtureBuilder from '../../fixture-builder';
import {
initCreateSessionScopes,
Expand All @@ -18,6 +17,7 @@ import {
getExpectedSessionScope,
addAccountInWalletAndAuthorize,
updateNetworkCheckboxes,
type FixtureCallbackArgs,
} from './testHelpers';

describe('Multichain API', function () {
Expand All @@ -31,13 +31,7 @@ describe('Multichain API', function () {
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
const scopesToIgnore = ['eip155:1338', 'eip155:1000'];
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
Expand Down Expand Up @@ -77,13 +71,7 @@ describe('Multichain API', function () {
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
const REQUEST_SCOPE = 'eip155:1337';
/**
* check {@link FixtureBuilder.withTrezorAccount} for second injected account address.
Expand Down Expand Up @@ -136,13 +124,7 @@ describe('Multichain API', function () {
fixtures: new FixtureBuilder().withPopularNetworks().build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
const requestScopesToNetworkMap = {
'eip155:1': 'Ethereum Mainnet',
'eip155:59141': 'Linea Sepolia',
Expand Down Expand Up @@ -204,13 +186,7 @@ describe('Multichain API', function () {
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
Expand Down Expand Up @@ -259,13 +235,7 @@ describe('Multichain API', function () {
fixtures: new FixtureBuilder().build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
Expand Down Expand Up @@ -304,13 +274,7 @@ describe('Multichain API', function () {
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
Expand Down Expand Up @@ -346,13 +310,7 @@ describe('Multichain API', function () {
fixtures: new FixtureBuilder().build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
Expand Down Expand Up @@ -400,7 +358,7 @@ describe('Multichain API', function () {
title: this.test?.fullTitle(),
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.withPermissionControllerConnectedToTestDappMultichainWithTwoAccounts(
.withPermissionControllerConnectedToMultichainTestDappWithTwoAccounts(
{
scopes: OLD_SCOPES,
},
Expand All @@ -409,13 +367,7 @@ describe('Multichain API', function () {
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
async ({ driver, extensionId }: FixtureCallbackArgs) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
Expand Down
Loading
Loading