seleniumhq.github.io icon indicating copy to clipboard operation
seleniumhq.github.io copied to clipboard

petesong/Add a Python example for the test practice

Open PeteSong opened this issue 1 year ago • 9 comments

User description

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

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

Description

  1. Correct the right link of Hugo Installation
  2. Add a Python example for the test practices.

Motivation and Context

For the test practices, there's no python example.

Types of changes

  • [x] Change to the site
  • [ ] 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

  • [x] I have read the contributing document.
  • [x] I have used hugo server to render the site/docs locally, but failed. Since I only have minor changes in the existing pages, and I am sure it works.

PR Type

Documentation, Tests


Description

  • Updated the Hugo installation link in the README to point directly to the official Hugo site, improving clarity and accessibility.
  • Added a detailed Python example using pytest and Selenium to the test practices documentation. This example demonstrates best practices with the "ActionBot" and "LoadableComponent" patterns.
  • The example includes multiple test cases for interacting with a Todo application, showcasing various functionalities such as adding, toggling, and deleting todos.

Changes walkthrough 📝

Relevant files
Documentation
README.md
Update Hugo installation link and instructions                     

README.md

  • Updated the Hugo installation link to a more direct source.
  • Provided clearer instructions for getting started with Hugo.
  • +1/-1     
    Tests
    design_strategies.en.md
    Add Python example for test practices with Selenium           

    website_and_docs/content/documentation/test_practices/design_strategies.en.md

  • Added a comprehensive Python example using pytest and Selenium.
  • Demonstrated best practices with "ActionBot" and "LoadableComponent".
  • Included multiple test cases for a Todo application.
  • +280/-0 

    💡 PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    PeteSong avatar Sep 05 '24 02:09 PeteSong

    Deploy Preview for selenium-dev canceled.

    Name Link
    Latest commit 1f36a5d290a9a5f6e1a0acf4a04d315535ef69fd
    Latest deploy log https://app.netlify.com/projects/selenium-dev/deploys/67aaede5febcc1000838045b

    netlify[bot] avatar Sep 05 '24 02:09 netlify[bot]

    CLA assistant check
    All committers have signed the CLA.

    CLAassistant avatar Sep 05 '24 02:09 CLAassistant

    PR Reviewer Guide 🔍

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Key issues to review

    Code Complexity
    The added Python example is quite long and complex. Consider breaking it down into smaller, more manageable sections or separate files for better readability and maintainability.

    Error Handling
    The is_loaded method in the TodoPage class uses a bare except clause, which might catch and suppress unexpected errors. Consider using a more specific exception or at least logging the error.

    Commented Code
    There is commented out code in the hover method of the ActionBot class. Consider removing it if it's not needed or add a comment explaining why it's kept.

    qodo-code-review[bot] avatar Sep 05 '24 02:09 qodo-code-review[bot]

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Best practice
    ✅ Use a context manager for WebDriver to ensure proper resource cleanup
    Suggestion Impact:The suggestion to use a context manager for the WebDriver was implemented, ensuring proper resource cleanup.

    code diff:

    +    with webdriver.Chrome() as driver:
    +        driver.set_window_size(1024, 768)
    +        driver.implicitly_wait(0.5)
    +        yield driver
    

    Consider using a context manager for the WebDriver to ensure proper resource
    cleanup, even if an exception occurs during the test execution.

    website_and_docs/content/documentation/test_practices/design_strategies.en.md [399-404]

     @pytest.fixture(scope="function")
     def chrome_driver():
    -    driver = webdriver.Chrome()
    -    driver.set_window_size(1024, 768)
    -    driver.implicitly_wait(0.5)
    -    yield driver
    -    driver.quit()
    +    with webdriver.Chrome() as driver:
    +        driver.set_window_size(1024, 768)
    +        driver.implicitly_wait(0.5)
    +        yield driver
     
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: This suggestion is a best practice for resource management, ensuring that the WebDriver is properly closed even if an exception occurs, which is crucial for preventing resource leaks.

    9
    Use specific exception handling instead of a bare except clause

    In the is_loaded method, consider using a more specific exception catch instead of a
    bare except clause to handle potential errors more gracefully and avoid masking
    unexpected exceptions.

    website_and_docs/content/documentation/test_practices/design_strategies.en.md [516-523]

     def is_loaded(self):
         try:
             WebDriverWait(self.driver, 10).until(
                 EC.visibility_of_element_located(self.new_todo_by)
             )
             return True
    -    except:
    +    except (NoSuchElementException, TimeoutException):
             return False
     
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 8

    Why: Using specific exceptions improves error handling by avoiding the masking of unexpected exceptions, which is a significant improvement in code robustness.

    8
    ✅ Add assertions to verify initial state in test methods
    Suggestion Impact:An assertion was added to verify the initial state of the todo count in the test method, which aligns with the suggestion to enhance test reliability by ensuring the test environment is correctly set up.

    code diff:

         def test_new_todo(self, page: TodoPage):
    +        assert page.todo_count() == 0
    

    In the test methods, consider adding assertions to verify the initial state before
    performing actions. This helps ensure that the test environment is in the expected
    state and can catch potential setup issues.

    website_and_docs/content/documentation/test_practices/design_strategies.en.md [571-573]

     def test_new_todo(self, page: TodoPage):
    +    assert page.todo_count() == 0, "Initial todo count should be 0"
         page.new_todo("aaa")
         assert page.count_todo_items_left() == page.build_count_todo_left(1)
     
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Adding assertions for initial state verification enhances test reliability by ensuring the test environment is correctly set up, which is a good practice for test accuracy.

    7
    Enhancement
    ✅ Convert static method to instance method for consistency and flexibility
    Suggestion Impact:The static method build_count_todo_left was converted to an instance method in the TodoPage class.

    code diff:

    -    @staticmethod
    -    def build_count_todo_left(count: int) -> str:
    +    def build_count_todo_left(self, count: int) -> str:
             if count == 1:
                 return "1 item left!"
             else:
    

    Instead of using a static method for build_count_todo_left, consider making it an
    instance method to improve consistency with other methods in the class and allow for
    potential future customization.

    website_and_docs/content/documentation/test_practices/design_strategies.en.md [503-507]

    -@staticmethod
    -def build_count_todo_left(count: int) -> str:
    +def build_count_todo_left(self, count: int) -> str:
         if count == 1:
             return "1 item left!"
         else:
             return f"{count} items left!"
     
    
    • [ ] Apply this suggestion
    Suggestion importance[1-10]: 5

    Why: While converting the static method to an instance method can improve consistency, it is not critical to the functionality and mainly enhances potential future flexibility.

    5

    qodo-code-review[bot] avatar Sep 05 '24 02:09 qodo-code-review[bot]

    PR Code Suggestions ✨

    Category Suggestion                                                                                                                                    Score Best practice ✅ Use a context manager for WebDriver to ensure proper resource cleanup 9 Use specific exception handling instead of a bare except clause 8 ✅ Add assertions to verify initial state in test methods 7 Enhancement ✅ Convert static method to instance method for consistency and flexibility 5

    Applied the suggestions.

    PeteSong avatar Sep 05 '24 09:09 PeteSong

    PR Reviewer Guide 🔍

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪ 🧪 PR contains tests 🔒 No security concerns identified ⚡ Key issues to review

    Code ComplexityThe added Python example is quite long and complex. Consider breaking it down into smaller, more manageable sections or separate files for better readability and maintainability.

    Error HandlingThe is_loaded method in the TodoPage class uses a bare except clause, which might catch and suppress unexpected errors. Consider using a more specific exception or at least logging the error.

    Commented CodeThere is commented out code in the hover method of the ActionBot class. Consider removing it if it's not needed or add a comment explaining why it's kept.

    Applied the suggestions.

    PeteSong avatar Sep 05 '24 09:09 PeteSong

    Thank you for the contribution @PeteSong! Before it can be properly reviewed a few things must be changed:

    1. the example must be moved into a separate executable file like our other examples
    2. the example must be properly formatted like other examples to pull from the example file
    3. the example must be propagated to all translations
    4. lines must be kept to 100 characters per the style guide https://www.selenium.dev/documentation/about/style/

    shbenzer avatar Sep 18 '24 14:09 shbenzer

    Thank you for the contribution @PeteSong! Before it can be properly reviewed a few things must be changed:

    1. the example must be moved into a separate executable file like our other examples
    2. the example must be properly formatted like other examples to pull from the example file
    3. the example must be propagated to all translations
    4. lines must be kept to 100 characters per the style guide https://www.selenium.dev/documentation/about/style/

    DONE

    PeteSong avatar Sep 26 '24 10:09 PeteSong

    Thank you for the contribution @PeteSong! Before it can be properly reviewed a few things must be changed:

    1. the example must be moved into a separate executable file like our other examples
    2. the example must be properly formatted like other examples to pull from the example file
    3. the example must be propagated to all translations
    4. lines must be kept to 100 characters per the style guide https://www.selenium.dev/documentation/about/style/

    DONE

    Awesome, thank you! @harsha1502

    shbenzer avatar Sep 26 '24 14:09 shbenzer

    @PeteSong please resolve conflicts for this PR.

    DONE

    PeteSong avatar Oct 26 '24 13:10 PeteSong

    The merging is blocked, who could help me to merge it?

    PeteSong avatar Mar 03 '25 05:03 PeteSong

    @shbenzer, @A1exKH , Hope you are doing well.

    The merging is blocked for quite a time. What should I do or who could help me to merge it?

    Best regards, Peter

    PeteSong avatar Mar 03 '25 05:03 PeteSong

    @PeteSong hi! You need a review and approval from people, who are contributors to this repository.

    A1exKH avatar Mar 15 '25 11:03 A1exKH

    Hello @PeteSong, thank you for your contributions!

    I have added some review comments, let me know if you have any questions. The main point I'm trying to get across as you refactor the examples is that these are examples - they don't need to be fully fleshed out.

    Since you have provided a full seemingly working example in python - what we can instead do is utilize the codeblock architecture:

    {{< gh-codeblock path="examples/python/tests/selenium_manager/usage.py#L10-L12" >}}
    {{< /tab >}}
    {{< tab header="CSharp" >}}
    {{< badge-code >}}
    {{< /tab >}}
    {{< tab header="Ruby" >}}
    {{< badge-code >}}
    {{< /tab >}}
    {{% tab header="JavaScript" %}}
    

    and therefore use all the code you've written throughout the page (I personally prefer this alternative) - and this way we can keep the java example, as well.

    shbenzer avatar Mar 17 '25 15:03 shbenzer

    Hi @shbenzer ,

    Thanks for your good comment. I have updated them per your suggestion.

    DONE!

    Best regards, Peter

    Hello @PeteSong, thank you for your contributions!

    I have added some review comments, let me know if you have any questions. The main point I'm trying to get across as you refactor the examples is that these are examples - they don't need to be fully fleshed out.

    Since you have provided a full seemingly working example in python - what we can instead do is utilize the codeblock architecture:

    {{< gh-codeblock path="examples/python/tests/selenium_manager/usage.py#L10-L12" >}}
    {{< /tab >}}
    {{< tab header="CSharp" >}}
    {{< badge-code >}}
    {{< /tab >}}
    {{< tab header="Ruby" >}}
    {{< badge-code >}}
    {{< /tab >}}
    {{% tab header="JavaScript" %}}
    

    and therefore use all the code you've written throughout the page (I personally prefer this alternative) - and this way we can keep the java example, as well.

    PeteSong avatar Mar 25 '25 01:03 PeteSong

    @shbenzer Hope you are doing well. Could you be kind to review the changes and approve the PR? Thank you very much

    Best regards, Peter

    PeteSong avatar Apr 13 '25 13:04 PeteSong

    Hey @PeteSong this looks good! Only thing I notice atm that needs to be changed is that you're missing the other languages in the codeblock elements. We use those so that readers can see where examples are missing and for ease of contributions.

    shbenzer avatar Apr 13 '25 16:04 shbenzer

    Hey @shbenzer,

    Good suggestion! DONE!

    Hey @PeteSong this looks good! Only thing I notice atm that needs to be changed is that you're missing the other languages in the codeblock elements. We use those so that readers can see where examples are missing and for ease of contributions.

    PeteSong avatar Apr 14 '25 03:04 PeteSong

    LGTM

    @harsha509 I don’t seem to have permissions to this repo, could you take a look?

    shbenzer avatar Apr 14 '25 16:04 shbenzer

    Hi @harsha509, hope you are doing well! Could I trouble you to take some time to review and merge it? Thank you very much.

    PeteSong avatar Apr 20 '25 02:04 PeteSong

    Alright, now that I have permissions I pulled locally. There's a few more changes that need to be made and you'll be good to go.

    1. lets put all examples in the codeblock elements
    2. in the codeblock elements, make sure that each language without an example has a badgecode so we can help facilitate contributions

    shbenzer avatar May 03 '25 14:05 shbenzer

    Alright, now that I have permissions I pulled locally. There's a few more changes that need to be made and you'll be good to go.

    1. lets put all examples in the codeblock elements
    2. in the codeblock elements, make sure that each language without an example has a badgecode so we can help facilitate contributions

    Hi @shbenzer, for 1), I already put all my examples in the codeblock elements. for 2), what is the badgecode? could you show me an example?

    PeteSong avatar May 04 '25 11:05 PeteSong

    Hi @shbenzer, for 1), I already put all my examples in the codeblock elements.

    That's correct! However, now that we're using multiple languages in this document, it'd be best to put the other code examples you didn't alter into codeblocks so the page is consistently formatted.

    for 2), what is the badgecode? could you show me an example?

    Gladly!

    Badge codes have this structure in codeblocks:

    {{< tab header="JavaScript" >}}
    {{< badge-code >}}
    {{< /tab >}}
    

    and they produce this when rendered:

    Screenshot 2025-05-04 at 12 40 27 PM

    Clicking the link then takes you to the creating examples section of the contribution guide

    shbenzer avatar May 04 '25 16:05 shbenzer

    Hi @shbenzer, hope you are doing well.

    1. for now, only one example in Python.
    2. added the badgecode.

    Best regards, Peter

    PeteSong avatar May 05 '25 08:05 PeteSong

    Hi @shbenzer, hope you are doing well.

    1. for now, only one example in Python.
    2. added the badgecode.

    Best regards, Peter

    Regarding 1, that's not what I meant, but it can be done in another PR.

    LGTM

    shbenzer avatar May 05 '25 15:05 shbenzer

    Thank you @PeteSong !

    shbenzer avatar May 05 '25 16:05 shbenzer