Skip to content
Open
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
7 changes: 6 additions & 1 deletion .github/workflows/tests_e2e_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ jobs:
max_attempts: 3
command: yarn tests:android:build

# JVM unit tests (no emulator). Produces module *.exec for merged Jacoco after Detox.
- name: Android JVM unit tests
run: yarn tests:android:unit

- name: Metro Bundler Cache Restore
# https://github.com/actions/cache/releases
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
Expand Down Expand Up @@ -290,11 +294,12 @@ jobs:
flags: e2e-ts-android
verbose: true

# Merged unit (*.exec) + e2e (*.ec) from jacocoTestReport (post-e2e-coverage).
- name: Upload Codecov Android native
uses: codecov/codecov-action@e53489f4d376d79066609109e7a95a29eb3740b1 # v7.0.0
continue-on-error: true
with:
files: tests/android/app/build/reports/jacoco/jacocoAndroidTestReport/jacocoAndroidTestReport.xml
files: tests/android/app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
flags: android-native
disable_search: true
verbose: true
Expand Down
15 changes: 9 additions & 6 deletions okf-bundle/ci-workflows/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

## E2E job shape (CI — mirrors workflow YAML; local: [running e2e](../testing/running-e2e.md))

1. `tests:android:test-cover --headless` — pass/fail gate
2. `tests:android:post-e2e-coverage` — poll/pull `coverage.ec`, Jacoco report (best-effort, never fails the job)
3. **Codecov upload** — two flagged uploads (`e2e-ts-android`, `android-native`); `continue-on-error: true` on the action steps. **`codecov/project/android-native`** fails if the native flag upload is missing (see [coverage design](../testing/coverage-design.md#native-gates)).
1. `tests:android:build`
2. `tests:android:unit` — JVM unit (no emulator); produces module Jacoco `*.exec` ([AndroidTest-AD-1](../testing/android-architecture-decisions.md))
3. `tests:android:test-cover --headless` — pass/fail gate
4. `tests:android:post-e2e-coverage` — poll/pull `coverage.ec`, merged **`jacocoTestReport`** (unit `*.exec` + e2e `*.ec`; best-effort, never fails the job)
5. **Codecov upload** — two flagged uploads (`e2e-ts-android`, `android-native` → `jacocoTestReport.xml`); `continue-on-error: true` on the action steps. **`codecov/project/android-native`** fails if the native flag upload is missing (see [coverage design](../testing/coverage-design.md#native-gates)).

Android native coverage is flushed in app process by `tests/app.js` Jet `after`; post-e2e pull runs after Detox exits.
Android native coverage is flushed in app process by `tests/app.js` Jet `after`; post-e2e pull runs after Detox exits and merges with JVM unit execution data. Full Jacoco contract: [coverage design](../testing/coverage-design.md) — do not duplicate here.

## CI failure: Jet 1006 → adb `reverse --remove` mid-run

Expand Down Expand Up @@ -71,9 +73,10 @@ Under load, Jet may run only a small prefix before mocha-remote desync, often af
| Symptom | Likely cause |
|---------|----------------|
| `[native-coverage] Android native coverage file not found after N attempts` | App-process flush did not run or failed; check Jet log for `[native-coverage] flushing android coverage` |
| Empty Jacoco XML (~235 bytes) | No `.ec` pulled — check post-e2e logs |
| Empty Jacoco XML (~235 bytes) | No `.ec` / `.exec` in merge — check post-e2e logs and that `yarn tests:android:unit` ran ([coverage design](../testing/coverage-design.md)) |

| `adb reverse --remove` in Detox logs | Expected on 1006; should be warn-only after Detox patch |
| Detox red, tests green in log | Pre-patch: teardown adb error; re-run or check patch applied |
| Emulator offline / hung / duplicate instance | Warm quickboot snapshot restore; `tests/.detoxrc.js` sets `bootArgs: '-no-snapshot-load -no-snapshot-save'` for cold boot when Detox launches TestingAVD |
| `codecov/project/android-native` fail | Jacoco XML not uploaded — check post-e2e logs and Codecov Uploads tab for `android-native` flag |
| `codecov/project/android-native` fail | Jacoco XML not uploaded — check post-e2e logs and Codecov Uploads tab for `android-native` flag; path must be `jacocoTestReport.xml` (merged), not e2e-only `jacocoAndroidTestReport.xml` |
| FIS 503 / `Too many server requests` / RC cascade | Live cloud quota (shared project) — not Android-specific; see [cloud API quota triage](../testing/firebase-testing-project.md#ci-triage-cloud-api-quota-pressure) |
2 changes: 1 addition & 1 deletion okf-bundle/ci-workflows/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GitHub Actions job shape, platform reliability, and artifact triage.
## Platforms

* [iOS](ios.md) — simulator boot, logging, troubleshooting, [CI baseload policy](ios.md#ci-baseload-policy-instrumentation)
* [Android](android.md) — idling, adb teardown, native coverage
* [Android](android.md) — JVM unit step, idling, adb teardown, merged Jacoco / native coverage
* [Other](other.md) — macOS e2e, Windows/shared

## Shared E2E dependencies
Expand Down
1 change: 1 addition & 0 deletions okf-bundle/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ okf_version: '0.1'
- [Running e2e tests](/testing/running-e2e.md) — canonical e2e commands, narrowing, environment, diagnosis
- [Validation checklist](/testing/validation-checklist.md) — compile, Jest, lint, `compare:types`, e2e, coverage
- [Published types ADR](/testing/architecture-decisions.md) — attw scope, Expo plugin checks, discarded resolutions
- [Android unit testing ADR](/testing/android-architecture-decisions.md) — Robolectric + Mockito JVM unit tests (`AndroidTest-AD-*`)
- [Coverage design](/testing/coverage-design.md) — unit/e2e coverage policy, native gates, Codecov
- [Firebase testing project](/testing/firebase-testing-project.md) — cloud vs emulator, live FIS/RC, helper callables, rules/indexes, deploy

Expand Down
29 changes: 26 additions & 3 deletions okf-bundle/testing/agent-command-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,21 @@ Single source for **which shell commands agents may run** in this repo. E2e is a

| Intent | Command | Never use instead |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| Install / refresh deps | `yarn` | `yarn workspace …`, `npm install` in a package, `yarn install` in `tests/` alone for root deps |
| Install / refresh deps | `yarn` (repo root) | `yarn workspace …`, `npm install`, `npm install` in a package, `yarn install` / `yarn` in `tests/` alone for root deps, skipping root `yarn` before e2e/build |
| Transpile `lib/**` → `dist/module/**` (all packages) | `yarn lerna:prepare` | `yarn workspace @react-native-firebase/* prepare`, `cd packages/<pkg> && yarn prepare`, `cd packages/<pkg> && yarn run build` |
| Transpile one package | `yarn lerna run prepare --scope @react-native-firebase/<pkg>` | `yarn workspace @react-native-firebase/<pkg> prepare` |
| After `packages/*/lib/**` edits (Metro serves `dist/module/**`) | `yarn lerna:prepare`; Metro restart when already running ([running e2e § prepare completion gate](running-e2e.md#prepare-completion-gate-blocking)) — platform `:build` only when [running e2e § Rules #3](running-e2e.md#rules) requires native/codegen/instrumentation, not for JS alone | ad-hoc `bob`, `babel`, or package-scoped prepare |
| TS/JS validation sequence | [validation checklist](validation-checklist.md) | ad-hoc `tsc` in package dirs unless listed there |
| JS lint (implementation / review gate) | `yarn lint:js`, `yarn lint:js --fix` | package-scoped `eslint`, `npx eslint` |
| Android Java format / lint | `yarn lint:android` | `yarn google-java-format`, bare `google-java-format`, `google-java-format -i`, `npx google-java-format`, any invented format script |
| Docs lint (when docs in diff) | `yarn lint:markdown`, `yarn lint:spellcheck` | ad-hoc prettier/eslint on single files |
| E2e + coverage | [running e2e](running-e2e.md) — **only** `yarn tests:*` | `jet`, `npx jet`, `yarn jet`, `detox test`, `cd tests && …`, direct Metro/emulator starts |
| Android JVM unit tests | `yarn tests:android:unit` | ad-hoc `./gradlew …` outside this yarn script; bare Robolectric/JUnit IDE-only as the agent gate |
| Android merged Jacoco (unit + e2e) | `yarn tests:android:post-e2e-coverage` (after e2e); `yarn tests:android:test:jacoco-report` when regenerating the merge report | `./gradlew jacocoAndroidTestReport` as Codecov path; inventing other jacoco yarn scripts |
| E2e + coverage | [running e2e](running-e2e.md) — **only** `yarn tests:*` | `jet`, `npx jet`, `yarn jet`, `detox test`, bare `detox`, `cd tests && …`, direct Metro/emulator starts |
| iOS Detox framework cache rebuild | `yarn tests:ios:detox-framework-cache:rebuild` | `cd tests && yarn detox clean-framework-cache`, `cd tests && yarn detox build-framework-cache`, bare `detox …` |
| Host pre-flight (before each `:test-cover`) | [running e2e § host-clear probes](running-e2e.md#host-clear-probes) | `pgrep`, polling `:8090`, spawn probes of Jet/Detox |


### Prepare / transpile (detail)

`yarn lerna:prepare` runs each package's **`prepare`** script (`build` → `compile` via react-native-builder-bob). That is what produces **`dist/module/**`** consumed by Metro in debug e2e — only **release\*\* builds pre-bundle/embed JS ([running e2e § Rules #3](running-e2e.md#rules)).
Expand Down Expand Up @@ -75,8 +79,11 @@ Single source for **which shell commands agents may run** in this repo. E2e is a
| ---------------------------------------------------------------- | -------------------------------------------------------------- |
| `yarn workspace @react-native-firebase/* prepare` (and variants) | Not canonical; breaks root devDependency binary resolution |
| `cd packages/<pkg> && yarn prepare` / `yarn run build` | Same trap; not the postinstall / lerna code path |
| `yarn google-java-format`, bare `google-java-format`, `npx google-java-format`, `google-java-format -i` | Invented format entrypoints — **only** `yarn lint:android` |
| `npm install` (any cwd) / `yarn` / `yarn install` only in `tests/` for monorepo deps | Root `yarn` applies patches and workspace links; tests-only install is insufficient |
| Ad-hoc `./gradlew …` outside allowlisted yarn scripts (`tests:android:unit`, `tests:android:build`, `tests:android:post-e2e-coverage`, `tests:android:test:jacoco-report`, etc.) | Wrong task / cwd / report path; invents CI that does not match Codecov |
| `yarn jet`, `npx jet`, `cd tests && yarn jet …` | [E2e agent rule](running-e2e.md#agent-rule-read-first) |
| `detox test`, `cd tests && detox …` | E2e agent rule |
| `detox test`, bare `detox`, `cd tests && detox …` | E2e agent rule |
| Ad-hoc Metro / emulator start | Use `yarn tests:packager:jet`, `yarn tests:emulator:start` |
| Spawn / PATH probes to “test” Jet or genversion | Log triage only; fix product code and re-run canonical command |

Expand All @@ -95,6 +102,18 @@ Single source for **which shell commands agents may run** in this repo. E2e is a
- **`yarn jet --help`** working or failing in `tests/` is **not** a valid e2e or install gate.
- Jet is started **internally** by `yarn tests:<platform>:test-cover`. Stale `:8090` → [pre-flight recovery](running-e2e.md#pre-flight-recovery), then re-run the same `:test-cover` command.

### Android Java format

- There is **no** `yarn google-java-format` script. Invented `google-java-format` / `npx google-java-format` invocations are forbidden.
- **Canonical:** `yarn lint:android` (repo root) — wraps `google-java-format --set-exit-if-changed --replace` on `packages/*/android/src` and fails if the tree would change.

### Android build / unit / Jacoco

- **Do not** invent `cd tests && yarn install`, then bare `./gradlew` from an arbitrary cwd.
- Unit: **`yarn tests:android:unit`** only ([AndroidTest-AD-1](android-architecture-decisions.md#androidtest-ad-1--robolectric--mockito-for-android-jvm-unit-tests--accepted)).
- Merged coverage after e2e: **`yarn tests:android:post-e2e-coverage`** (Codecov path is `jacocoTestReport`, not e2e-only `jacocoAndroidTestReport`) — [coverage design](coverage-design.md).
- Optional explicit merge: **`yarn tests:android:test:jacoco-report`**.

### TurboModule codegen

- **`cd packages/<pkg> && yarn ios:codegen`** (or `yarn android:codegen`) often fails with **`unknown command 'codegen'`** after a clean `yarn` — `@react-native-community/cli` resolves from the **test app** workspace.
Expand All @@ -109,9 +128,12 @@ Paste into Task / explore / work-queue prompts:
RNFB agent command policy: okf-bundle/testing/agent-command-policy.md ONLY.
E2e: okf-bundle/testing/running-e2e.md yarn tests:* ONLY.
Never: yarn workspace prepare, yarn jet, npx jet, cd packages/* && yarn prepare/build for diagnostics.
Never invent format/install: yarn google-java-format, bare/npx google-java-format, npm install, yarn install in tests/ alone — use root yarn first; Java format = yarn lint:android ONLY.
Never invent Android Gradle: ad-hoc ./gradlew outside yarn tests:android:unit / :build / :post-e2e-coverage / :test:jacoco-report; bare detox/jet/metro.
Prepare/install: yarn or yarn lerna:prepare must exit 0 before ANY other command — never parallelize with e2e/Metro/build.
Area harness: okf-bundle/testing/running-e2e.md#local-harness-overrides-harnessoverridesjs — copy harness.overrides.example.js to gitignored harness.overrides.js; set modules + RNFBDebug; delete overrides after run.
TurboModule contract test (NewArch-AD-17.1): packages/app/__tests__/nativeModuleContract.test.ts — yarn tests:jest -- packages/app/__tests__/nativeModuleContract.test.ts
Android JVM unit (AndroidTest-AD-1): yarn tests:android:unit — not a substitute for platform e2e.
On failure: fix product code, re-run the same canonical command.
Gate close / push: return [validation evidence package](validation-checklist.md#validation-evidence-package) and [coverage evidence package](coverage-design.md#coverage-evidence-package) when lib/native touched — required before commit or publication ([change authoring § validation evidence](change-authoring-workflow.md#validation-evidence-blocking)).
```
Expand All @@ -122,5 +144,6 @@ Gate close / push: return [validation evidence package](validation-checklist.md#
| ------------------------------- | ------------------------------------------------------------ |
| E2e commands, pre-flight, tiers | [running-e2e.md](running-e2e.md) |
| Handoff validation sequence | [validation-checklist.md](validation-checklist.md) |
| Android JVM unit ADR | [android-architecture-decisions.md](android-architecture-decisions.md) |
| Work types and gates | [change-authoring-workflow.md](change-authoring-workflow.md) |
| Doc / commit policy | [documentation-policy.md](../documentation-policy.md) |
Loading
Loading