From 24a1d3fe67958f1304274e41e72b078d58f4676a Mon Sep 17 00:00:00 2001 From: Curtis David Date: Wed, 1 Nov 2023 15:08:10 -0400 Subject: [PATCH] test: Enable Regression tests on Bitrise (#7645) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** The purpose of this PR is to set up the regression test pipeline in Bitrise. Currently, we conduct regression tests on our local machines, which has its limitations. An improved approach involves running these tests on a virtual machine, which offers more flexibility and scalability. The regression pipeline in bitrise is called: `pr_regression_e2e_tests` Also, I removed all flaky/failing tests from the regression tag and placed them in a quarantine folder. ## **Related issues** Fixes: # ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **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 - [ ] I've included manual testing steps - [ ] I've included screenshots/recordings if applicable - [x] I’ve included tests if applicable - [x] 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: - [ ] In case it's not yet "ready for review", I've set it to "draft". - [ ] In case it's "ready for review", I've changed it from "draft" to "non-draft". ## **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. --- bitrise.yml | 46 +++- e2e/pages/WalletView.js | 4 + .../approve-custom-erc20.failing.js} | 3 +- .../quarantine/contract-nickname.failing.js | 218 ++++++++++++++++++ e2e/specs/quarantine/deeplinks.failing.js | 187 +++++++++++++++ ...ystem-removing-imported-account.failing.js | 117 ++++++++++ .../swap-tokens.flaky.js} | 4 +- e2e/specs/quarantine/term-of-use.broken.js | 50 ++++ 8 files changed, 621 insertions(+), 8 deletions(-) rename e2e/specs/{confirmations/approve-custom-erc20.spec.js => quarantine/approve-custom-erc20.failing.js} (97%) create mode 100644 e2e/specs/quarantine/contract-nickname.failing.js create mode 100644 e2e/specs/quarantine/deeplinks.failing.js create mode 100644 e2e/specs/quarantine/permission-system-removing-imported-account.failing.js rename e2e/specs/{swaps/swap-tokens.spec.js => quarantine/swap-tokens.flaky.js} (98%) create mode 100644 e2e/specs/quarantine/term-of-use.broken.js diff --git a/bitrise.yml b/bitrise.yml index cbb065d13d2..f3166d02ed3 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -42,6 +42,7 @@ pipelines: release_e2e_pipeline: stages: - run_e2e_ios_android_stage: {} + # - run_regression_e2e_ios_android_stage: {} Enable whenever regression tests are running successfully. - notify: {} #PR_e2e_verfication (build ios & android), run iOS (smoke), emulator Android pr_smoke_e2e_pipeline: @@ -49,6 +50,12 @@ pipelines: - run_smoke_e2e_ios_android_stage: {} - notify: {} + #PR_e2e_verfication (build ios & android), run iOS (regression), emulator Android + pr_regression_e2e_pipeline: + stages: + - run_regression_e2e_ios_android_stage: {} + - notify: {} + #Stages refrence workflows. Those workflows cannot but utility "_this-is-a-utility" stages: create_build_release: @@ -88,6 +95,10 @@ stages: workflows: - ios_e2e_test: {} - android_e2e_test: {} + run_regression_e2e_ios_android_stage: + workflows: + - ios_run_regression_tests: {} + - android_run_regression_tests: {} run_e2e_ios_android_stage: workflows: - ios_e2e_test: {} @@ -273,6 +284,24 @@ workflows: title: All Tests Passed is_always_run: false # E2E Steps + + ### This workflow uses a flag (TEST_SUITE) that defines the specific set of tests to be run. + ## in this instance Regression. In future iterations we can rename to ios_test_suite_selection & android_test_suite_selection + ios_run_regression_tests: + envs: + - TEST_SUITE: 'regression' + after_run: + - ios_e2e_test + android_run_regression_tests: + meta: + bitrise.io: + stack: linux-docker-android-20.04 + machine_type_id: elite-xl + envs: + - TEST_SUITE: 'regression' + after_run: + - android_e2e_test + e2e_setup: steps: - yarn@: @@ -311,8 +340,13 @@ workflows: inputs: - content: |- #!/usr/bin/env bash + if [ "$TEST_SUITE" = "regression" ]; then + TEST_SUITE="regression" + else + TEST_SUITE="smoke" + fi node -v - IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:android:bitrise:debug --testNamePattern='Smoke' + IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:android:bitrise:debug --testNamePattern="$TEST_SUITE" title: Detox Build & Test is_always_run: false - custom-test-results-export@1: @@ -344,7 +378,6 @@ workflows: - deploy_path: $BITRISE_DEPLOY_DIR - is_compress: true - zip_name: 'E2E_Android_Failure_Screenshots' - meta: bitrise.io: stack: linux-docker-android-20.04 @@ -375,8 +408,13 @@ workflows: inputs: - content: |- #!/usr/bin/env bash + if [ "$TEST_SUITE" = "regression" ]; then + TEST_SUITE="regression" + else + TEST_SUITE="smoke" + fi node -v - IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:ios:debug --testNamePattern='Smoke' + IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:ios:debug --testNamePattern="$TEST_SUITE" title: Detox Build & Test is_always_run: false - custom-test-results-export@1: @@ -813,6 +851,7 @@ app: - opts: is_expand: false IOS_APP_LINK: '' + meta: bitrise.io: stack: osx-xcode-15.0.x @@ -828,3 +867,4 @@ trigger_map: pipeline: create_qa_builds_pipeline - tag: 'dev-e2e-*' pipeline: pr_smoke_e2e_pipeline + diff --git a/e2e/pages/WalletView.js b/e2e/pages/WalletView.js index e9534a516aa..76d970e124d 100644 --- a/e2e/pages/WalletView.js +++ b/e2e/pages/WalletView.js @@ -112,6 +112,10 @@ export default class WalletView { await TestHelpers.checkIfExists(NOTIFICATION_TITLE); } + static async toastNotificationNotVisible() { + await TestHelpers.checkIfNotVisible(NOTIFICATION_TITLE); + } + static async isNotVisible() { await TestHelpers.checkIfNotVisible(WALLET_CONTAINER_ID); } diff --git a/e2e/specs/confirmations/approve-custom-erc20.spec.js b/e2e/specs/quarantine/approve-custom-erc20.failing.js similarity index 97% rename from e2e/specs/confirmations/approve-custom-erc20.spec.js rename to e2e/specs/quarantine/approve-custom-erc20.failing.js index d57a943906d..f6dfd5731a4 100644 --- a/e2e/specs/confirmations/approve-custom-erc20.spec.js +++ b/e2e/specs/quarantine/approve-custom-erc20.failing.js @@ -1,5 +1,4 @@ 'use strict'; -import { Regression } from '../../tags'; import TestHelpers from '../../helpers'; import { loginToApp } from '../../viewHelper'; import FixtureBuilder from '../../fixtures/fixture-builder'; @@ -16,7 +15,7 @@ import { ContractApprovalModalSelectors } from '../../selectors/Modals/ContractA const HST_CONTRACT = SMART_CONTRACTS.HST; const WEBVIEW_TEST_DAPP_APPROVE_TOKENS_BUTTON_ID = 'approveTokens'; -describe(Regression('ERC20 tokens'), () => { +describe('ERC20 tokens', () => { beforeAll(async () => { jest.setTimeout(170000); if (device.getPlatform() === 'android') { diff --git a/e2e/specs/quarantine/contract-nickname.failing.js b/e2e/specs/quarantine/contract-nickname.failing.js new file mode 100644 index 00000000000..8b15fd30ea7 --- /dev/null +++ b/e2e/specs/quarantine/contract-nickname.failing.js @@ -0,0 +1,218 @@ +'use strict'; +import ImportWalletView from '../../pages/Onboarding/ImportWalletView'; +import OnboardingView from '../../pages/Onboarding/OnboardingView'; +import OnboardingCarouselView from '../../pages/Onboarding/OnboardingCarouselView'; + +import ContractNickNameView from '../../pages/ContractNickNameView'; +import SendView from '../../pages/SendView'; + +import MetaMetricsOptIn from '../../pages/Onboarding/MetaMetricsOptInView'; +import WalletView from '../../pages/WalletView'; +import EnableAutomaticSecurityChecksView from '../../pages/EnableAutomaticSecurityChecksView'; +import LoginView from '../../pages/LoginView'; + +import AddContactView from '../../pages/Drawer/Settings/Contacts/AddContactView'; +import ContactsView from '../../pages/Drawer/Settings/Contacts/ContactsView'; +import SettingsView from '../../pages/Drawer/Settings/SettingsView'; + +import { ContractApprovalModalSelectors } from '../../selectors/Modals/ContractApprovalModal.selectors'; +import NetworkListModal from '../../pages/modals/NetworkListModal'; +import OnboardingWizardModal from '../../pages/modals/OnboardingWizardModal'; +import NetworkEducationModal from '../../pages/modals/NetworkEducationModal'; +import WhatsNewModal from '../../pages/modals/WhatsNewModal'; +import SecurityAndPrivacy from '../../pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView'; + +import TestHelpers from '../../helpers'; +import { acceptTermOfUse } from '../../viewHelper'; +import Accounts from '../../../wdio/helpers/Accounts'; +import TabBarComponent from '../../pages/TabBarComponent'; +import WalletActionsModal from '../../pages/modals/WalletActionsModal'; + +describe('Adding Contract Nickname', () => { + const APPROVAL_DEEPLINK_URL = + 'https://metamask.app.link/send/0x326C977E6efc84E512bB9C30f76E30c160eD06FB@5/approve?address=0x178e3e6c9f547A00E33150F7104427ea02cfc747&uint256=5e8'; + const CONTRACT_NICK_NAME_TEXT = 'Ace RoMaIn'; + const GOERLI = 'Goerli Test Network'; + + //FIXME Deep linking to a contract address does not work on a sim. + + let validAccount; + + beforeAll(() => { + validAccount = Accounts.getValidAccount(); + }); + + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import via seed phrase and validate in settings', async () => { + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + + await OnboardingView.isVisible(); + await OnboardingView.tapImportWalletFromSeedPhrase(); + + await MetaMetricsOptIn.isVisible(); + await MetaMetricsOptIn.tapAgreeButton(); + + await acceptTermOfUse(); + await ImportWalletView.isVisible(); + }); + + it('should attempt to import wallet with invalid secret recovery phrase', async () => { + await ImportWalletView.enterSecretRecoveryPhrase(validAccount.seedPhrase); + await ImportWalletView.enterPassword(validAccount.password); + await ImportWalletView.reEnterPassword(validAccount.password); + await WalletView.isVisible(); + }); + + it('Should dismiss Automatic Security checks screen', async () => { + await TestHelpers.delay(3500); + await EnableAutomaticSecurityChecksView.isVisible(); + await EnableAutomaticSecurityChecksView.tapNoThanks(); + }); + + it('should dismiss the onboarding wizard', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(1000); + try { + await OnboardingWizardModal.isVisible(); + await OnboardingWizardModal.tapNoThanksButton(); + await OnboardingWizardModal.isNotVisible(); + } catch { + // + } + }); + + it('should tap on "Got it" Button in the whats new modal', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(2500); + try { + await WhatsNewModal.isVisible(); + await WhatsNewModal.tapGotItButton(); + } catch { + // + } + }); + + it('should switch to GOERLI', async () => { + await WalletView.tapNetworksButtonOnNavBar(); + await NetworkListModal.changeNetwork(GOERLI); + + await WalletView.isNetworkNameVisible(GOERLI); + await TestHelpers.delay(1500); + }); + + it('should dismiss network education modal', async () => { + await NetworkEducationModal.isVisible(); + await NetworkEducationModal.tapGotItButton(); + await NetworkEducationModal.isNotVisible(); + }); + it('should go to the Privacy and settings view', async () => { + await TabBarComponent.tapSettings(); + await SettingsView.tapSecurityAndPrivacy(); + + await SecurityAndPrivacy.scrollToTurnOnRememberMe(); + TestHelpers.delay(3000); + }); + + it('should enable remember me', async () => { + await SecurityAndPrivacy.isRememberMeToggleOff(); + await SecurityAndPrivacy.tapTurnOnRememberMeToggle(); + await SecurityAndPrivacy.isRememberMeToggleOn(); + + TestHelpers.delay(1500); + }); + + it('should relaunch the app then enable remember me', async () => { + // Relaunch app + await TestHelpers.relaunchApp(); + await LoginView.isVisible(); + await LoginView.toggleRememberMe(); + + await LoginView.enterPassword(validAccount.password); + await WalletView.isVisible(); + }); + it('should deep link to the approval modal', async () => { + await TestHelpers.openDeepLink(APPROVAL_DEEPLINK_URL); + await TestHelpers.delay(3000); + await ContractApprovalModalSelectors.isVisible(); + }); + + it('should add a nickname to the contract', async () => { + await ContractApprovalModalSelectors.tapAddNickName(); + + await ContractNickNameView.isVisible(); + await ContractNickNameView.typeContractNickName(CONTRACT_NICK_NAME_TEXT); + await ContractNickNameView.isContractNickNameInInputBoxVisible( + CONTRACT_NICK_NAME_TEXT, + ); + await ContractNickNameView.tapConfirmButton(); + + await ContractApprovalModalSelectors.isContractNickNameVisible( + CONTRACT_NICK_NAME_TEXT, + ); + }); + + it('should edit the contract nickname', async () => { + await ContractApprovalModalSelectors.tapEditNickName(); + + await ContractNickNameView.isContractNickNameInInputBoxVisible( + CONTRACT_NICK_NAME_TEXT, + ); + await ContractNickNameView.clearNickName(); + await ContractNickNameView.typeContractNickName('Ace'); + await ContractNickNameView.tapConfirmButton(); + + await ContractApprovalModalSelectors.isContractNickNameVisible('Ace'); + await ContractApprovalModalSelectors.tapToCopyContractAddress(); + await ContractApprovalModalSelectors.tapRejectButton(); + }); + + it('should verify contract does not appear in contacts view', async () => { + // Check that we are on the wallet screen + await WalletView.isVisible(); + await TabBarComponent.tapSettings(); + await SettingsView.tapContacts(); + + await ContactsView.isVisible(); + await ContactsView.isContactAliasVisible('Ace'); + }); + + it('should return to the send view', async () => { + // Open Drawer + await AddContactView.tapBackButton(); + await SettingsView.tapCloseButton(); + + await TabBarComponent.tapActions(); + await WalletActionsModal.tapSendButton(); + // Make sure view with my accounts visible + await SendView.isMyAccountsVisisble(); + }); + + it('should verify the contract nickname does not appear in send flow', async () => { + await SendView.isSavedAliasIsNotVisible('Ace'); + }); + + it('should deep link to the approval modal and approve transaction', async () => { + await TestHelpers.openDeepLink(APPROVAL_DEEPLINK_URL); + await TestHelpers.delay(3000); + await ContractApprovalModalSelectors.isVisible(); + await ContractApprovalModalSelectors.isContractNickNameVisible('Ace'); + + await ContractApprovalModalSelectors.tapApproveButton(); + await ContractApprovalModalSelectors.isNotVisible(); + }); + + it('should go to the send view again', async () => { + await TabBarComponent.tapActions(); + await WalletActionsModal.tapSendButton(); + // Make sure view with my accounts visible + await SendView.isMyAccountsVisisble(); + }); + + it('should verify the contract nickname does not appear in recents', async () => { + await SendView.isSavedAliasIsNotVisible('Ace'); + }); +}); diff --git a/e2e/specs/quarantine/deeplinks.failing.js b/e2e/specs/quarantine/deeplinks.failing.js new file mode 100644 index 00000000000..faa61ed1ec6 --- /dev/null +++ b/e2e/specs/quarantine/deeplinks.failing.js @@ -0,0 +1,187 @@ +'use strict'; +import TestHelpers from '../../helpers'; +import { Regression } from '../../tags'; + +import ConnectModal from '../../pages/modals/ConnectModal'; +import NetworkApprovalModal from '../../pages/modals/NetworkApprovalModal'; +import NetworkAddedModal from '../../pages/modals/NetworkAddedModal'; + +import Browser from '../../pages/Drawer/Browser'; +import NetworkView from '../../pages/Drawer/Settings/NetworksView'; +import SettingsView from '../../pages/Drawer/Settings/SettingsView'; +import LoginView from '../../pages/LoginView'; +import TransactionConfirmationView from '../../pages/TransactionConfirmView'; + +import SecurityAndPrivacy from '../../pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView'; + +import WalletView from '../../pages/WalletView'; +import { importWalletWithRecoveryPhrase } from '../../viewHelper'; +import Accounts from '../../../wdio/helpers/Accounts'; +import TabBarComponent from '../../pages/TabBarComponent'; + +const BINANCE_RPC_URL = 'https://bsc-dataseed1.binance.org'; + +const BINANCE_DEEPLINK_URL = + 'https://metamask.app.link/send/0xB8B4EE5B1b693971eB60bDa15211570df2dB228A@56?value=1e14'; + +const POLYGON_DEEPLINK_URL = + 'https://metamask.app.link/send/0x0000000000000000000000000000000000001010@137/transfer?address=0xC5b2b5ae370876c0122910F92a13bef85A133E56&uint256=3e18'; + +const ETHEREUM_DEEPLINK_URL = + 'https://metamask.app.link/send/0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6@1?value=1e13'; +const GOERLI_DEEPLINK_URL = + 'https://metamask.app.link/send/0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6@5?value=1e13'; + +const DAPP_DEEPLINK_URL = 'https://metamask.app.link/dapp/app.sushi.com'; + +const networkNotFoundText = 'Network not found'; +const networkErrorBodyMessage = + 'Network with chain id 56 not found in your wallet. Please add the network first.'; + +const validAccount = Accounts.getValidAccount(); + +describe(Regression('Deep linking Tests'), () => { + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import wallet and go to the wallet view', async () => { + await importWalletWithRecoveryPhrase(); + }); + + it('should go to the Privacy and settings view', async () => { + await TabBarComponent.tapSettings(); + await SettingsView.tapSecurityAndPrivacy(); + + await SecurityAndPrivacy.scrollToTurnOnRememberMe(); + TestHelpers.delay(3000); + }); + + it('should enable remember me', async () => { + await SecurityAndPrivacy.isRememberMeToggleOff(); + await SecurityAndPrivacy.tapTurnOnRememberMeToggle(); + await SecurityAndPrivacy.isRememberMeToggleOn(); + + TestHelpers.delay(1500); + }); + + it('should relaunch the app then enable remember me', async () => { + // Relaunch app + await TestHelpers.relaunchApp(); + await LoginView.isVisible(); + await LoginView.toggleRememberMe(); + + await LoginView.enterPassword(validAccount.password); + await WalletView.isVisible(); + }); + + it('should deep link to Binance Smart Chain & show a network not found error message', async () => { + await TestHelpers.openDeepLink(BINANCE_DEEPLINK_URL); + await TestHelpers.delay(3000); + await TestHelpers.checkIfElementWithTextIsVisible(networkNotFoundText); + await TestHelpers.checkIfElementWithTextIsVisible(networkErrorBodyMessage); + + await WalletView.tapOKAlertButton(); + }); + + it('should go to settings then networks', async () => { + await TabBarComponent.tapSettings(); + await SettingsView.tapNetworks(); + + await NetworkView.isNetworkViewVisible(); + }); + + it('should add BSC network', async () => { + // Tap on Add Network button + await TestHelpers.delay(3000); + await NetworkView.tapAddNetworkButton(); + + await NetworkView.isRpcViewVisible(); + await NetworkView.tapPopularNetworkByName('BNB Smart Chain'); + + await NetworkApprovalModal.isVisible(); + await NetworkApprovalModal.isDisplayNameVisible('BNB Smart Chain'); + await NetworkApprovalModal.isNetworkURLVisible(BINANCE_RPC_URL); + await NetworkApprovalModal.isChainIDVisible('56'); + await NetworkApprovalModal.tapApproveButton(); + + await NetworkAddedModal.isVisible(); + await NetworkAddedModal.tapCloseButton(); + await NetworkView.isRpcViewVisible(); + + //await WalletView.isVisible(); + }); + + it('should add polygon network', async () => { + await NetworkView.tapPopularNetworkByName('Polygon Mainnet'); + + await NetworkApprovalModal.isVisible(); + await NetworkApprovalModal.isDisplayNameVisible('Polygon Mainnet'); + await NetworkApprovalModal.isChainIDVisible('137'); + + await NetworkApprovalModal.tapApproveButton(); + await TestHelpers.delay(1000); + + await NetworkAddedModal.isVisible(); + await NetworkAddedModal.tapSwitchToNetwork(); + + await WalletView.isVisible(); + await WalletView.isNetworkNameVisible('Polygon Mainnet'); + }); + + it('should deep link to the send flow on matic', async () => { + await TestHelpers.openDeepLink(POLYGON_DEEPLINK_URL); //FIXME: this is failing on iOS simulator + + await TestHelpers.delay(4500); + await TransactionConfirmationView.isVisible(); + await TransactionConfirmationView.isNetworkNameVisible('Polygon Mainnet'); + await TestHelpers.delay(1500); + await TransactionConfirmationView.tapCancelButton(); + }); + it('should deep link to the send flow on BSC', async () => { + await TestHelpers.openDeepLink(BINANCE_DEEPLINK_URL); + await TestHelpers.delay(4500); + await TransactionConfirmationView.isVisible(); + await TransactionConfirmationView.isNetworkNameVisible('BNB Smart Chain'); + }); + + it('should deep link to the send flow on Goerli and submit the transaction', async () => { + await TestHelpers.openDeepLink(GOERLI_DEEPLINK_URL); + await TestHelpers.delay(4500); + await TransactionConfirmationView.isVisible(); + await TransactionConfirmationView.isNetworkNameVisible( + 'Goerli Test Network', + ); + await TransactionConfirmationView.isTransactionTotalCorrect( + '0.00001 GoerliETH', + ); + // Tap on the Send CTA + await TransactionConfirmationView.tapConfirmButton(); + // Check that we are on the wallet screen + await WalletView.isVisible(); + }); + + it('should deep link to the send flow on mainnet', async () => { + await TestHelpers.openDeepLink(ETHEREUM_DEEPLINK_URL); + await TestHelpers.delay(4500); + + await TransactionConfirmationView.isVisible(); + await TransactionConfirmationView.isNetworkNameVisible( + 'Ethereum Main Network', + ); + await TransactionConfirmationView.tapCancelButton(); + }); + + it('should deep link to a dapp (Sushi swap)', async () => { + await TestHelpers.openDeepLink(DAPP_DEEPLINK_URL); + await TestHelpers.delay(4500); + + await ConnectModal.isVisible(); + await ConnectModal.tapConnectButton(); + + await TestHelpers.checkIfElementWithTextIsVisible('app.sushi.com', 0); + + await Browser.isVisible(); + await ConnectModal.isNotVisible(); + }); +}); diff --git a/e2e/specs/quarantine/permission-system-removing-imported-account.failing.js b/e2e/specs/quarantine/permission-system-removing-imported-account.failing.js new file mode 100644 index 00000000000..dfd96b9d243 --- /dev/null +++ b/e2e/specs/quarantine/permission-system-removing-imported-account.failing.js @@ -0,0 +1,117 @@ +'use strict'; +import TestHelpers from '../../helpers'; +import { Regression } from '../../tags'; +import WalletView from '../../pages/WalletView'; +import ImportAccountView from '../../pages/ImportAccountView'; +import TabBarComponent from '../../pages/TabBarComponent'; + +import Browser from '../../pages/Drawer/Browser'; +import AccountListView from '../../pages/AccountListView'; + +import ConnectModal from '../../pages/modals/ConnectModal'; +import ConnectedAccountsModal from '../../pages/modals/ConnectedAccountsModal'; +import NetworkListModal from '../../pages/modals/NetworkListModal'; +import NetworkEducationModal from '../../pages/modals/NetworkEducationModal'; + +import Accounts from '../../../wdio/helpers/Accounts'; + +import { importWalletWithRecoveryPhrase } from '../../viewHelper'; +import AddAccountModal from '../../pages/modals/AddAccountModal'; + +const SEPOLIA = 'Sepolia Test Network'; + +const accountPrivateKey = Accounts.getAccountPrivateKey(); +describe( + Regression( + 'Permission System Test: Revoking accounts after connecting to a dapp', + ), + () => { + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import wallet and go to the wallet view', async () => { + await importWalletWithRecoveryPhrase(); + }); + + it('should navigate to browser', async () => { + await TestHelpers.delay(2000); + await TabBarComponent.tapBrowser(); + await Browser.isVisible(); + }); + + it('should trigger connect modal in the test dapp', async () => { + await TestHelpers.delay(3000); + await Browser.goToTestDappAndTapConnectButton(); + }); + + it('should go to multiconnect in the connect account modal', async () => { + await TestHelpers.delay(3000); + await ConnectModal.tapConnectMultipleAccountsButton(); + }); + + it('should import account', async () => { + await ConnectModal.tapImportAccountOrHWButton(); + await AddAccountModal.tapImportAccount(); + await ImportAccountView.isVisible(); + await ImportAccountView.enterPrivateKey(accountPrivateKey.keys); + await ImportAccountView.isImportSuccessSreenVisible(); + await ImportAccountView.tapCloseButtonOnImportSuccess(); + }); + + it('should connect multiple accounts to a dapp', async () => { + await ConnectModal.tapSelectAllButton(); + + await ConnectModal.tapAccountConnectMultiSelectButton(); + }); + + it('should switch to Sepolia', async () => { + await Browser.tapNetworkAvatarButtonOnBrowserWhileAccountIsConnectedToDapp(); + await ConnectedAccountsModal.tapNetworksPicker(); + await NetworkListModal.isVisible(); + await TestHelpers.delay(2000); + await NetworkListModal.tapTestNetworkSwitch(); + await NetworkListModal.changeNetwork(SEPOLIA); + }); + + it('should dismiss the network education modal', async () => { + await NetworkEducationModal.isVisible(); + await NetworkEducationModal.tapGotItButton(); + await NetworkEducationModal.isNotVisible(); + }); + + it('should set the imported account as primary account', async () => { + await TestHelpers.delay(1500); + await ConnectedAccountsModal.tapToSetAsPrimaryAccount(); + }); + + it('should navigate to wallet view', async () => { + await TestHelpers.delay(1500); + await TabBarComponent.tapWallet(); + await WalletView.isVisible(); + }); + + it('should remove imported account', async () => { + // Wait for page to load + await WalletView.tapIdenticon(); + await AccountListView.isVisible(); + await AccountListView.longPressImportedAccount(); + await AccountListView.tapYesToRemoveImportedAccountAlertButton(); + await AccountListView.accountNameNotVisible('Account 2'); + }); + + it('should return to browser', async () => { + await AccountListView.swipeToDimssAccountsModal(); + await TestHelpers.delay(4500); + await TabBarComponent.tapBrowser(); + // Check that we are on the browser screen + await Browser.isVisible(); + }); + + it('imported account is not visible', async () => { + await Browser.tapNetworkAvatarButtonOnBrowserWhileAccountIsConnectedToDapp(); + await ConnectedAccountsModal.isVisible(); + await AccountListView.accountNameNotVisible('Account 2'); + }); + }, +); diff --git a/e2e/specs/swaps/swap-tokens.spec.js b/e2e/specs/quarantine/swap-tokens.flaky.js similarity index 98% rename from e2e/specs/swaps/swap-tokens.spec.js rename to e2e/specs/quarantine/swap-tokens.flaky.js index efc74bc692d..dea25fc2ddf 100644 --- a/e2e/specs/swaps/swap-tokens.spec.js +++ b/e2e/specs/quarantine/swap-tokens.flaky.js @@ -1,7 +1,6 @@ 'use strict'; import { loginToApp } from '../../viewHelper'; -import { Regression } from '../../tags'; import Onboarding from '../../pages/swaps/OnBoarding'; import QuoteView from '../../pages/swaps/QuoteView'; import SwapView from '../../pages/swaps/SwapView'; @@ -24,7 +23,7 @@ import { getFixturesServerPort } from '../../fixtures/utils'; const fixtureServer = new FixtureServer(); -describe(Regression('Swap Tests'), () => { +describe('Swap Tests', () => { let swapOnboarded = false; beforeAll(async () => { await TestHelpers.reverseServerPort(); @@ -48,7 +47,6 @@ describe(Regression('Swap Tests'), () => { beforeEach(async () => { jest.setTimeout(150000); }); - it.each` quantity | sourceTokenSymbol | destTokenSymbol ${'1'} | ${'ETH'} | ${'WETH'} diff --git a/e2e/specs/quarantine/term-of-use.broken.js b/e2e/specs/quarantine/term-of-use.broken.js new file mode 100644 index 00000000000..8485039ad27 --- /dev/null +++ b/e2e/specs/quarantine/term-of-use.broken.js @@ -0,0 +1,50 @@ +import TermsOfUseModal from '../../pages/modals/TermsOfUseModal'; +import TestHelpers from '../../helpers'; +import OnboardingCarouselView from '../../pages/Onboarding/OnboardingCarouselView'; +import OnboardingView from '../../pages/Onboarding/OnboardingView'; +import MetaMetricsOptIn from '../../pages/Onboarding/MetaMetricsOptInView'; +import ImportWalletView from '../../pages/Onboarding/ImportWalletView'; + +describe('Term of service', () => { + beforeEach(() => { + jest.setTimeout(200000); + }); + + it('should displayed Term of Use when first launching app', async () => { + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + + await OnboardingView.isVisible(); + await OnboardingView.tapImportWalletFromSeedPhrase(); + + await MetaMetricsOptIn.isVisible(); + await MetaMetricsOptIn.tapAgreeButton(); + await TermsOfUseModal.isDisplayed(); + }); + + it('should prevent attempts to bypass term of use', async () => { + await TestHelpers.relaunchApp(); + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + await OnboardingView.isVisible(); + await OnboardingView.tapImportWalletFromSeedPhrase(); + await TermsOfUseModal.isDisplayed(); + }); + + it('should accept to term of use', async () => { + await TermsOfUseModal.tapScrollEndButton(); + await TermsOfUseModal.tapAgreeCheckBox(); + await TermsOfUseModal.tapAcceptButton(); + await TermsOfUseModal.isNotDisplayed(); + await ImportWalletView.isVisible(); + }); + + it('should restart app after accepting terms', async () => { + await TestHelpers.relaunchApp(); + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + await OnboardingView.isVisible(); + await OnboardingView.tapImportWalletFromSeedPhrase(); + await TermsOfUseModal.isNotDisplayed(); + }); +});