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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
# frozen_string_literal: true
module Capybara::Poltergeist
class Node < Capybara::Driver::Node
attr_reader :page_id, :id
def initialize(driver, page_id, id)
super(driver, self)
@page_id = page_id
@id = id
end
def browser
driver.browser
end
def command(name, *args)
browser.send(name, page_id, id, *args)
rescue BrowserError => error
case error.name
when 'Poltergeist.ObsoleteNode'
raise ObsoleteNode.new(self, error.response)
when 'Poltergeist.MouseEventFailed'
raise MouseEventFailed.new(self, error.response)
else
raise
end
end
def parents
command(:parents).map { |parent_id| self.class.new(driver, page_id, parent_id) }
end
def find(method, selector)
command(:find_within, method, selector).map { |id| self.class.new(driver, page_id, id) }
end
def find_xpath(selector)
find :xpath, selector
end
def find_css(selector)
find :css, selector
end
def all_text
filter_text command(:all_text)
end
def visible_text
if Capybara::VERSION.to_f < 3.0
filter_text command(:visible_text)
else
command(:visible_text).to_s
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
.gsub(/\n+/, "\n")
.tr("\u00a0", ' ')
end
end
def property(name)
command :property, name
end
def [](name)
# Although the attribute matters, the property is consistent. Return that in
# preference to the attribute for links and images.
if (tag_name == 'img' and name == 'src') or (tag_name == 'a' and name == 'href' )
#if attribute exists get the property
value = command(:attribute, name) && command(:property, name)
return value
end
value = property(name)
value = command(:attribute, name) if value.nil? || value.is_a?(Hash)
value
end
def attributes
command :attributes
end
def value
command :value
end
def set(value, options = {})
warn "Options passed to Node#set but Poltergeist doesn't currently support any - ignoring" unless options.empty?
if tag_name == 'input'
case self[:type]
when 'radio'
click
when 'checkbox'
click if value != checked?
when 'file'
files = value.respond_to?(:to_ary) ? value.to_ary.map(&:to_s) : value.to_s
command :select_file, files
else
command :set, value.to_s
end
elsif tag_name == 'textarea'
command :set, value.to_s
elsif self[:isContentEditable]
command :delete_text
send_keys(value.to_s)
end
end
def select_option
command :select, true
end
def unselect_option
command(:select, false) or
raise(Capybara::UnselectNotAllowed, "Cannot unselect option from single select box.")
end
def tag_name
@tag_name ||= command(:tag_name)
end
def visible?
command :visible?
end
def checked?
self[:checked]
end
def selected?
!!self[:selected]
end
def disabled?
command :disabled?
end
def click(keys=[], offset={})
command :click, keys, offset
end
def right_click(keys=[], offset={})
command :right_click, keys, offset
end
def double_click(keys=[], offset={})
command :double_click, keys, offset
end
def hover
command :hover
end
def drag_to(other)
command :drag, other.id
end
def drag_by(x, y)
command :drag_by, x, y
end
def trigger(event)
command :trigger, event
end
def ==(other)
(page_id == other.page_id) && command(:equals, other.id)
end
def send_keys(*keys)
command :send_keys, keys
end
alias_method :send_key, :send_keys
def path
command :path
end
# @api private
def to_json(*)
JSON.generate as_json
end
# @api private
def as_json(*)
{ ELEMENT: {page_id: @page_id, id: @id} }
end
private
def filter_text(text, visible = true)
if Capybara::VERSION.to_f < 3
Capybara::Helpers.normalize_whitespace(text.to_s)
else
text.gsub(/[\u200b\u200e\u200f]/, '')
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
.tr("\u00a0", ' ')
end
end
end
end
|