John Dvorak 066ef9f677 refactor: remove global registry fallbacks — factory pattern for test isolation
predicates.ts: Add populateDefaultPredicates(registry) accepting any
  PredicateRegistry. Add createDefaultPredicateRegistry() factory.
  registerDefaultPredicates() now delegates to populateDefaultPredicates
  on the global (backward compatible).

logic-engine.ts: Replace globalPredicateRegistry fallback with
  createDefaultPredicateRegistry() factory. Each evaluateLogic() call
  creates a fresh self-populated registry unless one is explicitly
  injected. No shared mutable state between evaluations.

engine.ts: Same pattern for clauses — add populateDefaultClauses(registry),
  createDefaultClauseRegistry() factory. registerDefaultClauses() now
  delegates to populateDefaultClauses on the global. evaluate() replaces
  globalClauseRegistry fallback with createDefaultClauseRegistry().

registry.ts: @deprecated tag on registerClause with migration note.

Both global registries remain for backward compatibility via the
  deprecated registerDefault*() functions, but the evaluation engines
  no longer depend on them. Every evaluation gets its own registry by
  default, so custom predicates registered by one test cannot leak
  into another. Tests using explicit registry injection are unaffected.

662 tests pass (315 DSL + 141 core + 149 solver + 57 E2E).
2026-05-22 15:44:44 -07:00

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

S
Description
No description provided
Readme 780 KiB
Languages
TypeScript 93.8%
JavaScript 3.4%
HTML 2.7%