From 65b4148014baf9f7e08ea3477976cbb8aa2c31f4 Mon Sep 17 00:00:00 2001 From: Quynh-Nga Pham Date: Wed, 7 May 2025 16:17:55 +0700 Subject: [PATCH 1/5] Support getPageSource endpoint --- .../Controllers/SourceController.cs | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/FlaUI.WebDriver/Controllers/SourceController.cs diff --git a/src/FlaUI.WebDriver/Controllers/SourceController.cs b/src/FlaUI.WebDriver/Controllers/SourceController.cs new file mode 100644 index 0000000..b58c860 --- /dev/null +++ b/src/FlaUI.WebDriver/Controllers/SourceController.cs @@ -0,0 +1,166 @@ +@@ -0,0 +1,165 @@ +using FlaUI.WebDriver.Models; +using Microsoft.AspNetCore.Mvc; +using FlaUI.Core.AutomationElements; +using FlaUI.WebDriver.Services; +using System.Xml; +using System.Text; + +namespace FlaUI.WebDriver.Controllers +{ + [ApiController] + [Route("session/{sessionId}/[controller]")] + public class SourceController : ControllerBase + { + private readonly ILogger _logger; + private readonly ISessionRepository _sessionRepository; + private const int InitialStringBuilderCapacity = 64 * 1024; // 64KB initial capacity + + public SourceController(ILogger logger, ISessionRepository sessionRepository) + { + _logger = logger; + _sessionRepository = sessionRepository; + } + + [HttpGet] + public async Task GetPageSource([FromRoute] string sessionId) + { + var session = GetActiveSession(sessionId); + var rootElement = session.App == null ? session.Automation.GetDesktop() : session.CurrentWindow; + var rootBounds = rootElement.BoundingRectangle; + var xml = ConvertElementToXml(rootElement, rootBounds); + return await Task.FromResult(WebDriverResult.Success(xml)); + } + + private string ConvertElementToXml(AutomationElement element, System.Drawing.Rectangle rootBounds) + { + var settings = new XmlWriterSettings + { + Indent = true, + IndentChars = " ", + Encoding = Encoding.Unicode, + OmitXmlDeclaration = true + }; + + var stringBuilder = new StringBuilder(InitialStringBuilderCapacity); + using var writer = XmlWriter.Create(stringBuilder, settings); + WriteElementToXml(writer, element, rootBounds); + return stringBuilder.ToString(); + } + + private void WriteElementToXml(XmlWriter writer, AutomationElement element, System.Drawing.Rectangle rootBounds) + { + var controlType = element.ControlType.ToString(); + writer.WriteStartElement(controlType); + + var properties = element.Properties; + WriteAttributeIfNotNull(writer, "AcceleratorKey", properties.AcceleratorKey); + WriteAttributeIfNotNull(writer, "AccessKey", properties.AccessKey); + WriteAttributeIfNotNull(writer, "AutomationId", properties.AutomationId); + WriteAttributeIfNotNull(writer, "ClassName", properties.ClassName); + WriteAttributeIfNotNull(writer, "FrameworkId", properties.FrameworkId); + WriteAttributeIfNotNull(writer, "HasKeyboardFocus", properties.HasKeyboardFocus); + WriteAttributeIfNotNull(writer, "HelpText", properties.HelpText); + WriteAttributeIfNotNull(writer, "IsContentElement", properties.IsContentElement); + WriteAttributeIfNotNull(writer, "IsControlElement", properties.IsControlElement); + WriteAttributeIfNotNull(writer, "IsEnabled", properties.IsEnabled); + WriteAttributeIfNotNull(writer, "IsKeyboardFocusable", properties.IsKeyboardFocusable); + WriteAttributeIfNotNull(writer, "IsOffscreen", properties.IsOffscreen); + WriteAttributeIfNotNull(writer, "IsPassword", properties.IsPassword); + WriteAttributeIfNotNull(writer, "IsRequiredForForm", properties.IsRequiredForForm); + WriteAttributeIfNotNull(writer, "ItemStatus", properties.ItemStatus); + WriteAttributeIfNotNull(writer, "ItemType", properties.ItemType); + WriteAttributeIfNotNull(writer, "LocalizedControlType", properties.LocalizedControlType); + WriteAttributeIfNotNull(writer, "Name", properties.Name); + WriteAttributeIfNotNull(writer, "Orientation", properties.Orientation); + WriteAttributeIfNotNull(writer, "ProcessId", properties.ProcessId); + WriteAttributeIfNotNull(writer, "RuntimeId", properties.RuntimeId); + + var bounds = element.BoundingRectangle; + writer.WriteAttributeString("x", (bounds.X - rootBounds.X).ToString()); + writer.WriteAttributeString("y", (bounds.Y - rootBounds.Y).ToString()); + writer.WriteAttributeString("width", bounds.Width.ToString()); + writer.WriteAttributeString("height", bounds.Height.ToString()); + + var patterns = element.Patterns; + if (patterns.Window.IsSupported) + { + var windowPattern = patterns.Window.Pattern; + WriteAttributeIfNotNull(writer, "CanMaximize", windowPattern.CanMaximize); + WriteAttributeIfNotNull(writer, "CanMinimize", windowPattern.CanMinimize); + WriteAttributeIfNotNull(writer, "IsModal", windowPattern.IsModal); + WriteAttributeIfNotNull(writer, "WindowVisualState", windowPattern.WindowVisualState); + WriteAttributeIfNotNull(writer, "WindowInteractionState", windowPattern.WindowInteractionState); + WriteAttributeIfNotNull(writer, "IsTopmost", windowPattern.IsTopmost); + } + + if (patterns.Scroll.IsSupported) + { + var scrollPattern = patterns.Scroll.Pattern; + WriteAttributeIfNotNull(writer, "HorizontallyScrollable", scrollPattern.HorizontallyScrollable); + WriteAttributeIfNotNull(writer, "VerticallyScrollable", scrollPattern.VerticallyScrollable); + WriteAttributeIfNotNull(writer, "HorizontalScrollPercent", scrollPattern.HorizontalScrollPercent); + WriteAttributeIfNotNull(writer, "VerticalScrollPercent", scrollPattern.VerticalScrollPercent); + WriteAttributeIfNotNull(writer, "HorizontalViewSize", scrollPattern.HorizontalViewSize); + WriteAttributeIfNotNull(writer, "VerticalViewSize", scrollPattern.VerticalViewSize); + } + + if (patterns.SelectionItem.IsSupported) + { + var selectionItemPattern = patterns.SelectionItem.Pattern; + WriteAttributeIfNotNull(writer, "IsSelected", selectionItemPattern.IsSelected); + if (selectionItemPattern.SelectionContainer != null) + { + writer.WriteAttributeString("SelectionContainer", selectionItemPattern.SelectionContainer.ToString()); + } + } + + if (patterns.ExpandCollapse.IsSupported) + { + WriteAttributeIfNotNull(writer, "ExpandCollapseState", patterns.ExpandCollapse.Pattern.ExpandCollapseState); + } + + WriteAttributeIfNotNull(writer, "IsAvailable", element.IsAvailable); + + var children = element.FindAllChildren(); + if (children != null) + { + foreach (var child in children) + { + WriteElementToXml(writer, child, rootBounds); + } + } + + writer.WriteEndElement(); + } + + private void WriteAttributeIfNotNull(XmlWriter writer, string name, T? value) + { + if (value != null) + { + writer.WriteAttributeString(name, value.ToString()); + } + } + + private Session GetActiveSession(string sessionId) + { + var session = GetSession(sessionId); + if (session.App != null && session.App.HasExited) + { + throw WebDriverResponseException.NoWindowsOpenForSession(); + } + return session; + } + + private Session GetSession(string sessionId) + { + var session = _sessionRepository.FindById(sessionId); + if (session == null) + { + throw WebDriverResponseException.SessionNotFound(sessionId); + } + session.SetLastCommandTimeToNow(); + return session; + } + } +} From 7db43ff0226c4c6c6243b253d4bbfc06549055d1 Mon Sep 17 00:00:00 2001 From: Quynh-Nga Pham Date: Wed, 7 May 2025 16:26:00 +0700 Subject: [PATCH 2/5] Simplify list of properties --- .../Controllers/SourceController.cs | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/FlaUI.WebDriver/Controllers/SourceController.cs b/src/FlaUI.WebDriver/Controllers/SourceController.cs index b58c860..b998fba 100644 --- a/src/FlaUI.WebDriver/Controllers/SourceController.cs +++ b/src/FlaUI.WebDriver/Controllers/SourceController.cs @@ -1,4 +1,4 @@ -@@ -0,0 +1,165 @@ +@@ -0,0 +1,139 @@ using FlaUI.WebDriver.Models; using Microsoft.AspNetCore.Mvc; using FlaUI.Core.AutomationElements; @@ -54,27 +54,11 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst writer.WriteStartElement(controlType); var properties = element.Properties; - WriteAttributeIfNotNull(writer, "AcceleratorKey", properties.AcceleratorKey); - WriteAttributeIfNotNull(writer, "AccessKey", properties.AccessKey); WriteAttributeIfNotNull(writer, "AutomationId", properties.AutomationId); WriteAttributeIfNotNull(writer, "ClassName", properties.ClassName); WriteAttributeIfNotNull(writer, "FrameworkId", properties.FrameworkId); - WriteAttributeIfNotNull(writer, "HasKeyboardFocus", properties.HasKeyboardFocus); - WriteAttributeIfNotNull(writer, "HelpText", properties.HelpText); - WriteAttributeIfNotNull(writer, "IsContentElement", properties.IsContentElement); - WriteAttributeIfNotNull(writer, "IsControlElement", properties.IsControlElement); WriteAttributeIfNotNull(writer, "IsEnabled", properties.IsEnabled); - WriteAttributeIfNotNull(writer, "IsKeyboardFocusable", properties.IsKeyboardFocusable); - WriteAttributeIfNotNull(writer, "IsOffscreen", properties.IsOffscreen); - WriteAttributeIfNotNull(writer, "IsPassword", properties.IsPassword); - WriteAttributeIfNotNull(writer, "IsRequiredForForm", properties.IsRequiredForForm); - WriteAttributeIfNotNull(writer, "ItemStatus", properties.ItemStatus); - WriteAttributeIfNotNull(writer, "ItemType", properties.ItemType); - WriteAttributeIfNotNull(writer, "LocalizedControlType", properties.LocalizedControlType); WriteAttributeIfNotNull(writer, "Name", properties.Name); - WriteAttributeIfNotNull(writer, "Orientation", properties.Orientation); - WriteAttributeIfNotNull(writer, "ProcessId", properties.ProcessId); - WriteAttributeIfNotNull(writer, "RuntimeId", properties.RuntimeId); var bounds = element.BoundingRectangle; writer.WriteAttributeString("x", (bounds.X - rootBounds.X).ToString()); @@ -90,8 +74,6 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst WriteAttributeIfNotNull(writer, "CanMinimize", windowPattern.CanMinimize); WriteAttributeIfNotNull(writer, "IsModal", windowPattern.IsModal); WriteAttributeIfNotNull(writer, "WindowVisualState", windowPattern.WindowVisualState); - WriteAttributeIfNotNull(writer, "WindowInteractionState", windowPattern.WindowInteractionState); - WriteAttributeIfNotNull(writer, "IsTopmost", windowPattern.IsTopmost); } if (patterns.Scroll.IsSupported) @@ -101,18 +83,12 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst WriteAttributeIfNotNull(writer, "VerticallyScrollable", scrollPattern.VerticallyScrollable); WriteAttributeIfNotNull(writer, "HorizontalScrollPercent", scrollPattern.HorizontalScrollPercent); WriteAttributeIfNotNull(writer, "VerticalScrollPercent", scrollPattern.VerticalScrollPercent); - WriteAttributeIfNotNull(writer, "HorizontalViewSize", scrollPattern.HorizontalViewSize); - WriteAttributeIfNotNull(writer, "VerticalViewSize", scrollPattern.VerticalViewSize); } if (patterns.SelectionItem.IsSupported) { var selectionItemPattern = patterns.SelectionItem.Pattern; WriteAttributeIfNotNull(writer, "IsSelected", selectionItemPattern.IsSelected); - if (selectionItemPattern.SelectionContainer != null) - { - writer.WriteAttributeString("SelectionContainer", selectionItemPattern.SelectionContainer.ToString()); - } } if (patterns.ExpandCollapse.IsSupported) @@ -120,8 +96,6 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst WriteAttributeIfNotNull(writer, "ExpandCollapseState", patterns.ExpandCollapse.Pattern.ExpandCollapseState); } - WriteAttributeIfNotNull(writer, "IsAvailable", element.IsAvailable); - var children = element.FindAllChildren(); if (children != null) { From 70eec6b8244bf7926660de2ea9449fc3dfa8c573 Mon Sep 17 00:00:00 2001 From: Quynh-Nga Pham Date: Wed, 7 May 2025 16:53:00 +0700 Subject: [PATCH 3/5] Update SourceController.cs --- .../Controllers/SourceController.cs | 99 ++++++++++++------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/src/FlaUI.WebDriver/Controllers/SourceController.cs b/src/FlaUI.WebDriver/Controllers/SourceController.cs index b998fba..1a4d2ca 100644 --- a/src/FlaUI.WebDriver/Controllers/SourceController.cs +++ b/src/FlaUI.WebDriver/Controllers/SourceController.cs @@ -1,4 +1,4 @@ -@@ -0,0 +1,139 @@ +@@ -0,0 +1,162 @@ using FlaUI.WebDriver.Models; using Microsoft.AspNetCore.Mvc; using FlaUI.Core.AutomationElements; @@ -14,7 +14,6 @@ public class SourceController : ControllerBase { private readonly ILogger _logger; private readonly ISessionRepository _sessionRepository; - private const int InitialStringBuilderCapacity = 64 * 1024; // 64KB initial capacity public SourceController(ILogger logger, ISessionRepository sessionRepository) { @@ -38,13 +37,17 @@ private string ConvertElementToXml(AutomationElement element, System.Drawing.Rec { Indent = true, IndentChars = " ", - Encoding = Encoding.Unicode, - OmitXmlDeclaration = true + Encoding = Encoding.Unicode }; - var stringBuilder = new StringBuilder(InitialStringBuilderCapacity); - using var writer = XmlWriter.Create(stringBuilder, settings); - WriteElementToXml(writer, element, rootBounds); + var stringBuilder = new StringBuilder(); + using (var writer = XmlWriter.Create(stringBuilder, settings)) + { + writer.WriteStartDocument(); + WriteElementToXml(writer, element, rootBounds); + writer.WriteEndDocument(); + } + return stringBuilder.ToString(); } @@ -53,12 +56,27 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst var controlType = element.ControlType.ToString(); writer.WriteStartElement(controlType); - var properties = element.Properties; - WriteAttributeIfNotNull(writer, "AutomationId", properties.AutomationId); - WriteAttributeIfNotNull(writer, "ClassName", properties.ClassName); - WriteAttributeIfNotNull(writer, "FrameworkId", properties.FrameworkId); - WriteAttributeIfNotNull(writer, "IsEnabled", properties.IsEnabled); - WriteAttributeIfNotNull(writer, "Name", properties.Name); + WritePropertyAttribute(writer, "AcceleratorKey", element.Properties.AcceleratorKey); + WritePropertyAttribute(writer, "AccessKey", element.Properties.AccessKey); + WritePropertyAttribute(writer, "AutomationId", element.Properties.AutomationId); + WritePropertyAttribute(writer, "ClassName", element.Properties.ClassName); + WritePropertyAttribute(writer, "FrameworkId", element.Properties.FrameworkId); + WritePropertyAttribute(writer, "HasKeyboardFocus", element.Properties.HasKeyboardFocus); + WritePropertyAttribute(writer, "HelpText", element.Properties.HelpText); + WritePropertyAttribute(writer, "IsContentElement", element.Properties.IsContentElement); + WritePropertyAttribute(writer, "IsControlElement", element.Properties.IsControlElement); + WritePropertyAttribute(writer, "IsEnabled", element.Properties.IsEnabled); + WritePropertyAttribute(writer, "IsKeyboardFocusable", element.Properties.IsKeyboardFocusable); + WritePropertyAttribute(writer, "IsOffscreen", element.Properties.IsOffscreen); + WritePropertyAttribute(writer, "IsPassword", element.Properties.IsPassword); + WritePropertyAttribute(writer, "IsRequiredForForm", element.Properties.IsRequiredForForm); + WritePropertyAttribute(writer, "ItemStatus", element.Properties.ItemStatus); + WritePropertyAttribute(writer, "ItemType", element.Properties.ItemType); + WritePropertyAttribute(writer, "LocalizedControlType", element.Properties.LocalizedControlType); + WritePropertyAttribute(writer, "Name", element.Properties.Name); + WritePropertyAttribute(writer, "Orientation", element.Properties.Orientation); + WritePropertyAttribute(writer, "ProcessId", element.Properties.ProcessId); + WritePropertyAttribute(writer, "RuntimeId", element.Properties.RuntimeId); var bounds = element.BoundingRectangle; writer.WriteAttributeString("x", (bounds.X - rootBounds.X).ToString()); @@ -66,49 +84,54 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst writer.WriteAttributeString("width", bounds.Width.ToString()); writer.WriteAttributeString("height", bounds.Height.ToString()); - var patterns = element.Patterns; - if (patterns.Window.IsSupported) + if (element.Patterns.Window.IsSupported) { - var windowPattern = patterns.Window.Pattern; - WriteAttributeIfNotNull(writer, "CanMaximize", windowPattern.CanMaximize); - WriteAttributeIfNotNull(writer, "CanMinimize", windowPattern.CanMinimize); - WriteAttributeIfNotNull(writer, "IsModal", windowPattern.IsModal); - WriteAttributeIfNotNull(writer, "WindowVisualState", windowPattern.WindowVisualState); + var windowPattern = element.Patterns.Window.Pattern; + WritePropertyAttribute(writer, "CanMaximize", windowPattern.CanMaximize); + WritePropertyAttribute(writer, "CanMinimize", windowPattern.CanMinimize); + WritePropertyAttribute(writer, "IsModal", windowPattern.IsModal); + WritePropertyAttribute(writer, "WindowVisualState", windowPattern.WindowVisualState); + WritePropertyAttribute(writer, "WindowInteractionState", windowPattern.WindowInteractionState); + WritePropertyAttribute(writer, "IsTopmost", windowPattern.IsTopmost); } - if (patterns.Scroll.IsSupported) + if (element.Patterns.Scroll.IsSupported) { - var scrollPattern = patterns.Scroll.Pattern; - WriteAttributeIfNotNull(writer, "HorizontallyScrollable", scrollPattern.HorizontallyScrollable); - WriteAttributeIfNotNull(writer, "VerticallyScrollable", scrollPattern.VerticallyScrollable); - WriteAttributeIfNotNull(writer, "HorizontalScrollPercent", scrollPattern.HorizontalScrollPercent); - WriteAttributeIfNotNull(writer, "VerticalScrollPercent", scrollPattern.VerticalScrollPercent); + var scrollPattern = element.Patterns.Scroll.Pattern; + WritePropertyAttribute(writer, "HorizontallyScrollable", scrollPattern.HorizontallyScrollable); + WritePropertyAttribute(writer, "VerticallyScrollable", scrollPattern.VerticallyScrollable); + WritePropertyAttribute(writer, "HorizontalScrollPercent", scrollPattern.HorizontalScrollPercent); + WritePropertyAttribute(writer, "VerticalScrollPercent", scrollPattern.VerticalScrollPercent); + WritePropertyAttribute(writer, "HorizontalViewSize", scrollPattern.HorizontalViewSize); + WritePropertyAttribute(writer, "VerticalViewSize", scrollPattern.VerticalViewSize); } - if (patterns.SelectionItem.IsSupported) + if (element.Patterns.SelectionItem.IsSupported) { - var selectionItemPattern = patterns.SelectionItem.Pattern; - WriteAttributeIfNotNull(writer, "IsSelected", selectionItemPattern.IsSelected); + var selectionItemPattern = element.Patterns.SelectionItem.Pattern; + WritePropertyAttribute(writer, "IsSelected", selectionItemPattern.IsSelected); + if (selectionItemPattern.SelectionContainer != null) + { + WritePropertyAttribute(writer, "SelectionContainer", selectionItemPattern.SelectionContainer.ToString()); + } } - if (patterns.ExpandCollapse.IsSupported) + if (element.Patterns.ExpandCollapse.IsSupported) { - WriteAttributeIfNotNull(writer, "ExpandCollapseState", patterns.ExpandCollapse.Pattern.ExpandCollapseState); + WritePropertyAttribute(writer, "ExpandCollapseState", element.Patterns.ExpandCollapse.Pattern.ExpandCollapseState); } - var children = element.FindAllChildren(); - if (children != null) + WritePropertyAttribute(writer, "IsAvailable", element.IsAvailable); + + foreach (var child in element.FindAllChildren()) { - foreach (var child in children) - { - WriteElementToXml(writer, child, rootBounds); - } + WriteElementToXml(writer, child, rootBounds); } writer.WriteEndElement(); } - private void WriteAttributeIfNotNull(XmlWriter writer, string name, T? value) + private void WritePropertyAttribute(XmlWriter writer, string name, T value) { if (value != null) { From 22905e675a7db0edf85088f675eeade90173b3cd Mon Sep 17 00:00:00 2001 From: Quynh-Nga Pham Date: Wed, 7 May 2025 17:32:43 +0700 Subject: [PATCH 4/5] Handle PropertyNotSupportedException --- src/FlaUI.WebDriver/Controllers/SourceController.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/FlaUI.WebDriver/Controllers/SourceController.cs b/src/FlaUI.WebDriver/Controllers/SourceController.cs index 1a4d2ca..8e27f88 100644 --- a/src/FlaUI.WebDriver/Controllers/SourceController.cs +++ b/src/FlaUI.WebDriver/Controllers/SourceController.cs @@ -1,4 +1,3 @@ -@@ -0,0 +1,162 @@ using FlaUI.WebDriver.Models; using Microsoft.AspNetCore.Mvc; using FlaUI.Core.AutomationElements; @@ -53,7 +52,15 @@ private string ConvertElementToXml(AutomationElement element, System.Drawing.Rec private void WriteElementToXml(XmlWriter writer, AutomationElement element, System.Drawing.Rectangle rootBounds) { - var controlType = element.ControlType.ToString(); + string controlType; + try + { + controlType = element.ControlType.ToString(); + } + catch (FlaUI.Core.Exceptions.PropertyNotSupportedException) + { + controlType = "Unknown"; + } writer.WriteStartElement(controlType); WritePropertyAttribute(writer, "AcceleratorKey", element.Properties.AcceleratorKey); From 48f9080a1f42594593eaaf1dd4682baf351f0653 Mon Sep 17 00:00:00 2001 From: Quynh-Nga Pham Date: Tue, 13 May 2025 16:08:13 +0700 Subject: [PATCH 5/5] Update getRunTimeId --- src/FlaUI.WebDriver/Controllers/SourceController.cs | 2 +- src/FlaUI.WebDriver/Session.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FlaUI.WebDriver/Controllers/SourceController.cs b/src/FlaUI.WebDriver/Controllers/SourceController.cs index 8e27f88..ebdf687 100644 --- a/src/FlaUI.WebDriver/Controllers/SourceController.cs +++ b/src/FlaUI.WebDriver/Controllers/SourceController.cs @@ -83,7 +83,7 @@ private void WriteElementToXml(XmlWriter writer, AutomationElement element, Syst WritePropertyAttribute(writer, "Name", element.Properties.Name); WritePropertyAttribute(writer, "Orientation", element.Properties.Orientation); WritePropertyAttribute(writer, "ProcessId", element.Properties.ProcessId); - WritePropertyAttribute(writer, "RuntimeId", element.Properties.RuntimeId); + WritePropertyAttribute(writer, "RuntimeId", Session.GetRuntimeId(element)); var bounds = element.BoundingRectangle; writer.WriteAttributeString("x", (bounds.X - rootBounds.X).ToString()); diff --git a/src/FlaUI.WebDriver/Session.cs b/src/FlaUI.WebDriver/Session.cs index 305cf8c..bb64b9f 100644 --- a/src/FlaUI.WebDriver/Session.cs +++ b/src/FlaUI.WebDriver/Session.cs @@ -172,7 +172,7 @@ public void Dispose() App?.Dispose(); } - private string? GetRuntimeId(AutomationElement element) + public static string? GetRuntimeId(AutomationElement element) { if (!element.Properties.RuntimeId.IsSupported) {