Module: RSpec::Signal::Symptoms::Selector
- Defined in:
- lib/rspec/signal/symptoms/selector.rb
Overview
A DOM node or piece of page text Capybara could not find.
The same selector missing from four pages is one missing partial, one
renamed data-testid, one component that never mounted. Capybara says
so two different ways depending on whether you used find or
have_css, and those two produce different exception classes and
different messages, so they are correctly different signatures -- but
they are obviously the same symptom.
The selector itself is the cluster key, compared exactly. Two different selectors never meet.
Constant Summary collapse
- TYPES =
"css|xpath|field|link or button|link|button|select box|checkbox|" \ "radio button|file field|fillable field|element|selector|table"
- TARGET =
The selector as Capybara printed it: inspected, or a bare token.
/"(?:[^"\\]|\\.)*"|\S+/.freeze
- VISIBILITY =
"(?:visible |invisible )?"- UNABLE =
find(...)and friends raise Capybara::ElementNotFound. /Unable to find #{VISIBILITY}(?<type>#{TYPES})\s+(?<target>#{TARGET})/i.freeze
- NO_MATCHES =
expect(page).to have_css(...)fails the matcher instead, with a different class and a different sentence for the same missing node. Regexp.new("expected to find #{VISIBILITY}(?<type>#{TYPES})\\s+(?<target>#{TARGET})" \ ".{0,200}?but there were no matches", Regexp::IGNORECASE)
- TEXT =
Page text is not a selector, but it goes missing for the same reasons.
/(?:Unable to find|expected to find) text (?<target>#{TARGET})/i.freeze
Class Method Summary collapse
- .call(_failure, text) ⇒ Object
- .missing_text(text) ⇒ Object
- .safe(target) ⇒ Object
-
.unquote(raw) ⇒ Object
Capybara prints the selector with
inspect, so a[data-testid="x"]arrives with its inner quotes escaped.
Class Method Details
.call(_failure, text) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rspec/signal/symptoms/selector.rb', line 35 def call(_failure, text) match = NO_MATCHES.match(text) || UNABLE.match(text) return missing_text(text) unless match target = unquote(match[:target]) return nil if target.empty? type = match[:type].to_s.downcase Symptom.new(kind: :selector, key: "selector:#{type}:#{target}", label: "missing #{type} selector `#{safe(target)}`", detail: "no match for #{type} #{target}") end |
.missing_text(text) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rspec/signal/symptoms/selector.rb', line 48 def missing_text(text) match = TEXT.match(text) return nil unless match target = unquote(match[:target]) return nil if target.empty? Symptom.new(kind: :missing_text, key: "text:#{target}", label: "missing page text `#{safe(target)}`", detail: "page did not contain \"#{target}\"") end |
.safe(target) ⇒ Object
68 69 70 |
# File 'lib/rspec/signal/symptoms/selector.rb', line 68 def safe(target) target.tr("`", "'") end |
.unquote(raw) ⇒ Object
Capybara prints the selector with inspect, so a [data-testid="x"]
arrives with its inner quotes escaped.
62 63 64 65 66 |
# File 'lib/rspec/signal/symptoms/selector.rb', line 62 def unquote(raw) text = raw.to_s text = text[1..-2].to_s.gsub('\\"', '"').gsub("\\\\", "\\") if text.start_with?('"') text.gsub(/\s+/, " ").strip end |