module Watir class RadioSet extend Forwardable include Watir::Exception include Enumerable delegate [:exists?, :present?, :visible?, :browser] => :source attr_reader :source, :frame def initialize(query_scope, selector) unless selector.kind_of? Hash raise ArgumentError, "invalid argument: #{selector.inspect}" end @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 = {}) n = name if !n.empty? && (!opt[:name] || opt[:name] == n) frame.radio(opt.merge name: n) elsif n.empty? return source else raise Watir::Exception::UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}" end end # # @return Watir::RadioCollection # def radios(opt = {}) n = name if !n.empty? && (!opt[:name] || opt[:name] == n) element_call(:wait_for_present) { frame.radios(opt.merge name: n) } elsif n.empty? Watir::RadioCollection.new(frame, element: source.wd) else raise Watir::Exception::UnknownObjectException, "#{opt[:name]} does not match name of RadioSet: #{n}" 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 source.send :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) found_by_value = radio(value: str_or_rx) found_by_text = radio(label: str_or_rx) if found_by_value.exist? found_by_value.click unless found_by_value.selected? return found_by_value.value elsif found_by_text.exist? found_by_text.click unless found_by_text.selected? return found_by_text.text else raise UnknownObjectException, "Unable to locate radio matching #{str_or_rx.inspect}" end end # # 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 sel = selected sel && sel.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 sel = selected sel && sel.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) return false unless other.kind_of?(self.class) radios == other.radios end alias_method :eql?, :== private def element_call(*args, &blk) source.send :element_call, *args, &blk end end # RadioSet module Container def radio_set(*args) RadioSet.new(self, extract_selector(args).merge(tag_name: "input", type: "radio")) end Watir.tag_to_class[:radio_set] = RadioSet end # Container end # Watir