|
| 1 | +# axe-core — Claude Code Context |
| 2 | + |
| 3 | +**Last updated:** 2026-03-19 |
| 4 | + |
| 5 | +## 0. Fundamental Standards |
| 6 | + |
| 7 | +- **Formatting:** Run `npm run fmt` (Prettier) and `npm run eslint` before every commit. No exceptions. |
| 8 | +- **Zero-Exception Testing:** 100% coverage goal. Run `npm test` before completion. `feat`/`fix` and other behavior-changing PRs require unit + integration tests where applicable; see `doc/code-submission-guidelines.md` for exceptions (e.g., some `chore`/docs changes). |
| 9 | +- **Import Rule:** Directory-level import restrictions are strictly enforced. See `eslint.config.js`. |
| 10 | +- **Commits:** Angular commit convention is mandatory. PRs with non-conforming commits will be rejected. See `doc/code-submission-guidelines.md`. |
| 11 | +- **Issues:** All unresolved issues tracked in [GitHub Issues](https://github.com/dequelabs/axe-core/issues). |
| 12 | + |
| 13 | +## 1. Technical Guidelines |
| 14 | + |
| 15 | +### Code Structure |
| 16 | + |
| 17 | +- **Return Early:** Keep the happy path left-aligned. Handle errors/edge cases first with early returns — never nest when you can exit. |
| 18 | +- **Exports:** Default export at the top of the file, immediately after imports. |
| 19 | +- **JSDoc:** Add JSDoc/DocBlock comments where appropriate, especially for exported APIs and complex logic. Document parameters and return types. See `doc/code-submission-guidelines.md` (source of truth) and `doc/developer-guide.md` for additional guidance. |
| 20 | +- **Naming:** Files and rule/check IDs in kebab-case. Functions in camelCase. Booleans prefixed `is`/`has`/`should`. Constants in `UPPER_SNAKE_CASE`. |
| 21 | +- **Variables:** Declare at point of use, not at the top of the function. |
| 22 | + |
| 23 | +### Virtual Nodes vs. HTMLElement |
| 24 | + |
| 25 | +- **Prefer Virtual Nodes** for attribute access and property reads (`virtualNode.attr()`, `virtualNode.props`). |
| 26 | +- **Use real DOM** only when you need DOM APIs (e.g., `getBoundingClientRect`, `getRootNode`). |
| 27 | +- **`core/utils/` functions** should default to real DOM inputs/outputs, except utilities that are explicitly documented as operating on `VirtualNode` (for example, tree or selector helpers). Avoid introducing new `VirtualNode`-dependent utilities unless there is a clear performance or API benefit. |
| 28 | +- **Conversion:** Use `getNodeFromTree()` from `core/utils` when you receive an ambiguous input (such as a `VirtualNode`, selector, or mixed type) and need to resolve it to a real DOM `Node`. |
| 29 | + |
| 30 | +### Import Restrictions (Hard Rules) |
| 31 | + |
| 32 | +- `standards/` → nothing (pure data, no imports). |
| 33 | +- `core/utils/` → other `core/utils`, `core/base`, `standards` via **direct file paths only** (no index). |
| 34 | +- `core/imports/` → node modules **only** (the only place npm imports are allowed). |
| 35 | +- `commons/` → other `commons` (direct paths), `core/utils` (index OK). |
| 36 | +- `checks/` and `rules/` → any directory (index OK). |
| 37 | +- **Never** import `commons` from `core/utils`. This is the most commonly rejected violation. |
| 38 | + |
| 39 | +### Checks & Rules |
| 40 | + |
| 41 | +- **Check evaluate functions:** Return `true` (pass), `false` (fail), or `undefined` (incomplete). Use `this.data()` to pass values to message templates and to provide incomplete-result detail. |
| 42 | +- **Rule JSON:** Use `all`, `any`, `none` check arrays. `selector` + optional `matches` to scope candidates. Valid `impact` values: `"minor"`, `"moderate"`, `"serious"`, `"critical"`. |
| 43 | +- **Standards data:** Never hardcode ARIA/HTML lists in checks. Query from `standards/` via `commons/standards` functions. |
| 44 | +- **Messages:** All user-facing strings live in check/rule JSON `metadata.messages`. Use `${data.property}` templates. Support singular/plural variants. Update `locales/_template.json` whenever messages change (auto-synced on `npm run build`). |
| 45 | + |
| 46 | +### High-Risk Areas (Extra Scrutiny Required) |
| 47 | + |
| 48 | +- **Color contrast:** Handles all CSS color formats, opacity, blend modes, stacking contexts, text-shadow. Return `undefined` when background cannot be determined. See `doc/developer-guide.md`. |
| 49 | +- **ARIA validation:** Must stay current with spec. Query roles/attrs from `standards/aria-roles.js` and `standards/aria-attrs.js`. Handle implicit vs. explicit roles. See `doc/rule-development.md`. |
| 50 | +- **Hidden elements:** Use `isVisibleToScreenReaders()`, not CSS visibility alone. Account for `aria-hidden="true"` and Shadow DOM boundaries. |
| 51 | +- **i18n:** Update `locales/_template.json` on every message change and commit the generated file alongside source. |
| 52 | + |
| 53 | +## 2. Testing |
| 54 | + |
| 55 | +- **Structure:** Mirror `lib/` exactly under `test/`. File `lib/commons/text/sanitize.js` → `test/commons/text/sanitize.js`. |
| 56 | +- **Checks:** Use `axe.testUtils.MockCheckContext()`. Only reset `checkContext` in `afterEach` — `fixture` and `axe._tree` are auto-cleared. |
| 57 | +- **Integration tests:** All rule changes require an HTML + JSON pair. Use `test/integration/rules/<rule-name>/` for mocha-hosted tests or `test/integration/full/<rule-name>/` when the rule requires a full HTML page. JSON selectors must use axe array format (`["#id"]`; iframes: `["iframe", "#id"]`). Also update or create virtual-rules tests where appropriate. |
| 58 | +- **Shadow DOM:** Every relevant check/rule must include an open Shadow DOM test case using `queryShadowFixture`. |
| 59 | +- **Logging:** Do not commit `console.log` statements. |
| 60 | + |
| 61 | +## 3. Build & Commits |
| 62 | + |
| 63 | +- **Bundles (`axe.js`, `axe.min.js`)** are auto-generated for releases/publishing and are not committed to the repo (they are gitignored). |
| 64 | +- **Locales template (`locales/_template.json`)** is auto-generated. When message strings change, regenerate this file and commit it in the same commit as the source changes — never in a separate commit. |
| 65 | +- **One change per PR.** Do not mix refactoring with feature work. |
| 66 | +- **Commit format:** `<type>(<scope>): <subject>` — imperative, lowercase, no period, ≤100 chars total. Body explains motivation. Footer: `Closes issue #123` or full URL. See `doc/code-submission-guidelines.md` for the full type list. |
| 67 | + |
| 68 | +**Example:** |
| 69 | + |
| 70 | +``` |
| 71 | +fix(aria-valid-attr-value): handle multiple aria-errormessage IDs |
| 72 | +
|
| 73 | +When aria-errormessage contains multiple space-separated IDs, verify |
| 74 | +all IDs exist in aria-describedby instead of matching the full string. |
| 75 | +
|
| 76 | +Closes issue #4957 |
| 77 | +``` |
| 78 | + |
| 79 | +## 4. Documentation & API Changes |
| 80 | + |
| 81 | +- **New rules:** Update `CHANGELOG.md`. `doc/rule-descriptions.md` is auto-generated by `npm run build`. |
| 82 | +- **API changes:** Update `doc/API.md` and `axe.d.ts` TypeScript definitions. |
| 83 | +- **Breaking changes:** Avoid breaking changes — prefer supporting both old and new formats simultaneously. If unavoidable, add `BREAKING CHANGE: description` to commit footer, include migration guide in `CHANGELOG.md`, and tag deprecated code with `@deprecated` JSDoc. |
| 84 | + |
| 85 | +## 5. Examples (Copy-Paste Reference) |
| 86 | + |
| 87 | +- **Code patterns:** `doc/examples/code-patterns.md` — return early, default export, imports, JSDoc, Virtual Node usage |
| 88 | +- **Test patterns:** `doc/examples/test-patterns.md` — unit tests, check tests, Shadow DOM tests, integration test HTML+JSON |
| 89 | +- **Rule & check templates:** `doc/examples/rule-check-templates.md` — JSON templates for rules and checks, evaluate function pattern |
| 90 | +- **PR review patterns:** `doc/examples/pr-review-patterns.md` — common reviewer feedback, anti-patterns, what reviewers look for |
| 91 | + |
| 92 | +## 6. Reference Docs & Help |
| 93 | + |
| 94 | +- **Contributing guide:** `CONTRIBUTING.md` |
| 95 | +- **Import rules detail:** `eslint.config.js` |
| 96 | +- **Code submission standards:** `doc/code-submission-guidelines.md` |
| 97 | +- **Developer guide:** `doc/developer-guide.md` |
| 98 | +- **Rule development:** `doc/rule-development.md` |
| 99 | +- **API reference:** `doc/API.md` |
| 100 | +- **Pull Request Checklist:** `doc/pull-request-checklist.md` |
| 101 | +- **Slack:** [axe-community](https://accessibility.deque.com/axe-community) |
| 102 | +- **Issues:** [GitHub Issues](https://github.com/dequelabs/axe-core/issues) |
0 commit comments