You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/integration-test/SKILL.md
+6-5Lines changed: 6 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ Do not read the full reference files until the decision tree or workflow sends y
49
49
50
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
51
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.
53
53
54
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).
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
75
76
76
77
## Workflow (summary)
77
78
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`.
79
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.
80
81
-**Update after change**: Same as write — review existing tests, update the harness if shape changed, update tests, run and self-review.
81
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.
@@ -116,7 +117,7 @@ For run-by-name, watch mode, or other options, see `references/reference.md` (Ru
116
117
117
118
## Golden Rules (Enforced)
118
119
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.
120
121
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.
| 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 |
119
120
120
121
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.
121
122
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.
Copy file name to clipboardExpand all lines: .agents/skills/integration-test/references/writing-tests.md
+14-2Lines changed: 14 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,11 +49,23 @@ Ask: "What can a user **do** that touches this controller?" — open / close / e
49
49
50
50
Drop anything that only exercises the harness defaults — every test must call at least one real method on the real instance.
51
51
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
53
65
54
66
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.
55
67
56
-
### 5. Run coverage on the file you're exercising and prioritise
68
+
### 6. Run coverage on the file you're exercising and prioritise
57
69
58
70
```bash
59
71
yarn jest -c jest.config.integration.js <test-path> \
-**wdio/** — `wdio/helpers/`, `wdio/screen-objects/`, `wdio/utils/`. Legacy WebdriverIO/Appium — **deprecated**. Use Detox + tests/smoke or Playwright for performance.
11
11
-**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`.
12
13
13
14
### Component-View Tests (Mandatory)
14
15
15
16
-[tests/component-view/AGENTS.md](component-view/AGENTS.md) — Agent index for component view tests: framework, canonical skill, run commands, enforcement.
16
17
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.
@@ -43,4 +49,5 @@ Unit tests under `tests/` (e.g. framework tests): [docs/testing/unit-testing.md]
43
49
-**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).
44
50
-**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.
45
51
-**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).
46
53
-**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).
Copy file name to clipboardExpand all lines: tests/integration/AGENTS.md
+6-4Lines changed: 6 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ Agent index for **integration tests** (`app/**/*.integration.test.ts`). Jest tes
6
6
7
7
## Scope
8
8
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).
10
10
11
11
---
12
12
@@ -43,7 +43,7 @@ The integration test framework is the code and conventions in `tests/integration
43
43
-**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.
44
44
-**Dedicated jest config** — `jest.config.integration.js` runs the suite. Tests are matched by `*.integration.test.ts?(x)`.
45
45
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(...)`.
47
47
48
48
### Framework structure {#framework-structure}
49
49
@@ -75,7 +75,9 @@ When the harness pattern doesn't fit a particular flow, that's a signal to **ext
75
75
76
76
### Mocks {#framework-mocks}
77
77
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.
79
81
80
82
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.
81
83
@@ -86,7 +88,7 @@ No `jest.mock` calls beyond what the harness declares are allowed in `*.integrat
0 commit comments