-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
aria_query_handler.rb
74 lines (67 loc) · 2.26 KB
/
aria_query_handler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Puppeteer::AriaQueryHandler
private def normalize(value)
value.gsub(/ +/, ' ').strip
end
# @param selector [String]
private def parse_aria_selector(selector)
known_attributes = %w(name role)
query_options = {}
attribute_regexp = /\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/
default_name = selector.gsub(attribute_regexp) do
attribute = $1.strip
value = $3
unless known_attributes.include?(attribute)
raise ArgumentError.new("Unkown aria attribute \"#{attribute}\" in selector")
end
query_options[attribute.to_sym] = normalize(value)
''
end
if default_name.length > 0
query_options[:name] ||= normalize(default_name)
end
query_options
end
def query_one(element, selector)
context = element.execution_context
parse_result = parse_aria_selector(selector)
res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
if res.empty?
nil
else
context.adopt_backend_node_id(res.first['backendDOMNodeId'])
end
end
def wait_for(dom_world, selector, visible: nil, hidden: nil, timeout: nil, root: nil)
# addHandlerToWorld
binding_function = Puppeteer::DOMWorld::BindingFunction.new(
name: 'ariaQuerySelector',
proc: -> (sel) { query_one(root || dom_world.send(:document), sel) },
)
dom_world.send(:wait_for_selector_in_page,
'(_, selector) => globalThis.ariaQuerySelector(selector)',
selector,
visible: visible,
hidden: hidden,
timeout: timeout,
binding_function: binding_function,
root: root,
)
end
def query_all(element, selector)
context = element.execution_context
parse_result = parse_aria_selector(selector)
res = element.query_ax_tree(accessible_name: parse_result[:name], role: parse_result[:role])
if res.empty?
nil
else
promises = res.map do |ax_node|
context.send(:async_adopt_backend_node_id, ax_node['backendDOMNodeId'])
end
await_all(*promises)
end
end
def query_all_array(element, selector)
element_handles = query_all(element, selector)
element.execution_context.evaluate_handle('(...elements) => elements', *element_handles)
end
end