dequelabs / dequelabs/axe-core
False positive: p-as-heading fires on <p role="heading" aria-level="n">
- Dominant language
- JavaScript
- Stars
- 7.5k
- Forks
- 933
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 17
Description
### Product
axe-core
### Product Version
4.12.1
### Latest Version
- [x] I have tested the issue with the latest version of the product
### Issue Description
#### Expectation
p-as-heading should not report a violation for a `
` element that carries an explicit role="heading" with aria-level. Such an element is exposed as a heading in the accessibility tree, and the pattern is [ARIA12](https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA12), a documented sufficient technique for SC 1.3.1. The element should not be matched by the rule at all (expected outcome: inapplicable).
#### Actual
The element is reported as a serious violation — `"Heading elements should be used instead of styled
elements"` — regardless of the role or aria-level present on it.
#### How to Reproduce
```html
Section title
Body copy that follows the heading.
```
```js
axe.run('#root', { runOnly: ['p-as-heading'] })
.then(results => console.log(results.violations));
```
Result: one violation, `target #root > p:nth-child(1)`.
#### Additional context
lib/rules/p-as-heading-matches.js checks only three things — non-empty text, fewer than two sentence terminators, and the presence of a following non-empty `
` sibling. Neither the matches function nor p-as-heading-evaluate calls getRole / getExplicitRole, so an explicit role="heading" can never exclude the element. Evaluation then proceeds purely on computed style (weight / italic / size ratio against the next paragraph).
Contributor guide
Research direction
Start with lib/rules/p-as-heading-matches.js and the p-as-heading-evaluate logic described in the issue; review how explicit roles are obtained elsewhere in the rule set. Verify the reproduced HTML with axe.run using the p-as-heading rule, then add coverage for p[role="heading"][aria-level] and confirm it is reported as inapplicable while the following paragraph case remains covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- accessibility, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100