Module: Dommy::Internal::ElementMatching
- Defined in:
- lib/dommy/internal/element_matching.rb
Overview
Element-type-specific finders for links, forms, selects, and checkable fields. Lives in dommy core so that companion gems (currently dommy-rails) share a single finder implementation instead of re-implementing the selector / filter logic per gem.
Attribute criteria (href:, action:, name:) accept a String
(exact match), a Regexp, or any object responding to matches? —
the extension point dommy-rails uses to inject URL normalization.
Class Method Summary collapse
- .attribute_matches?(element, attr_name, expected) ⇒ Boolean
- .field_label_matches?(field, expected_label) ⇒ Boolean
-
.field_labels(field) ⇒ Object
Labels associated with a field: a
-
.find_checkable_fields(scope, name: nil, checked: nil) ⇒ Object
Find checkable fields (input) matching the given criteria.
-
.find_forms(scope, action: nil, method: nil) ⇒ Object
Find
- .find_links(scope, text: nil, href: nil) ⇒ Object
-
.find_selects(scope, name: nil, label: nil) ⇒ Object
Find
- .form_method_matches?(form, expected_method) ⇒ Boolean
Class Method Details
.attribute_matches?(element, attr_name, expected) ⇒ Boolean
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/dommy/internal/element_matching.rb', line 54 def attribute_matches?(element, attr_name, expected) actual = element.get_attribute(attr_name).to_s case expected when Regexp actual.match?(expected) else if expected.respond_to?(:matches?) expected.matches?(actual) else actual == expected.to_s end end end |
.field_label_matches?(field, expected_label) ⇒ Boolean
95 96 97 |
# File 'lib/dommy/internal/element_matching.rb', line 95 def field_label_matches?(field, expected_label) field_labels(field).any? { |label| DomMatching.text_matches?(label.text_content, expected_label) } end |
.field_labels(field) ⇒ Object
Labels associated with a field: a
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/dommy/internal/element_matching.rb', line 72 def field_labels(field) labels = [] id = field.get_attribute("id").to_s unless id.empty? for_label = field.owner_document.query_selector_all("label").to_a.find do |label| label.get_attribute("for") == id end labels << for_label if for_label end parent = field.parent_node while parent if parent.respond_to?(:tag_name) && parent.tag_name == "LABEL" labels << parent break end parent = parent.respond_to?(:parent_node) ? parent.parent_node : nil end labels end |
.find_checkable_fields(scope, name: nil, checked: nil) ⇒ Object
Find checkable fields (input) matching the given criteria.
46 47 48 49 50 51 52 |
# File 'lib/dommy/internal/element_matching.rb', line 46 def find_checkable_fields(scope, name: nil, checked: nil) fields = scope.query_selector_all("input[type='checkbox'], input[type='radio']").to_a fields = fields.select { |el| attribute_matches?(el, "name", name) } if name fields = fields.select { |el| el.get_attribute("checked") } if checked == true fields = fields.reject { |el| el.get_attribute("checked") } if checked == false fields end |
.find_forms(scope, action: nil, method: nil) ⇒ Object
Find
29 30 31 32 33 34 |
# File 'lib/dommy/internal/element_matching.rb', line 29 def find_forms(scope, action: nil, method: nil) forms = scope.query_selector_all("form").to_a forms = forms.select { |el| attribute_matches?(el, "action", action) } if action forms = forms.select { |el| form_method_matches?(el, method) } if method forms end |
.find_links(scope, text: nil, href: nil) ⇒ Object
19 20 21 22 23 24 |
# File 'lib/dommy/internal/element_matching.rb', line 19 def find_links(scope, text: nil, href: nil) links = scope.query_selector_all("a[href]").to_a links = links.select { |el| DomMatching.text_matches?(el.text_content, text) } if text links = links.select { |el| attribute_matches?(el, "href", href) } if href links end |
.find_selects(scope, name: nil, label: nil) ⇒ Object
Find
37 38 39 40 41 42 |
# File 'lib/dommy/internal/element_matching.rb', line 37 def find_selects(scope, name: nil, label: nil) selects = scope.query_selector_all("select").to_a selects = selects.select { |el| attribute_matches?(el, "name", name) } if name selects = selects.select { |el| field_label_matches?(el, label) } if label selects end |
.form_method_matches?(form, expected_method) ⇒ Boolean
99 100 101 102 103 104 105 106 |
# File 'lib/dommy/internal/element_matching.rb', line 99 def form_method_matches?(form, expected_method) actual_method = form.get_attribute("method").to_s.downcase if actual_method == "post" hidden_method = form.query_selector("input[type='hidden'][name='_method']") actual_method = hidden_method.get_attribute("value").to_s.downcase if hidden_method end actual_method == expected_method.to_s.downcase end |