selenium icon indicating copy to clipboard operation
selenium copied to clipboard

[rb] Add backtrace locations and cause to errors

Open aguspe opened this issue 1 year ago • 9 comments

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

  • [x] Bug fix (non-breaking change which fixes an issue)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • [x] I have read the contributing document.
  • [ ] My change requires a change to the documentation.
  • [ ] I have updated the documentation accordingly.
  • [x] I have added tests to cover my changes.
  • [x] All new and existing tests passed.

PR Type

Enhancement, Tests


Description

  • Enhanced WebDriverError class by adding backtrace_locations method to fetch current thread's backtrace locations.
  • Enhanced WebDriverError class by adding cause method to fetch the error information.
  • Included English module for improved error handling.
  • Added tests to verify the presence of backtrace locations and cause in NoSuchElementError.

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

    aguspe avatar Jun 22 '24 00:06 aguspe

    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.

    qodo-code-review[bot] avatar Jun 22 '24 00:06 qodo-code-review[bot]

    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]

     def cause
    -  $ERROR_INFO
    +  super
     end
     
    
    • [ ] Apply this suggestion <!-- /improve --apply_suggestion=0 -->
    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]

    -expect(e.backtrace_locations).not_to be_empty
    +expect(e.backtrace_locations).to all(be_a(Thread::Backtrace::Location))
     
    
    • [ ] Apply this suggestion <!-- /improve --apply_suggestion=1 -->
    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]

    +expect(e.cause).not_to be_nil
     expect(e.cause).to be_a(WebDriver::Error::NoSuchElementError)
     
    
    • [ ] Apply this suggestion <!-- /improve --apply_suggestion=2 -->
    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]

     def backtrace_locations
    -  Thread.current.backtrace_locations
    +  Thread.current.backtrace_locations || []
     end
     
    
    • [ ] Apply this suggestion <!-- /improve --apply_suggestion=3 -->
    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

    qodo-code-review[bot] avatar Jun 22 '24 00:06 qodo-code-review[bot]

    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 avatar Jun 25 '24 19:06 aguspe

    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 avatar Jun 26 '24 13:06 aguspe

    @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

    aguspe avatar Jun 26 '24 14:06 aguspe

    @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
    

    p0deje avatar Jun 26 '24 18:06 p0deje

    @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 avatar Jun 27 '24 17:06 aguspe

    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 avatar Jun 29 '24 19:06 aguspe

    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
    >
    

    aguspe avatar Jun 29 '24 19:06 aguspe

    @p0deje whenever you have time could this get merged, so I can pull it to my other PR I'm working on and we do not need to re-run all the flows? Thank you one more time for all the help, and if anything needs update let me know

    aguspe avatar Jul 01 '24 08:07 aguspe

    This looks like it's going in the right direction! Nice work.

    ioquatix avatar Jul 13 '24 03:07 ioquatix

    This looks like it's going in the right direction! Nice work.

    Thank you so much, hopefully based on my last comment regarding the backtrace and cause we know where to go from here :) and also thank you @p0deje for all the help

    aguspe avatar Jul 13 '24 08:07 aguspe

    @p0deje I looked into the failures, and they seems to be related to the action builder and Firefox on windows, I can try to use parallels on my mac to look into them, but I'm not sure if those tests should be fixed on this PR

    aguspe avatar Jul 13 '24 21:07 aguspe

    @p0deje I looked into the failures, and they seems to be related to the action builder and Firefox on windows, I can try to use parallels on my mac to look into them, but I'm not sure if those tests should be fixed on this PR

    Don't worry about these, they are not related.

    p0deje avatar Jul 14 '24 00:07 p0deje

    You might want to split it if it's not an array of strings - you might want to test it.

    You can also see the output by using Exception#full_message which prints the message and backtrace.

    ioquatix avatar Jul 16 '24 12:07 ioquatix