Skip to content

Commit

Permalink
Merge branch 'develop' into test-scenario-sign3-hw
Browse files Browse the repository at this point in the history
  • Loading branch information
seaona authored Feb 20, 2024
2 parents 1c38748 + 3e3acf5 commit bb53ca9
Show file tree
Hide file tree
Showing 16 changed files with 228 additions and 27 deletions.
2 changes: 1 addition & 1 deletion test/e2e/mmi/specs/extension.visual.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ test.describe('MMI extension', () => {
);
});

test('Custodian token management', async ({ page, context }) => {
test.skip('Custodian token management', async ({ page, context }) => {
// Define const to compare in assertions
const arrayWithoutCustodianAccounts = ['Account 1'];
const arrayWithCustodianAccounts = [
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/mmi/specs/transactions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const sendTransaction = async (
};

test.describe('MMI send', () => {
test('Send a transaction from one account to another and confirm it from custody', async ({
test.skip('Send a transaction from one account to another and confirm it from custody', async ({
page,
context,
}) => {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/tests/settings-search.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Settings Search', function () {
security: 'Reveal Secret',
alerts: 'Browsing a website',
networks: 'Ethereum Mainnet',
experimental: 'Security alerts',
experimental: 'Nicknames',
about: 'Terms of Use',
};

Expand Down Expand Up @@ -98,7 +98,7 @@ describe('Settings Search', function () {
},
);
});
it('should find element inside the Security tab', async function () {
it('should find element inside the "Security & privacy" tab', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder().build(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Steps,Test Steps,Preconditions,Test Data,Expected Result,Notes
1,Open the extension.,,,The Welcome Back screen is shown.,
2,Proceed to Unlock the wallet.,,password (8 characters min).,"The Ether balance is shown on the overview.
The wallet address is shown on the overview.",
3,"Click on account menu icon. Click ""Add account or hardware wallet"".",,,"The ""Add account"" modal is shown.",
4,"On ""Add account"" modal, click ""Add hardware wallet"" button.",,,"""Connect a hardware wallet"" screen is shown. User can choose between different options to connect a hardware: Ledger, Trezor, Lattice, or QR-based. ""Continue"" button is disabled.",
5,Choose an option to connect hardware wallet.,We need to have a hardware wallet set up to test this functionality.,"e.g. choose ""Ledger""","""Continue"" button is enabled.",
6,"Plug the hardware wallet directly into computer, then unlock it.",,Password for hardware wallet,"Hardware wallet is detected by MetaMask. ""Select an account"" screen is shown on MetaMask, accounts on hardware wallet are shown on this screen.","If you use Ledger, you need to open the Ethereum app on Ledger. If you use Trezor, make sure you use the correct passphrase."
7,"Choose one or multiples accounts that user wants to connect. Then click ""Unlock"".",,,,
8,Click account menu icon to open accounts list.,,,"In accounts list, all selected hardware wallet accounts are shown, and they are all flagged with harware wallet name to be distinguished from other accounts.",
9,Select one hardware wallet account.,,,"The Ether balance for the selected hardware wallet account is shown on the overview.
The selected account address is shown on the overview.",
10,Open the test dapp in another tab.,,https://metamask.github.io/test-dapp/,,
11,Click Connect.,,,"The MetaMask popup is opened with the Connect with MetaMask screen displayed.
Your imported hardware wallet account is selected.",
12,Click Next and Connect with the hardware wallet account.,,,"The MetaMask popup is closed.
You are connected to the test dapp.",
13,"Click ""Sign Typed Data V4"".",,,"The info modal instructions for signing with hardware wallet is displayed.
The signature message is in JSON formatting.",
14,Accept the Signature in the hardware wallet device.,,,The signature hash is displayed on the test dapp.,
15,Verify signed hash.,,,The signed address is correctly verified.,The address shown in the test dapp is the same as the hardware wallet account.
2 changes: 1 addition & 1 deletion test/scenarios/2. keyring/connect hardware wallet.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Step,Test steps,Preconditions,Test data,Expected result,Notes
3,"Keep Ethereum Mainnet as the selected network. Click on account menu icon. Click ""Add account or hardware wallet"".",,,"The ""Add account"" modal is shown.",
4,"On ""Add account"" modal, click ""Add hardware wallet"" button.",,,"""Connect a hardware wallet"" screen is shown. User can choose between different options to connect a hardware: Ledger, Trezor, Lattice, or QR-based. ""Continue"" button is disabled.",
5,Choose an option to connect hardware wallet.,We need to have a hardware wallet setted up to test this functionality.,"e.g. choose ""Ledger""","""Continue"" button is enabled.",
6,"Plug the hardware wallet directly into computer, then unlock it.",,password for hardware wallet,"Hardware wallet is detected by MetaMask. ""Select an account"" screen is shown on MetaMask, accounts on hardware wallet are shown on this screen.","If you use Ledger, you need to open the Ethereum app on Ledger. If you use Trazor, make sure you use the correct passphrase."
6,"Plug the hardware wallet directly into computer, then unlock it.",,password for hardware wallet,"Hardware wallet is detected by MetaMask. ""Select an account"" screen is shown on MetaMask, accounts on hardware wallet are shown on this screen.","If you use Ledger, you need to open the Ethereum app on Ledger. If you use Trezor, make sure you use the correct passphrase."
7,"Choose one or multiples accounts that user wants to connect. Then click ""Unlock"".",,,,
8,Click account menu icon to open accounts list.,,,"In accounts list, all selected hardware wallet accounts are shown, and they are all flagged with harware wallet name to be distinguished from other accounts.",
9,"Select one hardware wallet account. ",,,"The Ether balance for the selected hardware wallet account is shown on the overview. The selected account address is shown on the overview. The selected network is Ethereum Mainnet. ",
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,11 @@ export default class TransactionListItemDetails extends PureComponent {
}
{transactionGroup.initialTransaction.type !==
TransactionType.incoming && (
<Disclosure title={t('activityLog')} size="small">
<Disclosure
title={t('activityLog')}
size="small"
isScrollToBottomOnOpen
>
<TransactionActivityLog
transactionGroup={transactionGroup}
className="transaction-list-item-details__transaction-activity-log"
Expand Down
41 changes: 41 additions & 0 deletions ui/components/ui/disclosure/__snapshots__/disclosure.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Disclosure matches snapshot with title prop 1`] = `
<div>
<div
class="disclosure"
data-testid="disclosure"
>
<details>
<summary
class="disclosure__summary"
>
<span
class="mm-box disclosure__summary--icon mm-icon mm-icon--size-sm mm-box--margin-inline-end-2 mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/add.svg');"
/>
Test Title
</summary>
<div
class="disclosure__content small"
>
Test
</div>
<div
class="disclosure__footer"
/>
</details>
</div>
</div>
`;

exports[`Disclosure matches snapshot without title prop 1`] = `
<div>
<div
class="disclosure"
data-testid="disclosure"
>
Test
</div>
</div>
`;
24 changes: 17 additions & 7 deletions ui/components/ui/disclosure/disclosure.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,32 @@ const renderSummaryByType = (variant, title, size) => {
}
};

const Disclosure = ({ children, title, size, variant }) => {
const Disclosure = ({
children,
isScrollToBottomOnOpen,
title,
size,
variant,
}) => {
const disclosureFooterEl = useRef(null);
const [open, setOpen] = useState(false);

const scrollToBottom = () => {
disclosureFooterEl &&
disclosureFooterEl.current &&
disclosureFooterEl.current.scrollIntoView({ behavior: 'smooth' });
disclosureFooterEl?.current?.scrollIntoView({ behavior: 'smooth' });
};

useEffect(() => {
if (open) {
if (isScrollToBottomOnOpen && open) {
scrollToBottom();
}
}, [open]);
}, [isScrollToBottomOnOpen, open]);

return (
<div className="disclosure" onClick={() => setOpen((state) => !state)}>
<div
className="disclosure"
data-testid="disclosure"
onClick={() => setOpen((state) => !state)}
>
{title ? (
<details>
{renderSummaryByType(variant, title)}
Expand All @@ -83,12 +91,14 @@ const Disclosure = ({ children, title, size, variant }) => {

Disclosure.propTypes = {
children: PropTypes.node.isRequired,
isScrollToBottomOnOpen: PropTypes.bool,
size: PropTypes.string,
title: PropTypes.string,
variant: PropTypes.string,
};

Disclosure.defaultProps = {
isScrollToBottomOnOpen: false,
size: 'normal',
title: null,
variant: DisclosureVariant.Default,
Expand Down
80 changes: 80 additions & 0 deletions ui/components/ui/disclosure/disclosure.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import Disclosure from './disclosure';

describe('Disclosure', () => {
it('matches snapshot without title prop', () => {
const { container } = render(<Disclosure variant="">Test</Disclosure>);
expect(container).toMatchSnapshot();
});

it('matches snapshot with title prop', () => {
const { container } = render(
<Disclosure title="Test Title" size="small">
Test
</Disclosure>,
);
expect(container).toMatchSnapshot();
});

it('renders content', () => {
const { container, getByText, rerender } = render(
<Disclosure title="Test Title">Test</Disclosure>,
);
expect(getByText('Test Title')).toBeInTheDocument();
expect(container.querySelector('.disclosure__content').textContent).toBe(
'Test',
);

expect(
container.querySelector('.disclosure__content.normal'),
).toBeInTheDocument();

rerender(
<Disclosure title="Test Title" size="small">
Test
</Disclosure>,
);

expect(
container.querySelector('.disclosure__content.small'),
).toBeInTheDocument();
});

describe('when clicking on disclosure', () => {
it('does not scroll down on open by default or when isScrollToBottomOnOpen is false', () => {
const mockScrollIntoView = jest.fn();
const originalScrollIntoView =
window.HTMLElement.prototype.scrollIntoView;
window.HTMLElement.prototype.scrollIntoView = mockScrollIntoView;

const { getByTestId } = render(
<Disclosure title="Test Title">Test</Disclosure>,
);
const element = getByTestId('disclosure');
fireEvent.click(element);
expect(mockScrollIntoView).not.toHaveBeenCalled();
window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
});

it('scrolls down on open when isScrollToBottomOnOpen is true', () => {
const mockScrollIntoView = jest.fn();
const originalScrollIntoView =
window.HTMLElement.prototype.scrollIntoView;
window.HTMLElement.prototype.scrollIntoView = mockScrollIntoView;

const { getByTestId } = render(
<Disclosure title="Test Title" isScrollToBottomOnOpen>
Test
</Disclosure>,
);
const element = getByTestId('disclosure');

fireEvent.click(element);
expect(mockScrollIntoView).toHaveBeenCalledWith({
behavior: 'smooth',
});
window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
});
});
});
50 changes: 41 additions & 9 deletions ui/helpers/constants/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,30 @@ export const SETTINGS_CONSTANTS = [
route: `${SECURITY_ROUTE}#proposed-nicknames`,
icon: 'fa fa-lock',
},
/**
* settingsRefs 15-17 will be handled in a future PR
*
* @see {@link https://github.com/MetaMask/metamask-extension/pull/22967}
*/
// securityAndPrivacy settingsRefs[15]
{
tabMessage: (t) => t('securityAndPrivacy'),
sectionMessage: (t) => t('securityAlerts'),
descriptionMessage: (t) => t('securityAlertsDescription'),
route: `${SECURITY_ROUTE}#security-alerts`,
icon: 'fa fa-lock',
},
// securityAndPrivacy settingsRefs[16]
{
tabMessage: (t) => t('securityAndPrivacy'),
sectionMessage: (t) => t('blockaid'),
descriptionMessage: (t) => t('blockaidMessage'),
route: `${SECURITY_ROUTE}#security-alerts-blockaid`,
icon: 'fa fa-lock',
},
// securityAndPrivacy settingsRefs[17]
{
tabMessage: (t) => t('securityAndPrivacy'),
sectionMessage: (t) => t('openSeaLabel'),
descriptionMessage: (t) => t('openSeaMessage'),
route: `${SECURITY_ROUTE}#security-alerts-opensea`,
icon: 'fa fa-lock',
},
{
tabMessage: (t) => t('alerts'),
sectionMessage: (t) => t('alertSettingsUnconnectedAccount'),
Expand Down Expand Up @@ -405,11 +424,24 @@ export const SETTINGS_CONSTANTS = [
route: `${ADVANCED_ROUTE}#restore-userdata`,
icon: 'fas fa-upload',
},
// experimental settingsRefs[0]
{
tabMessage: (t) => t('experimental'),
sectionMessage: (t) => t('securityAlerts'),
descriptionMessage: (t) => t('securityAlertsDescription'),
route: `${EXPERIMENTAL_ROUTE}#security-alerts`,
icon: 'fa fa-flask',
sectionMessage: (t) => t('petnamesEnabledToggle'),
descriptionMessage: (t) => t('petnamesEnabledToggleDescription'),
route: `${EXPERIMENTAL_ROUTE}#nicknames`,
icon: 'fas fa-flask',
},

///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
// since this route is only included with keyring-snaps feature flag, this needs to be the last settingsRef for the experimental tab
// experimental settingsRefs[1]
{
tabMessage: (t) => t('experimental'),
sectionMessage: (t) => t('snaps'),
descriptionMessage: (t) => t('addSnapAccountToggle'),
route: `${EXPERIMENTAL_ROUTE}#snaps`,
icon: 'fas fa-flask',
},
///: END:ONLY_INCLUDE_IF
];
6 changes: 3 additions & 3 deletions ui/helpers/utils/settings-search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ describe('Settings Search Utils', () => {
expect(getNumberOfSettingRoutesInTab(t, t('contacts'))).toStrictEqual(1);
});

it('returns "Security & Privacy" section count', () => {
it('returns "Security & privacy" section count', () => {
expect(
getNumberOfSettingRoutesInTab(t, t('securityAndPrivacy')),
).toStrictEqual(15);
).toStrictEqual(18);
});

it('returns "Alerts" section count', () => {
Expand All @@ -175,7 +175,7 @@ describe('Settings Search Utils', () => {

it('returns "Experimental" section count', () => {
expect(getNumberOfSettingRoutesInTab(t, t('experimental'))).toStrictEqual(
1,
2,
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exports[`Security Provider Banner Alert should match snapshot 1`] = `
</p>
<div
class="disclosure"
data-testid="disclosure"
>
<details>
<summary
Expand Down Expand Up @@ -104,6 +105,7 @@ exports[`Security Provider Banner Alert should render disclosure component if no
</p>
<div
class="disclosure"
data-testid="disclosure"
>
<details>
<summary
Expand Down
Loading

0 comments on commit bb53ca9

Please sign in to comment.