Skip to content

Commit e562667

Browse files
committed
Refactor methods and add mouse position model
Updated using directives in PublicExtensions.cs and UiaDriverTests.cs. Renamed several methods to use User32 naming convention. Added MoveUser32Mouse method for native mouse operations. Removed redundant check in WebDriverBase.cs. Introduced MousePositionInputModel class in G4.WebDriver.Models.
1 parent 381db3e commit e562667

File tree

4 files changed

+98
-12
lines changed

4 files changed

+98
-12
lines changed

src/G4.WebDriver.Remote.Uia/Extensions/PublicExtensions.cs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using G4.WebDriver.Remote;
1+
using G4.WebDriver.Models;
2+
using G4.WebDriver.Remote;
23

34
using System.Collections.Generic;
45
using System.Net.Http;
5-
using System.Reflection;
66
using System.Text.Json;
77

8-
#pragma warning disable S3011 // Necessary to interact with internal fields for sending native actions.
98
namespace G4.WebDriver.Extensions
109
{
1110
/// <summary>
@@ -29,7 +28,7 @@ public static class UiaExtensions
2928
/// <param name="element">The web element to get the attribute from.</param>
3029
/// <param name="name">The name of the attribute.</param>
3130
/// <returns>The attribute value as a string.</returns>
32-
public static string GetUiaAttribute(this IWebElement element, string name)
31+
public static string GetUser32Attribute(this IWebElement element, string name)
3332
{
3433
// Get the session ID and element ID from the web element
3534
var (sessionId, elementId) = GetRouteData(element);
@@ -63,11 +62,61 @@ public static string GetUiaAttribute(this IWebElement element, string name)
6362
return isValue ? $"{value}" : string.Empty;
6463
}
6564

65+
/// <summary>
66+
/// Moves the mouse pointer over the specified web element using default mouse position data.
67+
/// </summary>
68+
/// <param name="element">The target web element over which the mouse will be moved.</param>
69+
/// <remarks>This method is designed for Windows environments only, utilizing the user32.dll for native mouse operations.</remarks>
70+
public static void MoveUser32Mouse(this IWebElement element)
71+
{
72+
// Call the overload with a default MousePositionInputModel.
73+
MoveUser32Mouse(element, new MousePositionInputModel());
74+
}
75+
76+
/// <summary>
77+
/// Moves the mouse pointer over the specified web element using the provided mouse position data.
78+
/// </summary>
79+
/// <param name="element">The target web element over which the mouse will be moved.</param>
80+
/// <param name="positionData">The mouse position data to use when moving the mouse.</param>
81+
/// <remarks>This method is designed for Windows environments only, utilizing the user32.dll for native mouse operations.</remarks>
82+
public static void MoveUser32Mouse(this IWebElement element, MousePositionInputModel positionData)
83+
{
84+
// Retrieve the session ID and element ID from the web element for routing.
85+
var (sessionId, elementId) = GetRouteData(element);
86+
87+
// Retrieve the WebDriver instance associated with the element.
88+
var driver = element.Driver;
89+
90+
// Get the URI of the remote server from the command executor.
91+
var url = GetRemoteServerUri(driver);
92+
93+
// Construct the request URI for the native mouse move command.
94+
var requestUri = $"{url}/session/{sessionId}/user32/element/{elementId}/mouse/move";
95+
96+
// Serialize the mouse position input model to JSON.
97+
var jsonData = JsonSerializer.Serialize(positionData, JsonSerializerOptions);
98+
99+
// Create the HTTP content using the serialized JSON, specifying the content type.
100+
var content = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
101+
102+
// Construct the HTTP POST request with the target URI and content.
103+
var request = new HttpRequestMessage(HttpMethod.Post, requestUri)
104+
{
105+
Content = content
106+
};
107+
108+
// Send the HTTP request to move the mouse.
109+
var response = HttpClient.Send(request);
110+
111+
// Ensure that the HTTP response indicates a successful request.
112+
response.EnsureSuccessStatusCode();
113+
}
114+
66115
/// <summary>
67116
/// Sends a native click command to a web element.
68117
/// </summary>
69118
/// <param name="element">The web element to click.</param>
70-
public static void SendNativeClick(this IWebElement element)
119+
public static void SendUser32Click(this IWebElement element)
71120
{
72121
// Get the session ID and element ID from the web element
73122
var (sessionId, elementId) = GetRouteData(element);
@@ -95,7 +144,7 @@ public static void SendNativeClick(this IWebElement element)
95144
/// Sends a native double-click command to a web element.
96145
/// </summary>
97146
/// <param name="element">The web element to double-click.</param>
98-
public static void SendNativeDoubleClick(this IWebElement element)
147+
public static void SendUser32DoubleClick(this IWebElement element)
99148
{
100149
// Get the session ID and element ID from the web element
101150
var (sessionId, elementId) = GetRouteData(element);
@@ -123,7 +172,7 @@ public static void SendNativeDoubleClick(this IWebElement element)
123172
/// Sets focus on a web element.
124173
/// </summary>
125174
/// <param name="element">The web element to set focus on.</param>
126-
public static void SetFocus(this IWebElement element)
175+
public static void SetUser32Focus(this IWebElement element)
127176
{
128177
// Get the session ID and element ID from the web element
129178
var (sessionId, elementId) = GetRouteData(element);
@@ -157,8 +206,6 @@ private static string GetRemoteServerUri(IWebDriver driver)
157206
// Gets the session ID and element ID from a web element.
158207
private static (string SessionId, string ElementId) GetRouteData(IWebElement element)
159208
{
160-
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
161-
162209
// Get the WebDriver instance from the web element
163210
var driver = element.Driver;
164211

@@ -169,4 +216,4 @@ private static (string SessionId, string ElementId) GetRouteData(IWebElement ele
169216
return (sessionId, element.Id);
170217
}
171218
}
172-
}
219+
}

src/G4.WebDriver.Tests/UiaDriverTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using G4.WebDriver.Models;
1+
using G4.WebDriver.Extensions;
2+
using G4.WebDriver.Models;
23
using G4.WebDriver.Remote.Uia;
34

45
using Microsoft.VisualStudio.TestTools.UnitTesting;
56

7+
using System;
68
using System.IO;
79

810
namespace G4.WebDriver.Tests
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
namespace G4.WebDriver.Models
2+
{
3+
/// <summary>
4+
/// Represents the input model for specifying a mouse position.
5+
/// </summary>
6+
public class MousePositionInputModel
7+
{
8+
/// <summary>
9+
/// Gets or sets the alignment for the mouse position.
10+
/// </summary>
11+
/// <value>The alignment for the mouse position (e.g., TopLeft, MiddleCenter).</value>
12+
public string Alignment { get; set; } = "TopLeft";
13+
14+
/// <summary>
15+
/// Gets or sets the offset from the X-coordinate.
16+
/// </summary>
17+
/// <value>The offset from the X-coordinate.</value>
18+
public int OffsetX { get; set; } = 1;
19+
20+
/// <summary>
21+
/// Gets or sets the offset from the Y-coordinate.
22+
/// </summary>
23+
/// <value>The offset from the Y-coordinate.</value>
24+
public int OffsetY { get; set; } = 1;
25+
26+
/// <summary>
27+
/// Gets or sets the X-coordinate of the mouse position.
28+
/// </summary>
29+
/// <value>The X-coordinate of the mouse position.</value>
30+
public int X { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the Y-coordinate of the mouse position.
34+
/// </summary>
35+
/// <value>The Y-coordinate of the mouse position.</value>
36+
public int Y { get; set; }
37+
}
38+
}

src/G4.WebDriver/Remote/WebDriverBase.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ void AddCustomCommands()
5555
AddCustomCommands();
5656

5757
// If a new session is not required, exit the constructor early.
58-
5958
if (!session.StartNewSession)
6059
{
6160
return;

0 commit comments

Comments
 (0)