Skip to content

Commit

Permalink
test: Enable Regression tests on Bitrise (#7645)
Browse files Browse the repository at this point in the history
## **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**

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

### **Before**

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

### **After**

<!-- [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
- [ ] 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.
  • Loading branch information
cortisiko authored Nov 1, 2023
1 parent b20820b commit 24a1d3f
Show file tree
Hide file tree
Showing 8 changed files with 621 additions and 8 deletions.
46 changes: 43 additions & 3 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,20 @@ 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:
stages:
- 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:
Expand Down Expand Up @@ -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: {}
Expand Down Expand Up @@ -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@:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -813,6 +851,7 @@ app:
- opts:
is_expand: false
IOS_APP_LINK: ''

meta:
bitrise.io:
stack: osx-xcode-15.0.x
Expand All @@ -828,3 +867,4 @@ trigger_map:
pipeline: create_qa_builds_pipeline
- tag: 'dev-e2e-*'
pipeline: pr_smoke_e2e_pipeline

4 changes: 4 additions & 0 deletions e2e/pages/WalletView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use strict';
import { Regression } from '../../tags';
import TestHelpers from '../../helpers';
import { loginToApp } from '../../viewHelper';
import FixtureBuilder from '../../fixtures/fixture-builder';
Expand All @@ -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') {
Expand Down
218 changes: 218 additions & 0 deletions e2e/specs/quarantine/contract-nickname.failing.js
Original file line number Diff line number Diff line change
@@ -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');
});
});
Loading

0 comments on commit 24a1d3f

Please sign in to comment.