SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
29.73k stars 8.02k forks source link

[rb] Add backtrace locations and cause to errors #14170

Open aguspe opened 1 week ago

aguspe commented 1 week ago

User description

Description

The goal of this PR is to provide backtrace_locations and cause for users that need to consume it

Motivation and Context

A great detail explanation of the motivation is described here #13221 and also more information is provided in #13222

Types of changes

Checklist


PR Type

Enhancement, Tests


Description


Changes walkthrough ๐Ÿ“

Relevant files
Enhancement
error.rb
Add backtrace locations and cause methods to WebDriverError class

rb/lib/selenium/webdriver/common/error.rb
  • Added backtrace_locations method to WebDriverError class to fetch
    current thread's backtrace locations.
  • Added cause method to WebDriverError class to fetch the error
    information.
  • Included English module for error handling.
  • +10/-1   
    Tests
    error_spec.rb
    Add tests for backtrace locations and cause in NoSuchElementError

    rb/spec/integration/selenium/webdriver/error_spec.rb
  • Added test to check presence of backtrace locations in
    NoSuchElementError.
  • Added test to check presence of cause in NoSuchElementError.
  • +12/-0   

    ๐Ÿ’ก PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    codiumai-pr-agent-pro[bot] commented 1 week ago

    PR Reviewer Guide ๐Ÿ”

    โฑ๏ธ Estimated effort to review [1-5] 2
    ๐Ÿงช Relevant tests Yes
    ๐Ÿ”’ Security concerns No
    โšก Key issues to review Thread Safety:
    The method backtrace_locations uses Thread.current.backtrace_locations which is thread-specific. Ensure that this usage is safe in the context of how the WebDriverError class is utilized across different threads.
    Error Handling:
    The cause method returns $ERROR_INFO, which is a global variable provided by the 'English' library for the last raised exception. Confirm that this approach correctly captures the intended exceptions in all scenarios.
    codiumai-pr-agent-pro[bot] commented 1 week ago

    PR Code Suggestions โœจ

    CategorySuggestion                                                                                                                                    Score
    Best practice
    Use super to call the parent class's cause method instead of $ERROR_INFO ___ **Instead of using $ERROR_INFO to get the cause, use super to call the parent class's cause
    method. This ensures better compatibility and maintainability.** [rb/lib/selenium/webdriver/common/error.rb [46-48]](https://github.com/SeleniumHQ/selenium/pull/14170/files#diff-942df34e1c3e79a3a6ada80fc46e4ef30a799c7a133efdff252f8b3cce4d7ea1R46-R48) ```diff def cause - $ERROR_INFO + super end ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: Using `super` instead of `$ERROR_INFO` leverages Ruby's inheritance and is more maintainable and idiomatic in Ruby, addressing a significant maintainability issue.
    8
    Enhancement
    Ensure backtrace_locations returns an array of Thread::Backtrace::Location objects ___ **Add a check to ensure that backtrace_locations returns an array of
    Thread::Backtrace::Location objects to make the test more robust.** [rb/spec/integration/selenium/webdriver/error_spec.rb [36]](https://github.com/SeleniumHQ/selenium/pull/14170/files#diff-9a507396bce1fb2360f6852a8022c9df9dcaf6869be5a95feef6571adb2bcd20R36-R36) ```diff -expect(e.backtrace_locations).not_to be_empty +expect(e.backtrace_locations).to all(be_a(Thread::Backtrace::Location)) ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: This suggestion improves the robustness of the test by ensuring that `backtrace_locations` not only exists but contains the correct type of objects.
    7
    Ensure the cause method returns a non-nil value and is an instance of the expected error class ___ **Improve the test for the cause method by checking that the cause is not nil, in addition
    to being an instance of WebDriver::Error::NoSuchElementError.** [rb/spec/integration/selenium/webdriver/error_spec.rb [42]](https://github.com/SeleniumHQ/selenium/pull/14170/files#diff-9a507396bce1fb2360f6852a8022c9df9dcaf6869be5a95feef6571adb2bcd20R42-R42) ```diff +expect(e.cause).not_to be_nil expect(e.cause).to be_a(WebDriver::Error::NoSuchElementError) ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 6 Why: This suggestion enhances the test by ensuring that the `cause` method returns meaningful and correct results, although the existing test already checks for the correct instance type.
    6
    Possible issue
    Add a guard clause to handle nil values in backtrace_locations ___ **Add a guard clause to backtrace_locations to handle cases where
    Thread.current.backtrace_locations might return nil, preventing potential errors.** [rb/lib/selenium/webdriver/common/error.rb [42-44]](https://github.com/SeleniumHQ/selenium/pull/14170/files#diff-942df34e1c3e79a3a6ada80fc46e4ef30a799c7a133efdff252f8b3cce4d7ea1R42-R44) ```diff def backtrace_locations - Thread.current.backtrace_locations + Thread.current.backtrace_locations || [] end ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: Adding a guard clause is a good practice to prevent potential runtime errors if `Thread.current.backtrace_locations` returns nil, thus improving the code's robustness.
    7
    aguspe commented 4 days ago

    I resolved the conflicts after the merge of #14174 and updated the error class, all the tests seem to be working, could I get a review? @p0deje

    aguspe commented 3 days ago

    I am not sure I follow the implementation and how it works. What we discussed in #13222 was to stop manipulating backtrace, create a nextra error instance and explicitly pass cause for errors created from the remote server in

    https://github.com/SeleniumHQ/selenium/blob/5ce55558cbadcbc6d4172dc51be98bf21287c1e4/rb/lib/selenium/webdriver/remote/response.rb#L41-L43

    . Does this PR achieve the same in some other manner?

    Oh Maybe I miss understood this, because I tried to call both backtrace_locations and case on the ex, and I noticed I couldn't so I implemented the methods that are being inherited from exception, so now when creating an error both the case and backtrace_locations are set automatically

    So for example this test:

          it 'has cause' do
            driver.find_element(id: 'nonexistent')
          rescue WebDriver::Error::NoSuchElementError => e
            expect(e.cause).to be_a(WebDriver::Error::NoSuchElementError)
          end

    returns cause as:

    #<Selenium::WebDriver::Error::NoSuchElementError: no such element: Unable to locate element: {"method":"css selector","selector":"#nonexistent"}
      (Session info: chrome=126.0.6478.116); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception>

    And this test :

    it 'has backtrace locations' do
      driver.find_element(id: 'nonexistent')
      rescue WebDriver::Error::NoSuchElementError => e
      expect(e.backtrace_locations).not_to be_empty
    end
      Returns backtrace locations as:
    
     ["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/error.rb:57:in `backtrace_locations'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/error.rb:57:in `backtrace_locations'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:36:in `rescue in block (2 levels) in <module:WebDriver>'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:34:in `block (2 levels) in <module:WebDriver>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]
    

    Also these are the methods from the exception class that I'm overriding, that returns nil even if the backtrace is not set:

       # This method is not affected by Exception#set_backtrace().
      def backtrace_locations; end
    
      # Returns the previous exception ($!) at the time this exception was raised.
      # This is useful for wrapping exceptions and retaining the original exception
      # information.
      def cause; end
    aguspe commented 3 days ago

    @p0deje I see what you are saying and I updated the implementation by removing the backtrace manipulation, and the test kept working, now I will update the cause, thank you! it's my first time working with exceptions so sorry for the confusion

    p0deje commented 3 days ago

    @aguspe I think we're a bit misaligned on what needs to be done. Let me try to explain the current implementation:

    1. When Selenium::WebDriver is used with a local driver (e.g. chromedriver) and it raises an exception, it's returned as-is.
    2. When it's used with a remote driver (e.g. Grid + chromedriver), the Grid provides extra information about the error (e.g. Grid server logs). This information is then appended to a backtrace of an original error.

    Now, what we want to do is to replace implementation in 2:

    1. Don't change the backtrace of the original error.
    2. Create one more WebDriverError with a message and a stacktrace from the server.
    3. Make it cause of the original error.

    Roughly, it would look like this in response.rb

            def error
              error, message, backtrace = process_error
              klass = Error.for_error(error) || return
    
              ex = klass.new(message)
              if backtrace
                cause = WebDriverError.new(message)
                add_backtrace(cause, backtrace)
                ex.cause = cause
              end
    
              ex
            end
    aguspe commented 2 days ago

    @aguspe I think we're a bit misaligned on what needs to be done. Let me try to explain the current implementation:

    1. When Selenium::WebDriver is used with a local driver (e.g. chromedriver) and it raises an exception, it's returned as-is.
    2. When it's used with a remote driver (e.g. Grid + chromedriver), the Grid provides extra information about the error (e.g. Grid server logs). This information is then appended to a backtrace of an original error.

    Now, what we want to do is to replace implementation in 2:

    1. Don't change the backtrace of the original error.
    2. Create one more WebDriverError with a message and a stacktrace from the server.
    3. Make it cause of the original error.

    Roughly, it would look like this in response.rb

            def error
              error, message, backtrace = process_error
              klass = Error.for_error(error) || return
    
              ex = klass.new(message)
              if backtrace
                cause = WebDriverError.new(message)
                add_backtrace(cause, backtrace)
                ex.cause = cause
              end
    
              ex
            end

    Thank you so much for the explanation @p0deje,

    The only way I found on how to get the backtrace, the backtrace_locations and the cause was the last implementation I did, So I had to raise the cause, and rescue it, and then raise the expected exception and rescue it to get the cause set,

    With the backtrace I had this odd issue if I used the method set_backtrace that shouldn't affect the backtrace_locations, it always made the backtrace_locations to be nil

    If I only raise the cause error, the cause was also always nil

    I remove again the backtrace method because again, if I set the backtrace after parsing it I lost the backtrace_locations, I hope this makes sense, and thank you one more time for all the help

    Edit:

    A quick update @p0deje, I found a way to make it work by setting the backtrace at the end after adding the cause and then returning the exception, so I think with the last commit this is the best solution to fix this bug

    aguspe commented 10 hours ago

    I hope on my last comment here the implementation makes more sense and achieve what the goal is, I couldn't add the backtrace to the cause but the backtrace is still there and also the backtrace locations, so let me know if this is closer to what is expected

    thank you so much for the help!

    @p0deje @ioquatix

    Then my recommendation would be keeping the latest implementation with:

    Cause as:

    pp e.cause
    
    Selenium::WebDriver::Error::WebDriverError

    Backtrace as:

    pp e.backtrace
    
    ["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:62:in `rescue in add_cause'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:59:in `add_cause'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:41:in `error'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:34:in `initialize'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `new'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `create_response'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/default.rb:103:in `request'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:67:in `call'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:675:in `execute'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:543:in `find_element_by'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/search_context.rb:71:in `find_element'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:48:in `block (2 levels) in <module:WebDriver>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]

    Backtrace locations as:

    pp e.backtrace_locations
    
    ["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:62:in `rescue in add_cause'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:59:in `add_cause'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:41:in `error'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:34:in `initialize'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `new'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `create_response'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/default.rb:103:in `request'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:67:in `call'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:675:in `execute'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:543:in `find_element_by'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/search_context.rb:71:in `find_element'",
     "/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:34:in `block (2 levels) in <module:WebDriver>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
     "/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]
    
    aguspe commented 10 hours ago

    Thanks for the quick review now cause includes the backtrace @p0deje

    
    pp e.cause
    
    #<Selenium::WebDriver::Error::WebDriverError: 0   chromedriver                        0x00000001006f6a80 chromedriver + 4385408
    1   chromedriver                        0x00000001006ef38c chromedriver + 4354956
    2   chromedriver                        0x000000010030cb0c chromedriver + 281356
    3   chromedriver                        0x000000010034f2f8 chromedriver + 553720
    4   chromedriver                        0x0000000100387d24 chromedriver + 785700
    5   chromedriver                        0x0000000100343eec chromedriver + 507628
    6   chromedriver                        0x00000001003448c4 chromedriver + 510148
    7   chromedriver                        0x00000001006be43c chromedriver + 4154428
    8   chromedriver                        0x00000001006c2ea0 chromedriver + 4173472
    9   chromedriver                        0x00000001006a3ff8 chromedriver + 4046840
    10  chromedriver                        0x00000001006c378c chromedriver + 4175756
    11  chromedriver                        0x0000000100696fb8 chromedriver + 3993528
    12  chromedriver                        0x00000001006e121c chromedriver + 4297244
    13  chromedriver                        0x00000001006e1398 chromedriver + 4297624
    14  chromedriver                        0x00000001006eef84 chromedriver + 4353924
    15  libsystem_pthread.dylib             0x00000001940cef94 _pthread_start + 136
    16  libsystem_pthread.dylib             0x00000001940c9d34 thread_start + 8
    >