1bc92e1f7dcd01f06e73b99037d01bee647eefe1
CDP protocol fixes:
- session.ts: getDocumentRootNodeId() now pushes {depth:-1} full DOM tree
(was shallow default, causing querySelectorAll to find zero nodes)
- extraction.ts: serialize resolveSelector calls (was concurrent Promise.all,
CDP DOM.querySelectorAll is not safe for concurrent calls on same session)
Topology ID mismatch fixes (critical — backendNodeId vs solver subject ID):
- extraction.ts: add remapTopologyIds() — builds Map<backendNodeId,solverId>
from world.subjects.domNodeId/ids, remaps all 6 topology arrays +
clipping.subjectId + scroll.containerId
- topology.ts: createsStackingContext() now checks contain:paint|layout
(both create stacking contexts per CSS spec, was missing)
- topology.ts: evaluateInStackingContext() handles unary (no reference)
Predicate completeness:
- predicates.ts: 3 new evaluators — intersects, touches, hasGap (indices 31-33)
- predicates.ts: escapeClippingChainOf replaced indeterminate stub with
deterministic 2-ary evaluator (overflow + clip chain + ancestry checks)
- predicates.ts: attachedToScrollContainer arity 1→2, checks reference match
- predicates.ts: 7 aliases + 4 alignment aliases promoted to BUILTIN_PREDICATES
DSL grammar fixes:
- grammar.ts: isKeywordThatCanBePredicate() extended with all missing keywords
- lower-to-canonical.ts: add TopologyAssertion lowering (was silently dropped)
- compiler.ts: add intersects/touches/hasGap relation codes
- validator.ts: add option sets for new predicates
- lexer.ts: add intersects/touches/hasGap token kinds
Safety + infrastructure:
- joins.ts: MAX_CARTESIAN_TUPLES=100,000 guard with descriptive error
- extraction.ts: computeRequiredFacts() registers defaults + broadens topology gate
- package.json: add missing imhotep-state dependency to imhotep-playwright
Tests:
- 9 new predicate tests (intersects, touches, hasGap, escapeClippingChainOf)
- Convert stale separatedFrom/contains GAP tests to working assertions
- Add computeRequiredFacts topology gating tests (public.test.ts)
Imhotep
Declarative, relational UI testing for web applications. Imhotep lets you express spatial, semantic, dimensional, and property-based layout assertions using a fluent API or a dense DSL, then evaluates them through browser geometry extraction and a first-order logic solver.
import { imhotep } from 'imhotep';
const ui = await imhotep(page);
ui.expect('.header').to.be.above('.content', { minGap: 16 });
ui.expect('button').to.be.atLeast('44px').tall;
const result = await ui.checkAll();
// result.passed, result.diagnostics, result.normalizedContracts
Packages
| Package | Purpose |
|---|---|
imhotep |
Meta-package bundling the full public API |
imhotep-core |
Types, AST/IR definitions, diagnostics, contracts, canonical lowering |
imhotep-dsl |
Fluent API, dense DSL parser, FOL compiler, validator |
imhotep-solver |
Constraint solver with directional relations, gap/alignment/size predicates |
imhotep-playwright |
Playwright integration, page wrapping, runtime pooling, property runners |
imhotep-extractor |
DOM/geometry extraction and fact planning |
imhotep-cdp |
Chrome DevTools Protocol session management and DOM queries |
imhotep-reporter |
Diagnostic formatting, failure analysis, replay, shrinking |
imhotep-geometry |
Bounding-box computation, rect algebra, transform math |
imhotep-topology |
Stacking contexts, transform-aware evaluation, formatting contexts |
imhotep-state |
ARIA and native element state materialization |
imhotep-fixtures |
E2E test harness, fixture pages, Playwright test suite |
imhotep-cli |
Scaffolding CLI with framework presets |
imhotep-bench |
Performance benchmarks and profiling tools |
Quick Start (Consumer)
npm install imhotep
npx imhotep init --preset react
npx playwright install chromium
npm test
Available presets: react, vue, storybook, next, nuxt, remix, astro.
Development (Contributor)
npm install
npm run build
npm test
Key commands
npm run lint # ESLint across all packages
npm run typecheck # tsc --noEmit on every workspace
npm run build # Compile all 14 packages in dependency order
npm test # Unit tests across all workspaces
npm run test:e2e # Playwright E2E suite (215 tests)
npm run test:integration # Integration tests (pooling, property runner)
npm run test:external-smoke # Full smoke in a clean temp directory
npm run clean # Remove dist, tsbuildinfo, and generated src artifacts
Targeted runs
npm test -w imhotep-dsl
npm test -w imhotep-playwright
npx playwright test --config packages/imhotep-fixtures/playwright.config.ts
Assertion Styles
Fluent API:
ui.expect('.button').to.be.leftOf('.icon', { minGap: 8 });
ui.expect('.button').to.be.atLeast('44px').tall;
ui.expect.all('.card').to.be.centeredWithin('.container');
Dense DSL:
ui.spec('.button leftOf .icon gap 8px');
ui.spec('all .card centeredWithin .container');
ui.spec('forall $c in .card: $c width >= 200');
Property-based:
const fixture = imhotepFixture('grid.html');
await fixture.forAllProps(page, buttonDomain, async (scene, { width, label }) => {
scene.expect('[data-testid="btn"]').to.be.atLeast(`${width}px`).wide;
});
Diagnostics
Every assertion failure produces structured diagnostics with error codes, measured geometry, expected/observed comparisons, source references, and fix hints. Failing checks never pass silently.
| Category | Prefix |
|---|---|
| Parse | IMH_PARSE_* |
| Validation | IMH_VALID_* |
| Extraction | IMH_EXTRACT_*, IMH_SELECTOR_* |
| Relation | IMH_RELATION_* |
| Size | IMH_SIZE_* |
| Cardinality | IMH_CARDINALITY_* |
| Logic | IMH_LOGIC_* |
Requirements
- Node.js >= 18
- npm >= 9
- Chromium (auto-installed via Playwright)
CDP extraction requires a local Chromium-based browser session. Remote/debugging protocol access is not enabled by default.
License
MIT
Description
Languages
TypeScript
93.8%
JavaScript
3.4%
HTML
2.7%