# frozen_string_literal: true module Capybara module Node module Finders ## # # Find an {Capybara::Node::Element} based on the given arguments. {#find} will raise an error if the element # is not found. # # page.find('#foo').find('.bar') # page.find(:xpath, './/div[contains(., "bar")]') # page.find('li', text: 'Quox').click_link('Delete') # # @param (see #all) # # @macro waiting_behavior # # @!macro system_filters # @option options [String, Regexp] text Only find elements which contain this text or match this regexp # @option options [String, Boolean] exact_text # When String the elements contained text must match exactly, when Boolean controls whether the `text` option must match exactly. # Defaults to {Capybara.configure exact_text}. # @option options [Boolean] normalize_ws # Whether the `text`/`exact_text` options are compared against elment text with whitespace normalized or as returned by the driver. # Defaults to {Capybara.configure default_normalize_ws}. # @option options [Boolean, Symbol] visible Only find elements with the specified visibility: # * true - only finds visible elements. # * false - finds invisible _and_ visible elements. # * :all - same as false; finds visible and invisible elements. # * :hidden - only finds invisible elements. # * :visible - same as true; only finds visible elements. # @option options [Boolean] obscured Only find elements with the specified obscured state: # * true - only find elements whose centerpoint is not in the viewport or is obscured by another non-descendant element. # * false - only find elements whose centerpoint is in the viewport and is not obscured by other non-descendant elements. # @option options [String, Regexp] id Only find elements with an id that matches the value passed # @option options [String, Array, Regexp] class Only find elements with matching class/classes. # * Absence of a class can be checked by prefixing the class name with `!` # * If you need to check for existence of a class name that starts with `!` then prefix with `!!` # # class:['a', '!b', '!!!c'] # limit to elements with class 'a' and '!c' but not class 'b' # # @option options [String, Regexp, Hash] style Only find elements with matching style. String and Regexp will be checked against text of the elements `style` attribute, while a Hash will be compared against the elements full style # @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially. Defaults to {Capybara.configure exact}. # @option options [Symbol] match The matching strategy to use. Defaults to {Capybara.configure match}. # # @return [Capybara::Node::Element] The found element # @raise [Capybara::ElementNotFound] If the element can't be found before time expires # def find(*args, **options, &optional_filter_block) options[:session_options] = session_options synced_resolve Capybara::Queries::SelectorQuery.new(*args, **options, &optional_filter_block) end ## # # Find an {Capybara::Node::Element} based on the given arguments that is also an ancestor of the element called on. # {#ancestor} will raise an error if the element is not found. # # {#ancestor} takes the same options as {#find}. # # element.ancestor('#foo').find('.bar') # element.ancestor(:xpath, './/div[contains(., "bar")]') # element.ancestor('ul', text: 'Quox').click_link('Delete') # # @param (see #find) # # @macro waiting_behavior # # @return [Capybara::Node::Element] The found element # @raise [Capybara::ElementNotFound] If the element can't be found before time expires # def ancestor(*args, **options, &optional_filter_block) options[:session_options] = session_options synced_resolve Capybara::Queries::AncestorQuery.new(*args, **options, &optional_filter_block) end ## # # Find an {Capybara::Node::Element} based on the given arguments that is also a sibling of the element called on. # {#sibling} will raise an error if the element is not found. # # {#sibling} takes the same options as {#find}. # # element.sibling('#foo').find('.bar') # element.sibling(:xpath, './/div[contains(., "bar")]') # element.sibling('ul', text: 'Quox').click_link('Delete') # # @param (see #find) # # @macro waiting_behavior # # @return [Capybara::Node::Element] The found element # @raise [Capybara::ElementNotFound] If the element can't be found before time expires # def sibling(*args, **options, &optional_filter_block) options[:session_options] = session_options synced_resolve Capybara::Queries::SiblingQuery.new(*args, **options, &optional_filter_block) end ## # # Find a form field on the page. The field can be found by its name, id or label text. # # @overload find_field([locator], **options) # @param [String] locator name, id, {Capybara.configure test_id} attribute, placeholder or text of associated label element # # @macro waiting_behavior # # # @option options [Boolean] checked Match checked field? # @option options [Boolean] unchecked Match unchecked field? # @option options [Boolean, Symbol] disabled (false) Match disabled field? # * true - only finds a disabled field # * false - only finds an enabled field # * :all - finds either an enabled or disabled field # @option options [Boolean] readonly Match readonly field? # @option options [String, Regexp] with Value of field to match on # @option options [String] type Type of field to match on # @option options [Boolean] multiple Match fields that can have multiple values? # @option options [String, Regexp] id Match fields that match the id attribute # @option options [String] name Match fields that match the name attribute # @option options [String] placeholder Match fields that match the placeholder attribute # @option options [String, Array, Regexp] class Match fields that match the class(es) passed # @return [Capybara::Node::Element] The found element # def find_field(locator = nil, **options, &optional_filter_block) find(:field, locator, **options, &optional_filter_block) end ## # # Find a link on the page. The link can be found by its id or text. # # @overload find_link([locator], **options) # @param [String] locator id, {Capybara.configure test_id} attribute, title, text, or alt of enclosed img element # # @macro waiting_behavior # # @option options [String,Regexp,nil] href Value to match against the links href, if `nil` finds link placeholders (`` elements with no href attribute), if `false` ignores the href # @option options [String, Regexp] id Match links with the id provided # @option options [String] title Match links with the title provided # @option options [String] alt Match links with a contained img element whose alt matches # @option options [String, Array, Regexp] class Match links that match the class(es) provided # @return [Capybara::Node::Element] The found element # def find_link(locator = nil, **options, &optional_filter_block) find(:link, locator, **options, &optional_filter_block) end ## # # Find a button on the page. # This can be any `` element of type submit, reset, image, button or it can be a # `