@idomatic/core
v1.3.0
Published
CLI that injects stable, human-readable id attributes into React/HTML/Vue/Angular elements so Playwright, Cypress and Testing Library tests stop breaking.
Maintainers
Readme
@idomatic/core
Automatically add stable, readable id attributes to your components — so your Playwright, Cypress and Testing Library tests stop breaking.
idomatic is a CLI that scans your React/HTML/Vue/Angular code and injects human-readable, stable test selectors into elements that are missing them. No more brittle CSS/XPath selectors, no more nth-child, no more tests that break when you reorder a <div>.
Why
E2E tests break because they target selectors that were never meant to be stable — classes, text, DOM position. The fix is a dedicated, stable selector on every element you test. Adding those by hand is tedious, so idomatic does it for you — and the ids it generates are readable and deterministic:
// before
<button aria-label="Submit login">Log in</button>
<input name="email" placeholder="Email address" />
// after `npx idomatic scan --write`
<button aria-label="Submit login" id="button-submit-login">Log in</button>
<input name="email" placeholder="Email address" id="input-email" />await page.locator("#button-submit-login").click();Prefer a dedicated test attribute? Set
"attributeName": "data-testid"and idomatic emitsdata-testid="button-submit-login"instead.
Features
- Semantic ids — derived from
aria-label,name,placeholder,alt, text content or tag, not random UUIDs. - Idempotent — re-running never renames or duplicates an existing id; diffs stay clean and it's safe in CI.
- Framework-aware — React (JS/JSX/TS/TSX) via a real AST parser; HTML, Vue and Angular templates too.
- Dry-run first — preview every change before touching a file.
- Configurable — change the attribute name, add a prefix/namespace, exclude tags or files.
Installation
npm init @idomaticThis walks you through picking your framework, installs the right parser, and creates a .idomatic.config.json in your project root.
Usage
npx idomatic scan --dry # preview changes without writing
npx idomatic scan --write # apply changesRunning npx idomatic scan with no flag prints usage.
Configuration
.idomatic.config.json is created during setup:
{
"attributeName": "id",
"idStrategy": "semantic",
"prefix": "",
"excludeTags": ["html", "head", "script"],
"includeExtensions": ["js", "jsx", "ts", "tsx"],
"excludeFiles": ["node_modules", "public"]
}attributeName— the attribute to inject. Defaults toid; set"data-testid"(or"data-test", …) if you prefer a dedicated test attribute.idStrategy—"semantic"(default) for readable ids likebutton-submit, or"random"for${prefix}${uuid}.prefix— optional namespace, e.g."qa-"→qa-button-submit. Leave empty for clean ids.excludeTags— tags to skip.includeExtensions— for HTML/Vue/Angular this is["html", "vue", "ng.html"].excludeFiles— directories to ignore.
How it works
idomatic finds files matching your extensions (respecting .gitignore), then rewrites them through the right parser — @idomatic/parser-js for JS/JSX/TSX (recast + Babel AST) or @idomatic/parser-html for HTML/Vue/Angular (formatting-preserving). An id is added only to elements that don't already have one, using a name derived from context and made unique on collision.
Angular: use
templateUrlwith a separate.htmlfile. idomatic processes external templates but not inline templates defined in.tsfiles.
Contributing
Contributions welcome — open an issue or PR on GitHub.
