Skip to content

[py][bidi]: add event handlers for BiDi browsing context #15902

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 6 commits into
base: trunk
Choose a base branch
from

Conversation

navin772
Copy link
Member

@navin772 navin772 commented Jun 16, 2025

User description

🔗 Related Issues

💥 What does this PR do?

Adds event handlers for the browsing context module:

  1. on_browsing_context_created
  2. on_browsing_context_destroyed
  3. on_navigation_started
  4. on_fragment_navigated
  5. on_dom_content_loaded
  6. on_browsing_context_loaded
  7. on_download_will_begin
  8. on_navigation_aborted
  9. on_navigation_failed
  10. on_navigation_committed
  11. on_user_prompt_closed
  12. on_user_prompt_opened
  13. on_history_updated

🔧 Implementation Notes

💡 Additional Considerations

🔄 Types of changes

  • New feature (non-breaking change which adds functionality and tests!)

PR Type

Enhancement, Tests


Description

• Add 13 BiDi browsing context event handlers
• Implement context filtering for targeted event subscriptions
• Refactor event handling with improved callback management
• Add comprehensive test suite for all event types


Changes walkthrough 📝

Relevant files
Enhancement
browsing_context.py
Add BiDi event handlers with context filtering                     

py/selenium/webdriver/common/bidi/browsing_context.py

• Add 13 event handler methods (on_browsing_context_created,
on_navigation_started, etc.)
• Implement context filtering in
_on_event method
• Refactor event subscription/unsubscription logic

Simplify BrowsingContextEvent.from_json method

+110/-34
Tests
bidi_browsing_context_events_tests.py
Add comprehensive BiDi event handler tests                             

py/test/selenium/webdriver/common/bidi_browsing_context_events_tests.py

• Add comprehensive test suite with 562 lines of test code
• Test all
13 event handler methods
• Include context-specific event subscription
tests
• Test event handler removal and cleanup functionality

+562/-0 

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • @selenium-ci selenium-ci added C-py Python Bindings B-devtools Includes everything BiDi or Chrome DevTools related labels Jun 16, 2025
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    🎫 Ticket compliance analysis ❌

    1234 - Not compliant

    Non-compliant requirements:

    • Fix issue where JavaScript in link's href is not triggered on click() in Selenium 2.48
    • Ensure compatibility with Firefox 42.0
    • Restore functionality that worked in version 2.47.1

    5678 - Not compliant

    Non-compliant requirements:

    • Fix ChromeDriver ConnectFailure error on Ubuntu 16.04.4
    • Resolve connection refused errors after first ChromeDriver instantiation
    • Support Chrome 65.0.3325.181 with ChromeDriver 2.35
    • Fix issue affecting subsequent driver instances

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

    Possible Issue

    The BrowsingContextEvent.from_json method creates a dynamic object instead of returning a proper BrowsingContextEvent instance, which breaks the expected return type and could cause runtime errors when accessing event properties.

    event_data = type("EventData", (), {"params": json})()
    return event_data
    Logic Error

    Context filtering logic assumes all parsed event data has a 'context' attribute, but this may not be true for all event types, potentially causing AttributeError at runtime.

    event_context = parsed_data.context
    
    # Apply context filtering
    if contexts is not None and event_context not in contexts:
        return  # Skip this event as it's not for the specified contexts
    Test Issue

    The test cleanup in test_multiple_navigation_events attempts to remove the same callback_id for different event names, which is incorrect and may not properly clean up event handlers.

    for callback_id in callbacks:
        for event_name in ["navigation_started", "dom_content_loaded", "load"]:
            driver.browsing_context.remove_event_handler(event_name, callback_id)

    Copy link
    Contributor

    qodo-merge-pro bot commented Jun 16, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix callback ID event mapping
    Suggestion Impact:The commit directly implements the suggested fix, replacing the nested loop structure with an enumerated approach that correctly maps each callback ID to its corresponding event name

    code diff:

    -        for callback_id in callbacks:
    -            for event_name in ["navigation_started", "dom_content_loaded", "load"]:
    -                driver.browsing_context.remove_event_handler(event_name, callback_id)
    +        event_names = ["navigation_started", "dom_content_loaded", "load"]
    +        for i, callback_id in enumerate(callbacks):
    +            driver.browsing_context.remove_event_handler(event_names[i], callback_id)

    Using the same callback ID to remove handlers for different event types is
    incorrect. Each event handler registration returns a unique callback ID that
    should only be used with its corresponding event.

    py/test/selenium/webdriver/common/bidi_browsing_context_events_tests.py [560-562]

    -for callback_id in callbacks:
    -    for event_name in ["navigation_started", "dom_content_loaded", "load"]:
    -        driver.browsing_context.remove_event_handler(event_name, callback_id)
    +event_names = ["navigation_started", "dom_content_loaded", "load"]
    +for i, callback_id in enumerate(callbacks):
    +    driver.browsing_context.remove_event_handler(event_names[i], callback_id)

    [Suggestion processed]

    Suggestion importance[1-10]: 10

    __

    Why: This suggestion points out a critical bug in the test's cleanup logic. The original code incorrectly attempts to remove three different event handlers using every callback ID, while each ID is unique to a single event subscription. The proposed fix correctly maps each callback ID to its corresponding event name, ensuring proper resource cleanup.

    High
    General
    Add safety check for context attribute

    The code assumes parsed_data always has a context attribute, but this may not be
    true for all event types. Add a safety check to handle cases where the context
    attribute doesn't exist.

    py/selenium/webdriver/common/bidi/browsing_context.py [767-771]

    -event_context = parsed_data.context
    +event_context = getattr(parsed_data, 'context', None)
     
     # Apply context filtering
    -if contexts is not None and event_context not in contexts:
    +if contexts is not None and event_context and event_context not in contexts:
         return  # Skip this event as it's not for the specified contexts
    • Apply / Chat
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion correctly identifies a potential AttributeError. Not all event data types parsed by parser_class.from_json are guaranteed to have a context attribute. Adding a getattr with a default value makes the code more robust against different event data structures.

    Medium
    • Update

    navin772 and others added 2 commits June 16, 2025 21:45
    Co-authored-by: qodo-merge-pro[bot] <151058649+qodo-merge-pro[bot]@users.noreply.github.com>
    @navin772 navin772 requested a review from shbenzer June 23, 2025 10:32
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    B-devtools Includes everything BiDi or Chrome DevTools related C-py Python Bindings Review effort 4/5
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    2 participants