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
{