Mattermost Mobile

repository·main·Indexed 25 days ago

https://github.com/mattermost/mattermost-mobile

The official mobile client for the Mattermost collaboration platform, built with React Native for iOS and Android. Documentation includes guides on performance profiling using the Observable Profiler, Post List Performance Tracker, and React Profiler, as well as E2E testing configurations using Detox and Maestro.

Tokens
20K
Snippets
37
Records
120
Agent score
83%

What's inside mattermost-mobile

  1. Maestro File Structure Overview

    main

    The Maestro E2E test suite is organized into sub-flows, fixtures, and main flows:

    • subflows/: Reusable logic for authentication, navigation, calls, waits, and server/browser interactions.
    • fixtures/: Node scripts for seeding data (users, channels, files) or polling APIs.
    • flows/: The actual test scenarios, categorized by feature (account, calls, channels, multi-device, timezone).
    • scripts/: Orchestration scripts for running specific test types (e.g., two-device or timezone tests).
    detox/maestro/
      package.json                         # Maestro CLI version pin + npm scripts
      README.md                            # This file
      subflows/
        auth/
          login.yml                        # Reusable: app launch + login
          logout.yml                       # Reusable: logout from app
        navigation/
          navigate_to_channel.yml          # Reusable: tap channel in sidebar
          expand_channels_category.yml
          dismiss_scheduled_post_tooltip.yml
        calls/
          join_channel_call.yml
          wait_for_active_call.yml
        waits/
          wait_for_home_tab.yml
          wait_for_server_connect_complete.yml
        server/
          connect_server.yml
        browser/
          dismiss_chrome_interstitial.yml
          reopen_settings_screen.yml
        timezone/
          assert_timezone_region_label.yml
          assert_timezone_region_local.yml
      lib/
        env.ts                             # Env helpers for fixture scripts
        timezone_region.sh                 # Shell helper for timezone CI
      fixtures/
        seed.ts                            # Node script: create team/channel/user via API
        seed_file_preview.ts               # Node script: seed for file_type_preview flows
        calls_seed.ts                      # Node script: seed calls-specific data
        poll_for_message.ts               # Node script: poll API for SYNC_TOKEN message
      flows/
        account/
          attach_logs.yml                  # MM-T67856 (Zephyr MM-T3261 Report a Problem)
          help_url.yml                     # MM-T3260
        calls/
          call_ui_permission.yml           # MM-T1411 (Android PR CI only)
          leave_call.yml                   # MM-T4833 (Android PR CI only)
          mute_unmute.yml                  # MM-T4832 (Android PR CI only)
          start_call.yml                   # MM-T4829 (nightly/manual — calls_seed.ts)
        channels/
          channel_bookmark_file.yml        # MM-T5603
          channel_bookmark_file_android_picker.yml  # sub-flow (skipped in PR batch)
          channel_bookmark_file_ios_picker.yml     # sub-flow (skipped in PR batch)
          channel_bookmark_link_external.yml       # MM-T5611
          file_type_preview.yml             # MM-T3244 (nightly — seed_file_preview.ts)
        multi_device/
          device_a_start_call.yml          # MM-T4830 (two-device calls)
          device_b_join_call.yml           # MM-T4831 (two-device calls)
          user_a_sends_message.yml         # MM-T3055
          user_b_receives_message.yml      # MM-T3056
        timezone/
          clock_display.yml                 # MM-T1325
      scripts/
        run_two_device.sh                  # Orchestrate two-device tests
        run_timezone_test.sh              # Timezone test with simctl timezone setup
  2. System Requirements for Mattermost Mobile v2

    main

    Before using or building Mattermost Mobile v2, ensure your environment meets the following requirements:

    • Minimum Mattermost Server version: Current ESR version (10.11.0+)
    • Supported iOS version: 16.0+
    • Supported Android version: 7.0+
  3. Install CocoaPods on Apple Silicon Mac

    main

    To install CocoaPods, you must first set the system encoding to UTF-8 to avoid Unicode normalization errors. On Apple Silicon Macs, use the arch -x86_64 prefix and ensure RCT_NEW_ARCH_ENABLED=0 is set, as the project uses the legacy architecture.

    # Set UTF-8 encoding
    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8
    
    # Install Pods
    cd ios
    RCT_NEW_ARCH_ENABLED=0 arch -x86_64 pod install
  4. Configure Webhook Sidecar for integration tests

    main

    The webhook_server.js serves callbacks for mm_blocks_* and interactive dialog specs on port :3000.

    • Local Server: If SITE_1_URL is http://localhost:8065, no tunnel is needed. Run npm run start:webhook in the detox folder.
    • Remote/Cloud Server: The server must reach your machine via a public HTTPS origin. Use detox/scripts/start_webhook_sidecar.sh to start the sidecar. It resolves an origin in this priority:
      1. WEBHOOK_PUBLIC_BASE_URL: A provided HTTPS origin (e.g., ngrok).
      2. WEBHOOK_PUBLIC_BASE_URL + CLOUDFLARED_TUNNEL_TOKEN: A Cloudflare tunnel.
      3. Fallback: A trycloudflare.com quick tunnel (not recommended for reliable callbacks).

    Environment Variables:

    • WEBHOOK_PUBLIC_BASE_URL: The public HTTPS URL.
    • TUNNEL_TOKEN: The Cloudflare tunnel token.
    • CLOUDFLARED_VERSION: Pin a specific cloudflared version.
    # Local setup
    cd detox && npm run start:webhook
    
    # Remote setup with custom tunnel
    cd detox
    SITE_1_URL="https://your-test-server" \
    WEBHOOK_PUBLIC_BASE_URL="https://your-tunnel-hostname" \
    bash scripts/start_webhook_sidecar.sh
  5. Test Screens and UI components

    main

    When testing React components and screens:

    Rendering

    • Use renderWithEverything(ui, { database, serverUrl }) from @test/intl-test-helper if the component requires database or server context.
    • Use renderWithIntlAndTheme(ui) if it only requires theme and internationalization.

    Mocking

    • Mock heavy dependencies like navigation, remote actions, or useServerUrl using jest.mock(...).
    • Mocking child components:
      1. Mock the module with a factory returning { __esModule: true, default: jest.fn() }.
      2. Import the child component.
      3. Use jest.mocked(ChildComponent).mockImplementation((props) => React.createElement(View, { testID: '...', ...props })) to ensure the implementation runs in the test scope with access to React and View.

    Assertions

    • Assert on props: Query the screen for the element (e.g., getByTestId('...')) and use expect(element).toHaveProp('propName', value). Do not inspect jest.mocked(Component).mock.calls directly.
    • User interactions: Use fireEvent.press() for buttons/toggles. Wrap async updates in act() or waitFor.
  6. Build and run Detox Android tests

    main

    Follow these steps to run Detox tests on Android:

    1. Build the app: Navigate to the detox folder and run the build command. The debug APK will be located at android/app/build/outputs/apk/debug/app-debug.apk.
    2. Create an emulator: Use the provided script to create an Android Virtual Device (AVD).
    3. Run tests: Execute the Detox test suite from the detox folder.

    Resource Management (Local Defaults):

    • Detox uses 1 worker (override with DETOX_MAX_WORKERS).
    • Node heap is capped at 4096MB (unless NODE_OPTIONS is set).
    • Gradle heap is capped at 3072MB and uses at most 2 workers (override with MM_GRADLE_XX_MB or MM_GRADLE_WORKERS_MAX).
    • Emulator RAM defaults to 3072MB (override with MM_ANDROID_EMULATOR_RAM_MB).
  7. Setup iOS simulator for stable Maestro runs

    main

    To achieve CI parity on iOS, follow these steps to build the release simulator app, unzip it, and pre-warm the simulator using the provided scripts.

    Recommended Workflow:

    1. Set RUNNING_E2E=true in .env.
    2. Build the simulator app using Fastlane.
    3. Unzip the artifact to mobile-artifacts/.
    4. Run the preboot script.
    echo "RUNNING_E2E=true" > .env
    # Build release sim .app
    cd fastlane && bundle exec fastlane ios simulator --env ios.simulator && cd ..
    unzip -o Mattermost-simulator-*.app.zip -d mobile-artifacts/
    
    DEVICE_NAME="iPhone 17 Pro" DEVICE_OS_VERSION="iOS 26.2" \
      bash detox/scripts/preboot_ios_simulator.sh
  8. Test local actions in `app/actions/local/`

    main

    Local actions interact with the in-memory database. To test them:

    1. Use a real in-memory database by calling DatabaseManager.init([serverUrl]) in beforeEach and DatabaseManager.destroyServerDatabase(serverUrl) in afterEach.
    2. Use TestHelper to generate fake entities (e.g., TestHelper.fakeChannel(), TestHelper.fakePost()).
    3. Test the following scenarios:
      • not-found database: Provide an invalid serverUrl.
      • not-found entity: Attempt to act on a missing channel or post.
      • success path: Standard operation.
      • error path: Mock database.write or operator.batchRecords to throw an error.