207 lines
4.5 KiB
Ruby
207 lines
4.5 KiB
Ruby
# 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') && (name == 'src')) || ((tag_name == 'a') && (name == 'href'))
|
|
# if attribute exists get the property
|
|
return command(:attribute, name) && command(:property, name)
|
|
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) ||
|
|
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)
|
|
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
|