Skip to content
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

BugFix - 39710 - Implemented Cancellation For POM Learning #3832

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/POM/POMLearner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ limitations under the License.
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

#nullable enable
Expand Down Expand Up @@ -77,12 +78,12 @@ internal static POMLearner Create(string html, IBrowserElementProvider browserEl
return new POMLearner(htmlDocument, browserElementProvider, pomSetting, xpathImpl);
}

internal Task LearnElementsAsync(IList<ElementInfo> learnedElements)
internal Task LearnElementsAsync(IList<ElementInfo> learnedElements, CancellationToken cancellationToken = default)
{
return LearnDocumentElementsAsync(_htmlDocument, learnedElements);
return LearnDocumentElementsAsync(_htmlDocument, learnedElements, cancellationToken);
}

private async Task LearnDocumentElementsAsync(HtmlDocument htmlDocument, IList<ElementInfo> learnedElements)
private async Task LearnDocumentElementsAsync(HtmlDocument htmlDocument, IList<ElementInfo> learnedElements, CancellationToken cancellationToken)
{
await LearnHtmlNodeChildElements(htmlDocument.DocumentNode, shouldLearnNode: htmlNode =>
{
Expand All @@ -93,13 +94,17 @@ await LearnHtmlNodeChildElements(htmlDocument.DocumentNode, shouldLearnNode: htm
}

return true;
}, learnedElements);
}, learnedElements, cancellationToken);
}

private async Task LearnHtmlNodeChildElements(HtmlNode htmlNode, Predicate<HtmlNode> shouldLearnNode, IList<ElementInfo> learnedElements, IList<ElementInfo>? childElements = null)
private async Task LearnHtmlNodeChildElements(HtmlNode htmlNode, Predicate<HtmlNode> shouldLearnNode, IList<ElementInfo> learnedElements, CancellationToken cancellationToken, IList<ElementInfo>? childElements = null)
{
foreach (HtmlNode childNode in htmlNode.ChildNodes)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
eElementType childNodeElementType = GetElementType(childNode);
IBrowserElement? browserElement = null;
HTMLElementInfo? childElement = null;
Expand All @@ -125,11 +130,11 @@ private async Task LearnHtmlNodeChildElements(HtmlNode htmlNode, Predicate<HtmlN
IList<ElementInfo> grandChildElements = new List<ElementInfo>();
if (childNodeElementType == eElementType.Form)
{
await LearnHtmlNodeChildElements(childNode, ShouldLearnFormChildNode, learnedElements, grandChildElements);
await LearnHtmlNodeChildElements(childNode, ShouldLearnFormChildNode, learnedElements, cancellationToken, grandChildElements);
}
else if (!string.Equals(childNode.Name, "head", StringComparison.OrdinalIgnoreCase))
{
await LearnHtmlNodeChildElements(childNode, shouldLearnNode, learnedElements, grandChildElements);
await LearnHtmlNodeChildElements(childNode, shouldLearnNode, learnedElements, cancellationToken, grandChildElements);
}

if (childElement != null)
Expand All @@ -141,8 +146,8 @@ private async Task LearnHtmlNodeChildElements(HtmlNode htmlNode, Predicate<HtmlN
childElement.ChildElements.Clear();
childElement.ChildElements.AddRange(grandChildElements);

await LearnShadowDOMElementsAsync(childElement, learnedElements);
await LearnFrameElementsAsync(childElement, learnedElements);
await LearnShadowDOMElementsAsync(childElement, learnedElements, cancellationToken);
await LearnFrameElementsAsync(childElement, learnedElements, cancellationToken);
}
}
}
Expand Down Expand Up @@ -775,7 +780,7 @@ internal static string GenerateRelativeXPathFromHTMLElementInfo(HTMLElementInfo
}
}

private async Task LearnShadowDOMElementsAsync(HTMLElementInfo shadowHostElement, IList<ElementInfo> learnedElements)
private async Task LearnShadowDOMElementsAsync(HTMLElementInfo shadowHostElement, IList<ElementInfo> learnedElements, CancellationToken cancellationToken)
{
if (_pomSetting == null ||
!_pomSetting.LearnShadowDomElements ||
Expand All @@ -800,12 +805,12 @@ private async Task LearnShadowDOMElementsAsync(HTMLElementInfo shadowHostElement
HtmlDocument shadowRootHtmlDocument = new();
shadowRootHtmlDocument.LoadHtml(shadowRootHTML);

await LearnDocumentElementsAsync(shadowRootHtmlDocument, learnedElements);
await LearnDocumentElementsAsync(shadowRootHtmlDocument, learnedElements, cancellationToken);

await _browserElementProvider.OnShadowDOMExitAsync(shadowHostElement);
}

private async Task LearnFrameElementsAsync(HTMLElementInfo frameElement, IList<ElementInfo> learnedElements)
private async Task LearnFrameElementsAsync(HTMLElementInfo frameElement, IList<ElementInfo> learnedElements, CancellationToken cancellationToken)
{
if (frameElement.ElementTypeEnum != eElementType.Iframe)
{
Expand Down Expand Up @@ -837,7 +842,7 @@ private async Task LearnFrameElementsAsync(HTMLElementInfo frameElement, IList<E

await _browserElementProvider.OnFrameEnterAsync(frameElement);

await LearnDocumentElementsAsync(frameHtmlDocument, learnedElements);
await LearnDocumentElementsAsync(frameHtmlDocument, learnedElements, cancellationToken);

await _browserElementProvider.OnFrameExitAsync(frameElement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ limitations under the License.
using GingerCore.Actions.VisualTesting;
using GingerCoreNET.SolutionRepositoryLib.RepositoryObjectsLib.PlatformsLib;
using amdocs.ginger.GingerCoreNET;
using System.Threading;

#nullable enable
namespace Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.Playwright
Expand Down Expand Up @@ -616,7 +617,18 @@ public async Task<List<ElementInfo>> GetVisibleControls(PomSetting pomSetting, O
}

POMLearner pomLearner = POMLearner.Create(pageSource, new PlaywrightBrowserElementProvider(currentTab), pomSetting, xpathImpl: this);
await pomLearner.LearnElementsAsync(foundElementsList);
CancellationTokenSource cancellationTokenSource = new();
Task learnElementsTask = pomLearner.LearnElementsAsync(foundElementsList, cancellationTokenSource.Token);
_ = Task.Run(() =>
{
while (!StopProcess && !learnElementsTask.IsCompleted) ;

if (StopProcess)
{
cancellationTokenSource.Cancel();
}
});
await learnElementsTask;

//below part should ideally be handled in POMLearner itself but, when we add the learned element to the observable list, it sets the active status as true again
foreach (ElementInfo element in foundElementsList)
Expand Down
Loading