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

Merged
merged 34 commits into from
Jun 7, 2025

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 sandeepsuryaprasad force-pushed the refactor branch 2 times, most recently from 2c5d02f to 1e518ac Compare March 30, 2025 17:18
    @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 3 times, most recently from 14fc4f6 to 3caaf8c Compare March 31, 2025 10:32
    @sandeepsuryaprasad
    Copy link
    Contributor Author

    sandeepsuryaprasad commented Mar 31, 2025

    @cgoldberg there were some logical issues with newly developed Driver class. I have completely re-structured the entire class now. I ran below browser tests and all are passing without any issues on my local.

    • bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:common-chrome-bidi
    • bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:common-firefox-bidi
    • bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-chrome
    • bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-firefox
    • bazel test --jobs 1 //py:test-remote

    Could you please validate once and re-trigger the CI. Hopefully this time everything should be okay. It was little bit trickier than I thought it would be!

    @cgoldberg
    Copy link
    Contributor

    I just triggered CI.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg looks like the tests are passing except some flakey ones
    //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

    executed //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py separately once again..

    ~$ bazel test //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py
    INFO: Analyzed target //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py (0 packages loaded, 5 targets configured).
    INFO: Found 1 test target...
    Target //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py up-to-date:
      bazel-bin/py/common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py
      bazel-bin/py/common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py-runner.py
    INFO: Elapsed time: 2.470s, Critical Path: 0.31s
    INFO: 1 process: 1 internal.
    INFO: Build completed successfully, 1 total action
    //py:common-chrome-bidi-test/selenium/webdriver/common/api_example_tests.py (cached) PASSED in 35.5s
    
    Executed 0 out of 1 test: 1 test passes.
    There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
    

    @cgoldberg
    Copy link
    Contributor

    @sandeepsuryaprasad
    I pulled your branch and ran the tests that failed in CI, and they passed locally.

    However, I found one issue with the tests for WebKitGTK and WPEWebKit... I don't think we run these in CI (not sure why).

    for example, if I try to run any test using the --driver=webkitgtk arg, they will fail with AttributeError: module 'selenium.webdriver' has no attribute 'Webkitgtk'. Did you mean: 'webkitgtk'?.

    Note the Capitalization... It is trying to instantiate Webkitgtk() rather than the correct class name WebKitGTK().

    This is caused by the following line inside your driver function:
    driver_class = getattr(request, "param", "Chrome").capitalize()

    We can't make the assumption that the class name is always the capitalized request.param. This is not correct in the case of WebKitGTK and WPEWebKit.

    You could fix it by replacing that line with:

    driver_class = getattr(request, "param", "Chrome").capitalize()
    if driver_class == "Webkitgtk":
        driver_class = "WebKitGTK"
    elif driver_class == "Wpewebkit":
        driver_class = "WPEWebKit"
    

    ... but perhaps there is a nicer solution?

    (BTW, I can't get the --driver=wpewebkit tests to run locally even on trunk, but that is unrelated to your change and I will investigate that separately)

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg I am working on this issue to provide an elegant solution..

    @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.

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg @shbenzer I have made all the required changes which accommodates the changes made in PR's that recently got merged and that affected conftest.py. It would be great if you can review it and let me know your feedback. Thanks!

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @cgoldberg @shbenzer can we take a final call in this PR.. It's been quite a while since I started working on this PR. so just wanted to wrap it up if everything is okay to you guys.. Thanks!

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @shbenzer @cgoldberg can we have this PR merged to trunk... please let me know if you have any suggestions/changes to make.. I will do it.. Thanks!

    @shbenzer
    Copy link
    Contributor

    shbenzer commented Jun 6, 2025

    Failure in CI doesn't appear to be related to pr

    @sandeepsuryaprasad
    Copy link
    Contributor Author

    @shbenzer CI is passing now.. the problem is devtools_tests.py is flakey ..

    @shbenzer shbenzer merged commit cc3ea7b into SeleniumHQ:trunk Jun 7, 2025
    16 checks passed
    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.

    4 participants