Module: Dommy::Interaction::RoleQuery

Defined in:
lib/dommy/interaction/role_query.rb

Overview

Finds elements by their computed ARIA role (the accessibility-tree counterpart of Testing Library's getByRole). It walks the accessibility tree built for a scope, so the inclusion rules already applied there — aria-hidden and invisible subtrees excluded, presentational/generic nodes flattened — come for free. A node matches by role, optional accessible name (substring by default; exact: true or a Regexp for precision), and optional level.

The single query path is shared by Driver#find_by_role / #all_by_role / #has_role?, the have_role matcher, and assert_dom_has_role.

Class Method Summary collapse

Class Method Details

.available(scope) ⇒ Object

Human-readable "role" / "role "name"" descriptors of every accessible node in scope — the candidates a failed find_by_role lists.



29
30
31
32
33
# File 'lib/dommy/interaction/role_query.rb', line 29

def available(scope)
  nodes = []
  collect(tree_for(scope), nodes)
  nodes.map { |node| node.name.to_s.empty? ? node.role.to_s : "#{node.role} #{node.name.inspect}" }.uniq
end

.collect(node, out) ⇒ Object

Depth-first collect of nodes backed by a real element (skips :text and the synthetic :root).



44
45
46
47
48
49
# File 'lib/dommy/interaction/role_query.rb', line 44

def collect(node, out)
  node.children.each do |child|
    out << child if child.element
    collect(child, out)
  end
end

.match(scope, role:, name: nil, level: nil, exact: false) ⇒ Object

The elements under scope whose accessible node matches, in document order. scope may be an Element/Document (queried directly), a Session (its current document), or anything AccessibilityTree.build accepts.



21
22
23
24
25
# File 'lib/dommy/interaction/role_query.rb', line 21

def match(scope, role:, name: nil, level: nil, exact: false)
  nodes = []
  collect(tree_for(scope), nodes)
  nodes.select { |node| node_matches?(node, role, name, level, exact) }.map(&:element)
end

.node_matches?(node, role, name, level, exact) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
55
# File 'lib/dommy/interaction/role_query.rb', line 51

def node_matches?(node, role, name, level, exact)
  node.role.to_s == role.to_s &&
    (name.nil? || Internal::DomMatching.text_matches?(node.name, name, exact: exact)) &&
    (level.nil? || node.level == level)
end

.tree_for(scope) ⇒ Object



35
36
37
38
39
40
# File 'lib/dommy/interaction/role_query.rb', line 35

def tree_for(scope)
  return scope.accessibility_tree if scope.respond_to?(:accessibility_tree)
  return scope.document.accessibility_tree if scope.respond_to?(:document) && scope.document

  Internal::AccessibilityTree.build(scope)
end