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

[dotnet] Making SeleniumManager a thin wrapper #13833

Merged
merged 4 commits into from
Apr 18, 2024

Conversation

diemol
Copy link
Member

@diemol diemol commented Apr 17, 2024

User description

Also moving things to the driver classes and
DriverFinder.

Logging warnings from Selenium Manager as well,
and debug messages when that level is enabled.

.NET implementation for #13022

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.

Description

Motivation and Context

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.

Type

enhancement


Description

  • Refactored DriverFinder to be an instance class with enhanced capabilities for retrieving and validating browser and driver paths.
  • Updated ChromiumDriver, FirefoxDriver, InternetExplorerDriver, and SafariDriver to use DriverFinder for path resolution.
  • Enhanced SeleniumManager to accept arguments for Selenium Manager invocation and added logging for debug messages and warnings.
  • This update aims to make SeleniumManager a thin wrapper around driver and browser path resolution, improving maintainability and flexibility.

Changes walkthrough

Relevant files
Enhancement
ChromiumDriver.cs
Refactor ChromiumDriver to Use DriverFinder for Path Resolution

dotnet/src/webdriver/Chromium/ChromiumDriver.cs

  • Refactored to use DriverFinder for determining driver and browser
    paths.
  • Added logic to set binary location and browser version based on
    DriverFinder results.
  • +7/-1     
    DriverFinder.cs
    Enhance DriverFinder with Browser and Driver Path Retrieval

    dotnet/src/webdriver/DriverFinder.cs

  • Converted DriverFinder from static to instance class with
    DriverOptions dependency.
  • Added methods to retrieve browser and driver paths using Selenium
    Manager.
  • Implemented logic to validate paths and create Selenium Manager
    arguments.
  • +98/-20 
    DriverService.cs
    Update DriverService to Use DriverFinder for Executable Path

    dotnet/src/webdriver/DriverService.cs

  • Updated to use DriverFinder for setting driver service executable
    path.
  • +1/-1     
    FirefoxDriver.cs
    Refactor FirefoxDriver to Use DriverFinder for Path Resolution

    dotnet/src/webdriver/Firefox/FirefoxDriver.cs

  • Refactored to use DriverFinder for determining driver and browser
    paths.
  • Added logic to set binary location and browser version based on
    DriverFinder results.
  • +7/-1     
    InternetExplorerDriver.cs
    Update InternetExplorerDriver to Use DriverFinder               

    dotnet/src/webdriver/IE/InternetExplorerDriver.cs

    • Updated to use DriverFinder for determining driver service path.
    +2/-1     
    SafariDriver.cs
    Update SafariDriver to Use DriverFinder for Path Resolution

    dotnet/src/webdriver/Safari/SafariDriver.cs

    • Updated to use DriverFinder for determining driver service path.
    +2/-1     
    SeleniumManager.cs
    Refactor SeleniumManager to Support Enhanced Binary Path Retrieval

    dotnet/src/webdriver/SeleniumManager.cs

  • Refactored BinaryPaths method to accept arguments for Selenium Manager
    invocation.
  • Added logging for debug messages and warnings from Selenium Manager.
  • +30/-42 

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

    Also moving things to the driver classes and
    DriverFinder.
    
    Logging warnings from Selenium Manager as well,
    and debug messages when that level is enabled.
    Copy link
    Contributor

    PR Description updated to latest commit (b7fff80)

    Copy link
    Contributor

    PR Review

    ⏱️ Estimated effort to review [1-5]

    4, because the PR involves significant changes across multiple files, including architectural changes and the introduction of new functionalities. The complexity of integrating with an external tool (Selenium Manager) and handling binary paths increases the review effort. Understanding the implications of these changes on existing functionalities and ensuring backward compatibility requires a thorough review.

    🧪 Relevant tests

    No

    🔍 Possible issues

    Missing Validation: The PR lacks validation for the existence of keys in dictionaries before accessing them, which could lead to KeyNotFoundException.

    Exception Handling: The changes introduce new exception handling paths that might not be fully covered, especially in the BinaryPaths method of DriverFinder.cs. There's a risk of unhandled exceptions if the Selenium Manager does not return the expected output format.

    Logging Consistency: The PR introduces logging at various levels, but it's unclear if the logging levels are appropriately used throughout the changes. For instance, debug logs are generated under certain conditions without a clear policy on what is considered debug-worthy.

    🔒 Security concerns

    No


    ✨ Review tool usage guide:

    Overview:
    The review tool scans the PR code changes, and generates a PR review which includes several types of feedbacks, such as possible PR issues, security threats and relevant test in the PR. More feedbacks can be added by configuring the tool.

    The tool can be triggered automatically every time a new PR is opened, or can be invoked manually by commenting on any PR.

    • When commenting, to edit configurations related to the review tool (pr_reviewer section), use the following template:
    /review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=...
    
    [pr_reviewer]
    some_config1=...
    some_config2=...
    

    See the review usage page for a comprehensive guide on using this tool.

    Copy link
    Contributor

    PR Code Suggestions

    CategorySuggestions                                                                                                                                                       
    Possible issue
    Add key existence check before accessing dictionary values.

    Consider checking for the existence of keys in the paths dictionary before attempting to
    access them in the BinaryPaths method to avoid potential KeyNotFoundException.

    dotnet/src/webdriver/DriverFinder.cs [80]

    -if (!string.IsNullOrWhiteSpace(paths["driver_path"]))
    +if (paths.ContainsKey("driver_path") && !string.IsNullOrWhiteSpace(paths["driver_path"]))
     
    Add null checks for method parameters.

    To avoid potential null reference exceptions, add null checks for options before using
    them in the DriverFinder constructor.

    dotnet/src/webdriver/Chromium/ChromiumDriver.cs [154]

    +if (options == null) throw new ArgumentNullException(nameof(options));
     DriverFinder finder = new DriverFinder(options);
     
    Maintainability
    Use constants for repeated dictionary keys.

    To improve maintainability and avoid magic strings, consider defining constants for
    dictionary keys used multiple times, such as "driver_path" and "browser_path".

    dotnet/src/webdriver/DriverFinder.cs [52]

    -return BinaryPaths()["browser_path"];
    +private const string BrowserPathKey = "browser_path";
    +private const string DriverPathKey = "driver_path";
    +...
    +return BinaryPaths()[BrowserPathKey];
     
    Enhancement
    Add logging before throwing exceptions for missing paths.

    Instead of directly throwing NoSuchDriverException when paths do not exist, consider
    logging detailed information about the missing paths for easier debugging.

    dotnet/src/webdriver/DriverFinder.cs [93]

    +_logger.Error($"The driver path is not a valid file: {driverPath}");
     throw new NoSuchDriverException($"The driver path is not a valid file: {driverPath}");
     
    Best practice
    Use structured logging for Selenium Manager logs.

    To ensure consistency and readability, consider using a structured logging approach for
    the logs coming from Selenium Manager, especially when handling different log levels.

    dotnet/src/webdriver/SeleniumManager.cs [194-198]

    -if (entry.Key == "WARN")
    +switch (entry.Key)
    +{
    +    case "WARN":
    +        _logger.Warn(entry.Value);
    +        break;
    +    case "DEBUG":
    +    case "INFO":
    +        if (_logger.IsEnabled(LogEventLevel.Debug))
    +        {
    +            _logger.Debug(entry.Value);
    +        }
    +        break;
    +}
     

    ✨ Improve tool usage guide:

    Overview:
    The improve tool scans the PR code changes, and automatically generates suggestions for improving the PR code. The tool can be triggered automatically every time a new PR is opened, or can be invoked manually by commenting on a PR.

    • When commenting, to edit configurations related to the improve tool (pr_code_suggestions section), use the following template:
    /improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=...
    
    [pr_code_suggestions]
    some_config1=...
    some_config2=...
    

    See the improve usage page for a comprehensive guide on using this tool.

    @diemol diemol merged commit f36b334 into trunk Apr 18, 2024
    11 checks passed
    @diemol diemol deleted the selenium_manager_thin_wrapper_dotnet branch April 18, 2024 21:15
    return BinaryPaths()[DriverPathKey];
    }

    public bool HasBrowserPath()
    Copy link
    Member

    Choose a reason for hiding this comment

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

    Seems better having a property HasBrowserPath

    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    How would you do it as a property?

    /// </returns>
    public static string DriverPath(DriverOptions options)
    public static Dictionary<string, string> BinaryPaths(string arguments)
    Copy link
    Member

    Choose a reason for hiding this comment

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

    It is public API, where we should be careful. Can we split this method to two methods? For BrowserBinaryPath and DriverBinaryPath?

    Dictionary in public API doesn't look intuitive for users.

    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    Theoretically, BinaryPaths should only be used from DriverFinder. Should we make it private?

    @@ -214,6 +186,27 @@ public static string DriverPath(DriverOptions options)
    throw new WebDriverException($"Error deserializing Selenium Manager's response: {output}", ex);
    }

    if (result.ContainsKey("logs"))
    Copy link
    Member

    Choose a reason for hiding this comment

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

    result object can be strongly typed, just deserialize to object from the json, later it is comfortable to work with this object.

    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    Isn't this what I did in the following line?

    Dictionary<string, string> logs = result["logs"] as Dictionary<string, string>;
    

    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    Maybe I do not understand what you are suggesting.

    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