Skip to content

Web smart sync action Playwright#4072

Merged
Maheshkale447 merged 9 commits into
masterfrom
Feature/WebSmartSyncActionPlaywrightSupport
Feb 2, 2025
Merged

Web smart sync action Playwright#4072
Maheshkale447 merged 9 commits into
masterfrom
Feature/WebSmartSyncActionPlaywrightSupport

Conversation

@GokulBothe99

@GokulBothe99 GokulBothe99 commented Jan 24, 2025

Copy link
Copy Markdown
Contributor

Thank you for your contribution.
Before submitting this PR, please make sure:

  • PR description and commit message should describe the changes done in this PR
  • Verify the PR is pointing to correct branch i.e. Release or Beta branch if the code fix is for specific release , else point it to master
  • Latest Code from master or specific release branch is merged to your branch
  • No unwanted\commented\junk code is included
  • No new warning upon build solution
  • Code Summary\Comments are added to my code which explains what my code is doing
  • Existing unit test cases are passed
  • New Unit tests are added for your development
  • Sanity Tests are successfully executed for New and Existing Functionality
  • Verify that changes are compatible with all relevant browsers and platforms.
  • After creating pull request there should not be any conflicts
  • Resolve all Codacy comments
  • Builds and checks are passed before PR is sent for review
  • Resolve code review comments
  • Update the Help Library document to match any feature changes

Summary by CodeRabbit

  • New Features

    • Enhanced web element synchronization with new asynchronous methods for checking element states.
    • Added support for waiting on various web element conditions like visibility, presence, and clickability.
    • Improved browser tab interaction with new waiting and matching methods.
    • Introduced a new handler for managing web synchronization operations.
    • Added functionality for handling the "All" checkbox in column visibility management.
  • Improvements

    • Updated Playwright library to version 1.49.0.
    • Added NUnit support for Playwright testing.
  • Technical Updates

    • Expanded interfaces for browser elements and tabs with more robust checking methods.

@coderabbitai

coderabbitai Bot commented Jan 24, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This pull request introduces enhancements to web synchronization and element interaction capabilities within the Ginger automation framework. Key changes include the addition of the ActWebSmartSyncHandler class, which manages various asynchronous web synchronization operations. Furthermore, several interfaces and classes, such as IBrowserElement, IBrowserTab, PlaywrightBrowserElement, and PlaywrightBrowserTab, have been updated with new asynchronous methods for checking element states and waiting for specific conditions. These modifications provide robust mechanisms for handling web elements with timeout features.

Changes

File Change Summary
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs Introduced ActWebSmartSyncHandler class with multiple async methods for handling web synchronization operations, including element visibility, existence, alert presence, and more.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserElement.cs Added async methods for checking element visibility, attributes, text, clickability, and selection status.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs Updated WaitTillLoadedAsync method signature; added async methods for waiting on URL matches, alerts, and element states (enabled, checked, presence, visibility).
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs Implemented async methods for element state checks with error handling.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs Added async methods for waiting on various element and alert conditions.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs Updated to support ActWebSmartSync action with enhanced timeout handling and error reporting.
Ginger/GingerCoreNET/GingerCoreNET.csproj Updated Microsoft.Playwright package to version 1.49.0 and added Microsoft.Playwright.NUnit package.
Ginger/Ginger/Actions/ActionEditPage.xaml.cs Updated checkbox handling to support "All" checkbox functionality without altering existing logic.
Ginger/Ginger/Reports/HTMLReportTemplatePage.xaml.cs Added a blank line at the end of the HTMLReportTemplatePage class; no functional changes.

Poem

🐰 Async rabbits hop and wait,
Web elements dance at a steady rate.
Timeouts tick, conditions align,
Smart sync magic, simply divine!
Playwright's web, now smooth and bright 🌐


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 23

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 979f302 and 9e9ddb1.

📒 Files selected for processing (8)
  • Ginger/GingerCoreCommon/UIElement/ElementInfo.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserElement.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs (2 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs (2 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (2 hunks)
  • Ginger/GingerCoreNET/GingerCoreNET.csproj (1 hunks)
🧰 Additional context used
📓 Learnings (1)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (1)
Learnt from: IamRanjeetSingh
PR: Ginger-Automation/Ginger#3783
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs:129-129
Timestamp: 2024-11-12T02:45:14.501Z
Learning: User IamRanjeetSingh has indicated that the `RunAction` method in the `PlaywrightDriver` class should remain synchronous due to current constraints in the codebase.
🔇 Additional comments (15)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (4)

121-132: Ensure boundary handling for visibility checks.
HandleElementIsVisibleAsync uses ToBeVisibleAsync(waitUntilTimeout). If waitUntilTimeout is excessively large or very small, verify that the method handles edge cases gracefully (e.g., zero seconds or large timeouts).


164-175: Verify “selected” vs. “checked”.
HandleElementIsSelectedAsync aligns with some HTML elements (e.g., radio, checkbox). Ensure the right logic is called to confirm selection or that this method covers all relevant element types (select boxes, toggles, etc.).


195-206: The clickability check is well-structured.
The implementation for HandleElementToBeClickableAsync is clear and follows the existing pattern. Good job!


280-285: Invisibility polling approach is consistent.
HandleInvisibilityOfAllElementsLocatedByAsync uses a straightforward WaitForElementsInvisibleAsync method, consistent with the rest of the file. No issues found here.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs (1)

39-39: No functional changes apparent.
Line 39 seems to only adjust indentation for TitleAsync(). Nothing to address here.

Ginger/GingerCoreCommon/UIElement/ElementInfo.cs (1)

552-553: Add a quick usage reference

The new ByAttribute enum value is consistent with existing patterns. Ensure that test coverage or references to ByAttribute usage are in place—line 1176 of PlaywrightBrowserTab.cs indicates usage for this locate type.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs (2)

1082-1102: Consistent fallback handling

Returning false on TimeoutException or AssertionException aligns with other “WaitFor” patterns. Consider catching only these specific exceptions if that’s the intended logic.


1111-1131: Check overlapping elements

Even if an element is visible and enabled, overlapping elements might prevent real user clicks. Consider verifying pointer events or bounding rectangles to ensure true “clickability.”

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (3)

1051-1067: Confirm pattern usage

WaitForURLAsync(urlPattern) can be literal or regex. Update the doc string to clarify how urlPattern is interpreted, ensuring consistent usage.


1092-1099: Good approach

Relying on ElementState.Stable is a robust way to ensure presence. No immediate adjustments suggested.


1141-1164: Handle zero matches

When elements.Count is zero, calling WaitForElementStateAsync(...) can’t proceed. Use an early return or an alternative path for the no-element case.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (2)

285-326: Augment test coverage

Including ActWebSmartSync is beneficial. Verify how it interacts or overlaps with ActSmartSync. Comprehensive tests help confirm each action’s intended usage.


338-338: Adding to supported actions

Listing ActWebSmartSync among supported actions is correct. No issues with this addition.

Ginger/GingerCoreNET/GingerCoreNET.csproj (2)

315-315: LGTM! Good addition of Playwright NUnit testing support.

Adding Microsoft.Playwright.NUnit package will enable better integration with NUnit testing framework. The version matches the core Playwright package which is the recommended approach.


314-314: Verify compatibility with the upgraded Playwright version.

The Playwright version has been updated from 1.45.0 to 1.49.0. This is a significant version jump that may include breaking changes.

Run the following script to check the changelog for breaking changes:

Comment thread Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs Outdated

@Maheshkale447 Maheshkale447 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please test the changes with iframe and shadow root elements. also need to check if its supporting POM elements

Comment thread Ginger/GingerCoreCommon/UIElement/ElementInfo.cs Outdated
Comment thread Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs Outdated
@Maheshkale447
Maheshkale447 changed the base branch from Releases/Beta to master January 28, 2025 11:27

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 10

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e9ddb1 and 87a5c5c.

📒 Files selected for processing (3)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs (2 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (1 hunks)
🧰 Additional context used
📓 Learnings (3)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (2)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1084-1091
Timestamp: 2025-01-30T09:08:06.584Z
Learning: In Playwright-based element wait operations (like WaitForElementsInvisibleAsync), use ElementState.Hidden to check for elements that are present in the DOM but not visible, rather than checking if elements are detached/removed from the DOM.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1075-1083
Timestamp: 2025-01-30T09:07:12.356Z
Learning: In Playwright-based element wait operations (like WaitForElementsVisibleAsync), do not short-circuit when elements are initially absent, as the method is designed to keep polling until timeout to handle dynamic element appearance.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs (2)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1084-1091
Timestamp: 2025-01-30T09:08:06.584Z
Learning: In Playwright-based element wait operations (like WaitForElementsInvisibleAsync), use ElementState.Hidden to check for elements that are present in the DOM but not visible, rather than checking if elements are detached/removed from the DOM.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1075-1083
Timestamp: 2025-01-30T09:07:12.356Z
Learning: In Playwright-based element wait operations (like WaitForElementsVisibleAsync), do not short-circuit when elements are initially absent, as the method is designed to keep polling until timeout to handle dynamic element appearance.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (3)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:358-365
Timestamp: 2025-01-30T07:40:08.756Z
Learning: In the Ginger automation framework, when an element is expected to exist but is not found, the code should throw an exception rather than return null, as the element's presence is a precondition for the operation.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:137-150
Timestamp: 2025-01-30T07:38:05.310Z
Learning: In the Ginger automation framework, element existence checks using polling with 100ms delay is an acceptable approach, as confirmed by the maintainers.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:36-114
Timestamp: 2025-01-30T07:36:32.448Z
Learning: In the Ginger project's web synchronization code, keeping separate implementations for different synchronization operations is preferred over extracting common polling logic, as it improves readability and makes individual cases easier to understand and modify.
🔇 Additional comments (7)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (3)

98-99: Consider verifying element presence before waiting for invisibility
For HandleInvisibilityOfElementLocatedAsync, you immediately call GetFirstMatchingElementAsync() then check if it “becomes not visible.” If the element never existed in the first place, the logic might pass trivially after finding that single element is missing. You might want to handle the scenario where the element is supposed to exist first or handle the possibility that a brand-new element appears during the wait and becomes invisible.


147-158: Possibility of short-circuiting when elements are clearly missing
Here you poll for existence with a Stopwatch and a 100ms delay. Since you’re retrieving the element collection every loop, you allow them to appear dynamically. This is consistent with the existing logic and user preference, so just ensure you’re comfortable with repeatedly enumerating all elements on each pass, especially for very large documents.


190-201: Consider alternatives for page load completeness
In HandlePageHasBeenLoadedAsync, you check document.readyState repeatedly. This is a valid pattern, though you might also consider WaitForLoadStateAsync if you are confident in the correctness of the underlying driver’s load state detection.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (1)

1192-1205: Good usage of event unsubscription
WaitForAlertAsync unsubscribes from _playwrightPage.Dialog after the wait is done. This approach helps avoid memory leaks. Nicely done.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserElement.cs (3)

23-23: Confirm necessity of NUnit dependency
You have using NUnit.Framework; but are relying on Playwright’s Assertions. Double-check if you still need references to NUnit here. Removing unused references can prevent confusion.


1079-1108: Check for existence prior to checked state
In ElementIsSelectedAsync, you call WaitForAsync followed by ToBeCheckedAsync. If the element is never found, WaitForAsync may or may not throw. Confirm that your logic handles a scenario where no matching element is located.


1209-1239: Consider clarifying “not visible” vs. “hidden in DOM”
In ToBeNotVisibleAsync, you rely on WaitForOptions { State = WaitForSelectorState.Hidden } plus Not.ToBeVisibleAsync(...). Hidden elements can remain in the DOM but not displayed. If you also want to handle detached elements, mention this in the docs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
Ginger/Ginger/Actions/ActionEditPage.xaml.cs (1)

Line range hint 1056-1187: Improve method organization and reduce complexity.

The ColumnMultiSelectComboBox_ItemCheckBoxClick method is handling multiple responsibilities and directly modifying global state. Consider the following improvements:

  1. Extract the "All" checkbox logic into a separate method.
  2. Create a dedicated method for updating column preferences.
  3. Use constants for magic strings like "Description", "Path", etc.
  4. Consider using a dictionary to map column names to their configurations.

Here's a suggested refactoring:

+private const string ALL_COLUMN = "All";
+private const string DESCRIPTION_COLUMN = "Description";
+// ... other column constants

+private void HandleAllCheckboxClick(CheckBox checkBox)
+{
+    bool isChecked = checkBox.IsChecked == true;
+    for (int i = 1; i < 6; i++)
+    {
+        columnMultiSelectComboBox._nodeList[i].IsSelected = isChecked;
+    }
+}

+private void UpdateColumnPreferences(string columnName, bool isSelected)
+{
+    switch (columnName)
+    {
+        case DESCRIPTION_COLUMN:
+            columnPreferences = isSelected ? "Description," : "";
+            break;
+        // ... other cases
+    }
+}

 private void ColumnMultiSelectComboBox_ItemCheckBoxClick(object sender, EventArgs e)
 {
     customDynamicView.GridColsView = [];

     if (sender is System.Windows.Controls.CheckBox checkBox)
     {
-        if (checkBox.Content.ToString() == "All")
+        if (checkBox.Content.ToString() == ALL_COLUMN)
         {
-            if (checkBox.IsChecked == true)
-            {
-                for (int i = 1; i < 6; i++)
-                {
-                    columnMultiSelectComboBox._nodeList[i].IsSelected = true;
-                }
-            }
-            else
-            {
-                for (int i = 1; i < 6; i++)
-                {
-                    columnMultiSelectComboBox._nodeList[i].IsSelected = false;
-                }
-            }
+            HandleAllCheckboxClick(checkBox);
         }
     }
     
     columnPreferences = "";
     columnCount = 0;
     foreach (Node node in columnMultiSelectComboBox._nodeList)
     {
-        switch (node.Title)
-        {
-            case "Description":
-                // ... existing code
-            case "Path":
-                // ... existing code
-        }
+        UpdateColumnPreferences(node.Title, node.IsSelected);
     }
     // ... rest of the method
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87a5c5c and 1b035c5.

📒 Files selected for processing (1)
  • Ginger/Ginger/Actions/ActionEditPage.xaml.cs (2 hunks)

Comment thread Ginger/Ginger/Actions/ActionEditPage.xaml.cs
Comment thread Ginger/Ginger/Actions/ActionEditPage.xaml.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b035c5 and 3aaf29f.

📒 Files selected for processing (3)
  • Ginger/Ginger/Reports/HTMLReportTemplatePage.xaml.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (2 hunks)
🧰 Additional context used
📓 Learnings (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (2)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1084-1091
Timestamp: 2025-01-30T09:08:06.584Z
Learning: In Playwright-based element wait operations (like WaitForElementsInvisibleAsync), use ElementState.Hidden to check for elements that are present in the DOM but not visible, rather than checking if elements are detached/removed from the DOM.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1075-1083
Timestamp: 2025-01-30T09:07:12.356Z
Learning: In Playwright-based element wait operations (like WaitForElementsVisibleAsync), do not short-circuit when elements are initially absent, as the method is designed to keep polling until timeout to handle dynamic element appearance.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (1)
Learnt from: IamRanjeetSingh
PR: Ginger-Automation/Ginger#3783
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs:129-129
Timestamp: 2024-11-12T02:45:14.501Z
Learning: User IamRanjeetSingh has indicated that the `RunAction` method in the `PlaywrightDriver` class should remain synchronous due to current constraints in the codebase.
🔇 Additional comments (11)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (8)

1051-1070: Potential timeout unit mismatch in WaitForUrlMatchAsync
Currently, the method directly passes the float timeout to WaitForURLAsync. Playwright’s API expects the timeout in milliseconds, but it’s unclear whether the user is passing seconds or milliseconds.


1080-1086: Straightforward wrapper for visibility
The method simply calls WaitForElementsStateAsync with ElementState.Visible. Implementation appears correct.


1088-1094: Consistent usage of ElementState.Hidden
Using Hidden is appropriate for elements present in the DOM but not visible. This aligns well with Playwright-based element wait patterns.


1096-1102: Validate “Stable” state usage for presence
"Stable" ensures the element is not moving. If the intention is to confirm mere presence in DOM, consider using Attached instead to avoid confusion.


1145-1168: Return value for no elements in WaitForElementsStateAsync
When no elements match the selector, the method returns true without waiting. If “presence” is required, consider raising an exception when zero elements are found.


1188-1188: Field for tracking alert detection
The TaskCompletionSource<bool> usage looks fine and straightforward.


1190-1205: Clarify timeout units in WaitForAlertAsync
Task.Delay((int)timeout) might truncate decimals and interpret timeout as milliseconds or seconds differently. Ensure consistency with user expectations.


1207-1216: Dialog event handling
Setting the result when DialogType.Alert is received is correct and succinct.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs (2)

285-325: Inconsistent timeout usage for ActWebSmartSync
browserOptions.Timeout is set to waitUntilTime (likely seconds), but actWebSmartSyncHandler.HandleAsync uses waitUntilTime * 1000. Confirm that both are intended to be milliseconds or seconds to avoid confusion.


337-337: Newly supported action type
Recognizing ActWebSmartSync in IsActionSupported broadens driver coverage.

Ginger/Ginger/Reports/HTMLReportTemplatePage.xaml.cs (1)

1034-1034: No functional change
Only a blank line was added. No concerns.

@GokulBothe99

GokulBothe99 commented Jan 31, 2025

Copy link
Copy Markdown
Contributor Author

in SwitchFrameAsync method its wait until frame gets avilable its not using the time out so need use the stopwatch for specific amt of time

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jan 31, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2db646b and 7ce666c.

📒 Files selected for processing (3)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (1 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs (3 hunks)
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (4 hunks)
🧰 Additional context used
📓 Learnings (2)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (3)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1104-1143
Timestamp: 2025-01-31T13:25:31.910Z
Learning: In Playwright-based element wait operations (like WaitForElementsCheckedAsync), do not throw immediately when elements are initially absent, as the method is designed to keep polling until timeout to handle dynamic element appearance.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1075-1083
Timestamp: 2025-01-30T09:07:12.356Z
Learning: In Playwright-based element wait operations (like WaitForElementsVisibleAsync), do not short-circuit when elements are initially absent, as the method is designed to keep polling until timeout to handle dynamic element appearance.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs:1084-1091
Timestamp: 2025-01-30T09:08:06.584Z
Learning: In Playwright-based element wait operations (like WaitForElementsInvisibleAsync), use ElementState.Hidden to check for elements that are present in the DOM but not visible, rather than checking if elements are detached/removed from the DOM.
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (3)
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:358-365
Timestamp: 2025-01-30T07:40:08.756Z
Learning: In the Ginger automation framework, when an element is expected to exist but is not found, the code should throw an exception rather than return null, as the element's presence is a precondition for the operation.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:137-150
Timestamp: 2025-01-30T07:38:05.310Z
Learning: In the Ginger automation framework, element existence checks using polling with 100ms delay is an acceptable approach, as confirmed by the maintainers.
Learnt from: GokulBothe99
PR: Ginger-Automation/Ginger#4072
File: Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs:36-114
Timestamp: 2025-01-30T07:36:32.448Z
Learning: In the Ginger project's web synchronization code, keeping separate implementations for different synchronization operations is preferred over extracting common polling logic, as it improves readability and makes individual cases easier to understand and modify.
🔇 Additional comments (30)
Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs (2)

39-39: Method name consistency looks good.
The asynchronous naming convention (“TitleAsync”) aligns well with the rest of the interface methods (e.g. URLAsync).


103-112: Watch out for consistent timeout units.
All these new wait methods (WaitForUrlMatchAsync, WaitForAlertAsync, etc.) accept a float timeout. Ensure the implementation in the underlying classes consistently interprets the value as seconds or milliseconds. Consider clarifying in documentation or parameter naming (e.g., timeoutSeconds vs timeoutMs) to avoid confusion.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActWebSmartSyncHandler.cs (19)

39-44: Constructor logic looks correct.
The constructor properly initializes the handler’s dependencies (_actWebSmartSync, _browserTab, _elementLocator).


50-130: Default case includes a clear error message.
The switch statement covers all sync operations, ending with a default that sets an error message on the act object. This is good defensive coding.


135-143: Visibility check approach is straightforward.
No issues found; the method calls GetFirstMatchingElementAsync and checks visibility via element.ToBeVisibleAsync().


148-161: Element existence loop is well-structured.
The Stopwatch loop with a 100ms polling cycle is consistent with your chosen approach for waiting.


166-173: Alert presence check delegates to the browser tab.
Clean usage of _browserTab.WaitForAlertAsync, making the code readable and maintainable.


178-186: Element selected check is clear.
The method succinctly checks if the element is selected within the given timeout.


193-199: Page load check.
Relies on WaitTillLoadedAsync. Straightforward implementation; watch out for the meaning of the timeOut parameter in the underlying driver.


205-212: Element clickable verification.
Your flow to retrieve the element and test clickability is correct; no issues.


217-230: Text matching approach is robust.
You validate the input for text, throw if missing, then check if it matches. Good guard conditions.


235-254: Attribute matching handles invalid inputs.
Throwing InvalidDataException for missing attribute name/value helps ensure correct usage.


259-266: Delegate to IBrowserTab for enabling check.
Uses _browserTab.WaitForElementsEnabledAsync—a nice way to keep logic centralized in the driver layer.


272-284: [Duplicate of prior consolidation suggestions]
The method uses a polling loop with a Stopwatch and Task.Delay(100)—similar to other checks. Since you’ve expressed a preference for separate implementations, this is fine.


290-296: Simple invisibility check.
Delegates to WaitForElementsInvisibleAsync. The logic is consistent with other methods.


301-309: Single-element invisibility check.
Uses ToBeNotVisibleAsync for the first matching element. Straightforward logic.


315-321: Presence of elements verification.
Checks all required elements with _browserTab.WaitForElementsPresenceAsync.


327-333: Multiple element selected check.
Uses _browserTab.WaitForElementsCheckedAsync to verify all are selected.


338-350: URL match operation is comprehensive.
Ensures the input param is valid and delegates to _browserTab.WaitForUrlMatchAsync.


355-362: Visibility of all elements check.
Delegates to _browserTab.WaitForElementsVisibleAsync; consistent with other checks.


367-376: Throws if element is not found.
This matches the preference stated in the learnings: you throw an exception if the element is a precondition for the operation. Good approach.

Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightBrowserTab.cs (9)

36-36: Imports for concurrency look fine.
The additional using System.Threading; using System.Threading.Tasks; references are necessary for asynchronous tasks.


246-246: Mouse move check.
Calls ThrowIfClosed() to ensure the tab is active before proceeding, which is consistent with the rest of the code.


318-328: Catches Exception and returns false.
Returning false on any exception helps the caller understand load failure. Just ensure any ephemeral errors also get logged, if needed, for debugging.


1082-1088: Double-check if visibility state is mandatory.
WaitForElementsEnabledAsync calls WaitForElementsStateAsync with ElementState.Visible and ElementState.Enabled. If only enabled state is needed, consider removing the Visible requirement.


1090-1096: Single state usage is straightforward.
WaitForElementsVisibleAsync uses only ElementState.Visible, consistent with the method name.


1098-1105: Hidden state usage matches learnings.
WaitForElementsInvisibleAsync uses ElementState.Hidden to detect elements that remain in the DOM but are not visible. This aligns with the preferred approach in the learnings.


1114-1153: Re-check discovered elements repeatedly.
Elements are fetched once, then polled for check status. If new elements might appear later, they won’t be included. Confirm that this behavior is intended.


1180-1197: Selector generation is flexible.
Supports various locator types. No immediate issues as you’re escaping colons for ID-based queries.


1061-1080: ⚠️ Potential issue

Potential timeout unit mismatch in WaitForUrlMatchAsync.
Playwright’s PageWaitForURLOptions.Timeout expects milliseconds, but it looks like the timeout parameter is possibly in seconds. Convert or rename to avoid ~1000x discrepancy.

- await _playwrightPage.WaitForURLAsync(urlPattern, new PageWaitForURLOptions { Timeout = timeout });
+ await _playwrightPage.WaitForURLAsync(urlPattern, new PageWaitForURLOptions { Timeout = timeout * 1000 });

Likely invalid or redundant comment.

Comment thread Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/IBrowserTab.cs
@GokulBothe99
GokulBothe99 removed the request for review from prashelke February 1, 2025 10:13
@Maheshkale447
Maheshkale447 merged commit d8be0e1 into master Feb 2, 2025
@Maheshkale447
Maheshkale447 deleted the Feature/WebSmartSyncActionPlaywrightSupport branch February 2, 2025 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants