diff --git a/rb/lib/selenium/webdriver/remote/response.rb b/rb/lib/selenium/webdriver/remote/response.rb index 453a04a2c0695..ce544b948964e 100644 --- a/rb/lib/selenium/webdriver/remote/response.rb +++ b/rb/lib/selenium/webdriver/remote/response.rb @@ -58,12 +58,30 @@ def assert_ok def add_cause(ex, error, backtrace) cause = Error::WebDriverError.new + backtrace = backtrace_from_remote(backtrace) if backtrace.is_a?(Array) cause.set_backtrace(backtrace) raise ex, cause: cause rescue Error.for_error(error) ex end + def backtrace_from_remote(server_trace) + server_trace.filter_map do |frame| + next unless frame.is_a?(Hash) + + file = frame['fileName'] + line = frame['lineNumber'] + method = frame['methodName'] + + class_name = frame['className'] + file = "#{class_name}(#{file})" if class_name + + method = 'unknown' if method.nil? || method.empty? + + "[remote server] #{file}:#{line}:in `#{method}'" + end + end + def process_error return unless self['value'].is_a?(Hash) diff --git a/rb/sig/lib/selenium/webdriver/remote/response.rbs b/rb/sig/lib/selenium/webdriver/remote/response.rbs index c2955447fa993..29c806ff74283 100644 --- a/rb/sig/lib/selenium/webdriver/remote/response.rbs +++ b/rb/sig/lib/selenium/webdriver/remote/response.rbs @@ -22,6 +22,8 @@ module Selenium def add_cause: (Error::WebDriverError ex, String error, Array[String] backtrace) -> Error::WebDriverError + def backtrace_from_remote: -> Array[String] + def process_error: () -> Array[Hash[untyped, untyped]] end end diff --git a/rb/spec/integration/selenium/webdriver/error_spec.rb b/rb/spec/integration/selenium/webdriver/error_spec.rb index 936b2186e6491..7a72860c0340c 100644 --- a/rb/spec/integration/selenium/webdriver/error_spec.rb +++ b/rb/spec/integration/selenium/webdriver/error_spec.rb @@ -47,6 +47,18 @@ module WebDriver rescue WebDriver::Error::NoSuchElementError => e expect(e.backtrace).not_to be_empty end + + it 'has backtrace when using a remote server', only: {driver: :remote, + reason: 'This test should only apply to remote drivers'} do + unless driver.is_a?(WebDriver::Remote::Driver) + raise 'This error needs to be risen for the pending test not to fail on local drivers' + end + + driver.send(:bridge).instance_variable_set(:@session_id, 'fake_session_id') + driver.window_handle + rescue WebDriver::Error::InvalidSessionIdError => e + expect(e.backtrace).not_to be_empty + end end end # WebDriver end # Selenium