# frozen_string_literal: true module Watir class RadioSet extend Forwardable include Exception include Enumerable delegate %i[exist? exists? present? visible? browser] => :source attr_reader :source, :frame def initialize(query_scope, selector) raise ArgumentError, "invalid argument: #{selector.inspect}" unless selector.is_a? Hash @source = Radio.new(query_scope, selector) @frame = @source.parent(tag_name: 'form') end # # Yields each Radio associated with this set. # # @example # radio_set = browser.radio_set # radio_set.each do |radio| # puts radio.text # end # # @yieldparam [Watir::RadioSet] element iterate through the radio buttons. # def each(&block) radios.each(&block) end # # Get the n'th radio button in this set # # @return Watir::Radio # def [](idx) radios[idx] end # # @return Watir::Radio # def radio(opt = {}) if !name.empty? && (!opt[:name] || opt[:name] == name) frame.radio(opt.merge(name: name)) elsif name.empty? source else raise UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{name}" end end # # @return Watir::RadioCollection # def radios(opt = {}) if !name.empty? && (!opt[:name] || opt[:name] == name) element_call(:wait_for_present) { frame.radios(opt.merge(name: name)) } elsif name.empty? single_radio_collection else raise UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{name}" end end # # Returns true if any radio buttons in the set are enabled. # # @return [Boolean] # def enabled? any?(&:enabled?) end # # Returns true if all radio buttons in the set are disabled. # # @return [Boolean] # def disabled? !enabled? end # # Returns the name attribute for the set. # # @return [String] # def name @name ||= source.name end # # If RadioSet exists, this always returns 'radio'. # # @return [String] # def type assert_exists 'radio' end # # Returns true if the radio set has one or more radio buttons where label matches the given value. # # @param [String, Regexp] str_or_rx # @return [Boolean] # def include?(str_or_rx) radio(label: str_or_rx).exist? end # # Select the radio button whose value or label matches the given string. # # @param [String, Regexp] str_or_rx # @raise [Watir::Exception::UnknownObjectException] if the Radio does not exist. # @return [String] The value or text of the radio selected. # def select(str_or_rx) %i[value label].each do |key| radio = radio(key => str_or_rx) next unless radio.exist? radio.click unless radio.selected? return key == :value ? radio.value : radio.text end raise UnknownObjectException, "Unable to locate radio matching #{str_or_rx.inspect}" end alias set select # # Returns true if any of the radio button label matches the given value. # # @param [String, Regexp] str_or_rx # @raise [Watir::Exception::UnknownObjectException] if the options do not exist # @return [Boolean] # def selected?(str_or_rx) found = frame.radio(label: str_or_rx) return found.selected? if found.exist? raise UnknownObjectException, "Unable to locate radio matching #{str_or_rx.inspect}" end # # Returns the value of the selected radio button in the set. # Returns nil if no radio is selected. # # @return [String, nil] # def value selected&.value end # # Returns the text of the selected radio button in the set. # Returns nil if no option is selected. # # @return [String, nil] # def text selected&.text end # # Returns the selected Radio element. # Returns nil if no radio button is selected. # # @return [Watir::Radio, nil] # def selected find(&:selected?) end # # Returns true if two elements are equal. # # @example # browser.radio_set(id: 'new_user_newsletter_yes') == browser.radio_set(id: 'new_user_newsletter_no') # #=> true # def ==(other) other.is_a?(self.class) && radios == other.radios end alias eql? == # Delegating to Private Methods %i[assert_exists element_call].each do |method| define_method(method) do |*args, &blk| source.send(method, *args, &blk) end end private def single_radio_collection collection = RadioCollection.new(frame, source.selector) collection.first.cache = source.wd collection end end # RadioSet module Container def radio_set(opts = {}) RadioSet.new(self, opts.merge(tag_name: 'input', type: 'radio')) end Watir.tag_to_class[:radio_set] = RadioSet end # Container end # Watir