review-tests
ChromeDevTools/devtools-frontend/.agents/skills/review-tests/SKILL.md
Reviews Chrome DevTools frontend changes in target directories (\.test\.ts$, ^test/, ^front_end/testing/), strictly reflecting review standards, architectural invariants, and security boundaries derived from historical code reviews.
What's in it
- Chrome DevTools frontend reviewer skill: tests
- Path group tests (9 rules)
- TESTSHAREDFIXTUREANDHELPERREUSE: Reuse canonical frontend/testing helpers and beforeEach setup without mutating cached s
- TESTMODULARHOOKSANDTESTUNIVERSE: Use lightweight modular setup hooks and TestUniverse instead of heavyweight describeWit
- TESTDETERMINISTICASYNCSYNCHRONIZATION: Synchronize asynchronous test assertions using lifecycle promises, expectCall, or
- TESTSTRICTASSERTIONSANDLITERALEXPECTATIONS: Use strict Chai and Sinon assertions against literal expected values rather
- TESTVIEWANDPRESENTERISOLATION: Test presenters via createViewFunctionStub and test pure view functions directly without
- TESTPUBLICAPIANDENCAPSULATION: Exercise classes through public APIs and constructor-injected dependencies rather than ac
- TESTSINGLERESPONSIBILITYANDCONCISENESS: Keep each it() block focused on a single behavior and prune duplicate or obsolet
- TESTTYPESAFEMOCKSANDEVENTS: Construct typed stubs and real DOM or event instances instead of casting fake objects with a
- TESTCLEANUPMUTATEDGLOBALSANDWIDGETS: Restore mutated global properties and detach manually instantiated widgets or singl
---
name: review-tests
description: >-
Reviews Chrome DevTools frontend changes in target directories (\.test\.ts$, ^test/, ^front_end/testing/),
strictly reflecting review standards, architectural invariants, and security boundaries
derived from historical code reviews.
---
# Chrome DevTools frontend reviewer skill: tests
This skill provides review guidance for Chrome DevTools frontend changes matching the target directories (\.test\.ts$, ^test/, ^front_end/testing/). It focuses specifically on code review verification for test changes, complementing authoring guidance in `devtools-testing-guidance` and integrating with the general review checklist in `code-review`. Every rule below recurred in at least 5 CLs from 2 distinct reviewers in historical reviews; cite the rule id in findings.
## Path group `tests` (9 rules)
### `TEST_SHARED_FIXTURE_AND_HELPER_REUSE`: Reuse canonical front_end/testing helpers and beforeEach setup without mutating cached shared fixtures
- **Severity**: WARNING
- **Why**: Duplicating mock factories (`createTarget`, `createNetworkRequest`, `mockAidaClient`, `cleanTextContent`) or mutating cached objects returned by `TraceLoader` causes cross-test state corruption and maintenance drift across the test suite.
- **Look for**: Custom inline network request or AIDA client mocks in `.test.ts` files, in-place mutation of `parsedTrace` objects returned by `TraceLoader`, or manual `div` container creation around `renderElementIntoDOM(widget)`.
- **Do not flag**: Specialized test helpers inside `front_end/testing/` that define the canonical factory implementations themselves.
### `TEST_MODULAR_HOOKS_AND_TEST_UNIVERSE`: Use lightweight modular setup hooks and TestUniverse instead of heavyweight describeWithEnvironment wrappers
- **Severity**: WARNING
- **Why**: Wrapping unit tests in `describeWithEnvironment` initializes all DevTools global singletons and settings, slowing down tests and hiding implicit global dependencies. Tests should use `TestUniverse` or granular hooks (`setupLocaleHooks()`, `setupSettingsHooks()`, `updateHostConfig()`) and never mix `TestUniverse` with `describeWithEnvironment`.
- **Look for**: `describeWithEnvironment` in unit tests that only need locale, settings, or `TestUniverse`, or suites combining `new TestUniverse()` with `describeWithEnvironment`, or direct mutation of `Root.Runtime.hostConfig` instead of `updateHostConfig(...)`.
- **Do not flag**: Integration-style panel tests that exercise legacy singleton classes not yet migrated to `Universe` dependency injection.
### `TEST_DETERMINISTIC_ASYNC_SYNCHRONIZATION`: Synchronize asynchronous test assertions using lifecycle promises, expectCall, or raf instead of arbitrary setTimeout delays
- **Severity**: ERROR
- **Why**: Waiting on wall-clock `setTimeout` delays or arbitrary microtask ticks makes unit tests slow and flaky under CPU contention on CI bots. Tests should await explicit widget update promises (`await widget.updateComplete`), event promises (`target.once(...)`), stub invocation helpers (`expectCall(stub)`), or `raf()`.
- **Look for**: `new Promise(r => setTimeout(r, ...))` in `.test.ts` files, synchronous DOM assertions immediately after `requestUpdate()`, or redundant `clock.tick()` calls when no fake timers are pending.
- **Do not flag**: Tests specifically verifying debounce/throttle timer expiration using `sinon.useFakeTimers()`.
### `TEST_STRICT_ASSERTIONS_AND_LITERAL_EXPECTATIONS`: Use strict Chai and Sinon assertions against literal expected values rather than assert.isNotNull on undefined-unions or conditional guards
- **Severity**: ERROR
- **Why**: Calling `assert.isNotNull(x)` on a value typed as `T | undefined` passes when `x` is `undefined`, silently skipping assertions. Similarly, wrapping assertions inside `if (el)` or computing expected values by calling the same production helper under test allows broken code to pass.
- **Look for**: `assert.isNotNull(...)` on `container?.querySelector` / `Map.get` / `Array.find` / optional properties, `if (el) { assert... }` blocks, `assert.isTrue(spy.called)` instead of `sinon.assert.calledWith`, or assertions comparing output against production formatting helpers.
- **Do not flag**: Variables whose static return type is strictly `T | null` (and never `undefined`).
### `TEST_VIEW_AND_PRESENTER_ISOLATION`: Test presenters via createViewFunctionStub and test pure view functions directly without piercing internal DOM structures
- **Severity**: WARNING
- **Why**: In DevTools' MVP (`UI.Widget` + `DEFAULT_VIEW`) architecture, presenter tests should follow the view stubbing conventions documented in [`docs/ui_engineering.md`](../../../docs/ui_engineering.md) by stubbing the view function with `createViewFunctionStub(Presenter)` and asserting on `await view.nextInput`, while view rendering tests should invoke `DEFAULT_VIEW(input, output, target)` directly or use screenshot assertions.
- **Look for**: Presenter tests instantiating full DOM trees and querying shadow/child DOM selectors to simulate clicks when the widget accepts a `view` function, or view tests instantiating full presenters just to test template markup.
- **Do not flag**: Legacy widgets that have not yet separated their template rendering into a standalone `DEFAULT_VIEW` function.
### `TEST_PUBLIC_API_AND_ENCAPSULATION`: Exercise classes through public APIs and constructor-injected dependencies rather than accessing private members or stubbing unused singletons
- **Severity**: WARNING
- **Why**: Accessing `#private` or `private` methods via `(instance as any)` or `@ts-expect-error`, piercing child component shadow roots, or stubbing `Class.instance()` when dependencies are already passed via constructor couples tests to internal implementation details.
- **Look for**: `@ts-expect-error` or `(obj as any).privateMethod()` calls in `.test.ts` files, `sinon.stub(Class, 'instance')` alongside `new UnderTest(mockInstance)`, or `child.shadowRoot.querySelector(...)` inside parent component tests.
- **Do not flag**: Intentional negative type tests documented with an explanatory `@ts-expect-error` comment.
### `TEST_SINGLE_RESPONSIBILITY_AND_CONCISENESS`: Keep each it() block focused on a single behavior and prune duplicate or obsolete tests when features change
- **Severity**: WARNING
- **Why**: Combining multiple independent user interactions or feature scenarios into a single monolithic `it()` block obscures failure root causes, while leaving duplicate or orphaned tests behind increases suite runtime and maintenance burden.
- **Look for**: `it('... and ...')` blocks testing multiple orthogonal interactions sequentially, nested `{ ... }` scope blocks inside a single `it()`, or identical test cases duplicated across `describe` blocks.
- **Do not flag**: Multi-step stateful workflow tests where earlier steps are required preconditions to reach the state under test.
### `TEST_TYPE_SAFE_MOCKS_AND_EVENTS`: Construct typed stubs and real DOM or event instances instead of casting fake objects with as unknown as
- **Severity**: WARNING
- **Why**: Casting partial object literals via `as unknown as T` or `as any` bypasses TypeScript compile-time checks, masks missing methods when interfaces evolve, and causes brittle runtime failures. Using `sinon.createStubInstance(Class)`, real DOM/Event constructors (`DataTransfer`, `ClipboardEvent`), or typed fixture helpers preserves type safety.
- **Look for**: `as unknown as` or `as any` casts on mock objects, fake DOM nodes, or synthetic events in `.test.ts` files, or untyped `querySelector(...) as HTMLElement` calls.
- **Do not flag**: Tests explicitly verifying runtime handling of malformed untrusted payloads or narrow generic type parameters inside shared `front_end/testing/` helpers.
### `TEST_CLEANUP_MUTATED_GLOBALS_AND_WIDGETS`: Restore mutated global properties and detach manually instantiated widgets or singletons in afterEach or finally blocks
- **Severity**: WARNING
- **Why**: While Sinon stubs are restored automatically, direct mutations to `window`, `globalThis`, prototypes, or `localStorage`, as well as widgets and panels instantiated with `.markAsRoot()` or `show()`, persist across tests and leak listeners unless explicitly cleaned up in `afterEach` or `try...finally`.
- **Look for**: Direct assignments to `window.*`, `globalThis.*`, `Object.prototype.*`, `localStorage.*`, or `panel.show(document.body)` in `.test.ts` files without a matching restoration or `detach()` in `afterEach` or `finally`.
- **Do not flag**: Widgets mounted directly via `renderElementIntoDOM(widget)`, which detaches widgets automatically during global harness teardown.
More agent context in ChromeDevTools/devtools-frontend
21 other files this repository gives its agents.
Skill
- code-review.agents/skills/code-review/SKILL.md
- devtools-imports.agents/skills/devtools-imports/SKILL.md
- devtools-model-management.agents/skills/devtools-model-management/SKILL.md
- devtools-setting-migration.agents/skills/devtools-setting-migration/SKILL.md
- devtools-source-maps.agents/skills/devtools-source-maps/SKILL.md
- devtools-testing-guidance.agents/skills/devtools-testing-guidance/SKILL.md
- devtools-unicode-escaping.agents/skills/devtools-unicode-escaping/SKILL.md
- devtools-verification.agents/skills/devtools-verification/SKILL.md
- fix-tests.agents/skills/fix-tests/SKILL.md
- foundation-test-migration.agents/skills/foundation-test-migration/SKILL.md
- merging-devtools-module.agents/skills/merging-devtools-module/SKILL.md
- migrate-chromium-test.agents/skills/migrate-chromium-test/SKILL.md
- review-models-core.agents/skills/review-models-core/SKILL.md
- review-ui-widgets.agents/skills/review-ui-widgets/SKILL.md
- ui-eng-vision-local-lit-renderer.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md
- ui-eng-vision-logic-consolidator.agents/skills/ui-eng-vision-logic-consolidator/SKILL.md
- ui-eng-vision-orchestrator.agents/skills/ui-eng-vision-orchestrator/SKILL.md
- ui-eng-vision-test-scaffolder.agents/skills/ui-eng-vision-test-scaffolder/SKILL.md
- ui-eng-vision-widget-promoter.agents/skills/ui-eng-vision-widget-promoter/SKILL.md
- devtools-ui-widgets.agents/skills/ui-widgets/SKILL.md
- devtools-version-control.agents/skills/version-control/SKILL.md
Discussion
Evidence it works
Elsewhere, people who say they tested it. Read them for what they measured.
- Feb 2, 2024 · GitHub · microsoft/typescript-benchmarking · Benchmark suggestions
Talked about elsewhere, linking to ChromeDevTools/devtools-frontend
- Chrome: CPU profile parser is fixing n missing samples
Stack Overflow · 4 votes · Dec 26, 2019
- Chrome DevToolsのフロントエンドは、TypeScriptとCSSで書かれていて、ブラウザ上で動く開発者ツール本体のことらしい。ソースコードは公開されていて、カスタマイズや機能追加ができそうだよ。 yug1224 starred…
Bluesky · @yug1224.com · 1 likes and reposts · Sep 28, 2025
- ☂ "Unable to load the page"
GitHub · GoogleChrome/lighthouse · 54 reactions · 46 comments · Jul 28, 2017
- Word wrap in Chrome Dev Tools?
Stack Overflow · 3 votes · Sep 23, 2019
- product_registry_impl_module.js causes 404
GitHub · electron/electron · 4 reactions · 4 comments · May 2, 2018
- Block Specific Request URL in chrome, but URL with sub-directory should pass
Stack Overflow · 2 votes · May 17, 2021
- same console.logs within the same ms are not shown
GitHub · liriliri/chobitsu · 2 reactions · 1 comments · Jan 21, 2025
- debugging chrome remotely - doesn't open websocket
Stack Overflow · 2 votes · Mar 3, 2021
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

