Skip to content

Improve mobile element highlighting and rectangle accuracy#4480

Merged
ravirk91 merged 1 commit into
Releases/Official-Releasefrom
bugfix/issue_61080_highlight_not_working
Apr 7, 2026
Merged

Improve mobile element highlighting and rectangle accuracy#4480
ravirk91 merged 1 commit into
Releases/Official-Releasefrom
bugfix/issue_61080_highlight_not_working

Conversation

@tanushahande2003
Copy link
Copy Markdown
Contributor

@tanushahande2003 tanushahande2003 commented Apr 6, 2026

Enhances reliability of UI element highlighting and rectangle drawing, especially for Android automation. Ensures up-to-date element details are used, validates and refreshes element bounds before drawing overlays, and preserves correct element identity for web highlights. Adds error handling and makes driver highlight requests more robust, addressing issues with invalid rectangles and incorrect element selection in live spy and mobile scenarios.

Description

Type of Change

  • Bug fix - [ ] New feature - [ ] Breaking change - [ ] Plugin update

Checklist

  • PR description clearly describes the changes
  • Target branch is correct (master for features, Releases/* for fixes)
  • Latest code from target branch merged
  • No commented/junk code included
  • No new build warnings or errors
  • All existing unit tests pass
  • New unit tests added for new functionality
  • Cross-platform compatibility verified (Windows/Linux/macOS)
  • CI/CD pipeline passes
  • Code follows project conventions (Act{Platform}{Type}, {Platform}Driver)
  • Repository objects use [IsSerializedForLocalRepository] where needed
  • Error handling uses Reporter.ToLog() pattern
  • Documentation updated for user-facing changes
  • Self-review completed and code review comments addressed

Summary by CodeRabbit

Release Notes

Bug Fixes

  • Improved element detection by enriching element information when initial searches fail, allowing the system to retry with more complete data.
  • Enhanced element dimension validation with automatic bounds refresh when dimensions are invalid.
  • Refined element highlighting behavior with better control over app-based highlighting versus screenshot-based highlighting.
  • Strengthened element identity preservation during filtering operations to ensure correct element references are maintained.

Enhances reliability of UI element highlighting and rectangle drawing, especially for Android automation. Ensures up-to-date element details are used, validates and refreshes element bounds before drawing overlays, and preserves correct element identity for web highlights. Adds error handling and makes driver highlight requests more robust, addressing issues with invalid rectangles and incorrect element selection in live spy and mobile scenarios.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 6, 2026

Walkthrough

The pull request enhances element handling in mobile and POM automation workflows. Key changes include capturing enriched element instances returned by LearnElementInfoDetails() for conditional use, adding optional control over element highlighting behavior in WindowExplorerPage, and improving device bounds enrichment and validation logic in the mobile driver with safer null-handling and size calculations.

Changes

Cohort / File(s) Summary
Element Learning Enrichment
PomAllElementsPage.xaml.cs, LiveSpyPage.xaml.cs
Captures return value from LearnElementInfoDetails() and conditionally updates mSpyElement with the enriched instance when non-null, enabling subsequent logic to operate on enriched element data.
Window Explorer Highlighting Control
WindowExplorerPage.xaml.cs
Adds highlightInApp boolean parameter (default true) to DrawElementRectangleAsync() to selectively disable in-app highlighting; adds pre-draw validation that attempts to update element bounds if invalid and early-exits with logging.
Mobile Driver Bounds Enrichment
GenericAppiumDriver.cs
Enhances EnsureDeviceBounds() with safer null-safe property lookup and more robust bounds parsing using Max(0, computed-value) logic; refines HighLightElement() to preserve element identity for web highlights when locating by locators; updates GetElementInfoforXmlNode() to populate width/height from bounds coordinates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested reviewers

  • ravirk91
  • Maheshkale447

Poem

🐰 A spy that learns grows oh so wise,
With bounds refined and element prize,
We paint the screens with careful care,
And let the driver breathe fresh air! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a clear overview of the changes and their purpose, but the checklist items are not marked as complete, which is required by the template. Mark the relevant checklist items as complete (at minimum: PR description, target branch, code review, and testing items that apply to this changeset).
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: improving mobile element highlighting and rectangle accuracy, which aligns with the core focus of the changeset across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/issue_61080_highlight_not_working

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codacy-production
Copy link
Copy Markdown

Not up to standards ⛔

TIP This summary will be updated as you push new changes. Give us feedback

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Ginger/Ginger/AutomatePageLib/AddActionMenu/LiveSpy/LiveSpyPage.xaml.cs`:
- Line 269: The code calls LearnElementInfoDetails on
xWindowSelectionUC.mWindowExplorerDriver causing potential reference drift;
replace that call to use the active field mWindowExplorerDriver instead (i.e.,
call mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement)) so the single
source of truth is used; ensure the existing null/guard check around
mWindowExplorerDriver remains in place before invoking LearnElementInfoDetails.

In
`@Ginger/Ginger/AutomatePageLib/AddActionMenu/WindowExplorer/Common/WindowExplorerPage.xaml.cs`:
- Around line 1501-1504: The catch blocks currently logging exceptions with
Reporter.ToLog at eLogLevel.DEBUG are error paths and should be changed to
eLogLevel.ERROR; update the Reporter.ToLog calls inside
DrawElementRectangleAsync (the catch around UpdateElementInfoFields) and the
other two catch blocks referenced (around lines 1635–1644) to use
eLogLevel.ERROR instead of eLogLevel.DEBUG so failures are logged as errors;
keep the same message and exception parameter when replacing the log level for
Reporter.ToLog.

In
`@Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs`:
- Around line 1804-1814: The code is using ei.Properties.FirstOrDefault(...) to
read a cached "bounds" which can be stale; change the logic in
GenericAppiumDriver (where boundsAttr is set) and in
GetLocationAndSizeOfElement()/EnsureDeviceBounds() to prefer the live value from
the IWebElement: always call we.GetAttribute("bounds") when ei.ElementObject is
an IWebElement and use that result (falling back to ei.Properties only if
GetAttribute returns null/empty), then write the fresh bounds back into
ei.Properties["bounds"] (update existing key or add) so subsequent reads reflect
the latest rectangle and duplicate stale values are not preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b038127a-27da-4deb-937d-1bb86411ff69

📥 Commits

Reviewing files that changed from the base of the PR and between 25af07b and e33f4b3.

📒 Files selected for processing (4)
  • Ginger/Ginger/ApplicationModelsLib/POMModels/PomAllElementsPage.xaml.cs
  • Ginger/Ginger/AutomatePageLib/AddActionMenu/LiveSpy/LiveSpyPage.xaml.cs
  • Ginger/Ginger/AutomatePageLib/AddActionMenu/WindowExplorer/Common/WindowExplorerPage.xaml.cs
  • Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs

// Learn details (fills properties/locators)
xWindowSelectionUC.mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
// Learn details (fills properties/locators) and keep enriched instance if returned
var learnedElement = xWindowSelectionUC.mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
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.

🧹 Nitpick | 🔵 Trivial

Use the active driver field for element learning to avoid reference drift.

Line 269 calls LearnElementInfoDetails via xWindowSelectionUC.mWindowExplorerDriver while this flow is guarded by mWindowExplorerDriver. Prefer a single source of truth here to avoid null/out-of-sync edge failures.

Suggested change
- var learnedElement = xWindowSelectionUC.mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
+ var learnedElement = mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var learnedElement = xWindowSelectionUC.mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
var learnedElement = mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Ginger/Ginger/AutomatePageLib/AddActionMenu/LiveSpy/LiveSpyPage.xaml.cs` at
line 269, The code calls LearnElementInfoDetails on
xWindowSelectionUC.mWindowExplorerDriver causing potential reference drift;
replace that call to use the active field mWindowExplorerDriver instead (i.e.,
call mWindowExplorerDriver.LearnElementInfoDetails(mSpyElement)) so the single
source of truth is used; ensure the existing null/guard check around
mWindowExplorerDriver remains in place before invoking LearnElementInfoDetails.

Comment on lines +1501 to +1504
catch (Exception exUpd)
{
Reporter.ToLog(eLogLevel.DEBUG, "DrawElementRectangleAsync: UpdateElementInfoFields failed before rectangle draw: " + exUpd.Message, exUpd);
}
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.

⚠️ Potential issue | 🟡 Minor

Use ERROR level in these exception paths.

Line 1503, Line 1637, and Line 1644 log caught failures with DEBUG. These are error paths and should use eLogLevel.ERROR for consistency and alerting fidelity.

Suggested change
- Reporter.ToLog(eLogLevel.DEBUG, "DrawElementRectangleAsync: UpdateElementInfoFields failed before rectangle draw: " + exUpd.Message, exUpd);
+ Reporter.ToLog(eLogLevel.ERROR, "DrawElementRectangleAsync: UpdateElementInfoFields failed before rectangle draw: " + exUpd.Message, exUpd);

- Reporter.ToLog(eLogLevel.DEBUG, "Driver HighLightElement failed", ex);
+ Reporter.ToLog(eLogLevel.ERROR, "Driver HighLightElement failed", ex);

- Reporter.ToLog(eLogLevel.DEBUG, "Request to driver highlight element failed", ex);
+ Reporter.ToLog(eLogLevel.ERROR, "Request to driver highlight element failed", ex);

As per coding guidelines: **/*.cs: Use Reporter.ToLog(eLogLevel.ERROR, message) for logging errors.

Also applies to: 1635-1644

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Ginger/Ginger/AutomatePageLib/AddActionMenu/WindowExplorer/Common/WindowExplorerPage.xaml.cs`
around lines 1501 - 1504, The catch blocks currently logging exceptions with
Reporter.ToLog at eLogLevel.DEBUG are error paths and should be changed to
eLogLevel.ERROR; update the Reporter.ToLog calls inside
DrawElementRectangleAsync (the catch around UpdateElementInfoFields) and the
other two catch blocks referenced (around lines 1635–1644) to use
eLogLevel.ERROR instead of eLogLevel.DEBUG so failures are logged as errors;
keep the same message and exception parameter when replacing the log level for
Reporter.ToLog.

Comment on lines +1804 to +1814
string boundsAttr = ei.Properties?
.FirstOrDefault(p => string.Equals(p.Name, "bounds", StringComparison.InvariantCultureIgnoreCase))
?.Value;
if (ei.ElementObject is IWebElement we)
{
try
{
boundsAttr = we.GetAttribute("bounds");
if (string.IsNullOrEmpty(boundsAttr))
{
boundsAttr = we.GetAttribute("bounds");
}
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.

⚠️ Potential issue | 🟠 Major

Refresh bounds from the live element, not the first cached property.

This now prefers ei.Properties["bounds"], but EnsureDeviceBounds() also writes "bounds" back into ei.Properties. On a reused ElementInfo, FirstOrDefault() keeps returning the oldest rectangle, and GetLocationAndSizeOfElement() also keeps the first duplicate, so the highlight can stay stale after a refresh.

💡 Suggested fix
-                string boundsAttr = ei.Properties?
-                    .FirstOrDefault(p => string.Equals(p.Name, "bounds", StringComparison.InvariantCultureIgnoreCase))
-                    ?.Value;
+                string boundsAttr = null;
                 if (ei.ElementObject is IWebElement we)
                 {
                     try
                     {
-                        if (string.IsNullOrEmpty(boundsAttr))
-                        {
-                            boundsAttr = we.GetAttribute("bounds");
-                        }
+                        boundsAttr = we.GetAttribute("bounds");
                     }
                     catch { boundsAttr = null; }
                 }
+
+                if (string.IsNullOrEmpty(boundsAttr))
+                {
+                    boundsAttr = ei.Properties?
+                        .LastOrDefault(p => string.Equals(p.Name, "bounds", StringComparison.InvariantCultureIgnoreCase))
+                        ?.Value;
+                }
-                        if (ei.Properties == null) ei.Properties = new ObservableList<ControlProperty>();
-                        ei.Properties.Add(new ControlProperty() { Name = "bounds", Value = $"[{l},{t}][{r},{b}]" });
+                        if (ei.Properties == null) ei.Properties = new ObservableList<ControlProperty>();
+                        var existingBounds = ei.Properties
+                            .FirstOrDefault(p => string.Equals(p.Name, "bounds", StringComparison.InvariantCultureIgnoreCase));
+                        if (existingBounds != null)
+                        {
+                            existingBounds.Value = $"[{l},{t}][{r},{b}]";
+                        }
+                        else
+                        {
+                            ei.Properties.Add(new ControlProperty() { Name = "bounds", Value = $"[{l},{t}][{r},{b}]" });
+                        }

Also applies to: 1835-1837

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs`
around lines 1804 - 1814, The code is using ei.Properties.FirstOrDefault(...) to
read a cached "bounds" which can be stale; change the logic in
GenericAppiumDriver (where boundsAttr is set) and in
GetLocationAndSizeOfElement()/EnsureDeviceBounds() to prefer the live value from
the IWebElement: always call we.GetAttribute("bounds") when ei.ElementObject is
an IWebElement and use that result (falling back to ei.Properties only if
GetAttribute returns null/empty), then write the fresh bounds back into
ei.Properties["bounds"] (update existing key or add) so subsequent reads reflect
the latest rectangle and duplicate stale values are not preserved.

@ravirk91 ravirk91 merged commit 44a50fc into Releases/Official-Release Apr 7, 2026
13 of 14 checks passed
@ravirk91 ravirk91 deleted the bugfix/issue_61080_highlight_not_working branch April 7, 2026 07:12
@coderabbitai coderabbitai Bot mentioned this pull request Apr 13, 2026
15 tasks
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