Skip to content

Commit

Permalink
test: Onboarding add custom default ETH Mainnet (#8723)
Browse files Browse the repository at this point in the history
## **Description**
New test for adding a custom default ETH Mainnet during Onboarding after
MMM has been installed on device.
Added this test as part of the Regression tests.

## **Related issues**

Fixes: MetaMask/mobile-planning#1455

## **Manual testing steps**
On local machine run on this branch...
Android: `yarn test:e2e:android:debug:single
./e2e/specs/onboarding/add-custom-eth-mainnet.spec.js`
iOS: `yarn test:e2e:ios:debug:single
./e2e/specs/onboarding/add-custom-eth-mainnet.spec.js`

On bitrise run `pr_regression_e2e_pipeline` on this branch.

Above steps should pass.

## **Screenshots/Recordings**

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

### **Before**

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

### **After**
Regression tests:
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/27207577-3107-4fdb-b0b7-56561831c263
Smoke tests:
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/6d64d3b0-8537-4c24-8b98-a832bfdd4211


https://github.com/MetaMask/metamask-mobile/assets/6626407/c3311213-42d1-4843-b672-510a3da8d2c0



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

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained what problem this PR is solving and how it
is solved.
- [x] I've linked related issues
- [x] I've included manual testing steps
- [x] I've included screenshots/recordings if applicable
- [x] 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.
- [x] I’ve properly set the pull request status:
  - [x] In case it's not yet "ready for review", I've set it to "draft".
- [x] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [x] 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
chrisleewilcox authored Mar 8, 2024
1 parent c02483c commit 9103133
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 31 deletions.
28 changes: 10 additions & 18 deletions app/components/UI/OptinMetrics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
BackHandler,
Alert,
InteractionManager,
Platform,
} from 'react-native';
import PropTypes from 'prop-types';
import { baseStyles, fontStyles } from '../../../styles/common';
Expand All @@ -24,17 +23,9 @@ import {
MetaMetricsEvents,
withMetricsAwareness,
} from '../../hooks/useMetrics';

import DefaultPreference from 'react-native-default-preference';
import { ThemeContext } from '../../../util/theme';
import generateTestId from '../../../../wdio/utils/generateTestId';
import {
OPTIN_METRICS_I_AGREE_BUTTON_ID,
OPTIN_METRICS_NO_THANKS_BUTTON_ID,
OPTIN_METRICS_TITLE_ID,
METAMETRICS_OPT_IN_CONTAINER_ID,
OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID,
} from '../../../../wdio/screen-objects/testIDs/Screens/OptinMetricsScreen.testIds';
import { MetaMetricsOptInSelectorsIDs } from '../../../../e2e/selectors/Onboarding/MetaMetricsOptIn.selectors';
import Button, {
ButtonVariants,
ButtonSize,
Expand Down Expand Up @@ -416,7 +407,9 @@ class OptinMetrics extends PureComponent {
<Button
variant={ButtonVariants.Secondary}
onPress={this.onCancel}
{...generateTestId(Platform, OPTIN_METRICS_NO_THANKS_BUTTON_ID)}
testID={
MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_NO_THANKS_BUTTON_ID
}
style={styles.button}
label={strings('privacy_policy.cta_no_thanks')}
size={ButtonSize.Lg}
Expand All @@ -426,7 +419,7 @@ class OptinMetrics extends PureComponent {
<Button
variant={ButtonVariants.Primary}
onPress={this.onConfirm}
{...generateTestId(Platform, OPTIN_METRICS_I_AGREE_BUTTON_ID)}
testID={MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_I_AGREE_BUTTON_ID}
style={styles.button}
label={strings('privacy_policy.cta_i_agree')}
size={ButtonSize.Lg}
Expand Down Expand Up @@ -488,7 +481,7 @@ class OptinMetrics extends PureComponent {
return (
<SafeAreaView
style={styles.root}
{...generateTestId(Platform, METAMETRICS_OPT_IN_CONTAINER_ID)}
testID={MetaMetricsOptInSelectorsIDs.METAMETRICS_OPT_IN_CONTAINER_ID}
>
<ScrollView
style={styles.root}
Expand All @@ -500,16 +493,15 @@ class OptinMetrics extends PureComponent {
<View style={styles.wrapper}>
<Text
style={styles.title}
{...generateTestId(Platform, OPTIN_METRICS_TITLE_ID)}
testID={MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_TITLE_ID}
>
{strings('privacy_policy.description_title')}
</Text>
<Text
style={styles.content}
{...generateTestId(
Platform,
OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID,
)}
testID={
MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID
}
>
{strings('privacy_policy.description_content_1')}
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import {
Linking,
} from 'react-native';
import { connect } from 'react-redux';
import { isSafeChainId, toHex } from '@metamask/controller-utils';

import { typography } from '@metamask/design-tokens';
import {
fontStyles,
Expand Down Expand Up @@ -66,6 +64,8 @@ import {
} from '../../../../../selectors/networkController';
import { regex } from '../../../../../../app/util/regex';
import { NetworksViewSelectorsIDs } from '../../../../../../e2e/selectors/Settings/NetworksView.selectors';
import { isSafeChainId, toHex } from '@metamask/controller-utils';
import { CustomDefaultNetworkIDs } from '../../../../../../e2e/selectors/Onboarding/CustomDefaultNetwork.selectors';
import { updateIncomingTransactions } from '../../../../../util/transaction-controller';
import { withMetricsAwareness } from '../../../../../components/hooks/useMetrics';
import { CHAIN_IDS } from '@metamask/transaction-controller/dist/constants';
Expand Down Expand Up @@ -1250,6 +1250,7 @@ class NetworkSettings extends PureComponent {
size={ButtonSize.Lg}
disabled={isActionDisabled}
width={ButtonWidthTypes.Full}
testID={CustomDefaultNetworkIDs.USE_THIS_NETWORK_BUTTON_ID}
/>
) : (
(addMode || editable) && (
Expand Down
31 changes: 31 additions & 0 deletions e2e/pages/Onboarding/DefaultNetworkView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Matchers from '../../utils/Matchers';
import Gestures from '../../utils/Gestures';
import NetworksView from '../Settings/NetworksView';
import {
CustomDefaultNetworkIDs,
CustomDefaultNetworkTexts,
} from '../../selectors/Onboarding/CustomDefaultNetwork.selectors';

class DefaultNetworkView {
get useThisNetworkButton() {
return device.getPlatform() === 'ios'
? Matchers.getElementByID(
CustomDefaultNetworkIDs.USE_THIS_NETWORK_BUTTON_ID,
)
: Matchers.getElementByLabel(
CustomDefaultNetworkTexts.USE_THIS_NETWORK_BUTTON_TEXT,
);
}

async tapUseThisNetworkButton() {
await Gestures.waitAndTap(this.useThisNetworkButton);
await Gestures.waitAndTap(this.useThisNetworkButton);
}

async typeRpcURL(rpcURL) {
await (await NetworksView.rpcURLInput).clearText();
await NetworksView.typeInRpcUrl(rpcURL);
}
}

export default new DefaultNetworkView();
30 changes: 20 additions & 10 deletions e2e/pages/Onboarding/MetaMetricsOptInView.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import {
OPTIN_METRICS_I_AGREE_BUTTON_ID,
OPTIN_METRICS_NO_THANKS_BUTTON_ID,
OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID,
METAMETRICS_OPT_IN_CONTAINER_ID,
} from '../../../wdio/screen-objects/testIDs/Screens/OptinMetricsScreen.testIds';
import { MetaMetricsOptInSelectorsIDs } from '../../selectors/Onboarding/MetaMetricsOptIn.selectors';
import Matchers from '../../utils/Matchers';
import Gestures from '../../utils/Gestures';

class MetaMetricsOptIn {
get container() {
return Matchers.getElementByID(METAMETRICS_OPT_IN_CONTAINER_ID);
return Matchers.getElementByID(
MetaMetricsOptInSelectorsIDs.METAMETRICS_OPT_IN_CONTAINER_ID,
);
}

get optInMetricsContent() {
return Matchers.getElementByID(
OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID,
MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID,
);
}

get iAgreeButton() {
return Matchers.getElementByID(OPTIN_METRICS_I_AGREE_BUTTON_ID);
return Matchers.getElementByID(
MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_I_AGREE_BUTTON_ID,
);
}

get noThanksButton() {
return Matchers.getElementByID(OPTIN_METRICS_NO_THANKS_BUTTON_ID);
return Matchers.getElementByID(
MetaMetricsOptInSelectorsIDs.OPTIN_METRICS_NO_THANKS_BUTTON_ID,
);
}

async tapAgreeButton() {
Expand All @@ -35,6 +36,15 @@ class MetaMetricsOptIn {
await Gestures.swipe(this.optInMetricsContent, 'up', 'fast', 0.9);
await Gestures.waitAndTap(this.noThanksButton);
}

async tapEditDefaultNetworkHere() {
await Gestures.swipe(this.optInMetricsContent, 'up', 'fast', 0.9);
if (device.getPlatform() === 'ios') {
await Gestures.tapAtPoint(this.container, { x: 333, y: 534 });
} else {
await Gestures.tapAtPoint(this.optInMetricsContent, { x: 15, y: 570 });
}
}
}

export default new MetaMetricsOptIn();
4 changes: 3 additions & 1 deletion e2e/resources/blacklistURLs.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
".*rpc.tenderly.co/.*",
".*api-goerli.etherscan.io/.*",
".*cloudflare-ipfs.com/.*",
".*stale.*"
".*stale.*",
".*phishing-detection.metafi.codefi.network/.*",
".*token-api.metaswap.codefi.network/.*"
]
}
9 changes: 9 additions & 0 deletions e2e/resources/networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,14 @@
"nickname": "Gnosis",
"ticker": "xDAI"
}
},
"EthereumMainCustom": {
"providerConfig": {
"type": "rpc",
"chainId": "1",
"rpcUrl": "https://eth.llamarpc.com",
"nickname": "Ethereum Main Custom",
"ticker": "ETH"
}
}
}
9 changes: 9 additions & 0 deletions e2e/selectors/Onboarding/CustomDefaultNetwork.selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import messages from '../../../locales/languages/en.json';

export const CustomDefaultNetworkIDs = {
USE_THIS_NETWORK_BUTTON_ID: 'use-this-network',
};

export const CustomDefaultNetworkTexts = {
USE_THIS_NETWORK_BUTTON_TEXT: messages.app_settings.networks_default_cta,
};
13 changes: 13 additions & 0 deletions e2e/selectors/Onboarding/MetaMetricsOptIn.selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// eslint-disable-next-line import/prefer-default-export
export const MetaMetricsOptInSelectorsIDs = {
OPTIN_METRICS_TITLE_ID: 'optin-metrics-title-id',
OPTIN_METRICS_NO_THANKS_BUTTON_ID: 'optin-metrics-no-thanks-button-id',
OPTIN_METRICS_I_AGREE_BUTTON_ID: 'optin-metrics-i-agree-button-id',
OPTIN_METRICS_PRIVACY_POLICY_DESCRIPTION_CONTENT_1_ID:
'optin-metrics-privacy-policy-description',
OPTIN_METRICS_HERE_DEFAULT_NETWORK_ID: 'optin-metrics-default-network-id',
DEFAULT_NETWORK_RPC_URL: 'default-network-rpc-url',
DEFAULT_NETWORK_USE_THIS_NETWORK_BUTTON_ID:
'default-network-use-this-button-id',
METAMETRICS_OPT_IN_CONTAINER_ID: 'meta-metrics-container',
};
60 changes: 60 additions & 0 deletions e2e/specs/onboarding/add-custom-eth-mainnet.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Regression } from '../../tags';
import OnboardingCarouselView from '../../pages/Onboarding/OnboardingCarouselView';
import OnboardingView from '../../pages/Onboarding/OnboardingView';
import Assertions from '../../utils/Assertions';
import MetaMetricsOptIn from '../../pages/Onboarding/MetaMetricsOptInView';
import DefaultNetworkView from '../../pages/Onboarding/DefaultNetworkView';
import TermsOfUseModal from '../../pages/modals/TermsOfUseModal';
import CreatePasswordView from '../../pages/Onboarding/CreatePasswordView';
import EnableAutomaticSecurityChecksView from '../../pages/EnableAutomaticSecurityChecksView';
import SkipAccountSecurityModal from '../../pages/modals/SkipAccountSecurityModal';
import WalletView from '../../pages/WalletView';
import ProtectYourWalletView from '../../pages/Onboarding/ProtectYourWalletView';
import NetworksView from '../../pages/Settings/NetworksView';
import Accounts from '../../../wdio/helpers/Accounts';
import { DEFAULT_MAINNET_CUSTOM_NAME } from '../../../app/constants/network';
import Networks from '../../resources/networks.json';

const validAccount = Accounts.getValidAccount();

describe(Regression('Add custom default ETH Mainnet'), () => {
beforeAll(async () => {
await device.launchApp();
});

it('should navigate to edit custom default ETH Mainnet from Opt-In screen', async () => {
await OnboardingCarouselView.tapOnGetStartedButton();
await OnboardingView.tapCreateWallet();
await Assertions.checkIfVisible(MetaMetricsOptIn.container);
});

it('should not edit default network with invalid RPC', async () => {
await MetaMetricsOptIn.tapEditDefaultNetworkHere();
await DefaultNetworkView.typeRpcURL('https//rpc.mevblocker.io');
await Assertions.checkIfVisible(NetworksView.rpcWarningBanner);
});

it('should edit default ETH Mainnet with valid RPC', async () => {
await DefaultNetworkView.typeRpcURL(
Networks.EthereumMainCustom.providerConfig.rpcUrl,
);
await DefaultNetworkView.tapUseThisNetworkButton();
await Assertions.checkIfVisible(MetaMetricsOptIn.container);
});

it('should show custom default ETH Mainnet as active', async () => {
await MetaMetricsOptIn.tapAgreeButton();
await TermsOfUseModal.tapScrollEndButton();
await TermsOfUseModal.tapAgreeCheckBox();
await TermsOfUseModal.tapAcceptButton();
await CreatePasswordView.enterPassword(validAccount.password);
await CreatePasswordView.reEnterPassword(validAccount.password);
await CreatePasswordView.tapIUnderstandCheckBox();
await CreatePasswordView.tapCreatePasswordButton();
await ProtectYourWalletView.tapOnRemindMeLaterButton();
await SkipAccountSecurityModal.tapIUnderstandCheckBox();
await SkipAccountSecurityModal.tapSkipButton();
await EnableAutomaticSecurityChecksView.tapNoThanks();
await WalletView.isNetworkNameVisible(DEFAULT_MAINNET_CUSTOM_NAME);
});
});

0 comments on commit 9103133

Please sign in to comment.