Skip to content

Commit bbec19c

Browse files
authored
Merge branch 'main' into predict/PRED-978
2 parents 0d169ac + 887370f commit bbec19c

389 files changed

Lines changed: 20982 additions & 4126 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
name: integration-test
3+
description:
4+
Write, fix, and update integration tests (*.integration.test.ts) for MetaMask
5+
Mobile using the tests/integration/ framework. Use when creating a new integration
6+
test file, fixing a failing integration test, updating tests after a controller
7+
change, or creating / extending a per-domain harness.
8+
---
9+
10+
# Integration Test Agent
11+
12+
**Goal**: Create, update, and fix integration tests (`*.integration.test.ts`) in the MetaMask Mobile codebase using the `tests/integration/` framework.
13+
14+
Use this skill whenever you need to:
15+
16+
- Write a new integration test file
17+
- Update tests after a controller / service / harness has changed
18+
- Diagnose and fix a failing integration test
19+
- Add a new per-domain harness or extend an existing one
20+
21+
Your job is to figure out whether the user needs to **write a new test**, **fix a failing test**, **update tests after a controller change**, or **add/extend a harness**, then follow the corresponding path and open the relevant reference when that path indicates.
22+
23+
**Decision tree — which reference to use:**
24+
25+
```
26+
Task → What do you need?
27+
├─ Write new test or update after change
28+
│ → Read controller/service + existing tests
29+
│ → Open references/writing-tests.md (use cases, harness selection, file structure, assertions)
30+
│ → If the harness doesn't fit → also open references/harness-extension.md
31+
│ → After writing: run tests, then open references/reference.md for self-review
32+
33+
├─ Fix failing test
34+
│ → Run: yarn jest -c jest.config.integration.js <path> --runInBand --silent --coverage=false
35+
│ → Identify error type → Open references/reference.md (Diagnosing Failures)
36+
37+
├─ Add a new domain harness or extend an existing one
38+
│ → Open references/harness-extension.md (when to extend, structure, REAL/MOCKED split, AGENTS.md updates)
39+
40+
└─ Run tests or self-review after tests pass
41+
→ Open references/reference.md (Run the Tests, Self-Review Checklist)
42+
```
43+
44+
Do not read the full reference files until the decision tree or workflow sends you there.
45+
46+
---
47+
48+
## What Are Integration Tests?
49+
50+
Integration tests are **controller-app integration** tests that exercise real controller / provider / service code with the I/O boundary mocked. They live alongside the code as `<feature>.integration.test.ts` and use a dedicated framework in `tests/integration/`.
51+
52+
Key constraint: **only the I/O boundary may be mocked** (SDK clients, wallet, subscription services, native modules, keyring). Shape B/C harnesses may also mock documented app-shell glue when the real target chain still runs. The controller, its services, validation logic, and state transitions all run for real at the chosen boundary. The harness for each domain owns the standard `jest.mock(...)` declarations; tests don't add their own.
53+
54+
For the full strategy (why this layer exists, how it relates to CV / Unit / E2E, the perps rollout plan), see [`tests/integration/STRATEGY.md`](../../tests/integration/STRATEGY.md). For the framework rules, see [`tests/integration/AGENTS.md`](../../tests/integration/AGENTS.md).
55+
56+
---
57+
58+
## The Framework at a Glance
59+
60+
```
61+
tests/integration/
62+
├── AGENTS.md ← framework rules + per-domain harness inventory
63+
├── STRATEGY.md ← four-layer strategy + comparison tables + rollout plan
64+
├── coverage.svg ← diagram (which test type runs real code at which layer)
65+
├── coverage-and-tracking.md ← coverage targets + bug-tracking mechanisms
66+
├── perps-use-cases.md ← every perps use case → primary test layer
67+
└── harnesses/
68+
├── perps.ts ← Shape A: provider-level harness
69+
├── perps-flow.ts ← Shape B: hook-flow harness
70+
└── perps-component.tsx ← Shape C: rendered-component harness
71+
```
72+
73+
Tests live next to the code they test, named `<feature>.integration.test.ts`. They run via `yarn jest -c jest.config.integration.js`.
74+
75+
---
76+
77+
## Workflow (summary)
78+
79+
- **Write new test**: Read controller / service and existing tests → list use cases (or pull from per-domain use-case file) and map to test patterns → check coverage and deduplicate → choose Shape A/B/C based on the boundary under test → call the matching harness factory → write test (call real action, assert on state / selector output / return value). Every test must call at least one real method on the real instance returned by the harness — no harness-only setup. Run tests, then run the self-review checklist in `references/reference.md`.
80+
- **Fix failing test**: Run with `jest.config.integration.js` → identify error type from the table in `references/reference.md` (Diagnosing Failures) → apply the fix (extend harness, override mock for one test, await async settlement, reset module-level singleton state, etc.) → re-run.
81+
- **Update after change**: Same as write — review existing tests, update the harness if shape changed, update tests, run and self-review.
82+
- **Add or extend a harness**: Open `references/harness-extension.md` → identify whether you're adding a new domain or extending an existing one → follow the structure (jest.mock + factory + REAL/MOCKED header) → update `tests/integration/AGENTS.md` if it's a new domain.
83+
84+
For full detail, use the reference files when the decision tree sends you there.
85+
86+
---
87+
88+
## Run the tests
89+
90+
Always use `jest.config.integration.js` — the default Jest config picks up integration tests but doesn't apply the integration-suite-specific settings (single worker, longer timeout, force exit).
91+
92+
**Run a single test (no coverage):**
93+
94+
```bash
95+
yarn jest -c jest.config.integration.js <path> --runInBand --silent --coverage=false
96+
```
97+
98+
Example: `yarn jest -c jest.config.integration.js app/components/UI/Perps/hooks/usePerpsFlipPosition.integration.test.ts --runInBand --silent --coverage=false`
99+
100+
**Run the full integration suite:**
101+
102+
```bash
103+
yarn jest -c jest.config.integration.js
104+
```
105+
106+
**Coverage for a feature folder** (run with `--collectCoverageFrom` pointed at the controller / provider you're exercising — coverage on the test file itself will always be near zero):
107+
108+
```bash
109+
yarn jest -c jest.config.integration.js <test-path> \
110+
--coverage \
111+
--collectCoverageFrom="app/controllers/perps/providers/HyperLiquidProvider.ts"
112+
```
113+
114+
For run-by-name, watch mode, or other options, see `references/reference.md` (Run the Tests).
115+
116+
---
117+
118+
## Golden Rules (Enforced)
119+
120+
1. **Only the harness mocks the I/O boundary** — no arbitrary `jest.mock()` in `*.integration.test.ts` files. The harness file (`tests/integration/harnesses/<domain>.ts`) owns the full set; tests just import it. Shape B/C may also mock documented app-shell glue inside the harness when the real target chain still runs. If you find yourself wanting a new mock, extend the harness instead.
121+
122+
2. **Drive behaviour through real method calls on the real instance** — call `provider.placeOrder(...)`, `controller.flipPosition(...)`, etc. The harness returns the real instance; the test exercises it. No simulating state transitions by reaching inside the controller's internals.
123+
124+
3. **Assert on observable outcomes** — return values, post-call state, selector output. Mock-call assertions are allowed only when verifying a side effect (e.g. that the SDK was called with the right args) is the explicit point of the test.
125+
126+
4. **Reuse harnesses** — never rebuild the controller setup from scratch in a test. If the harness doesn't expose what you need, extend it.
127+
128+
5. **No fake timers** — never use `jest.useFakeTimers()`, `jest.advanceTimersByTime()`, or `jest.useRealTimers()`. Use `await` and `waitFor` for async settlement.
129+
130+
6. **No snapshot tests** — assert on specific values. State shape changes are caught by integration tests that exercise the relevant flow, not by snapshotting the controller output.
131+
132+
7. **Follow AAA** — Arrange (build harness, set mocks) → Act (call real method) → Assert (check return value / state). Blank lines between sections. One test = one user flow or one rejection path; multiple chained calls in one test are fine when they represent one user journey.
133+
134+
8. **No harness-only tests** — every test must call at least one real method on the harness's instance. Tests that only construct the harness and assert on default state are not integration tests; they're testing the harness defaults, which is wasted effort.
135+
136+
9. **One test = one use case from the matrix** — each `it` should map to a row in the per-domain use-case file (e.g. `perps-use-cases.md`). If a test doesn't fit any use case, ask whether the use case is missing from the matrix or the test is in the wrong layer.
137+
138+
10. **Module-level singleton state is reset per test** — the harness handles this for known singletons (`TradingReadinessCache`, etc.). If you depend on a new singleton, add its reset to the harness; don't rely on test-order.
139+
140+
---
141+
142+
## Reference files (when to use)
143+
144+
Documentation is split by **action**. Open only the reference that matches what you are doing.
145+
146+
| Action | File | When to open it |
147+
| ----------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
148+
| **Writing or updating integration tests** | [`references/writing-tests.md`](references/writing-tests.md) | New test file, new use case, updated controller. Read before writing, use cases and matrix, file structure, harness usage, assertion patterns. |
149+
| **Adding or extending a harness** | [`references/harness-extension.md`](references/harness-extension.md) | New domain, new mock, new helper, new option. REAL/MOCKED split, factory shape, AGENTS.md updates. |
150+
| **Running tests, self-review, fixing failures** | [`references/reference.md`](references/reference.md) | Run the Tests, Self-Review Checklist, Diagnosing Failures, assertion patterns, module-singleton state, What NOT to Do, Quick Reference. |
151+
152+
**Where self-review and What NOT to Do live:** Both are in `references/reference.md`. Self-review is the checklist you run after tests pass. What NOT to Do is the antipatterns section in the same file. Keeping them there means when you run tests or fix failures you have run commands, the checklist, the failure table, and the antipatterns in one place — open that reference for any run/fix/review task.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
interface:
2+
display_name: "Integration Test"
3+
short_description: "Write and fix *.integration.test.ts tests for MetaMask Mobile."
4+
default_prompt: "Use $integration-test to write, fix, or update integration tests with the tests/integration/ framework."

0 commit comments

Comments
 (0)