-
Notifications
You must be signed in to change notification settings - Fork 62
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
Enhancement - Playwright Window Explorer And Visual Testing Action Support #3850
Changes from all commits
72351b9
29fa6aa
2413dae
0cee04d
4a69670
b863fa9
966ed65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -161,6 +161,16 @@ public override void RunAction(Act act) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
ActGotoURLHandler actGotoURLHandler = new(actGotoURL, _browser); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
actGotoURLHandler.HandleAsync().Wait(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case ActVisualTesting actVisualTesting: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (actVisualTesting.VisualTestingAnalyzer != ActVisualTesting.eVisualTestingAnalyzer.Applitools) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
actVisualTesting.Execute(this); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
act.Error = $"{actVisualTesting.VisualTestingAnalyzer} is not supported by Playwright driver, use Selenium driver instead."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
act.Error = $"This Action is not supported for Playwright driver"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -172,7 +182,7 @@ public bool IsActionSupported(Act act, out string message) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
message = string.Empty; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (act is ActWithoutDriver) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (act is ActWithoutDriver or ActScreenShot) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -219,9 +229,10 @@ public bool IsActionSupported(Act act, out string message) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return isLocatorSupported && isOperationSupported; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else if (act is ActScreenShot) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else if (act is ActVisualTesting actVisualTesting) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
message = $"{actVisualTesting.VisualTestingAnalyzer} is not supported by Playwright driver, use Selenium driver instead."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return actVisualTesting.VisualTestingAnalyzer != ActVisualTesting.eVisualTestingAnalyzer.Applitools; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -731,13 +742,14 @@ public List<ElementInfo> GetElementChildren(ElementInfo elementInfo) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await SwitchToFrameOfElementAsync(elementInfo); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string xpath = GenerateXPathFromHTMLElementInfo(htmlElementInfo); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IEnumerable<IBrowserElement> browserElements = await _browser.CurrentWindow.CurrentTab.GetElementsAsync(eLocateBy.ByXPath, xpath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string childrenXPath = GenerateChildrenXPath(xpath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IEnumerable<IBrowserElement> browserElements = await _browser.CurrentWindow.CurrentTab.GetElementsAsync(eLocateBy.ByXPath, childrenXPath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
List<HTMLElementInfo> htmlElements = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
foreach (IBrowserElement browserElement in browserElements) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
HTMLElementInfo newHtmlElement = await CreateHtmlElementAsync(browserElement); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (string.IsNullOrEmpty(newHtmlElement.ID)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (string.IsNullOrEmpty(newHtmlElement.ID) && htmlElementInfo.HTMLElementObject != null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
newHtmlElement.ID = htmlElementInfo.HTMLElementObject.Id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -767,6 +779,27 @@ public List<ElementInfo> GetElementChildren(ElementInfo elementInfo) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
}).Result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private string GenerateChildrenXPath(string parentXPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string[] parentXPathSegments = parentXPath.Split("/", StringSplitOptions.RemoveEmptyEntries); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string elementType = parentXPathSegments[^1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int index = elementType.IndexOf('['); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (index != -1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elementType = elementType.AsSpan(0, index).ToString(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (string.Equals(elementType, "iframe") || string.Equals(elementType, "frame")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return "/html/*"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return parentXPath + "/*"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+782
to
+801
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optimize the XPath generation logic. The method generates XPath for child elements but can be optimized for readability and performance. - string[] parentXPathSegments = parentXPath.Split("/", StringSplitOptions.RemoveEmptyEntries);
- string elementType = parentXPathSegments[^1];
- int index = elementType.IndexOf('[');
- if (index != -1)
- {
- elementType = elementType.AsSpan(0, index).ToString();
- }
- if (string.Equals(elementType, "iframe") || string.Equals(elementType, "frame"))
- {
- return "/html/*";
- }
- else
- {
- return parentXPath + "/*";
- }
+ var elementType = parentXPath.Split("/", StringSplitOptions.RemoveEmptyEntries).Last().Split('[').First();
+ return (elementType.Equals("iframe", StringComparison.OrdinalIgnoreCase) || elementType.Equals("frame", StringComparison.OrdinalIgnoreCase))
+ ? "/html/*"
+ : $"{parentXPath}/*"; Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public ObservableList<ControlProperty> GetElementProperties(ElementInfo elementInfo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (elementInfo is not HTMLElementInfo htmlElementInfo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1494,7 +1527,7 @@ public void ChangeAppWindowSize(int width, int height) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string s_Script = $"return document.elementFromPoint({ptX}, {ptY});"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string s_Script = $"document.elementFromPoint({ptX}, {ptY});"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IBrowserElement? ele = await _browser.CurrentWindow.CurrentTab.GetElementAsync(s_Script); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure proper error handling for asynchronous calls.
The asynchronous calls to
SizeAsync
andPositionAsync
should include error handling to manage potential exceptions that may arise.Committable suggestion