Skip to content

[rb] fix select being able to select options hidden by css rules#17037

Open
FFederi wants to merge 3 commits into
SeleniumHQ:trunkfrom
FFederi:should-not-select-hidden-options
Open

[rb] fix select being able to select options hidden by css rules#17037
FFederi wants to merge 3 commits into
SeleniumHQ:trunkfrom
FFederi:should-not-select-hidden-options

Conversation

@FFederi
Copy link
Copy Markdown
Contributor

@FFederi FFederi commented Feb 1, 2026

🔗 Related Issues

Related to issue: [🚀 Feature]: Unifying Select Class Across All Bindings

💥 What does this PR do?

Modifies select behaviour to make it the same as python and Java bindings.
In particular, makes it so selecting an option hidden by CSS rules raises an exception.

🔧 Implementation Notes

I couldn't find (or understand) a general way to check visibility of an element, so I added a simple check on CSS values like it's been done with Java and python.

🔄 Types of changes

  • Bug fix (backwards compatible)

@qodo-code-review
Copy link
Copy Markdown
Contributor

PR Type

Bug fix


Description

  • Prevents selecting/deselecting options hidden by CSS rules

  • Adds visibility check using CSS properties (visibility, display, opacity)

  • Raises ElementNotInteractableError for invisible options

  • Aligns Ruby bindings behavior with Python and Java implementations


File Walkthrough

Relevant files
Bug fix
select.rb
Add visibility checks to select/deselect operations           

rb/lib/selenium/webdriver/support/select.rb

  • Added css_property_and_visible? helper method to check element
    visibility
  • Modified select_option to raise ElementNotInteractableError for
    invisible options
  • Modified deselect_option to raise ElementNotInteractableError for
    invisible options
  • Checks CSS properties (visibility, display, opacity) against hidden
    values
+19/-0   
Tests
select_spec.rb
Add tests for invisible option selection behavior               

rb/spec/integration/selenium/webdriver/select_spec.rb

  • Added multi_invisible fixture for testing invisible select elements
  • Added test case for selecting invisible options by text
  • Added test case for deselecting invisible options by text
  • Both test cases verify ElementNotInteractableError is raised
+17/-0   

@selenium-ci selenium-ci added C-rb Ruby Bindings B-support Issue or PR related to support classes labels Feb 1, 2026
@selenium-ci
Copy link
Copy Markdown
Member

Thank you, @FFederi for this code suggestion.

The support packages contain example code that many users find helpful, but they do not necessarily represent
the best practices for using Selenium, and the Selenium team is not currently merging changes to them.

After reviewing the change, unless it is a critical fix or a feature that is needed for Selenium
to work, we will likely close the PR.

We actively encourage people to add the wrapper and helper code that makes sense for them to their own frameworks.
If you have any questions, please contact us

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Feb 1, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🟡
🎫 #15265
🟢 Make `Select` class behavior consistent across language bindings (tracking item: Ruby).
Ensure selection by visible text (and "contains visible text" where applicable) does not
allow selecting options hidden by CSS, considering the CSS properties visibility, display,
and opacity and the values hidden, none, 0, 0.0.
Confirm that Ruby’s "contains visible text" selection path (if supported in this
binding/version) also routes through the same option selection logic and therefore raises
the same exception for CSS-hidden options in real browser runs.
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status:
Potentially misleading name: The method css_property_and_visible? implies a full visibility check but only tests a
small set of CSS property values, which may confuse readers about its actual behavior.

Referred Code
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
end

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Incomplete visibility checks: The new CSS-based invisibility detection in css_property_and_visible? may miss edge cases
(e.g., other opacity string formats, inherited styles, or other visibility-affecting CSS
values), potentially allowing still-non-interactable options through or blocking valid
ones.

Referred Code
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
end

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Feb 1, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Improve visibility check for correctness

Improve the css_property_and_visible? method by checking each CSS property
(display, visibility, opacity) against its specific "hiding" value for a more
correct and robust visibility check.

rb/lib/selenium/webdriver/support/select.rb [280-287]

 def css_property_and_visible?(element)
-  css_value_candidates = %w[hidden none 0 0.0].to_set
-  css_property_candidates = %w[visibility display opacity]
+  return false if element.css_value('display') == 'none'
+  return false if element.css_value('visibility') == 'hidden'
+  return false if element.css_value('opacity').to_f.zero?
 
-  css_property_candidates.none? do |property|
-    css_value_candidates.include?(element.css_value(property))
-  end
+  true
 end
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the visibility check logic is flawed by using a single set of values for different CSS properties, and proposes a more robust and correct implementation.

Medium
  • Update

Comment thread rb/lib/selenium/webdriver/support/select.rb Outdated
Comment thread rb/lib/selenium/webdriver/support/select.rb Outdated
Comment thread rb/lib/selenium/webdriver/support/select.rb Outdated
Comment thread rb/spec/integration/selenium/webdriver/select_spec.rb
@FFederi FFederi force-pushed the should-not-select-hidden-options branch from 7e9ae08 to 5422054 Compare April 27, 2026 11:33
@FFederi
Copy link
Copy Markdown
Contributor Author

FFederi commented Apr 27, 2026

@aguspe
Sorry for the delay, thanks for your review!
I tried addressing the points you raised trying to prioritizing making the logic similar to Java's, what do you think?

@aguspe
Copy link
Copy Markdown
Contributor

aguspe commented May 10, 2026

@aguspe Sorry for the delay, thanks for your review! I tried addressing the points you raised trying to prioritizing making the logic similar to Java's, what do you think?

@FFederi thank you for the awesome work! I just have one small comment in Java selectByVisibleText also calls assertSelectIsEnabled() and assertSelectIsVisible() on the parent select before iterating options, want to add the same here?

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented May 10, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Action required

1. Missing Set require 🐞 Bug ☼ Reliability
Description
Select initializes HIDDEN_CSS_VALUES using .to_set during file load, but the codebase does not
require Ruby’s stdlib set, so loading this file can raise NoMethodError for to_set. This is a
new hard-failure path because the constant is evaluated immediately when the file is required.
Code

rb/lib/selenium/webdriver/support/select.rb[24]

+        HIDDEN_CSS_VALUES = %w[hidden none 0 0.0].to_set.freeze
Evidence
The PR adds a constant initialized via .to_set in support/select.rb; .to_set is provided by
Ruby’s stdlib set and isn’t available unless set is loaded. The Selenium Ruby entrypoint
requires various stdlibs but does not require set, and there is no local require in
support/select.rb, so requiring Support/Select can fail at load time.

rb/lib/selenium/webdriver/support/select.rb[20-26]
rb/lib/selenium/webdriver.rb[20-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`rb/lib/selenium/webdriver/support/select.rb` now calls `.to_set` while defining `HIDDEN_CSS_VALUES`. In Ruby, `Enumerable#to_set` is defined by the stdlib `set` and is not available unless `set` has been required, so loading this file can raise `NoMethodError` at require-time.

### Issue Context
This is particularly risky because the `.to_set` call happens during constant initialization (file load), so it can break any consumer that loads `Selenium::WebDriver::Support` / `Select` without having previously loaded `set`.

### Fix Focus Areas
- rb/lib/selenium/webdriver/support/select.rb[20-26]
- rb/lib/selenium/webdriver.rb[20-30]

### Suggested fix
Add `require 'set'` either:
1) locally at the top of `rb/lib/selenium/webdriver/support/select.rb`, or
2) centrally in `rb/lib/selenium/webdriver.rb` (preferred if you want to support other existing `.to_set` usages across the library).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

module WebDriver
module Support
class Select
HIDDEN_CSS_VALUES = %w[hidden none 0 0.0].to_set.freeze
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Missing set require 🐞 Bug ☼ Reliability

Select initializes HIDDEN_CSS_VALUES using .to_set during file load, but the codebase does not
require Ruby’s stdlib set, so loading this file can raise NoMethodError for to_set. This is a
new hard-failure path because the constant is evaluated immediately when the file is required.
Agent Prompt
### Issue description
`rb/lib/selenium/webdriver/support/select.rb` now calls `.to_set` while defining `HIDDEN_CSS_VALUES`. In Ruby, `Enumerable#to_set` is defined by the stdlib `set` and is not available unless `set` has been required, so loading this file can raise `NoMethodError` at require-time.

### Issue Context
This is particularly risky because the `.to_set` call happens during constant initialization (file load), so it can break any consumer that loads `Selenium::WebDriver::Support` / `Select` without having previously loaded `set`.

### Fix Focus Areas
- rb/lib/selenium/webdriver/support/select.rb[20-26]
- rb/lib/selenium/webdriver.rb[20-30]

### Suggested fix
Add `require 'set'` either:
1) locally at the top of `rb/lib/selenium/webdriver/support/select.rb`, or
2) centrally in `rb/lib/selenium/webdriver.rb` (preferred if you want to support other existing `.to_set` usages across the library).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-support Issue or PR related to support classes C-rb Ruby Bindings Review effort 2/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants