# 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. # # @!macro waiting_behavior # If the driver is capable of executing JavaScript, +$0+ will wait for a set amount of time # and continuously retry finding the element until either the element is found or the time # expires. The length of time +find+ will wait is controlled through {Capybara.default_max_wait_time} # and defaults to 2 seconds. # @option options [false, Numeric] wait (Capybara.default_max_wait_time) Maximum time to wait for matching element to appear. # # +find+ takes the same options as +all+. # # page.find('#foo').find('.bar') # page.find(:xpath, './/div[contains(., "bar")]') # page.find('li', text: 'Quox').click_link('Delete') # # @param (see Capybara::Node::Finders#all) # # @option options [Boolean] match The matching strategy to use. # # @return [Capybara::Node::Element] The found element # @raise [Capybara::ElementNotFound] If the element can't be found before time expires # def find(*args, &optional_filter_block) query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block) synchronize(query.wait) do if (query.match == :smart or query.match == :prefer_exact) and query.supports_exact? result = query.resolve_for(self, true) result = query.resolve_for(self, false) if result.empty? && !query.exact? else result = query.resolve_for(self) end if query.match == :one or query.match == :smart and result.size > 1 raise Capybara::Ambiguous.new("Ambiguous match, found #{result.size} elements matching #{query.description}") end if result.empty? raise Capybara::ElementNotFound.new("Unable to find #{query.description}") end result.first end.tap(&:allow_reload!) 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, 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] 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] Match fields that match the class(es) passed # @return [Capybara::Node::Element] The found element # def find_field(locator=nil, options={}, &optional_filter_block) locator, options = nil, locator if locator.is_a? Hash find(:field, locator, options, &optional_filter_block) end alias_method :field_labeled, :find_field ## # # 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, title, text, or alt of enclosed img element # # @macro waiting_behavior # # @option options [String,Regexp] href Value to match against the links href # @option options [String] 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] 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) locator, options = nil, locator if locator.is_a? Hash 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 # \