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
5 changes: 4 additions & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ app/components/UI/CollectibleContractOverview @MetaMask/metamask-assets
app/components/UI/CollectibleContracts @MetaMask/metamask-assets
app/components/UI/CollectibleDetectionModal @MetaMask/metamask-assets
app/components/UI/CollectibleMedia @MetaMask/metamask-assets
app/components/UI/CollectibleModal @MetaMask/metamask-assets
app/components/UI/CollectibleOverview @MetaMask/metamask-assets
app/components/UI/ConfirmAddAsset @MetaMask/metamask-assets
app/components/UI/DeFiPositions @MetaMask/metamask-assets
Expand Down Expand Up @@ -375,6 +374,10 @@ tests/websocket/ @MetaMask/qa
.github/actions/smart-e2e-selection/ @MetaMask/qa
.github/workflows/ai-pr-risk-analysis.yml @MetaMask/qa
.github/workflows/auto-label-not-ready-for-e2e.yml @MetaMask/qa
.github/workflows/run-appium-e2e-workflow.yml @MetaMask/qa
.github/workflows/run-appium-smoke-tests-android.yml @MetaMask/qa
.github/workflows/run-appium-smoke-tests-ios.yml @MetaMask/qa
.github/workflows/prebuild-wda-ios.yml @MetaMask/qa
.github/workflows/run-e2e-workflow.yml @MetaMask/qa
.github/workflows/run-e2e-api-specs.yml @MetaMask/qa
.github/workflows/run-e2e-regression-tests-android.yml @MetaMask/qa
Expand Down
14 changes: 11 additions & 3 deletions .github/actions/setup-e2e-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ inputs:
— Detox does not require the Pods directory to run tests.
required: false
default: 'false'
install-applesimutils:
description: >-
Whether to install applesimutils (iOS only). Required by Detox but not
by Appium — set to 'false' for Appium test jobs
required: false
default: 'true'

runs:
using: 'composite'
Expand Down Expand Up @@ -176,7 +182,9 @@ runs:
run: |
set -euo pipefail
sudo mkdir -p "$CACHE_PATH" /opt/android-sdk/.temp
sudo chown -R "$(id -u):$(id -g)" "$CACHE_PATH" /opt/android-sdk/.temp
# chown the parent dir too so sdkmanager can create x86_64.backup
# next to x86_64 during installation (requires write on the parent).
sudo chown -R "$(id -u):$(id -g)" "$(dirname "$CACHE_PATH")" /opt/android-sdk/.temp
shell: bash

# Restore exact system image from cache (GitHub only — Namespace uses nscloud-cache-action in callers)
Expand Down Expand Up @@ -444,7 +452,7 @@ runs:
COCOAPODS_DISABLE_STATS: 'true'

- name: Install applesimutils
if: ${{ inputs.platform == 'ios' }}
if: ${{ inputs.platform == 'ios' && inputs.install-applesimutils == 'true' }}
run: |
if ! brew list applesimutils &>/dev/null; then
brew tap wix/brew
Expand All @@ -455,6 +463,6 @@ runs:
shell: bash

- name: Check simutils
if: ${{ inputs.platform == 'ios' }}
if: ${{ inputs.platform == 'ios' && inputs.install-applesimutils == 'true' }}
run: xcrun simctl list devices
shell: bash
58 changes: 58 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,64 @@ jobs:
runner_provider: ${{ inputs.runner_provider }}
secrets: inherit

appium-smoke-gate:
name: 'Appium Smoke Gate'
runs-on: ${{ inputs.runner_provider == 'namespace' && 'namespace-profile-metamask-ci-linux' || 'ubuntu-latest' }}
needs: [smart-e2e-selection]
outputs:
enabled: ${{ steps.gate.outputs.enabled }}
steps:
- name: Checkout (Namespace)
uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1
if: ${{ inputs.runner_provider == 'namespace' }}
- name: Checkout
uses: actions/checkout@v6
if: ${{ inputs.runner_provider != 'namespace' }}
with:
sparse-checkout: |
scripts/e2e/appium-smoke-tags.mjs

- name: Evaluate whether Appium smoke should run
id: gate
env:
SELECTED_TAGS: >-
${{
(fromJSON(needs.smart-e2e-selection.outputs.ai_confidence || '0') >= 85 &&
needs.smart-e2e-selection.outputs.ai_e2e_test_tags) ||
'["ALL"]'
}}
run: |
enabled=$(node scripts/e2e/appium-smoke-tags.mjs "$SELECTED_TAGS")
echo "enabled=${enabled}" >> "$GITHUB_OUTPUT"

# Android Appium smoke (PR CI). iOS: run-appium-smoke-tests-ios-scheduled.yml.
appium-smoke-tests-android:
name: 'Appium Smoke Tests (Android)'
if: >-
${{
!cancelled() &&
needs.appium-smoke-gate.outputs.enabled == 'true' &&
needs.build-android-apks.result == 'success'
}}
permissions:
contents: read
checks: write
id-token: write
needs: [build-android-apks, smart-e2e-selection, appium-smoke-gate]
uses: ./.github/workflows/run-appium-smoke-tests-android.yml
with:
build_type: 'main'
metamask_environment: 'e2e'
# Appium Android on Cirrus/GitHub-hosted runners until Namespace parity is ready.
runner_provider: current
selected_tags: >-
${{
(fromJSON(needs.smart-e2e-selection.outputs.ai_confidence || '0') >= 85 &&
needs.smart-e2e-selection.outputs.ai_e2e_test_tags) ||
'["ALL"]'
}}
secrets: inherit

# Fixture validation — ensures committed E2E fixtures match the live app state schema
validate-e2e-fixtures:
name: 'Validate E2E Fixtures'
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/prebuild-wda-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Prebuild WebDriverAgent for Appium iOS smoke tests.
#
# Called from run-appium-smoke-tests-ios-scheduled.yml alongside build-ios-e2e.yml.
# Writes DerivedData to ~/appium-wda for prepare-ios-appium-runner.mjs and actions/cache.

name: Prebuild WDA (Appium iOS)

on:
workflow_call:
inputs:
runner_provider:
description: 'Runner provider (namespace or current)'
required: false
type: string
default: 'current'

permissions:
contents: read

jobs:
prebuild-wda:
name: prebuild-wda-ios
runs-on: ${{ inputs.runner_provider == 'namespace' && 'namespace-profile-metamask-ios-e2e' || 'macos-latest' }}

steps:
- name: Checkout (Namespace)
uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1
if: ${{ inputs.runner_provider == 'namespace' }}
- name: Checkout
uses: actions/checkout@v4
if: ${{ inputs.runner_provider != 'namespace' }}

- name: Setup E2E environment (WDA prebuild only)
uses: ./.github/actions/setup-e2e-env
with:
platform: ios
setup-simulator: 'false'
configure-keystores: 'false'
install-foundry: 'false'
skip-pod-install: 'true'
install-applesimutils: 'false'
runner_provider: ${{ inputs.runner_provider }}

- name: Resolve XCUITest driver version for WDA cache key
id: xcuitest-version
run: echo "version=$(node scripts/e2e/resolve-xcuitest-driver-version.mjs)" >> "$GITHUB_OUTPUT"

- name: Get Xcode version for WDA cache key
id: xcode-version
run: echo "version=$(xcodebuild -version 2>/dev/null | head -1 | tr ' ' '-')" >> "$GITHUB_OUTPUT"

- name: Restore WDA DerivedData cache
uses: actions/cache@v4
with:
path: ~/appium-wda
key: wda-derived-data-xcuitest-${{ steps.xcuitest-version.outputs.version }}-${{ steps.xcode-version.outputs.version }}-${{ runner.os }}
restore-keys: |
wda-derived-data-xcuitest-${{ steps.xcuitest-version.outputs.version }}-${{ steps.xcode-version.outputs.version }}-

- name: Prebuild WDA if cache miss
run: node scripts/e2e/prebuild-wda.mjs
env:
IOS_SIMULATOR_NAME: iPhone 16 Pro
Loading
Loading