John Dvorak 8ac69254d4 feat: fact planning derived from predicate specs with fulfillment tracking
predicate-specs.ts:
  - Add FactCategory enum (geometry, topology, styles, fragments,
    domAncestry, clipping, scroll, visibility, transforms, text)
  - Add FactPlan interface with predicateFacts provenance map and
    per-category fulfillment tracking (fulfilled/failed/approximated/skipped)
  - Add requiredFactToCategory() — centralized mapping from required-fact
    strings to FactCategory values, replacing scattered inline checks
  - Add planRequiredFacts() — builds a complete FactPlan from collected
    predicate facts + AST structural analysis (CssLengthMetrics, domAncestry)
  - Add createEmptyFactPlan() factory

extraction.ts:
  - computeRequiredFacts returns FactPlan (was inline record), uses
    planRequiredFacts from spec infrastructure
  - extractWorld/extractWorldFastGeometry/extractWorldCdp accept FactPlan
    instead of inline requiredFacts record
  - After successful extraction, populate FactPlan.fulfillment with
    per-category 'fulfilled' status, providing a structured audit trail
    of which facts were requested and obtained

Adding a new predicate with new required facts now requires only a
spec entry — the fact planner, extraction engine, and fulfillment
tracker all derive behavior from the spec table automatically.

658 tests pass.
2026-05-22 15:02:20 -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%