-
Notifications
You must be signed in to change notification settings - Fork 881
axe-core's selectors incorrectly handle the xmlns attribute #4302
Description
Product
axe-core
Product Version
4.8.1
Latest Version
- I have tested the issue with the latest version of the product
Issue Description
Expectation
The selector produced by axe-core should match an element on the page.
Actual
The selector produced by axe-core does not match an element on the page. This manifests itself in the axe DevTools Extension as being unable to highlight or inspect an element.
How to Reproduce
The underlying problem can be reproduced using this code snippet:
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
<svg xmlns="http://www.w3.org/1999/svg">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
</body>
</html>Using axe-core's utilities to generate a selector results in an unusable selector:
const tree = axe.utils.getFlattenedTree(document)
> undefined
axe._selectorData = axe.commons.utils.getSelectorData(tree)
> {classes: {…}, tags: {…}, attributes: {…}}
axe.commons.utils.getSelector(document.querySelectorAll('circle')[0])
> ':root > circle'
Additional context
I've dug into axe-core, and it looks like the reason why this happens is because similar.length === 0 here. The reason why the list of similar is empty is because the clippath element does not "match" the selector svg[viewBox="0 0 80 80"][fill="none"][xmlns="http://www.w3.org/2000/svg"] > defs > clippath , even though it "should". The problem is with the xmlns attribute selector. If you remove it, the selector works. You can even play around with it with the code snippet I'll post in the thread and using document.querySelectorAll--the browser does not like the xmlns attribute. I was about to post an issue in Chromium, but tried it out in other browsers and realized they all have the same issue. After further digging, it seems that not supporting namespaces is just part of the spec.
A possible solution is to add xmlns to the list of ignored attributes:
| const ignoredAttributes = [ |