Skip to content

axe-core's selectors incorrectly handle the xmlns attribute #4302

@thuey

Description

@thuey

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 = [

Metadata

Metadata

Assignees

No one assigned

    Labels

    ungroomedTicket needs a maintainer to prioritize and label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions