Skip to content

[py] Refactored conftest.py in a more object oriented design approach #15495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: trunk
Choose a base branch
from

Conversation

sandeepsuryaprasad
Copy link
Contributor

@sandeepsuryaprasad sandeepsuryaprasad commented Mar 23, 2025

User description

Thanks for contributing to Selenium!
A PR well described will help maintainers to quickly review and merge it

Before submitting your PR, please check our contributing guidelines.
Avoid large PRs, help reviewers by making them as simple and short as possible.

Refactored conftest.py in a more object oriented design approach

Motivation and Context

Refactored conftest.py in a more object oriented design approach so that the code is more readable and easy to make changes in the future.

Types of changes

  • 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

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

PR Type

Enhancement


Description

  • Refactored conftest.py to an object-oriented design for better readability.

  • Introduced a Driver class to encapsulate driver-related logic and properties.

  • Simplified driver initialization and teardown using the Driver class.

  • Removed redundant functions and streamlined driver configuration handling.


Changes walkthrough 📝

Relevant files
Enhancement
conftest.py
Refactored `conftest.py` with a `Driver` class                     

py/conftest.py

  • Introduced a Driver class to encapsulate driver logic.
  • Simplified driver initialization and teardown processes.
  • Removed redundant helper functions for driver options and services.
  • Improved code readability and maintainability with object-oriented
    design.
  • +111/-111

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Incorrect Property Usage

    The driver property doesn't return the driver instance if it's already initialized. It only returns a value when _driver is None, which could lead to unexpected behavior.

    @property
    def driver(self):
        if not self._driver:
            return self._initialize_driver()
    Platform Reference Error

    The code references 'driver_instance.exe_platform' but this attribute doesn't exist. It should be using 'selenium_driver.exe_platform' instead.

    if driver_class == "Safari" and driver_instance.exe_platform != "Darwin":
        pytest.skip("Safari tests can only run on an Apple OS")
    if driver_class == "Ie" and driver_instance.exe_platform != "Windows":
        pytest.skip("IE and EdgeHTML Tests can only run on Windows")
    if "WebKit" in driver_class and driver_instance.exe_platform != "Linux":
        pytest.skip("Webkit tests can only run on Linux")
    Redundant Fixture

    The 'stop_driver' fixture at line 236 appears to be empty and redundant since driver cleanup is now handled by the Driver class's stop_driver method.

    @pytest.fixture(scope="session", autouse=True)
    def stop_driver(request):
        def fin():

    Copy link
    Contributor

    qodo-merge-pro bot commented Mar 23, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix platform detection
    Suggestion Impact:The commit directly implemented the suggestion by changing self._platform = platform to self._platform = platform.system(), fixing the platform detection bug. This change is also reflected in the platform comparison checks later in the code.

    code diff:

    -        self._platform = platform
    +        self._platform = platform.system()

    The property is storing the platform module instead of the platform name. It
    should call platform.system() to get the actual platform name.

    py/conftest.py [113-116]

     @property
     def exe_platform(self):
    -    self._platform = platform
    +    self._platform = platform.system()
         return self._platform

    [Suggestion has been applied]

    Suggestion importance[1-10]: 10

    __

    Why: This fixes a critical bug where the platform module object is being stored instead of the actual platform name (string). This would cause platform-specific checks to fail, as seen in lines 212-217 where platform comparisons are made.

    High
    Return existing driver instance
    Suggestion Impact:The suggestion was directly implemented in the commit. Line 37 adds 'return self._driver' to the driver property method, exactly as suggested, ensuring the property returns the existing driver instance when it's already initialized.

    code diff:

             if not self._driver:
                 return self._initialize_driver()
    +        return self._driver

    The driver property doesn't return the driver instance when it's already
    initialized. It should return self._driver if it exists, otherwise initialize
    and return it.

    py/conftest.py [184-187]

     @property
     def driver(self):
         if not self._driver:
             return self._initialize_driver()
    +    return self._driver

    [Suggestion has been applied]

    Suggestion importance[1-10]: 9

    __

    Why: This is a critical bug fix. The current implementation only returns a value when initializing a new driver but doesn't return anything when the driver already exists, which would cause the property to return None in subsequent calls, breaking driver functionality.

    High
    Return None for missing executable
    Suggestion Impact:The suggestion was directly implemented in the commit. Line 31 of the diff shows the exact addition of 'return None' to the service property method when executable is falsy, exactly as suggested.

    code diff:

    @@ -180,15 +179,19 @@
                 module = getattr(webdriver, self._driver_class.lower())
                 self._service = module.service.Service(executable_path=executable)
                 return self._service
    +        return None

    The service property doesn't return anything when executable is falsy, which
    could cause unexpected behavior. It should return None explicitly in this case.

    py/conftest.py [176-182]

     @property
     def service(self):
         executable = self.driver_path
         if executable:
             module = getattr(webdriver, self._driver_class.lower())
             self._service = module.service.Service(executable_path=executable)
             return self._service
    +    return None

    [Suggestion has been applied]

    Suggestion importance[1-10]: 7

    __

    Why: This improves code clarity and prevents potential issues by explicitly returning None when no executable is provided. Without this fix, the property would return undefined, which could lead to unexpected behavior when the service property is accessed.

    Medium
    • Update

    @sandeepsuryaprasad sandeepsuryaprasad changed the title Refactored conftest.py in a more object oriented design approach [py] Refactored conftest.py in a more object oriented design approach Mar 23, 2025
    @titusfortner titusfortner requested a review from cgoldberg March 23, 2025 15:54
    Copy link
    Contributor

    @cgoldberg cgoldberg left a comment

    Choose a reason for hiding this comment

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

    @sandeepsuryaprasad thanks for the PR! Overall this looks really nice.

    I pulled your branch and ran some tests, and noticed that the browser now closes and re-opens between every test. Previously, it was re-using the same browser instance between tests.

    For example, if you run pytest py/test/selenium/webdriver/common/typing_tests.py you will notice this. The same tests running against trunk behave different. This makes the tests take significantly longer to run. Can you look into that and make it so it behaves like it used to?

    Also, the AI bot found some minor issues. Could you address these?:
    #15495 (comment)

    @cgoldberg
    Copy link
    Contributor

    There are some TypeError failures in CI that seem to be related to this PR also:

    https://github.com/SeleniumHQ/selenium/actions/runs/14020548932/job/39252777029?pr=15495#annotation:18:66830

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg sure.. I figured out what went wrong.. I will fix it and push the code once agin.

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad great, I'll give it another look once you update.

    @cgoldberg
    Copy link
    Contributor

    cgoldberg commented Mar 24, 2025

    @sandeepsuryaprasad I tried again after your latest changes and there are still issues.

    • the browser still closes/re-opens between tests

    • something is wrong with driver_class?

    If I try to run tests with the argument --driver=safari (I'm on Linux), the tests should be skipped. This isn't happening, and all tests attempt to run and fail.

    Similarly, if I run tests with the argument --driver=webkitgtk, all tests fail with messages like this:

    request = <SubRequest 'driver' for <Function test_should_type_an_integer[webkitgtk]>>
    
        @pytest.fixture(scope="function")
        def driver(request):
            global driver_instance
            driver_class = getattr(request, "param", "Chrome").capitalize()
            selenium_driver = Driver(driver_class, request)
    >       driver_instance = selenium_driver.driver
    
    py/conftest.py:212: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    py/conftest.py:187: in driver
        return self._initialize_driver()
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    self = <conftest.Driver object at 0x7fb251afafd0>
    
        def _initialize_driver(self):
            if self.options:
                self.kwargs["options"] = self.options
            if self.driver_path:
                self.kwargs["service"] = self.service
    >       self._driver = getattr(webdriver, self._driver_class)(**self.kwargs)
    E       AttributeError: module 'selenium.webdriver' has no attribute 'Webkitgtk'
    
    py/conftest.py:195: AttributeError
    

    I haven't looked into what is causing these, but they need to be fixed before we can merge this.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I am working on it..running tests on my local machine..

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg can you try it now.. except remote tests all other tests are passing when I run CI on my machine. Regarding closing and re-opening of the browser for every test, the scope of the fixture driver is at function level @pytest.fixture(scope="function") and i have not changed the scope of this fixture in my latest change.. so the setup and teardown is happening for each test method. Do you suspect any other thing going wrong here?..

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad The issues I mentioned in my last comment are still there... I don't see any changes that fix them.

    As far as the browser closing/re-opening... I haven't investigated the cause, but it didn't do that before (run the tests against trunk to see). We don't want to introduce that change, so it needs to function the same way as it did previously.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I have fixed driver_class issues. Now the tests are getting skipped if there is a platform and browser mismatch. Below are the results when executed on Mac. Can you please re-validate once again.

    ============================= test session starts ==============================
    platform darwin -- Python 3.11.1, pytest-7.4.4, pluggy-1.5.0
    rootdir: /Users/sandeep/Documents/selenium/py
    configfile: pyproject.toml
    plugins: instafail-0.4.2, html-3.2.0, mock-3.10.0, trio-0.8.0, xdist-3.3.1, metadata-2.0.4
    collected 30 items
    
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_press_events[webkitgtk] SKIPPED [  3%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_down_events[webkitgtk] SKIPPED [  6%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_up_events[webkitgtk] SKIPPED [ 10%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_lower_case_letters[webkitgtk] SKIPPED [ 13%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_capital_letters[webkitgtk] SKIPPED [ 16%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_quote_marks[webkitgtk] SKIPPED [ 20%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_the_at_character[webkitgtk] SKIPPED [ 23%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_mix_upper_and_lower_case_letters[webkitgtk] SKIPPED [ 26%]
    py/test/selenium/webdriver/common/typing_tests.py::test_arrow_keys_should_not_be_printable[webkitgtk] SKIPPED [ 30%]
    py/test/selenium/webdriver/common/typing_tests.py::test_list_of_arrow_keys_should_not_be_printable[webkitgtk] SKIPPED [ 33%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_use_arrow_keys[webkitgtk] SKIPPED [ 36%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_up_when_entering_text_into_input_elements[webkitgtk] SKIPPED [ 40%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_down_when_entering_text_into_input_elements[webkitgtk] SKIPPED [ 43%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_press_when_entering_text_into_input_elements[webkitgtk] SKIPPED [ 46%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_up_when_entering_text_into_text_areas[webkitgtk] SKIPPED [ 50%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_down_when_entering_text_into_text_areas[webkitgtk] SKIPPED [ 53%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_press_when_entering_text_into_text_areas[webkitgtk] SKIPPED [ 56%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_report_key_code_of_arrow_keys_up_down_events[webkitgtk] SKIPPED [ 60%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numeric_non_shift_keys[webkitgtk] SKIPPED [ 63%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numeric_shift_keys[webkitgtk] SKIPPED [ 66%]
    py/test/selenium/webdriver/common/typing_tests.py::test_lower_case_alpha_keys[webkitgtk] SKIPPED [ 70%]
    py/test/selenium/webdriver/common/typing_tests.py::test_uppercase_alpha_keys[webkitgtk] SKIPPED [ 73%]
    py/test/selenium/webdriver/common/typing_tests.py::test_all_printable_keys[webkitgtk] SKIPPED [ 76%]
    py/test/selenium/webdriver/common/typing_tests.py::test_arrow_keys_and_page_up_and_down[webkitgtk] SKIPPED [ 80%]
    py/test/selenium/webdriver/common/typing_tests.py::test_delete_and_backspace_keys[webkitgtk] SKIPPED [ 83%]
    py/test/selenium/webdriver/common/typing_tests.py::test_special_space_keys[webkitgtk] SKIPPED [ 86%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numberpad_and_function_keys[webkitgtk] SKIPPED [ 90%]
    py/test/selenium/webdriver/common/typing_tests.py::test_shift_selection_deletes[webkitgtk] SKIPPED [ 93%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_into_input_elements_that_have_no_type_attribute[webkitgtk] SKIPPED [ 96%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_an_integer[webkitgtk] SKIPPED [100%]
    
    ============================= 30 skipped in 0.11s ==============================
    
    ============================= test session starts ==============================
    platform darwin -- Python 3.11.1, pytest-7.4.4, pluggy-1.5.0
    rootdir: /Users/sandeep/Documents/selenium/py
    configfile: pyproject.toml
    plugins: instafail-0.4.2, html-3.2.0, mock-3.10.0, trio-0.8.0, xdist-3.3.1, metadata-2.0.4
    collected 30 items
    
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_press_events[ie] SKIPPED [  3%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_down_events[ie] SKIPPED [  6%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_fire_key_up_events[ie] SKIPPED [ 10%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_lower_case_letters[ie] SKIPPED [ 13%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_capital_letters[ie] SKIPPED [ 16%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_quote_marks[ie] SKIPPED [ 20%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_type_the_at_character[ie] SKIPPED [ 23%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_mix_upper_and_lower_case_letters[ie] SKIPPED [ 26%]
    py/test/selenium/webdriver/common/typing_tests.py::test_arrow_keys_should_not_be_printable[ie] SKIPPED [ 30%]
    py/test/selenium/webdriver/common/typing_tests.py::test_list_of_arrow_keys_should_not_be_printable[ie] SKIPPED [ 33%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_be_able_to_use_arrow_keys[ie] SKIPPED [ 36%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_up_when_entering_text_into_input_elements[ie] SKIPPED [ 40%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_down_when_entering_text_into_input_elements[ie] SKIPPED [ 43%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_press_when_entering_text_into_input_elements[ie] SKIPPED [ 46%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_up_when_entering_text_into_text_areas[ie] SKIPPED [ 50%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_down_when_entering_text_into_text_areas[ie] SKIPPED [ 53%]
    py/test/selenium/webdriver/common/typing_tests.py::test_will_simulate_akey_press_when_entering_text_into_text_areas[ie] SKIPPED [ 56%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_report_key_code_of_arrow_keys_up_down_events[ie] SKIPPED [ 60%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numeric_non_shift_keys[ie] SKIPPED [ 63%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numeric_shift_keys[ie] SKIPPED [ 66%]
    py/test/selenium/webdriver/common/typing_tests.py::test_lower_case_alpha_keys[ie] SKIPPED [ 70%]
    py/test/selenium/webdriver/common/typing_tests.py::test_uppercase_alpha_keys[ie] SKIPPED [ 73%]
    py/test/selenium/webdriver/common/typing_tests.py::test_all_printable_keys[ie] SKIPPED [ 76%]
    py/test/selenium/webdriver/common/typing_tests.py::test_arrow_keys_and_page_up_and_down[ie] SKIPPED [ 80%]
    py/test/selenium/webdriver/common/typing_tests.py::test_delete_and_backspace_keys[ie] SKIPPED [ 83%]
    py/test/selenium/webdriver/common/typing_tests.py::test_special_space_keys[ie] SKIPPED [ 86%]
    py/test/selenium/webdriver/common/typing_tests.py::test_numberpad_and_function_keys[ie] SKIPPED [ 90%]
    py/test/selenium/webdriver/common/typing_tests.py::test_shift_selection_deletes[ie] SKIPPED [ 93%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_into_input_elements_that_have_no_type_attribute[ie] SKIPPED [ 96%]
    py/test/selenium/webdriver/common/typing_tests.py::test_should_type_an_integer[ie] SKIPPED [100%]
    
    ============================= 30 skipped in 0.12s ==============================
    

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg working on browser closing/re-opening issue.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg Looks like there is some bug in the below code that I have taken from contest.py from trunk. The teardown code which is defined in function fin and request.addfinalizer(fin) gets executed only if
    marker = request.node.get_closest_marker(f"xfail_{driver_class.lower()}") condition evaluates to truthy.

    But the variable marker never gets evaluated to boolean True for the test that have been marked as expected failure. Below are the test that are marked as expected failure in typing_tests.py which are expected to fail on safari

    • test_will_simulate_akey_up_when_entering_text_into_input_elements
    • test_will_simulate_akey_down_when_entering_text_into_input_elements
    • test_will_simulate_akey_press_when_entering_text_into_input_elements
    • test_will_simulate_akey_up_when_entering_text_into_text_areas
    • test_will_simulate_akey_down_when_entering_text_into_text_areas
    • test_will_simulate_akey_press_when_entering_text_into_text_areas

    If you carefully observe the execution, except for the above tests, for all other tests a new instance of chrome opens (setup part) and closes (teardown part, request.addfinalizer(fin) gets executed). But for the above mentioned tests, teardown code never gets executed.. the reason is if marker is not None: is never truthy. because marker will be None so request.addfinalizer(fin) never gets executed and typing happens on the same browser that was opened by the test test_will_simulate_akey_up_when_entering_text_into_input_elements Below is the current code in trunk/conftest.py which I suspect is buggy.

    # conditionally mark tests as expected to fail based on driver
    marker = request.node.get_closest_marker(f"xfail_{driver_class.lower()}")
    
        if marker is not None:
            if "run" in marker.kwargs:
                if marker.kwargs["run"] is False:
                    pytest.skip()
                    yield
                    return
            if "raises" in marker.kwargs:
                marker.kwargs.pop("raises")
            pytest.xfail(**marker.kwargs)
    
            def fin():
                global driver_instance
                if driver_instance is not None:
                    driver_instance.quit()
                driver_instance = None
    
            request.addfinalizer(fin)
    

    But in the PR that I have raised, the teardown part request.addfinalizer(selenium_driver.stop_driver) is outside the condition if marker is not None: So the teardown code gets executed irrespective of weather if marker is not None: evaluates to truthy or falsy. And this should be the expected behaviour. Because all of the 6 tests that are mentioned above are independant tests and for each of the tests, the fixture driver is passed and the scope of the fixture is function. So the right behaviour is setup and teardown must be executed irrespective of what happens to if marker is not None: condition. Below is the code in my PR.

    # conditionally mark tests as expected to fail based on driver
    marker = request.node.get_closest_marker(f"xfail_{driver_class.lower()}")
    
    if marker is not None:
            if "run" in marker.kwargs:
                if marker.kwargs["run"] is False:
                    pytest.skip()
                    yield
                    return
            if "raises" in marker.kwargs:
                marker.kwargs.pop("raises")
            pytest.xfail(**marker.kwargs)
    
    request.addfinalizer(selenium_driver.stop_driver)
    

    Please let me know your thoughts on this. Thanks!

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I have fixed all the review comments. After the code change in this PR, the behaviour is exactly same as it was on trunk. Can you please re-trigger the CI. I have executed all tests on my local and it's passing.

    • Fixed browser closing/reopening issue
    • The tests will be skipped if ran on browser with incompatible platform.

    @cgoldberg
    Copy link
    Contributor

    I just triggered CI again.

    @sandeepsuryaprasad sandeepsuryaprasad force-pushed the refactor branch 2 times, most recently from a4b0eb6 to 3caaf8c Compare March 31, 2025 09:14
    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I have modified the code, introduced one more level of abstraction for handling driver classes and options classes. Please let me know your feedback. I ran all the tests on my local and it's passing.

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad I realized that the issue I brought up in my last comment exists in the current (trunk) code. I fixed it in a separate PR that was just merged. See PR #15550 for details. This will cause conflicts with your branch. Could you please roll back your latest commit and incorporate the changes I made that are now in trunk? Thanks.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I have resolved the conflicts and committed the latest changes. All tests are passing in local. Now the driver classes and option classes are being maintained in a separate class just to get rid of driver class hassle. Please let me know your feedback on this.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg done! now I am catching TypeError as well. But the function def get_driver_class(driver_option): is no more required since we are maintaining driver classes and option classes in a separate data class..

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg can you trigger CI for this one please.

    @cgoldberg
    Copy link
    Contributor

    CI is running now.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I took a look at the results.. tests are passing apart from 3 flaky tests

    //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py FAILED in 3 out of 3 in 4.4s
    //py:common-edge-bidi-test/selenium/webdriver/common/w3c_interaction_tests.py FAILED in 3 out of 3 in 10.4s
    //py:test-remote-test/selenium/webdriver/common/quit_tests.py            FAILED in 3 out of 3 in 6.0s
    

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg can we have this PR merged to the main trunk. Thanks!

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg there is no change in the test results.. except for those 3 flakey tests, others are passing.. I think we can merge this PR to main trunk.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg can you please get this one merged.. or is there anything that needs to be changed from my end. There was one merge conflict.. I have resolved it..

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I have resolved the merge conflicts.. I have included the Firefox change from trunk to the current branch.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg can we have this one merged if everything is okay.

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad I need to take a look again and decide if this PR improves things or just adds complexity. I will update this issue once I get a chance.

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad

    There are 2 failures in CI. The error coming from api_example_tests.py seems to be a bad test that I will investigate.

    However, the other one (bidi_network_tests.py) seems to be legitimate. On my local machine, I can run it fine using trunk, but it consistently fails in your branch.

    Can you take a look?

    Note: this is a new test covering new functionality, so I'm not that familiar with it yet... but it only fails in your branch. Also, the test seems to pass if I run it alone, but fails when I run the full test file, so it leads me to believe there is something wrong in one of the pytest fixtures.

    $ pytest py/test/selenium/webdriver/common/bidi_network_tests.py --bidi
    =========================================================================================== test session starts ===========================================================================================
    platform linux -- Python 3.13.2, pytest-7.4.4, pluggy-1.5.0
    rootdir: /home/cgoldberg617/code/selenium/py
    configfile: pyproject.toml
    plugins: mock-3.12.0, instafail-0.5.0, trio-0.8.0
    collected 8 items                                                                                                                                                                                         
    
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_network_initialized PASSED                                                                                                            [ 12%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_add_intercept PASSED                                                                                                                  [ 25%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_remove_intercept FAILED                                                                                                               [ 37%]
    ------------------------------------------------------------------------------------------- live log logreport --------------------------------------------------------------------------------------------
    ERROR    websocket:_logging.py:77 Connection to remote host was lost. - goodbye
    
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_add_and_remove_request_handler PASSED                                                                                                 [ 50%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_clear_request_handlers PASSED                                                                                                         [ 62%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_continue_request XFAIL                                                                                                                [ 75%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_continue_with_auth XFAIL                                                                                                              [ 87%]
    py/test/selenium/webdriver/common/bidi_network_tests.py::test_remove_auth_handler XFAIL                                                                                                             [100%]
    -------------------------------------------------------------------------------------------- live log teardown --------------------------------------------------------------------------------------------
    ERROR    websocket:_logging.py:77 Connection to remote host was lost. - goodbye
    
    
    ================================================================================================ FAILURES =================================================================================================
    __________________________________________________________________________________________ test_remove_intercept __________________________________________________________________________________________
    
    driver = <selenium.webdriver.chrome.webdriver.WebDriver (session="74d80a0c37ffb9c2c9934ad66e8ce726")>
    
        def test_remove_intercept(driver):
            result = driver.network._add_intercept()
            driver.network._remove_intercept(result["intercept"])
    >       assert driver.network.intercepts == [], "Intercept not removed"
    E       AssertionError: Intercept not removed
    E       assert ['e33b122b-b5...ac4716599bfd'] == []
    E         Left contains one more item: 'e33b122b-b59d-474f-955b-ac4716599bfd'
    E         Full diff:
    E         - []
    E         + ['e33b122b-b59d-474f-955b-ac4716599bfd']
    
    py/test/selenium/webdriver/common/bidi_network_tests.py:36: AssertionError
    ========================================================================================= short test summary info =========================================================================================
    FAILED py/test/selenium/webdriver/common/bidi_network_tests.py::test_remove_intercept - AssertionError: Intercept not removed
    ================================================================================= 1 failed, 4 passed, 3 xfailed in 3.56s ==================================================================================
    

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg sure... I will take a look at that test... I will update on that.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    2 participants