Skip to content

Commit 98d77dc

Browse files
committed
Merge remote-tracking branch 'origin/main' into matt/be-7192-linear-toggle-resolve-flag
# Conflicts: # src/composables/useFeatureFlags.test.ts
2 parents c973fe3 + 38b07da commit 98d77dc

470 files changed

Lines changed: 18536 additions & 4249 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.

.agents/setup

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ cd "$repo_root"
66

77
if [[ "${AMP_ORB:-}" == 1 ]]; then
88
gh auth setup-git
9+
10+
if ! command -v docker >/dev/null 2>&1 ||
11+
! command -v dockerd >/dev/null 2>&1; then
12+
echo "Installing Docker"
13+
sudo install -m 0755 -d /etc/apt/keyrings
14+
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
15+
-o /etc/apt/keyrings/docker.asc
16+
sudo chmod a+r /etc/apt/keyrings/docker.asc
17+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
18+
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
19+
sudo apt-get update
20+
sudo apt-get install -y \
21+
docker-ce \
22+
docker-ce-cli \
23+
containerd.io \
24+
docker-buildx-plugin \
25+
docker-compose-plugin
26+
fi
927
fi
1028

1129
node_major="$(tr -d '[:space:]' < "$repo_root/.nvmrc")"
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
name: consolidating-test-setup
3+
description: Consolidates repeated test setup and teardown into the narrowest shared lifecycle owner. Use when test files repeat initialization, cleanup, environment management, fixtures, or equivalent test doubles.
4+
---
5+
6+
# Consolidating test setup
7+
8+
Move repeated test plumbing to the narrowest shared owner that can provide it
9+
reliably. Keep test files focused on behavior.
10+
11+
## Principles
12+
13+
### Prove the code is equivalent
14+
15+
Repetition is evidence, not proof. Similar code may use different defaults,
16+
ordering, or lifetimes. Group candidates by behavior before treating them as
17+
duplicates.
18+
19+
### Centralize invariants, not scenarios
20+
21+
Shared setup should establish conditions that hold for every test in its scope.
22+
State that explains one scenario belongs with that scenario.
23+
24+
### Use the narrowest owner
25+
26+
Prefer the mechanism that already owns the lifecycle. Use runner configuration
27+
before hooks, scoped fixtures before global setup, and local setup for local
28+
requirements. Wider reuse is not better reuse.
29+
30+
### Treat setup and teardown as one contract
31+
32+
Define who creates state, how long it lives, and who releases it. Cleanup must
33+
finish even when a test fails. Tests must not depend on execution order or on
34+
another test's cleanup.
35+
36+
A shared default should be deterministic and easy to override. Local exceptions
37+
must not weaken isolation elsewhere.
38+
39+
### Subtract before abstracting
40+
41+
Remove suspected cargo-cult setup and run the affected tests. A targeted pass
42+
only marks it provisionally unnecessary. Delete it after the complete relevant
43+
suite and runner-specific lifecycle checks pass. If a test fails, use the
44+
failure to identify the contract before designing shared setup.
45+
46+
A helper must own a policy or lifecycle, or remove meaningful reader effort.
47+
Moving the same lines behind a new name is not an improvement.
48+
49+
### Preserve test intent
50+
51+
Do not hide state that matters to the behavior under test. Check history before
52+
removing synchronization or cleanup because it may guard a past regression.
53+
Preserve that guarantee even if the implementation changes.
54+
55+
## Runner-specific guidance
56+
57+
Load only the reference for the runner in use:
58+
59+
- [`reference/vitest.md`](reference/vitest.md) for Vitest and similar
60+
in-process unit-test runners
61+
- [`reference/playwright.md`](reference/playwright.md) for Playwright and
62+
similar browser-test runners
63+
64+
These references supplement the repository's testing guide. They do not replace
65+
it. Load both only when the task spans both runners.
66+
67+
## Workflow
68+
69+
### 1. Discover
70+
71+
Read the runner configuration, setup files, fixtures, helpers, and test guidance.
72+
Count repeated lifecycle behavior and note the suites that use it.
73+
74+
### 2. Classify
75+
76+
For each candidate, record:
77+
78+
- the state it owns
79+
- its lifetime and scope
80+
- whether it is an invariant or scenario detail
81+
- intentional differences between suites
82+
- behavior already supplied by the runner
83+
84+
### 3. Challenge
85+
86+
Remove the candidate and run every affected suite. Classify it as unnecessary,
87+
universal, common with exceptions, or suite-specific.
88+
89+
Subagents may evaluate disjoint groups of suites. Require evidence and exception
90+
reports from each. Keep the design and integration decision in the parent task.
91+
92+
### 4. Place
93+
94+
Choose the required lifetime and scope first. Then use the simplest owner at
95+
that exact boundary:
96+
97+
- native runner behavior that supports the required scope
98+
- existing shared setup, fixture, or hook
99+
- a focused helper or test double
100+
- the individual suite
101+
102+
Do not move state to a broader owner because its mechanism appears earlier in
103+
the list.
104+
105+
### 5. Migrate
106+
107+
Move one responsibility at a time. Add the shared owner, then remove only the
108+
local code it replaces. Keep intentional exceptions and scenario setup visible.
109+
Avoid unrelated test rewrites.
110+
111+
### 6. Prove
112+
113+
Run affected tests, tests of the shared lifecycle, repository static checks, and
114+
the complete relevant suite. Measure before and after when the new behavior runs
115+
for every test. Use enough comparable samples to separate a real change from
116+
normal variance.
117+
118+
## Report
119+
120+
State the repeated contract, its new owner, retained exceptions, rejected
121+
alternatives, duplication removed, and validation results. Include performance
122+
evidence when shared setup could affect suite runtime.
123+
124+
## Guardrails
125+
126+
- Do not replace native runner behavior with a custom abstraction.
127+
- Do not widen setup scope without evidence.
128+
- Do not add a helper merely to move code.
129+
- Do not hide global mutable state behind helper indirection.
130+
- Do not trade visible test intent for shorter files.
131+
- Do not trust targeted tests alone after changing shared lifecycle behavior.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Playwright setup consolidation
2+
3+
Use this reference for Playwright and similar browser-test runners.
4+
5+
## Read first
6+
7+
Read the Playwright configuration, global setup and teardown, affected fixtures,
8+
and canonical browser-test guidance. In this repository, inspect:
9+
10+
- `playwright.config.ts`
11+
- `browser_tests/globalSetup.ts` and `browser_tests/globalTeardown.ts`
12+
- the fixtures used by the affected specs
13+
- `docs/guidance/playwright.md`
14+
- `.agents/checks/playwright-e2e.md`
15+
- `browser_tests/README.md`
16+
17+
Read fixture code directly. Do not guess its setup order or cleanup guarantees.
18+
19+
## Map the lifetime
20+
21+
Browser tests span the run, worker, browser context, page, application session,
22+
and external services. Put state at the narrowest boundary that matches its real
23+
lifetime.
24+
25+
Reserve run-wide hooks for run-wide resources. Worker fixtures must own isolated
26+
worker resources. Keep mutable test state test-scoped unless broader ownership
27+
is proven safe under parallel execution.
28+
29+
## Give fixtures full ownership
30+
31+
Use composable fixtures for resources that need setup and teardown. The fixture
32+
that creates or mutates a resource must restore or release it after the handoff,
33+
including when the test fails.
34+
35+
Keep roles separate:
36+
37+
- fixtures own lifecycle and resources
38+
- page objects own locators and interactions for one UI area
39+
- helpers coordinate domain actions
40+
- data fixtures contain data, not runner behavior
41+
42+
Compose fixtures instead of growing a central page object or adding unrelated
43+
global hooks.
44+
45+
## Preserve ordering
46+
47+
Install configuration, request interception, identity, and initial state before
48+
the navigation that consumes them. Resolving a high-level fixture may navigate
49+
before a hook body runs. Read the dependency graph and use fixture options or a
50+
lower-level dependency for pre-navigation setup.
51+
52+
Do not boot the application and then repair state that should have existed at
53+
startup.
54+
55+
## Account for external state
56+
57+
Assume parallel execution and fresh workers on retry. Resource identities must
58+
not collide. Cleanup must affect only resources owned by that test or worker.
59+
60+
Resetting a page or context does not clean backend state or other external
61+
resources. Define the complete boundary. Use opt-in cleanup when a universal
62+
reset would erase persistence that a test needs to verify.
63+
64+
Retries expose pollution and readiness problems; they do not solve them.
65+
66+
## Preserve readiness guarantees
67+
68+
A fixture should hand control to the test only after observable readiness. Do
69+
not centralize arbitrary delays or timing assumptions that belong to one suite.
70+
71+
Check history before removing waits, resets, or teardown. Preserve any race or
72+
regression guarantee.
73+
74+
## Migrate and prove
75+
76+
For one lifecycle responsibility at a time:
77+
78+
1. Map fixture dependencies and external resources.
79+
2. Identify setup required before navigation.
80+
3. Test whether repeated local setup is necessary.
81+
4. Choose test, worker, or run scope from the resource lifetime.
82+
5. Put guaranteed cleanup in the owning fixture.
83+
6. Keep opt-outs for tests that depend on retained state.
84+
85+
Run affected specs first. Repeat them and exercise parallel execution when
86+
pollution or timing is plausible. Verify failure cleanup for external resources.
87+
Then run the complete relevant browser suite and static checks. Inspect flaky or
88+
retried outcomes instead of relying on the final green status.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Vitest setup consolidation
2+
3+
Use this reference for Vitest and similar in-process unit-test runners.
4+
5+
## Read first
6+
7+
Read the active Vitest configuration, its full `setupFiles` chain, package-level
8+
overrides, and the repository's unit-test guidance. In this repository, inspect:
9+
10+
- `vite.config.mts`
11+
- `vitest.setup.ts` and `vitest.timer.setup.ts`
12+
- package-level Vitest configuration and setup
13+
- `docs/guidance/vitest.md`
14+
- `docs/testing/vitest-patterns.md`
15+
16+
Check behavior against the installed Vitest version. Defaults change, and setup
17+
files compose.
18+
19+
## Place the responsibility
20+
21+
Use native configuration for lifecycle behavior Vitest already supports. Use a
22+
setup file only for invariants configuration cannot express. Keep package-only
23+
behavior out of repository-wide setup.
24+
25+
Separate runner-managed resets, fresh mutable state, process-wide modes that
26+
need restoration, and scenario state that must remain local. Add hooks only for
27+
the part of the contract Vitest does not already own.
28+
29+
A global default must fit every test in scope. Find the common behavior from the
30+
tests, then preserve deliberate opt-outs. When choosing a deterministic
31+
baseline, keep absolute values local when the value itself is under test.
32+
33+
## Handle mocks carefully
34+
35+
Runner-level reset and restoration can change module-scope test doubles. Check
36+
whether their default implementations survive and whether tests reprogram them
37+
during a scenario.
38+
39+
Share a module mock only when it reduces reader effort and preserves behavior.
40+
Keep assertion handles explicit. Test module re-evaluation because it can replace
41+
shared mock state while a test still holds the old identity.
42+
43+
Keep test-specific `vi.mock` calls in the test module. A call inside an imported
44+
helper is not hoisted ahead of that test module's static imports. For shared
45+
implementations, use `__mocks__` with a local `vi.mock`. For runtime selection,
46+
call `vi.doMock` before a subsequent dynamic import.
47+
48+
Check whether a setup file imports the mock target, directly or transitively.
49+
Vitest cannot replace that cached module. Prefer removing the setup import. If it
50+
is unavoidable, call `vi.resetModules()` inside `vi.hoisted` before the test
51+
imports the target, and account for setup and test code holding different module
52+
instances.
53+
54+
Skip the extraction if typed shared code is no simpler than the local mocks or
55+
needs global mutable indirection.
56+
57+
## Migrate
58+
59+
Work on one lifecycle responsibility at a time:
60+
61+
1. Count and classify local occurrences.
62+
2. Remove them without adding a replacement.
63+
3. Use failures to find the contract and exceptions.
64+
4. Prefer configuration, then the narrowest setup file.
65+
5. Remove only calls the new owner makes redundant.
66+
6. Keep mid-test resets and scenario state local.
67+
68+
Subagents may check independent suites, but each must report observed necessity
69+
and exceptions.
70+
71+
## Prove
72+
73+
Run affected files, setup-contract tests, static checks, and the complete unit
74+
suite. Shared process state can fail only when unrelated suites run together.
75+
76+
Profile changes that execute for every test. Compare several equivalent runs and
77+
report variance instead of treating normal noise as a result.

0 commit comments

Comments
 (0)