2016-03-08 00:52:19 +00:00
# frozen_string_literal: true
2010-11-21 13:37:36 +00:00
module Capybara
module Node
2010-11-21 13:49:00 +00:00
##
#
# A {Capybara::Node::Simple} is a simpler version of {Capybara::Node::Base} which
# includes only {Capybara::Node::Finders} and {Capybara::Node::Matchers} and does
# not include {Capybara::Node::Actions}. This type of node is returned when
# using {Capybara.string}.
#
# It is useful in that it does not require a session, an application or a driver,
# but can still use Capybara's finders and matchers on any string that contains HTML.
#
2010-11-21 13:37:36 +00:00
class Simple
include Capybara :: Node :: Finders
include Capybara :: Node :: Matchers
2014-02-16 17:13:58 +00:00
include Capybara :: Node :: DocumentMatchers
2010-11-21 13:37:36 +00:00
attr_reader :native
def initialize ( native )
2013-04-29 20:50:14 +00:00
native = Capybara :: HTML ( native ) if native . is_a? ( String )
2010-11-21 13:37:36 +00:00
@native = native
end
2010-11-21 13:49:00 +00:00
##
#
# @return [String] The text of the element
#
2013-02-17 14:45:14 +00:00
def text ( type = nil )
2010-11-21 13:37:36 +00:00
native . text
end
2010-11-21 13:49:00 +00:00
##
#
# Retrieve the given attribute
#
# element[:title] # => HTML title attribute
#
2013-03-29 02:15:07 +00:00
# @param [Symbol] name The attribute name to retrieve
# @return [String] The value of the attribute
2010-11-21 13:49:00 +00:00
#
2010-11-21 13:37:36 +00:00
def [] ( name )
attr_name = name . to_s
if attr_name == 'value'
value
elsif 'input' == tag_name and 'checkbox' == native [ :type ] and 'checked' == attr_name
native [ 'checked' ] == 'checked'
else
native [ attr_name ]
end
end
2010-11-21 13:49:00 +00:00
##
#
# @return [String] The tag name of the element
#
2010-11-21 13:37:36 +00:00
def tag_name
native . node_name
end
2010-11-21 13:49:00 +00:00
##
#
# An XPath expression describing where on the page the element can be found
#
# @return [String] An XPath expression
#
2010-11-21 13:37:36 +00:00
def path
native . path
end
2010-11-21 13:49:00 +00:00
##
#
# @return [String] The value of the form element
#
2010-11-21 13:37:36 +00:00
def value
if tag_name == 'textarea'
2017-01-16 20:39:44 +00:00
native [ '_capybara_raw_value' ]
2010-11-21 13:37:36 +00:00
elsif tag_name == 'select'
if native [ 'multiple' ] == 'multiple'
native . xpath ( " .//option[@selected='selected'] " ) . map { | option | option [ :value ] || option . content }
else
option = native . xpath ( " .//option[@selected='selected'] " ) . first || native . xpath ( " .//option " ) . first
option [ :value ] || option . content if option
end
2013-10-28 22:58:04 +00:00
elsif tag_name == 'input' && %w( radio checkbox ) . include? ( native [ :type ] )
native [ :value ] || 'on'
2010-11-21 13:37:36 +00:00
else
native [ :value ]
end
end
2010-11-21 13:49:00 +00:00
##
#
# Whether or not the element is visible. Does not support CSS, so
# the result may be inaccurate.
#
2014-05-19 18:16:54 +00:00
# @param [Boolean] check_ancestors Whether to inherit visibility from ancestors
2010-11-21 13:49:00 +00:00
# @return [Boolean] Whether the element is visible
#
2014-05-19 18:16:54 +00:00
def visible? ( check_ancestors = true )
2016-03-04 19:30:51 +00:00
return false if ( tag_name == 'input' ) && ( native [ :type ] == " hidden " )
2014-05-19 18:16:54 +00:00
if check_ancestors
#check size because oldest supported nokogiri doesnt support xpath boolean() function
native . xpath ( " ./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head'] " ) . size ( ) == 0
else
#no need for an xpath if only checking the current element
! ( native . has_attribute? ( 'hidden' ) || ( native [ :style ] =~ / display: \ s?none / ) || %w( script head ) . include? ( tag_name ) )
end
2010-11-21 13:37:36 +00:00
end
2011-03-25 10:35:59 +00:00
##
#
# Whether or not the element is checked.
#
# @return [Boolean] Whether the element is checked
#
def checked?
2016-02-01 18:54:51 +00:00
native . has_attribute? ( 'checked' )
2011-03-25 10:35:59 +00:00
end
2013-01-29 08:54:14 +00:00
##
#
# Whether or not the element is disabled.
#
# @return [Boolean] Whether the element is disabled
def disabled?
2016-02-01 18:54:51 +00:00
native . has_attribute? ( 'disabled' )
2013-01-29 08:54:14 +00:00
end
2011-03-25 10:35:59 +00:00
##
#
# Whether or not the element is selected.
#
# @return [Boolean] Whether the element is selected
#
def selected?
2016-02-01 18:54:51 +00:00
native . has_attribute? ( 'selected' )
2011-03-25 10:35:59 +00:00
end
2013-02-25 21:12:03 +00:00
def synchronize ( seconds = nil )
2012-02-01 13:16:17 +00:00
yield # simple nodes don't need to wait
end
2012-06-11 15:29:58 +00:00
def allow_reload!
# no op
end
2016-10-10 21:43:40 +00:00
##
#
# @return [String] The title of the document
2013-02-16 08:59:07 +00:00
def title
2015-05-28 19:10:13 +00:00
if native . respond_to? :title
native . title
else
#old versions of nokogiri don't have #title - remove in 3.0
native . xpath ( '/html/head/title | /html/title' ) . first . text
end
2013-02-16 08:59:07 +00:00
end
2014-02-16 17:13:58 +00:00
def inspect
%( # <Capybara::Node::Simple tag=" #{ tag_name } " path=" #{ path } "> )
2013-02-16 08:59:07 +00:00
end
2014-02-16 17:13:58 +00:00
# @api private
def find_css ( css )
native . css ( css )
2013-02-16 08:59:07 +00:00
end
2014-02-16 17:13:58 +00:00
# @api private
def find_xpath ( xpath )
native . xpath ( xpath )
2010-11-21 13:37:36 +00:00
end
2016-12-15 17:04:01 +00:00
# @api private
def session_options
Capybara . session_options
end
2010-11-21 13:37:36 +00:00
end
end
end