Skip to content
34 changes: 22 additions & 12 deletions rb/lib/selenium/webdriver/firefox/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,35 @@ def initialize(args: nil, **)
args << '0'
end

if ENV.key?('SE_DEBUG')
remove_log_args(args)
args << '-v'
end
configure_debug_args(args) if ENV.key?('SE_DEBUG')

super
end

def launch
configure_debug_args(args) if ENV.key?('SE_DEBUG')

super
end

private

def remove_log_args(args)
if (index = args.index('--log'))
args.delete_at(index) # delete '--log'
args.delete_at(index) if args[index] && !args[index].start_with?('-') # delete value if present
warn_driver_log_override
elsif (index = args.index { |arg| arg.start_with?('--log=') })
args.delete_at(index)
warn_driver_log_override
def configure_debug_args(args)
# An explicit geckodriver log setting is more specific than Selenium's
# generic SE_DEBUG fallback, so preserve it and skip adding `-v`.
if args.any? { |arg| arg.start_with?('--log') }
warn_explicit_log_preference unless @log_preference_warned
@log_preference_warned = true
args.reject! { |arg| /\A-v+\z/.match?(arg) }
Copy link
Copy Markdown
Contributor

@aguspe aguspe May 4, 2026

Choose a reason for hiding this comment

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

so SE_DEBUG does not overrides the user's --log and the warning's gone, is that what we want? and why?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good point. I've amended the PR.

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.

Quick question / Minor nit. Looking at the regex here we're checking absolute starts. This can be more optimally done with #start_with? unless I'm misreading.

So you could write.

args.reject! { |arg| arg.start_with?('-v') }

return
end

args << '-v' unless args.any? { |arg| /\A-v+\z/.match?(arg) }
end

def warn_explicit_log_preference
WebDriver.logger.warn('SE_DEBUG is set; preserving user-specified geckodriver --log setting instead of ' \
'adding -v', id: :se_debug)
end
end # Service
end # Firefox
Expand Down
3 changes: 2 additions & 1 deletion rb/sig/lib/selenium/webdriver/firefox/service.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module Selenium

private

def remove_log_args: (Array[String] args) -> void
def configure_debug_args: (Array[String] args) -> void
def warn_explicit_log_preference: () -> void
end
end
end
Expand Down
7 changes: 3 additions & 4 deletions rb/spec/integration/selenium/webdriver/bidi/script_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ def a_stack_frame(**options)
)
# Stack traces on console messages are optional.
expect(log_entry.stack_trace).to be_nil.or match(
# Some browsers include stack traces from parts of the runtime, so we
# just check the first frames that come from user code.
# Some browsers include stack traces from parts of the runtime, and
# Firefox beta may only report the first user-code frame here.
'callFrames' => start_with(
a_stack_frame('functionName' => 'helloWorld'),
a_stack_frame('functionName' => 'onclick')
a_stack_frame('functionName' => 'helloWorld')
)
)
end
Expand Down
22 changes: 12 additions & 10 deletions rb/spec/integration/selenium/webdriver/remote/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@
module Selenium
module WebDriver
describe Element, exclusive: {bidi: false, reason: 'Not yet implemented with BiDi'} do
def uploaded_body_text
driver.switch_to.frame('upload_target')
wait.until do
text = driver.find_element(tag_name: 'body').text
text unless text.empty?
rescue Error::StaleElementReferenceError
nil
end
end

before do
driver.file_detector = lambda(&:first)
end
Expand All @@ -39,11 +49,7 @@ module WebDriver
driver.find_element(id: 'go').click
wait.until { driver.find_element(id: 'upload_label').displayed? }

driver.switch_to.frame('upload_target')
wait.until { !driver.find_element(xpath: '//body').text.empty? }

body = driver.find_element(xpath: '//body')
expect(body.text.scan('This is a dummy test file').count).to eq(1)
expect(uploaded_body_text.scan('This is a dummy test file').count).to eq(1)
end
end

Expand All @@ -60,11 +66,7 @@ module WebDriver
driver.find_element(id: 'go').click
wait.until { driver.find_element(id: 'upload_label').displayed? }

driver.switch_to.frame('upload_target')
wait.until { !driver.find_element(xpath: '//body').text.empty? }

body = driver.find_element(xpath: '//body')
expect(body.text.scan('This is a dummy test file').count).to eq(2)
expect(uploaded_body_text.scan('This is a dummy test file').count).to eq(2)
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion rb/spec/tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,13 @@ def rb_integration_test(name, srcs, deps = [], data = [], browsers = BROWSERS.ke
target_compatible_with = BROWSERS[browser]["target_compatible_with"],
)

def rb_unit_test(name, srcs, deps, data = []):
def rb_unit_test(name, srcs, deps, data = [], flaky = False):
rb_test(
name = name,
size = "small",
srcs = srcs,
args = ["rb/spec/"],
flaky = flaky,
main = "@bundle//bin:rspec",
data = data,
tags = ["no-sandbox"], # TODO: Do we need this?
Expand Down
12 changes: 11 additions & 1 deletion rb/spec/unit/selenium/webdriver/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ rb_unit_test(
],
)

rb_unit_test(
name = "zipper",
srcs = ["zipper_spec.rb"],
flaky = True,
deps = ["//rb/lib/selenium/webdriver:common"],
)

[
rb_unit_test(
name = file[:-8],
Expand All @@ -32,6 +39,9 @@ rb_unit_test(
)
for file in glob(
["*_spec.rb"],
exclude = ["search_context_spec.rb"],
exclude = [
"search_context_spec.rb",
"zipper_spec.rb",
],
)
]
52 changes: 43 additions & 9 deletions rb/spec/unit/selenium/webdriver/firefox/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,18 @@ module Firefox
describe '#new' do
let(:service_path) { "/path/to/#{Service::EXECUTABLE}" }

around do |example|
original_debug = ENV.fetch('SE_DEBUG', nil)
ENV.delete('SE_DEBUG')
example.run
ensure
original_debug ? ENV['SE_DEBUG'] = original_debug : ENV.delete('SE_DEBUG')
end

before do
allow(Platform).to receive(:assert_executable)
allow(WebDriver.logger).to receive(:debug?).and_return(false)
allow(WebDriver.logger).to receive(:warn)
end

it 'uses default port and nil path' do
Expand Down Expand Up @@ -103,10 +112,11 @@ module Firefox

context 'when SE_DEBUG is set' do
around do |example|
original_debug = ENV.fetch('SE_DEBUG', nil)
ENV['SE_DEBUG'] = '1'
example.run
ensure
ENV.delete('SE_DEBUG')
original_debug ? ENV['SE_DEBUG'] = original_debug : ENV.delete('SE_DEBUG')
end

it 'adds -v flag' do
Expand All @@ -115,27 +125,51 @@ module Firefox
expect(service.extra_args).to include('-v')
end

it 'removes conflicting --log args with value' do
it 'preserves conflicting --log args with value and warns' do
service = described_class.new(args: ['--log', 'info'])

expect(service.extra_args).to include('-v')
expect(service.extra_args).not_to include('--log')
expect(service.extra_args).not_to include('info')
expect(service.extra_args).not_to include('-v')
expect(service.extra_args).to include('--log')
expect(service.extra_args).to include('info')
expect(WebDriver.logger).to have_received(:warn).with(
'SE_DEBUG is set; preserving user-specified geckodriver --log setting instead of adding -v',
id: :se_debug
)
end

it 'removes conflicting --log= args' do
it 'preserves conflicting --log= args and warns' do
service = described_class.new(args: ['--log=info'])

expect(service.extra_args).to include('-v')
expect(service.extra_args).not_to include('--log=info')
expect(service.extra_args).not_to include('-v')
expect(service.extra_args).to include('--log=info')
expect(WebDriver.logger).to have_received(:warn).with(
'SE_DEBUG is set; preserving user-specified geckodriver --log setting instead of adding -v',
id: :se_debug
)
end

it 'does not remove next arg if --log has no value' do
service = described_class.new(args: ['--log', '--other-flag'])

expect(service.extra_args).to include('-v')
expect(service.extra_args).not_to include('-v')
expect(service.extra_args).to include('--log')
expect(service.extra_args).to include('--other-flag')
end

it 'preserves conflicting --log args added after initialization' do
service = described_class.new(path: service_path)
manager = instance_double(ServiceManager, start: nil)
service.args.push('--log', 'trace')

allow(ServiceManager).to receive(:new).with(service).and_return(manager)

service.launch

expect(service.extra_args).not_to include('-v')
expect(service.extra_args).to include('--log')
expect(service.extra_args).to include('trace')
expect(WebDriver.logger).to have_received(:warn).once
end
end
end

Expand Down
15 changes: 14 additions & 1 deletion rb/spec/unit/selenium/webdriver/support/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ load("//rb/spec:tests.bzl", "rb_unit_test")

package(default_visibility = ["//rb:__subpackages__"])

rb_unit_test(
name = "select",
srcs = ["select_spec.rb"],
flaky = True,
deps = [
"//rb/lib/selenium/webdriver:common",
"//rb/lib/selenium/webdriver:remote",
],
)

[
rb_unit_test(
name = file[:-8],
Expand All @@ -11,5 +21,8 @@ package(default_visibility = ["//rb:__subpackages__"])
"//rb/lib/selenium/webdriver:remote",
],
)
for file in glob(["*_spec.rb"])
for file in glob(
["*_spec.rb"],
exclude = ["select_spec.rb"],
)
]
Loading