Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 0 additions & 4 deletions .github/guidelines/LABELING_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ The check can be bypassed when necessary, either by setting the changelog entry

Any label can be manually added on demand depending on the PR's content. For instance, the label **QA passed** will indicate that a thorough manual testing has been performed and the PR is ready to be merged. In addition, following labels have some specific use cases.

### Run Flask Android E2E tests

- **run-android-flask-e2e-smoke**: The Android Flask E2E smoke tests jobs will run in the given PR. They also run on schedule on main branch.

### Bypass Quality Gates

Using any of these labels should be exceptional in case of CI friction and urgencies. Please use them reasonably and verify new changes and regressions manually.
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ jobs:
repository: ${{ github.repository }}
post-comment: 'true'

# Main E2E tests

build-android-apks:
name: 'Build Android APKs'
if: ${{ github.event_name != 'merge_group' && needs.needs_e2e_build.outputs.android_changed == 'true' }}
Expand Down Expand Up @@ -314,6 +316,34 @@ jobs:
changed_files: ${{ needs.needs_e2e_build.outputs.changed_files }}
secrets: inherit

# Flask E2E tests

build-android-flask-apks:
name: 'Build Android Flask APKs'
if: ${{ github.event_name != 'merge_group' && needs.needs_e2e_build.outputs.android_changed == 'true' }}
permissions:
contents: read
id-token: write
needs: [needs_e2e_build]
uses: ./.github/workflows/build-android-e2e.yml
with:
build_type: 'flask'
metamask_environment: 'e2e'
keystore_target: 'flask'
secrets: inherit

e2e-smoke-tests-android-flask:
name: 'Android Flask E2E Smoke Tests'
if: ${{ github.event_name != 'merge_group' && needs.needs_e2e_build.outputs.android_changed == 'true' }}
permissions:
contents: read
id-token: write
needs: [needs_e2e_build, build-android-flask-apks]
uses: ./.github/workflows/run-e2e-smoke-tests-android-flask.yml
with:
changed_files: ${{ needs.needs_e2e_build.outputs.changed_files }}
secrets: inherit

js-bundle-size-check:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -501,6 +531,7 @@ jobs:
- needs_e2e_build
- e2e-smoke-tests-android
- e2e-smoke-tests-ios
- e2e-smoke-tests-android-flask
steps:
- run: |
# Check if all non-E2E jobs passed
Expand All @@ -519,6 +550,10 @@ jobs:
echo "iOS E2E tests failed"
exit 1
fi
if [[ "${{ needs.e2e-smoke-tests-android-flask.result }}" == "failure" ]]; then
echo "Android Flask E2E tests failed"
exit 1
fi
fi

echo "All required jobs passed"
Expand Down
52 changes: 12 additions & 40 deletions .github/workflows/run-e2e-smoke-tests-android-flask.yml
Original file line number Diff line number Diff line change
@@ -1,69 +1,41 @@
name: Android Flask E2E Smoke Tests

on:
pull_request:
types: [labeled, opened, synchronize]
schedule:
# Run the full suite every 3 hours
# This helps to identy the flaky and failed tests on main branch
- cron: '0 */3 * * *'
workflow_call:
inputs:
changed_files:
description: 'Changed files'
required: false
type: string
default: ''

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !(contains(github.ref, 'refs/heads/main') || contains(github.ref, 'refs/heads/stable')) }}
permissions:
contents: read
id-token: write

jobs:
needs_e2e_build:
name: 'Detect Mobile Build Changes'
# Execution rules:
# - schedule: always run
# - merge_group: never run
# - pull_request: run only if PR has 'run-android-flask-e2e-smoke' label
if: ${{ github.event_name != 'merge_group' && (github.event_name == 'schedule' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-android-flask-e2e-smoke') && github.event.pull_request.merged == false)) }}
uses: ./.github/workflows/needs-e2e-build.yml

build-android-flask-apps:
name: 'Build Android Flask Apps'
# Execution rules:
# - schedule: always run
# - merge_group: never run
# - pull_request: run only if PR has 'run-android-flask-e2e-smoke' label AND android_changed == 'true'
if: ${{ github.event_name != 'merge_group' && ( github.event_name == 'schedule' || ( github.event_name == 'pull_request' && needs.needs_e2e_build.outputs.android_changed == 'true' && contains(github.event.pull_request.labels.*.name, 'run-android-flask-e2e-smoke') ) ) }}
permissions:
contents: read
id-token: write
needs: [needs_e2e_build]
uses: ./.github/workflows/build-android-e2e.yml
with:
build_type: 'flask'
metamask_environment: 'e2e'
keystore_target: 'flask'
secrets: inherit

flask-android-smoke:
strategy:
matrix:
split: [1, 2, 3]
fail-fast: false
needs: [build-android-flask-apps]
uses: ./.github/workflows/run-e2e-workflow.yml
with:
test-suite-name: flask-android-smoke-${{ matrix.split }}
platform: android
test_suite_tag: 'FlaskBuildTests'
split_number: ${{ matrix.split }}
total_splits: 3
changed_files: ${{ inputs.changed_files }}
build_type: 'flask'
metamask_environment: 'e2e'
secrets: inherit

report-android-smoke-tests:
name: Report Android Smoke Tests
runs-on: ubuntu-latest
if: ${{ !cancelled() && needs.flask-android-smoke.result != 'skipped' }}
if: ${{ !cancelled() }}
needs:
- flask-android-smoke

steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
15 changes: 4 additions & 11 deletions app/components/UI/AssetOverview/AssetOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ import {
} from '../../../util/analytics/actionButtonTracking';
import { selectSelectedAccountGroup } from '../../../selectors/multichainAccounts/accountTreeController';
import { selectSelectedInternalAccountByScope } from '../../../selectors/multichainAccounts/accounts';
import { useRampNavigation, RampMode } from '../Ramp/hooks/useRampNavigation';
import { RampType as AggregatorRampType } from '../Ramp/Aggregator/types';
import { useRampNavigation } from '../Ramp/hooks/useRampNavigation';
import { TokenI } from '../Tokens/types';
import AssetDetailsActions from '../../../components/Views/AssetDetails/AssetDetailsActions';
import {
Expand All @@ -87,7 +86,7 @@ import { formatChainIdToCaip } from '@metamask/bridge-controller';
import { InitSendLocation } from '../../Views/confirmations/constants/send';
import { useSendNavigation } from '../../Views/confirmations/hooks/useSendNavigation';
import { selectMultichainAccountsState2Enabled } from '../../../selectors/featureFlagController/multichainAccounts';
import parseRampIntent from '../Ramp/Aggregator/utils/parseRampIntent';
import parseRampIntent from '../Ramp/utils/parseRampIntent';
///: BEGIN:ONLY_INCLUDE_IF(tron)
import TronEnergyBandwidthDetail from './TronEnergyBandwidthDetail/TronEnergyBandwidthDetail';
///: END:ONLY_INCLUDE_IF
Expand Down Expand Up @@ -169,7 +168,7 @@ const AssetOverview: React.FC<AssetOverviewProps> = ({
///: END:ONLY_INCLUDE_IF

const currentAddress = asset.address as Hex;
const { goToRamps } = useRampNavigation();
const { goToBuy } = useRampNavigation();

const { data: prices = [], isLoading } = useTokenHistoricalPrices({
asset,
Expand Down Expand Up @@ -339,13 +338,7 @@ const AssetOverview: React.FC<AssetOverviewProps> = ({
assetId = undefined;
}

goToRamps({
mode: RampMode.AGGREGATOR,
params: {
rampType: AggregatorRampType.BUY,
intent: assetId ? { assetId } : undefined,
},
});
goToBuy({ assetId });

trackEvent(
createEventBuilder(MetaMetricsEvents.BUY_BUTTON_CLICKED)
Expand Down
10 changes: 3 additions & 7 deletions app/components/UI/BalanceEmptyState/BalanceEmptyState.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import BalanceEmptyState from './BalanceEmptyState';
import { BalanceEmptyStateProps } from './BalanceEmptyState.types';

// Mock useRampNavigation hook
const mockGoToRamps = jest.fn();
const mockGoToBuy = jest.fn();
jest.mock('../Ramp/hooks/useRampNavigation', () => ({
useRampNavigation: jest.fn(() => ({ goToRamps: mockGoToRamps })),
RampMode: { AGGREGATOR: 'AGGREGATOR', DEPOSIT: 'DEPOSIT' },
useRampNavigation: jest.fn(() => ({ goToBuy: mockGoToBuy })),
}));

describe('BalanceEmptyState', () => {
Expand Down Expand Up @@ -49,9 +48,6 @@ describe('BalanceEmptyState', () => {

fireEvent.press(actionButton);

expect(mockGoToRamps).toHaveBeenCalledWith({
mode: 'AGGREGATOR',
params: { rampType: expect.anything() },
});
expect(mockGoToBuy).toHaveBeenCalled();
});
});
10 changes: 3 additions & 7 deletions app/components/UI/BalanceEmptyState/BalanceEmptyState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import { MetaMetricsEvents, useMetrics } from '../../hooks/useMetrics';
import { getDecimalChainId } from '../../../util/networks';
import { selectChainId } from '../../../selectors/networkController';
import { trace, TraceName } from '../../../util/trace';
import { useRampNavigation, RampMode } from '../Ramp/hooks/useRampNavigation';
import { RampType } from '../Ramp/Aggregator/types';
import { useRampNavigation } from '../Ramp/hooks/useRampNavigation';
import { BalanceEmptyStateProps } from './BalanceEmptyState.types';
import bankTransferImage from '../../../images/bank-transfer.png';
import { getDetectedGeolocation } from '../../../reducers/fiatOrders';
Expand All @@ -38,13 +37,10 @@ const BalanceEmptyState: React.FC<BalanceEmptyStateProps> = ({
const chainId = useSelector(selectChainId);
const { trackEvent, createEventBuilder } = useMetrics();
const rampGeodetectedRegion = useSelector(getDetectedGeolocation);
const { goToRamps } = useRampNavigation();
const { goToBuy } = useRampNavigation();

const handleAction = () => {
goToRamps({
mode: RampMode.AGGREGATOR,
params: { rampType: RampType.BUY },
});
goToBuy();

trackEvent(
createEventBuilder(MetaMetricsEvents.BUY_BUTTON_CLICKED).build(),
Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/Card/Views/CardHome/CardHome.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ describe('CardHome Component', () => {
'../../../Ramp/hooks/useRampNavigation',
);
(useRampNavigation as jest.Mock).mockReturnValue({
goToRamps: jest.fn(),
goToBuy: jest.fn(),
});

(useMetrics as jest.Mock).mockReturnValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@ import { trace, TraceName } from '../../../../../util/trace';
import { CardTokenAllowance, AllowanceState } from '../../types';
import { renderScreen } from '../../../../../util/test/renderWithProvider';
import { backgroundState } from '../../../../../util/test/initial-root-state';
import {
useRampNavigation,
RampMode,
} from '../../../Ramp/hooks/useRampNavigation';
import { useRampNavigation } from '../../../Ramp/hooks/useRampNavigation';
import { CardHomeSelectors } from '../../../../../../e2e/selectors/Card/CardHome.selectors';

// Mock hooks first - must be hoisted before imports
const mockUseParams = jest.fn();
const mockGoBack = jest.fn();
const mockNavigate = jest.fn();
const mockGoToRamps = jest.fn();
const mockGoToDeposit = jest.fn();

// Mock dependencies
jest.mock('../../../Ramp/hooks/useRampNavigation');
Expand Down Expand Up @@ -64,6 +61,18 @@ jest.mock('../../../../../util/theme', () => ({
},
},
})),
mockTheme: {
colors: {
background: {
default: '#ffffff',
},
text: {
default: '#000000',
alternative: '#666666',
},
},
themeAppearance: 'light',
},
}));

jest.mock('./AddFundsBottomSheet.styles', () => ({
Expand Down Expand Up @@ -141,7 +150,7 @@ describe('AddFundsBottomSheet', () => {
});

(useRampNavigation as jest.Mock).mockReturnValue({
goToRamps: mockGoToRamps,
goToDeposit: mockGoToDeposit,
});

(useDepositEnabled as jest.Mock).mockReturnValue({
Expand Down Expand Up @@ -301,7 +310,7 @@ describe('AddFundsBottomSheet', () => {

fireEvent.press(getByText('Fund with cash'));

expect(mockGoToRamps).toHaveBeenCalledWith({ mode: RampMode.DEPOSIT });
expect(mockGoToDeposit).toHaveBeenCalled();
});

it('renders component correctly', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ import { useOpenSwaps } from '../../hooks/useOpenSwaps';
import { MetaMetricsEvents, useMetrics } from '../../../../hooks/useMetrics';
import { strings } from '../../../../../../locales/i18n';
import { CardHomeSelectors } from '../../../../../../e2e/selectors/Card/CardHome.selectors';
import {
useRampNavigation,
RampMode,
} from '../../../Ramp/hooks/useRampNavigation';
import { useRampNavigation } from '../../../Ramp/hooks/useRampNavigation';
import { safeFormatChainIdToHex } from '../../util/safeFormatChainIdToHex';
import { getDetectedGeolocation } from '../../../../../reducers/fiatOrders';
import {
Expand Down Expand Up @@ -64,7 +61,7 @@ const AddFundsBottomSheet: React.FC = () => {
});
const { trackEvent, createEventBuilder } = useMetrics();
const rampGeodetectedRegion = useSelector(getDetectedGeolocation);
const { goToRamps } = useRampNavigation();
const { goToDeposit } = useRampNavigation();

const closeBottomSheetAndNavigate = useCallback(
(navigateFunc: () => void) => {
Expand All @@ -82,7 +79,7 @@ const AddFundsBottomSheet: React.FC = () => {

const openDeposit = useCallback(() => {
closeBottomSheetAndNavigate(() => {
goToRamps({ mode: RampMode.DEPOSIT });
goToDeposit();
});
trackEvent(
createEventBuilder(
Expand All @@ -108,7 +105,7 @@ const AddFundsBottomSheet: React.FC = () => {
}, [
rampGeodetectedRegion,
closeBottomSheetAndNavigate,
goToRamps,
goToDeposit,
trackEvent,
createEventBuilder,
priorityToken,
Expand Down
Loading
Loading