Skip to content

Conversation

@titusfortner
Copy link
Member

@titusfortner titusfortner commented Jan 13, 2026

User description

🔗 Related Issues

Similar to #16900
I actually thought Ruby already did this.

💥 What does this PR do?

  • when WebDriver.logger.debug? adds driver log output to logger

🔧 Implementation Notes

  • we could have a separate setting for this in logger instead of forcing it on existing debug setups. Or toggle it based on SE_DEBUG (the new behavior)

PR Type

Enhancement


Description

  • Enable verbose driver logging when WebDriver debug mode is active

  • Add automatic log level configuration for Chrome, Edge, Firefox, IE

  • Remove conflicting log-level arguments before applying debug settings

  • Unify debug logging behavior across all supported browser drivers


Diagram Walkthrough

flowchart LR
  A["WebDriver.logger.debug?"] -->|enabled| B["Chrome/Edge Service"]
  A -->|enabled| C["Firefox Service"]
  A -->|enabled| D["IE Service"]
  B -->|add --verbose| E["Driver Logs"]
  C -->|set --log debug| E
  D -->|add --log-level=DEBUG| E
Loading

File Walkthrough

Relevant files
Enhancement
service.rb
Add verbose logging for Chrome when debug enabled               

rb/lib/selenium/webdriver/chrome/service.rb

  • Override initialize method to check WebDriver debug status
  • Remove any existing --log-level arguments from args
  • Add --verbose flag when debug mode is enabled
  • Call parent class initialization with modified arguments
+10/-0   
service.rb
Add verbose logging for Edge when debug enabled                   

rb/lib/selenium/webdriver/edge/service.rb

  • Override initialize method to check WebDriver debug status
  • Remove any existing --log-level arguments from args
  • Add --verbose flag when debug mode is enabled
  • Call parent class initialization with modified arguments
+11/-0   
service.rb
Add debug logging for Firefox when debug enabled                 

rb/lib/selenium/webdriver/firefox/service.rb

  • Extend existing initialize method with debug logging logic
  • Remove existing --log arguments and their values if present
  • Add --log debug arguments when debug mode is enabled
  • Preserve existing websocket port configuration logic
+12/-0   
service.rb
Add debug logging for IE when debug enabled                           

rb/lib/selenium/webdriver/ie/service.rb

  • Override initialize method to check WebDriver debug status
  • Remove any existing --log-level arguments from args
  • Add --log-level=DEBUG flag when debug mode is enabled
  • Call parent class initialization with modified arguments
+10/-0   

@titusfortner titusfortner requested review from aguspe and p0deje January 13, 2026 18:11
@selenium-ci selenium-ci added the C-rb Ruby Bindings label Jan 13, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 13, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Sensitive information exposure

Description: Enabling verbose/debug driver logging automatically when WebDriver.logger.debug? is true
(also in Edge/Firefox/IE service initializers) may cause sensitive data (URLs with tokens,
cookies, PII in form values, internal paths) to be written to logs in environments where
debug is enabled unintentionally or logs are centrally collected.
service.rb [29-37]

Referred Code
def initialize(path: nil, port: nil, log: nil, args: nil)
  args ||= []
  if WebDriver.logger.debug?
    args.reject! { |arg| arg.start_with?('--log-level') }
    args << '--verbose'
  end

  super
end
Ticket Compliance
🟡
🎫 #5678
🔴 Fix/avoid repeated ChromeDriver instantiation failures that produce "Error: ConnectFailure
(Connection refused)" on subsequent driver starts (Ubuntu 16.04 / Chrome 65 / ChromeDriver
2.35 context).
🟡
🎫 #1234
🔴 Restore/ensure that clicking a link with javascript in its href triggers the expected
behavior in Firefox (regression from Selenium 2.47.1 to 2.48.x per provided repro).
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: Meaningful Naming and Self-Documenting Code

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

Status: Passed

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: 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: 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: Secure Logging Practices

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

Status:
Verbose logging risk: Enabling driver --verbose (and similar debug flags across drivers) when
WebDriver.logger.debug? is true may cause sensitive data (e.g., URLs with credentials,
session identifiers, or other request details) to be written to logs depending on driver
behavior and should be reviewed/guarded accordingly.

Referred Code
def initialize(path: nil, port: nil, log: nil, args: nil)
  args ||= []
  if WebDriver.logger.debug?
    args.reject! { |arg| arg.start_with?('--log-level') }
    args << '--verbose'
  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
Contributor

qodo-code-review bot commented Jan 13, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix bug in argument parsing logic

Fix a bug in the Firefox service argument parsing by checking if the value for
--log is a valid value and not another option flag before removing it.

rb/lib/selenium/webdriver/firefox/service.rb [37-42]

 if (index = args.index('--log'))
-  args.delete_at(index) # delete '--log'
-  args.delete_at(index) # delete the value (now at same index)
+  # also remove value if it's not an option flag
+  if args[index + 1] && !args[index + 1].start_with?('-')
+    args.delete_at(index + 1)
+  end
+  args.delete_at(index)
 elsif (index = args.index { |arg| arg.start_with?('--log=') })
   args.delete_at(index)
 end
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug in the new argument parsing logic that could cause incorrect driver configuration, and the proposed fix is accurate.

Medium
High-level
Unify driver log configuration logic
Suggestion Impact:The commit modified the debug logging argument-handling logic in both Chrome and IE services in a parallel/standardized way (changing how args are duplicated/normalized and how log-related args are removed), but it did not introduce any shared helper or otherwise remove the duplication as suggested.

code diff:

# File: rb/lib/selenium/webdriver/chrome/service.rb
@@ -26,10 +26,10 @@
         SHUTDOWN_SUPPORTED = true
         DRIVER_PATH_ENV_KEY = 'SE_CHROMEDRIVER'
 
-        def initialize(path: nil, port: nil, log: nil, args: nil)
-          args ||= []
+        def initialize(args: nil, **)
           if WebDriver.logger.debug?
-            args.reject! { |arg| arg.start_with?('--log-level') }
+            args = Array(args.dup)
+            args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
             args << '--verbose'
           end

# File: rb/lib/selenium/webdriver/ie/service.rb
@@ -26,10 +26,10 @@
         SHUTDOWN_SUPPORTED = true
         DRIVER_PATH_ENV_KEY = 'SE_IEDRIVER'
 
-        def initialize(path: nil, port: nil, log: nil, args: nil)
-          args ||= []
+        def initialize(args: nil, **)
           if WebDriver.logger.debug?
-            args.reject! { |arg| arg.start_with?('--log-level') }
+            args = Array(args.dup)
+            args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
             args << '--log-level=DEBUG'
           end

The logic for enabling debug logs is duplicated across the Chrome, Edge, and IE
service classes. This repeated code should be abstracted into a shared helper
method to improve maintainability.

Examples:

rb/lib/selenium/webdriver/chrome/service.rb [29-37]
        def initialize(path: nil, port: nil, log: nil, args: nil)
          args ||= []
          if WebDriver.logger.debug?
            args.reject! { |arg| arg.start_with?('--log-level') }
            args << '--verbose'
          end

          super
        end
rb/lib/selenium/webdriver/ie/service.rb [29-37]
        def initialize(path: nil, port: nil, log: nil, args: nil)
          args ||= []
          if WebDriver.logger.debug?
            args.reject! { |arg| arg.start_with?('--log-level') }
            args << '--log-level=DEBUG'
          end

          super
        end

Solution Walkthrough:

Before:

# In chrome/service.rb & edge/service.rb
def initialize(args: nil)
  args ||= []
  if WebDriver.logger.debug?
    args.reject! { |arg| arg.start_with?('--log-level') }
    args << '--verbose'
  end
  super
end

# In ie/service.rb
def initialize(args: nil)
  args ||= []
  if WebDriver.logger.debug?
    args.reject! { |arg| arg.start_with?('--log-level') }
    args << '--log-level=DEBUG'
  end
  super
end

After:

# In a shared helper or parent class
def apply_debug_logging(args, remove_prefix:, add_arg:)
  return unless WebDriver.logger.debug?

  args.reject! { |arg| arg.start_with?(remove_prefix) }
  args << add_arg
end

# In chrome/service.rb & edge/service.rb
def initialize(args: nil)
  args ||= []
  apply_debug_logging(args, remove_prefix: '--log-level', add_arg: '--verbose')
  super
end

# In ie/service.rb
def initialize(args: nil)
  args ||= []
  apply_debug_logging(args, remove_prefix: '--log-level', add_arg: '--log-level=DEBUG')
  super
end
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies significant code duplication in the initialize methods of Chrome, Edge, and IE services and proposes a valid abstraction to improve maintainability.

Medium
Learned
best practice
Defensive copy of input arrays
Suggestion Impact:The commit changes the initialization logic to defensively copy `args` (via `args = Array(args.dup)`) before calling `reject!`/mutation in debug mode, addressing the core concern about mutating a caller-owned array. It does not follow the exact suggested pattern (copying unconditionally and explicitly passing args to `super` is not shown here).

code diff:

-        def initialize(path: nil, port: nil, log: nil, args: nil)
-          args ||= []
+        def initialize(args: nil, **)
           if WebDriver.logger.debug?
-            args.reject! { |arg| arg.start_with?('--log-level') }
+            args = Array(args.dup)
+            args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
             args << '--verbose'

args may be a caller-owned array; duplicating it before reject!/<< prevents
surprising external side effects. Create a new array (e.g., Array(args).dup) and
pass it to super explicitly.

rb/lib/selenium/webdriver/chrome/service.rb [29-37]

 def initialize(path: nil, port: nil, log: nil, args: nil)
-  args ||= []
+  args = Array(args).dup
   if WebDriver.logger.debug?
     args.reject! { |arg| arg.start_with?('--log-level') }
     args << '--verbose'
   end
 
-  super
+  super(path: path, port: port, log: log, args: args)
 end

[Suggestion processed]

Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Avoid mutating caller-provided collections; make a defensive copy of collection-like inputs before modifying/storing them.

Low
Centralize repeated debug-arg logic

The same debug-arg manipulation logic is duplicated across multiple service
classes; move it into WebDriver::Service (or a shared helper) to keep behavior
consistent and easier to maintain.

rb/lib/selenium/webdriver/edge/service.rb [29-37]

 def initialize(path: nil, port: nil, log: nil, args: nil)
-  args ||= []
-  if WebDriver.logger.debug?
-    args.reject! { |arg| arg.start_with?('--log-level') }
-    args << '--verbose'
-  end
-
-  super
+  args = with_debug_driver_args(args, remove_prefix: '--log-level', add: '--verbose')
+  super(path: path, port: port, log: log, args: args)
 end
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Reduce duplication by centralizing repeated behavior into a shared helper or base type.

Low
  • Update

@CLAassistant
Copy link

CLAassistant commented Jan 14, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds automatic debug logging to the Selenium WebDriver Ruby bindings by enabling verbose driver output when WebDriver.logger.debug? is true. The implementation modifies the service initialization for Chrome, Edge, Firefox, and IE drivers to automatically inject appropriate debug flags.

Changes:

  • Override initialize method in Chrome, Edge, IE, and Firefox service classes to detect debug mode
  • Remove conflicting log-level arguments before adding debug flags
  • Add appropriate verbose flags for each driver (--verbose for Chrome/Edge, -v for Firefox, --log-level=DEBUG for IE)

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
rb/lib/selenium/webdriver/chrome/service.rb Add initialize override to inject --verbose flag when debug is enabled
rb/lib/selenium/webdriver/edge/service.rb Add initialize override to inject --verbose flag when debug is enabled
rb/lib/selenium/webdriver/firefox/service.rb Modify initialize to inject -v flag when debug is enabled
rb/lib/selenium/webdriver/ie/service.rb Add initialize override to inject --log-level=DEBUG when debug is enabled
rb/sig/lib/selenium/webdriver/chrome/service.rbs Add type signature for new initialize method
rb/sig/lib/selenium/webdriver/edge/service.rbs Add type signature for new initialize method
rb/sig/lib/selenium/webdriver/ie/service.rbs Add type signature for new initialize method
rb/spec/unit/selenium/webdriver/chrome/service_spec.rb Stub debug? to return false in tests
rb/spec/unit/selenium/webdriver/edge/service_spec.rb Stub debug? to return false in tests
rb/spec/unit/selenium/webdriver/firefox/service_spec.rb Stub debug? to return false in tests, update test description
rb/spec/unit/selenium/webdriver/ie/service_spec.rb Stub debug? to return false in tests
rb/spec/unit/selenium/webdriver/common/service_spec.rb Stub debug? to return false, update Firefox test expectation

Comment on lines +29 to +33
def initialize(args: nil, **)
if WebDriver.logger.debug?
args = Array(args.dup)
args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
args << '--verbose'
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new debug logging behavior lacks test coverage. There should be tests that verify the service adds the verbose flag when WebDriver.logger.debug? returns true, and that it properly removes conflicting log-level arguments before adding the verbose flag.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +33
def initialize(args: nil, **)
if WebDriver.logger.debug?
args = Array(args.dup)
args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
args << '--verbose'
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new debug logging behavior lacks test coverage. There should be tests that verify the service adds the verbose flag when WebDriver.logger.debug? returns true, and that it properly removes conflicting log-level arguments before adding the verbose flag.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +44
if WebDriver.logger.debug?
if (index = args.index('--log'))
args.delete_at(index) # delete '--log'
args.delete_at(index) # delete the value (now at same index)
elsif (index = args.index { |arg| arg.start_with?('--log=') })
args.delete_at(index)
end
args << '-v'
end
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new debug logging behavior lacks test coverage. There should be tests that verify the service adds the -v flag when WebDriver.logger.debug? returns true, and that it properly removes conflicting --log arguments before adding the -v flag.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +34
def initialize(args: nil, **)
if WebDriver.logger.debug?
args = Array(args.dup)
args.reject! { |arg| arg.include?('log-level') || arg.include?('silent') }
args << '--log-level=DEBUG'
end
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new debug logging behavior lacks test coverage. There should be tests that verify the service adds the --log-level=DEBUG flag when WebDriver.logger.debug? returns true, and that it properly removes conflicting log-level arguments before adding the DEBUG flag.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants