diff --git a/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActSmartSyncHandler.cs b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActSmartSyncHandler.cs new file mode 100644 index 0000000000..9b26aaad81 --- /dev/null +++ b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/ActionHandlers/ActSmartSyncHandler.cs @@ -0,0 +1,103 @@ +#region License +/* +Copyright © 2014-2024 European Support Limited + +Licensed under the Apache License, Version 2.0 (the "License") +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#endregion +using Amdocs.Ginger.Common; +using GingerCore.Actions; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.ActionHandlers +{ + internal class ActSmartSyncHandler + { + private ActSmartSync _actSmartSync; + private IBrowserTab _browserTab; + private IBrowserElementLocator _elementLocator; + private Act mAct; + + internal ActSmartSyncHandler(ActSmartSync actSmartSync, IBrowserTab browserTab, IBrowserElementLocator elementLocator) + { + _actSmartSync = actSmartSync; + _browserTab = browserTab; + _elementLocator = elementLocator; + } + + /// + /// Handles the smart synchronization action asynchronously. + /// + /// The action to be handled. + /// A task representing the asynchronous operation. + internal async Task HandleAsync(Act act, int timeout) + { + mAct = act; + Stopwatch st = new Stopwatch(); + try + { + st.Start(); + IBrowserElement element; + + if (_actSmartSync.SmartSyncAction == ActSmartSync.eSmartSyncAction.WaitUntilDisplay) + { + do + { + if (st.ElapsedMilliseconds > timeout) + { + mAct.Error = "Smart Sync of WaitUntilDisplay is timeout"; + break; + } + await Task.Delay(100); + element = await GetFirstMatchingElementAsync(); + } while (element == null || !await element.IsVisibleAsync() || !await element.IsEnabledAsync()); + } + else if (_actSmartSync.SmartSyncAction == ActSmartSync.eSmartSyncAction.WaitUntilDisapear) + { + do + { + if (st.ElapsedMilliseconds > timeout) + { + mAct.Error = "Smart Sync of WaitUntilDisapear is timeout"; + break; + } + await Task.Delay(100); + element = await GetFirstMatchingElementAsync(); + } while (element != null || (element != null && !await element.IsVisibleAsync())); + } + } + catch (Exception ex) + { + Reporter.ToLog(eLogLevel.ERROR, "Failed to handle Smart Sync", ex); + } + finally + { + st.Stop(); + } + } + /// + /// Gets the first matching browser element asynchronously. + /// + /// The first matching browser element. + private async Task GetFirstMatchingElementAsync() + { + IEnumerable elements = await _elementLocator.FindMatchingElements(mAct.LocateBy, mAct.LocateValue); + IBrowserElement? firstElement = elements.FirstOrDefault(); + return firstElement; + } + } +} diff --git a/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs index ee99b6bc5d..73ce81f4e2 100644 --- a/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs +++ b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Web/Playwright/PlaywrightDriver.cs @@ -31,6 +31,7 @@ limitations under the License. using GingerCore.Actions; using GingerCore.Actions.Common; using GingerCore.Actions.VisualTesting; +using GingerCore.Drivers; using GingerCore.Drivers.Common; using GingerCoreNET.SolutionRepositoryLib.RepositoryObjectsLib.PlatformsLib; using HtmlAgilityPack; @@ -82,12 +83,13 @@ public override string GetDriverConfigsEditPageName(Agent.eDriverType driverSubT return null; } } + PlaywrightBrowser.Options browserOptions; public override void StartDriver() { ValidateBrowserTypeSupport(BrowserType); IPlaywright playwright = Microsoft.Playwright.Playwright.CreateAsync().Result; - PlaywrightBrowser.Options browserOptions = BuildPlaywrightBrowserOptions(); + browserOptions = BuildPlaywrightBrowserOptions(); if (BrowserPrivateMode) { _browser = new PlaywrightNonPersistentBrowser(playwright, BrowserType, browserOptions, OnBrowserClose); @@ -251,6 +253,35 @@ public override void RunAction(Act act) } actAccessibilityTestingHandler.HandleAsync().Wait(); break; + case ActSmartSync actSmartSync: + ActSmartSyncHandler actSmartSyncHandler = new( + actSmartSync, + _browser.CurrentWindow.CurrentTab, + new BrowserElementLocator( + _browser.CurrentWindow.CurrentTab, + new() + { + BusinessFlow = BusinessFlow, + Environment = Environment, + POMExecutionUtils = new POMExecutionUtils(act, act.LocateValue), + Agent = BusinessFlow.CurrentActivity.CurrentAgent, + })); + float? driverDefaultTimeout = browserOptions.Timeout; + try + { + int smartSyncTimeout = DriverBase.GetMaxTimeout(actSmartSync) * 1000; + browserOptions.Timeout = smartSyncTimeout; + actSmartSyncHandler.HandleAsync(act, smartSyncTimeout).Wait(); + } + catch (Exception ex) + { + act.Error = ex.Message; + } + finally + { + browserOptions.Timeout = driverDefaultTimeout; + } + break; default: act.Error = $"This Action is not supported for Playwright driver"; break; @@ -262,7 +293,7 @@ public bool IsActionSupported(Act act, out string message) { message = string.Empty; - if (act is ActWithoutDriver or ActScreenShot or ActGotoURL or ActAccessibilityTesting) + if (act is ActWithoutDriver or ActScreenShot or ActGotoURL or ActAccessibilityTesting or ActSmartSync) { return true; } diff --git a/Ginger/GingerCoreNET/RunLib/DriverBase.cs b/Ginger/GingerCoreNET/RunLib/DriverBase.cs index 7d14cbee50..f23103c2b4 100644 --- a/Ginger/GingerCoreNET/RunLib/DriverBase.cs +++ b/Ginger/GingerCoreNET/RunLib/DriverBase.cs @@ -300,8 +300,8 @@ public virtual double ScreenShotInitialZoom() return 0.5; } - Regex AttRegexWeb = new Regex("@[a-zA-Z]*", RegexOptions.Compiled); - Regex AttRegexMobile = new Regex("{[a-zA-Z]*}", RegexOptions.Compiled); + Regex AttRegexWeb = new("@[a-zA-Z]*", RegexOptions.Compiled); + Regex AttRegexMobile = new("{[a-zA-Z]*}", RegexOptions.Compiled); public ElementLocator GetUserDefinedCustomLocatorFromTemplates(string locatorTemplate, eLocateBy locateBy, List elementProperties) { try @@ -379,7 +379,7 @@ public ElementLocator GetUserDefinedCustomLocatorFromTemplates(string locatorTem } } - protected static int GetMaxTimeout(ActSmartSync act) + public static int GetMaxTimeout(ActSmartSync act) { try {