Skip to content

Commit af7f065

Browse files
committed
revert
1 parent 1f86460 commit af7f065

9 files changed

Lines changed: 47 additions & 18 deletions

File tree

.agents/skills/integration-test/SKILL.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Do not read the full reference files until the decision tree or workflow sends y
4949

5050
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/`.
5151

52-
Key constraint: **only the I/O boundary may be mocked** (SDK clients, wallet, subscription services, native modules, keyring). The controller, its services, validation logic, and state transitions all run for real. The harness for each domain owns the standard `jest.mock(...)` declarations; tests don't add their own.
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.
5353

5454
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).
5555

@@ -65,8 +65,9 @@ tests/integration/
6565
├── coverage-and-tracking.md ← coverage targets + bug-tracking mechanisms
6666
├── perps-use-cases.md ← every perps use case → primary test layer
6767
└── harnesses/
68-
└── perps.ts ← jest.mock + buildPerpsIntegrationHarness
69-
(one file per domain)
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
7071
```
7172

7273
Tests live next to the code they test, named `<feature>.integration.test.ts`. They run via `yarn jest -c jest.config.integration.js`.
@@ -75,7 +76,7 @@ Tests live next to the code they test, named `<feature>.integration.test.ts`. Th
7576

7677
## Workflow (summary)
7778

78-
- **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 → call `build<Domain>IntegrationHarness()` from the right harness → 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`.
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`.
7980
- **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.
8081
- **Update after change**: Same as write — review existing tests, update the harness if shape changed, update tests, run and self-review.
8182
- **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.
@@ -116,7 +117,7 @@ For run-by-name, watch mode, or other options, see `references/reference.md` (Ru
116117

117118
## Golden Rules (Enforced)
118119

119-
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. If you find yourself wanting a new mock, extend the harness instead.
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.
120121

121122
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.
122123

.agents/skills/integration-test/references/harness-extension.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,14 @@ The line between REAL and MOCKED is the **I/O boundary**. Real: anything that's
114114
| Wallet / keyring service | MOCKED | Native module I/O |
115115
| WebSocket subscription service | MOCKED | Network + timing I/O |
116116
| Module-level caches that hit storage | MOCKED | Disk I/O |
117-
| Stream managers / orchestrators | MOCKED | UI subscription — different concern |
117+
| Stream managers / orchestrators | MOCKED | UI subscription/runtime plumbing — different concern |
118118
| Validation utility functions in separate files | MOCKED | Existing pattern in codebase; class methods stay real |
119+
| App-shell glue for hook/rendered harnesses | MOCKED in B/C | Engine/navigation/runtime plumbing, documented in harness |
119120

120121
When in doubt, ask: **does this code talk to the outside world (network, disk, keyring, native module, websocket)?** If yes, mock it. If no, leave it real.
121122

123+
For Shape B/C, also ask: **is this app-shell glue required only to mount the hook/screen while the real controller/service/provider chain still runs?** If yes, the harness may mock it, but the header must list the mock and explain which real chain remains covered.
124+
122125
---
123126

124127
## Adding a new domain harness

.agents/skills/integration-test/references/writing-tests.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,23 @@ Ask: "What can a user **do** that touches this controller?" — open / close / e
4949

5050
Drop anything that only exercises the harness defaults — every test must call at least one real method on the real instance.
5151

52-
### 4. Deduplicate against existing tests
52+
### 4. Pick the narrowest harness shape
53+
54+
Use the lightest harness that proves the use case:
55+
56+
| Shape | Harness | Use when |
57+
| ----- | ------- | -------- |
58+
| A | `buildPerpsIntegrationHarness` | Direct provider/service behavior is enough: validation, order placement, close/cancel branches, mocked SDK side effects. |
59+
| B | `buildPerpsFlowHarness` | The risk includes hook wiring or the `TradingService` -> provider seam, but rendering UI is not part of the behavior. |
60+
| C | `buildPerpsComponentHarness` | A rendered user interaction must prove it reaches real perps trading code. Do not use for pure UI variants. |
61+
62+
Shape B/C may mock app-shell glue in the harness (Engine shim, network hook, native runtime providers, confirmation/pay plumbing). Those mocks must stay harness-owned and documented in the REAL/MOCKED header; test files still never add `jest.mock(...)`.
63+
64+
### 5. Deduplicate against existing tests
5365

5466
Read the existing `*.integration.test.ts` for the area (if any) and remove candidates already covered. Look at the test bodies, not just titles, since one `it` might cover several rows of the matrix.
5567

56-
### 5. Run coverage on the file you're exercising and prioritise
68+
### 6. Run coverage on the file you're exercising and prioritise
5769

5870
```bash
5971
yarn jest -c jest.config.integration.js <test-path> \

tests/AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ Single agent index for **tests/**, and **wdio/**. Pointers only; details live in
99
- **tests/**`tests/framework/`, `tests/api-mocking/`, `tests/docs/`, `tests/regression/`, `tests/smoke/`, etc. Framework, fixtures, mocking, regression/smoke specs.
1010
- **wdio/**`wdio/helpers/`, `wdio/screen-objects/`, `wdio/utils/`. Legacy WebdriverIO/Appium — **deprecated**. Use Detox + tests/smoke or Playwright for performance.
1111
- **component view tests**`app/**/*.view.test.tsx`. Jest component view tests.
12+
- **integration tests**`app/**/*.integration.test.ts?(x)`. Jest controller-app integration tests that use `tests/integration/` harnesses and `jest.config.integration.js`.
1213

1314
### Component-View Tests (Mandatory)
1415

1516
- [tests/component-view/AGENTS.md](component-view/AGENTS.md) — Agent index for component view tests: framework, canonical skill, run commands, enforcement.
1617

18+
### Integration Tests (Mandatory)
19+
20+
- [tests/integration/AGENTS.md](integration/AGENTS.md) — Agent index for integration tests: harnesses, layer boundaries, canonical skill, run commands, enforcement.
21+
1722
### E2E Tests (Detox smoke/regression + Appium smoke)
1823

1924
- [docs/testing/e2e-testing.md](../docs/testing/e2e-testing.md) — Canonical guide: patterns, Page Objects, assertions, gestures, prohibited patterns.
@@ -31,6 +36,7 @@ Single agent index for **tests/**, and **wdio/**. Pointers only; details live in
3136
- [tests/docs/analytics-e2e.md](docs/analytics-e2e.md) — MetaMetrics E2E: `analyticsExpectations` on `withFixtures`, presets, `runAnalyticsExpectations`.
3237
- [tests/docs/CONTROLLER_MOCKING.md](docs/CONTROLLER_MOCKING.md) — Controller mocking.
3338
- [tests/docs/MODULE_MOCKING.md](docs/MODULE_MOCKING.md) — Module mocking.
39+
- [tests/integration/AGENTS.md](integration/AGENTS.md) — Integration test harnesses and rules.
3440
- [tests/framework/index.ts](framework/index.ts) — Assertions, Gestures, Matchers, Utilities, PlaywrightAdapter.
3541
- [tests/framework/fixtures/FixtureHelper.ts](framework/fixtures/FixtureHelper.ts), [FixtureBuilder.ts](framework/fixtures/FixtureBuilder.ts) — Fixtures.
3642
- [AGENTS.md](../AGENTS.md) — Root index; commands, architecture.
@@ -43,4 +49,5 @@ Unit tests under `tests/` (e.g. framework tests): [docs/testing/unit-testing.md]
4349
- **tests/** — Use `withFixtures` + `FixtureBuilder`; Page Object methods only; no `TestHelpers.delay()`; selectors in `tests/selectors/` or page folder; import from `tests/framework/index.ts`. Detox commands: [docs/readme/e2e-testing.md](../docs/readme/e2e-testing.md). Appium smoke: [docs/testing/appium-smoke-testing.md](../docs/testing/appium-smoke-testing.md).
4450
- **tests/** — Framework/mocking: read tests/docs/README and MOCKING; keep exports in `tests/framework/index.ts`. Regression/smoke: same as e2e (withFixtures, Page Objects, no delay). Yarn only.
4551
- **component view tests** — No fake timers (`jest.useFakeTimers` / `advanceTimersByTime`); use `waitFor` or real delays. See [docs/testing/component-view-tests.md](../docs/testing/component-view-tests.md).
52+
- **integration tests** — Use `tests/integration/harnesses/<domain>.ts`; no test-local `jest.mock(...)`; run with `yarn jest -c jest.config.integration.js`. See [tests/integration/AGENTS.md](integration/AGENTS.md).
4653
- **wdio/** — Do not extend. New work: Detox + tests/smoke|regression or Appwright (`tests/`). If maintaining: legacy section in [docs/readme/e2e-testing.md](../docs/readme/e2e-testing.md).

tests/integration/AGENTS.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Agent index for **integration tests** (`app/**/*.integration.test.ts`). Jest tes
66

77
## Scope
88

9-
- **integration tests**`app/**/*.integration.test.ts`. Tests that instantiate real controllers / providers / services and only mock the I/O boundary (SDK clients, network, native modules, keyring, websocket subscriptions). Targeted at the bug class that today only e2e catches: bugs at the seam between controller behaviour and the app, where each piece works in isolation. Consume the [framework](#framework) (per-domain harnesses, dedicated jest config).
9+
- **integration tests**`app/**/*.integration.test.ts`. Tests that instantiate real controllers / providers / services and only mock the I/O boundary (SDK clients, network, native modules, keyring, websocket subscriptions). Shape B/C harnesses may also mock explicitly documented app-shell glue (Engine shim, navigation/runtime providers) when the real target chain still runs. Targeted at the bug class that today only e2e catches: bugs at the seam between controller behaviour and the app, where each piece works in isolation. Consume the [framework](#framework) (per-domain harnesses, dedicated jest config).
1010

1111
---
1212

@@ -43,7 +43,7 @@ The integration test framework is the code and conventions in `tests/integration
4343
- **Convention** — test files import the harness; the import side effect triggers the jest.mock hoisting; the named import is the factory. No setup boilerplate per test.
4444
- **Dedicated jest config**`jest.config.integration.js` runs the suite. Tests are matched by `*.integration.test.ts?(x)`.
4545

46-
Tests **must** follow the rules below: real controller code is exercised; only the I/O boundary is mocked; tests assert on observable outcomes (state, selector output, return values) and not on mock calls except where verifying a side effect is the point of the test.
46+
Tests **must** follow the rules below: real controller code is exercised; only the I/O boundary is mocked; tests assert on observable outcomes (state, selector output, return values) and not on mock calls except where verifying a side effect is the point of the test. The only allowed extra mocks are harness-owned, documented app-shell shims in Shape B/C; test files still never add their own `jest.mock(...)`.
4747

4848
### Framework structure {#framework-structure}
4949

@@ -75,7 +75,9 @@ When the harness pattern doesn't fit a particular flow, that's a signal to **ext
7575

7676
### Mocks {#framework-mocks}
7777

78-
The harness mocks the I/O boundary. For perps that means `HyperLiquidClientService`, `HyperLiquidWalletService`, `HyperLiquidSubscriptionService`, `TradingReadinessCache`, `PerpsStreamManager`, and the `hyperLiquidValidation` utility module. The class methods on `HyperLiquidProvider` itself (including `validateOrder`) are NOT mocked — that's where production bugs live.
78+
The harness mocks the I/O boundary. For perps Shape A that means `HyperLiquidClientService`, `HyperLiquidWalletService`, `HyperLiquidSubscriptionService`, `TradingReadinessCache`, the injected `streamManager` platform dependency, and the `hyperLiquidValidation` utility module. The class methods on `HyperLiquidProvider` itself (including `validateOrder`) are NOT mocked — that's where production bugs live.
79+
80+
Shape B/C add harness-owned app-shell mocks so hooks and rendered components can mount: an `Engine.context.PerpsController` shim, network-management hook shim, native runtime shims, and confirmation/pay plumbing that is outside the perps trading chain. These mocks must stay in the harness and must be listed in the harness REAL/MOCKED header.
7981

8082
No `jest.mock` calls beyond what the harness declares are allowed in `*.integration.test.ts` files. If a test seems to need one, the right move is to extend the harness, not bypass it.
8183

@@ -86,7 +88,7 @@ No `jest.mock` calls beyond what the harness declares are allowed in `*.integrat
8688
### Perps — [`harnesses/perps.ts`](harnesses/perps.ts)
8789

8890
- **Real:** `HyperLiquidProvider` (mobile), all of its order / close / validation logic, asset-map lookups, in-memory state transitions
89-
- **Mocked:** `HyperLiquidClientService`, `HyperLiquidWalletService`, `HyperLiquidSubscriptionService`, `TradingReadinessCache`, `PerpsStreamManager`, `hyperLiquidValidation` utility module
91+
- **Mocked:** `HyperLiquidClientService`, `HyperLiquidWalletService`, `HyperLiquidSubscriptionService`, `TradingReadinessCache`, injected `streamManager` platform dependency, `hyperLiquidValidation` utility module
9092
- **Factory:** `buildPerpsIntegrationHarness({ isTestnet?, assetMapping?, cachedPrices? })`
9193
- **Returns:** `{ provider, setCachedPrice, mocks: { client, wallet, subscription } }`
9294
- **Use cases the harness covers:** see [`perps-use-cases.md`](perps-use-cases.md) for the full enumeration

0 commit comments

Comments
 (0)