Sitelet https://github.com/SeleniumHQ/selenium/pull/17037/commits/b1e0eaea0eae3a268b3631610285f5682b34b928
Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[rb] refactoring, adding tests
  • Loading branch information
FFederi committed May 18, 2026
commit b1e0eaea0eae3a268b3631610285f5682b34b928
31 changes: 12 additions & 19 deletions rb/lib/selenium/webdriver/support/select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ module Selenium
module WebDriver
module Support
class Select
HIDDEN_CSS_VALUES = %w[hidden none 0 0.0].to_set.freeze
Comment thread
FFederi marked this conversation as resolved.
VISIBILITY_PROPERTIES = %w[visibility display opacity].freeze

#
# @param [Element] element The select element to use
#
Expand Down Expand Up @@ -163,9 +166,14 @@ def deselect_all
def select_by_text(text)
opts = find_by_text text

return select_options(opts) unless opts.empty?
raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}" if opts.empty?

raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
opts.each do |opt|
raise Error::NoSuchElementError, "invisible option with text: #{text.inspect}" unless option_visible?(opt)

select_option(opt)
break unless multiple?
end
end

def select_by_index(index)
Expand Down Expand Up @@ -217,20 +225,10 @@ def deselect_by_index(index)
def select_option(option)
raise Error::UnsupportedOperationError, 'You may not select a disabled option' unless option.enabled?

unless css_property_and_visible?(option)
raise Error::ElementNotInteractableError,
'You may not select an invisible option'
end

option.click unless option.selected?
end

def deselect_option(option)
unless css_property_and_visible?(option)
raise Error::ElementNotInteractableError,
'You may not deselect an invisible option'
end

option.click if option.selected?
end

Expand Down Expand Up @@ -277,13 +275,8 @@ def find_by_value(value)
@element.find_elements(xpath: ".//option[@value = #{Escaper.escape value}]")
end

def css_property_and_visible?(element)
css_value_candidates = %w[hidden none 0 0.0].to_set
css_property_candidates = %w[visibility display opacity]

css_property_candidates.none? do |property|
css_value_candidates.include?(element.css_value(property))
end
def option_visible?(element)
VISIBILITY_PROPERTIES.none? { |property| HIDDEN_CSS_VALUES.include?(element.css_value(property)) }
end
end # Select
end # Support
Expand Down
31 changes: 24 additions & 7 deletions rb/spec/integration/selenium/webdriver/select_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ module Support
%w[Apples Pears Oranges Lemons].each do |text|
expect {
multi_invisible.select_by(:text, text)
}.to raise_exception(Error::ElementNotInteractableError)
}.to raise_exception(Error::NoSuchElementError)
end
end
end
Expand Down Expand Up @@ -156,6 +156,11 @@ module Support
it 'errors when not found' do
expect { multi_select.select_by(:index, 5) }.to raise_exception(Error::NoSuchElementError)
end

it 'selects invisible option' do
multi_invisible.select_by(:index, 1)
expect(multi_invisible.selected_options).to include(driver.find_element(css: 'option[value=pears]'))
end
end

context 'when by value' do
Expand Down Expand Up @@ -185,6 +190,11 @@ module Support
it 'errors when not found' do
expect { multi_select.select_by(:value, 'invalid') }.to raise_exception(Error::NoSuchElementError)
end

it 'selects invisible option' do
multi_invisible.select_by(:value, 'pears')
expect(multi_invisible.selected_options).to include(driver.find_element(css: 'option[value=pears]'))
end
end
end

Expand Down Expand Up @@ -308,12 +318,9 @@ module Support
expect { multi_select.deselect_by(:text, 'invalid') }.to raise_exception(Error::NoSuchElementError)
end

it 'errors when option is invisible', :aggregate_failures do
%w[Apples Pears Oranges Lemons].each do |text|
expect {
multi_invisible.deselect_by(:text, text)
}.to raise_exception(Error::ElementNotInteractableError)
end
it 'deselects invisible option' do
multi_invisible.deselect_by(:text, 'Apples')
expect(multi_invisible.selected_options).not_to include(driver.find_element(css: 'option[value=apples]'))
end
end

Expand All @@ -337,6 +344,11 @@ module Support
it 'errors when not found' do
expect { multi_select.deselect_by(:index, 5) }.to raise_exception(Error::NoSuchElementError)
end

it 'deselects invisible option' do
multi_invisible.deselect_by(:index, 0)
expect(multi_invisible.selected_options).not_to include(driver.find_element(css: 'option[value=apples]'))
end
end

context 'when by value' do
Expand All @@ -359,6 +371,11 @@ module Support
it 'errors when not found' do
expect { multi_select.deselect_by(:value, 'invalid') }.to raise_exception(Error::NoSuchElementError)
end

it 'deselects invisible option' do
multi_invisible.deselect_by(:value, 'apples')
expect(multi_invisible.selected_options).not_to include(driver.find_element(css: 'option[value=apples]'))
end
end
end

Expand Down