Skip to content
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

Add python example to Selenium webdriver support listener #2202

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

Conversation

touero
Copy link

@touero touero commented Feb 28, 2025

User description

Description

Add python example for webdriver listener support.

Motivation and Context

Make site more comprehensive and it helpful to newer.

Types of changes

  • Change to the site (I have double-checked the Netlify deployment, and my changes look good)
  • Code example added (and I also added the example to all translated languages)
  • Improved translation
  • Added new translation (and I also added a notice to each document missing translation)

Checklist

  • I have read the contributing document.
  • I have used hugo to render the site/docs locally and I am sure it works.

My test

excute:

pytest tests/support/test_listener.py --cache-clear -s

output:

================================================================================= test session starts ==================================================================================
platform linux -- Python 3.10.12, pytest-8.3.4, pluggy-1.5.0
rootdir: /home/weiensong/data/repo/seleniumhq.github.io/examples/python
plugins: trio-0.8.0, rerunfailures-14.0
collected 4 items

tests/support/test_listener.py before_navigate_to: https://www.selenium.dev/selenium/web/
after_navigate_to: https://www.selenium.dev/selenium/web/
before_navigate_to: https://www.selenium.dev/selenium/web/clicks.html
after_navigate_to: https://www.selenium.dev/selenium/web/clicks.html
before_navigate_back
after_navigate_back
before_navigate_forward
after_navigate_forward
before_quit
after_quit
['before_navigate_to', 'after_navigate_to', 'before_navigate_to', 'after_navigate_to', 'before_navigate_back', 'after_navigate_back', 'before_navigate_forward', 'after_navigate_forward', 'before_quit', 'after_quit']
.before_navigate_to: https://www.selenium.dev/selenium/web/clicks.html
after_navigate_to: https://www.selenium.dev/selenium/web/clicks.html
before_find
after_find
before_click
after_click
before_close
after_close
['before_navigate_to', 'after_navigate_to', 'before_find', 'after_find', 'before_click', 'after_click', 'before_close', 'after_close']
.before_navigate_to: https://www.selenium.dev/selenium/web/inputs.html
after_navigate_to: https://www.selenium.dev/selenium/web/inputs.html
before_find
after_find
['before_navigate_to', 'after_navigate_to', 'before_find', 'after_find']
before_change_value
after_change_value
.before_navigate_to: https://www.selenium.dev/selenium/web/
after_navigate_to: https://www.selenium.dev/selenium/web/
before_find
on_exception
Exception: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[name="no_type"]"}
  (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
#0 0x5e8de94841fa <unknown>
#1 0x5e8de8f94810 <unknown>
#2 0x5e8de8fe3506 <unknown>
#3 0x5e8de8fe37a1 <unknown>
#4 0x5e8de9028c24 <unknown>
#5 0x5e8de90075ad <unknown>
#6 0x5e8de9026007 <unknown>
#7 0x5e8de9007323 <unknown>
#8 0x5e8de8fd5de0 <unknown>
#9 0x5e8de8fd6dbe <unknown>
#10 0x5e8de945012b <unknown>
#11 0x5e8de94540c7 <unknown>
#12 0x5e8de943d6cc <unknown>
#13 0x5e8de9454c47 <unknown>
#14 0x5e8de942267f <unknown>
#15 0x5e8de9473288 <unknown>
#16 0x5e8de9473450 <unknown>
#17 0x5e8de9483076 <unknown>
#18 0x743768294ac3 <unknown>

before_navigate_to: https://www.selenium.dev/selenium/web/inputs.html
after_navigate_to: https://www.selenium.dev/selenium/web/inputs.html
before_find
after_find
['before_navigate_to', 'after_navigate_to', 'before_find', 'on_exception', 'before_navigate_to', 'after_navigate_to', 'before_find', 'after_find']
before_execute_script
after_execute_script
.

================================================================================== 4 passed in 10.54s ==================================================================================

PR Type

Tests, Documentation


Description

  • Added Python tests for Selenium WebDriver event listeners.

    • Implemented MyListener class to log WebDriver events.
    • Created multiple test cases to validate listener functionality.
  • Updated documentation to include Python examples for event listeners.

    • Added code snippets for defining and using listeners.
    • Translated updates into multiple languages (Japanese, Portuguese, Chinese).

Changes walkthrough 📝

Relevant files
Tests
test_listener.py
Added Python tests for WebDriver event listeners                 

examples/python/tests/support/test_listener.py

  • Added MyListener class to log WebDriver events.
  • Implemented test cases for navigation, element interaction, and script
    execution.
  • Validated listener events through assertions in tests.
  • +156/-0 
    Documentation
    listeners.en.md
    Updated English documentation with Python listener examples

    website_and_docs/content/documentation/webdriver/support_features/listeners.en.md

  • Added Python example for defining and using event listeners.
  • Included code snippets for MyListener and its usage.
  • +33/-1   
    listeners.ja.md
    Updated Japanese documentation with Python listener examples

    website_and_docs/content/documentation/webdriver/support_features/listeners.ja.md

  • Translated Python listener example into Japanese.
  • Updated documentation structure for defining and using listeners.
  • +36/-4   
    listeners.pt-br.md
    Updated Portuguese documentation with Python listener examples

    website_and_docs/content/documentation/webdriver/support_features/listeners.pt-br.md

  • Translated Python listener example into Portuguese.
  • Updated documentation structure for defining and using listeners.
  • +36/-4   
    listeners.zh-cn.md
    Updated Chinese documentation with Python listener examples

    website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md

  • Translated Python listener example into Chinese.
  • Updated documentation structure for defining and using listeners.
  • +30/-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.
  • Copy link

    netlify bot commented Feb 28, 2025

    👷 Deploy request for selenium-dev pending review.

    Visit the deploys page to approve it

    Name Link
    🔨 Latest commit 61431b9

    @CLAassistant
    Copy link

    CLAassistant commented Feb 28, 2025

    CLA assistant check
    All committers have signed the CLA.

    @touero touero marked this pull request as ready for review February 28, 2025 07:44
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    🎫 Ticket compliance analysis ❌

    8 - Not compliant

    Non-compliant requirements:

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

    Resource Cleanup

    The test cases create Chrome driver instances but don't properly close them in case of exceptions. This could lead to resource leaks.

        driver = webdriver.Chrome()
        listener = MyListener()
        event_driver = EventFiringWebDriver(driver, listener)
        event_driver.get("https://www.selenium.dev/selenium/web/")
        event_driver.get("https://www.selenium.dev/selenium/web/clicks.html")
        event_driver.back()
        event_driver.forward()
        event_driver.quit()
        print(listener.events)
    
        assert "before_navigate_to" in listener.events
        assert "after_navigate_to" in listener.events
        assert "before_navigate_back" in listener.events
        assert "after_navigate_back" in listener.events
        assert "before_navigate_forward" in listener.events
        assert "after_navigate_forward" in listener.events
        assert "before_quit" in listener.events
        assert "after_quit" in listener.events
    
    def test_find_and_click_and_close():
        driver = webdriver.Chrome()
        listener = MyListener()
        event_driver = EventFiringWebDriver(driver, listener)
        event_driver.get("https://www.selenium.dev/selenium/web/clicks.html")
        element = event_driver.find_element(By.ID, "new-window")
    
        assert 'before_find' in listener.events
        assert 'after_find' in listener.events
    
        element.click()
    
        assert 'before_click' in listener.events
        assert 'after_click' in listener.events
    
        event_driver.switch_to.window(event_driver.window_handles[-1])
        event_driver.close()
    
        assert 'before_close' in listener.events
    
        event_driver.switch_to.window(event_driver.window_handles[0])
        print(listener.events)
    
    def test_change_value():
        driver = webdriver.Chrome()
        listener = MyListener()
        event_driver = EventFiringWebDriver(driver, listener)
        event_driver.get("https://www.selenium.dev/selenium/web/inputs.html")
        element = event_driver.find_element(By.NAME, "no_type")
        print(listener.events)
        element.clear()
    
        assert 'before_change_value' in listener.events
        assert 'after_change_value' in listener.events
    
    def test_execute_script_and_exception():
        driver = webdriver.Chrome()
        listener = MyListener()
        event_driver = EventFiringWebDriver(driver, listener)
        urls = ["https://www.selenium.dev/selenium/web/",
                "https://www.selenium.dev/selenium/web/inputs.html"]
        for url in urls:
            event_driver.get(url)
            try:
                element = event_driver.find_element(By.NAME, "no_type")
                print(listener.events)
                event_driver.execute_script("arguments[0].value = 'test'", element)
            except Exception as e:
                print(f"Exception: {e}")
                continue
    
        assert 'before_execute_script' in listener.events
        assert 'after_execute_script' in listener.events

    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Add error handling and cleanup

    Add error handling and cleanup in test_navigate_and_quit() to ensure driver is
    properly closed even if assertions fail.

    examples/python/tests/support/test_listener.py [86-95]

     def test_navigate_and_quit():
         driver = webdriver.Chrome()
         listener = MyListener()
         event_driver = EventFiringWebDriver(driver, listener)
    -    event_driver.get("https://www.selenium.dev/selenium/web/")
    -    event_driver.get("https://www.selenium.dev/selenium/web/clicks.html")
    -    event_driver.back()
    -    event_driver.forward()
    -    event_driver.quit()
    -    print(listener.events)
    +    try:
    +        event_driver.get("https://www.selenium.dev/selenium/web/")
    +        event_driver.get("https://www.selenium.dev/selenium/web/clicks.html")
    +        event_driver.back()
    +        event_driver.forward()
    +        print(listener.events)
    +        assert "before_navigate_to" in listener.events
    +        assert "after_navigate_to" in listener.events
    +        assert "before_navigate_back" in listener.events
    +        assert "after_navigate_back" in listener.events
    +        assert "before_navigate_forward" in listener.events
    +        assert "after_navigate_forward" in listener.events
    +    finally:
    +        event_driver.quit()
    +        assert "before_quit" in listener.events
    +        assert "after_quit" in listener.events
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion adds important error handling with try/finally to ensure the WebDriver is properly closed even if assertions fail, preventing resource leaks and improving test reliability.

    Medium
    Possible issue
    Ensure proper driver cleanup

    Add error handling in test_execute_script_and_exception() to properly close the
    driver after test completion.

    examples/python/tests/support/test_listener.py [141-155]

     def test_execute_script_and_exception():
         driver = webdriver.Chrome()
         listener = MyListener()
         event_driver = EventFiringWebDriver(driver, listener)
    -    urls = ["https://www.selenium.dev/selenium/web/",
    -            "https://www.selenium.dev/selenium/web/inputs.html"]
    -    for url in urls:
    -        event_driver.get(url)
    -        try:
    -            element = event_driver.find_element(By.NAME, "no_type")
    -            print(listener.events)
    -            event_driver.execute_script("arguments[0].value = 'test'", element)
    -        except Exception as e:
    -            print(f"Exception: {e}")
    -            continue
    +    try:
    +        urls = ["https://www.selenium.dev/selenium/web/",
    +                "https://www.selenium.dev/selenium/web/inputs.html"]
    +        for url in urls:
    +            event_driver.get(url)
    +            try:
    +                element = event_driver.find_element(By.NAME, "no_type")
    +                print(listener.events)
    +                event_driver.execute_script("arguments[0].value = 'test'", element)
    +            except Exception as e:
    +                print(f"Exception: {e}")
    +                continue
    +        assert 'before_execute_script' in listener.events
    +        assert 'after_execute_script' in listener.events
    +    finally:
    +        event_driver.quit()
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion adds critical cleanup with try/finally block to ensure WebDriver is properly closed after test completion, preventing resource leaks and improving test robustness.

    Medium
    • More

    @touero
    Copy link
    Author

    touero commented Mar 7, 2025

    @titusfortner
    Hi, who will come to review my code and merge it into SeleniumHQ.

    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