diff --git a/Ginger/.editorconfig b/Ginger/.editorconfig
index 6624fe59dc..d383cc1f02 100644
--- a/Ginger/.editorconfig
+++ b/Ginger/.editorconfig
@@ -75,6 +75,7 @@ csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_style_var_for_built_in_types = true:none
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_elsewhere = true:none
+csharp_indent_braces = false
[*.vb]
#### Naming styles ####
diff --git a/Ginger/Ginger/Actions/ActionEditPage.xaml b/Ginger/Ginger/Actions/ActionEditPage.xaml
index f40196f15c..5c70f39500 100644
--- a/Ginger/Ginger/Actions/ActionEditPage.xaml
+++ b/Ginger/Ginger/Actions/ActionEditPage.xaml
@@ -304,12 +304,15 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/Ginger/Ginger/Actions/ActionEditPage.xaml.cs b/Ginger/Ginger/Actions/ActionEditPage.xaml.cs
index 721b05af40..3e1265910c 100644
--- a/Ginger/Ginger/Actions/ActionEditPage.xaml.cs
+++ b/Ginger/Ginger/Actions/ActionEditPage.xaml.cs
@@ -559,11 +559,14 @@ private void InitExecutionReportTabView()
if (mActParentActivity != null && mActParentActivity.GetType() == typeof(ErrorHandler))
{
xScreenshotsConfigsPnl.Visibility = Visibility.Collapsed;
- xScreenShotsPnl.Visibility = Visibility.Collapsed;
+ xScreenShotsPnl.Visibility = Visibility.Collapsed;
}
else
{
BindingHandler.ObjFieldBinding(xTakeScreenShotCheckBox, CheckBox.IsCheckedProperty, mAction, nameof(Act.TakeScreenShot));
+
+ BindingHandler.ObjFieldBinding(xAutoScreenShotOnFailureCheckBox, CheckBox.IsCheckedProperty, mAction, nameof(Act.AutoScreenShotOnFailure));
+
xWindowsToCaptureCombo.BindControl(mAction, nameof(Act.WindowsToCapture));
//remove full page for other platforms excepts web
if (mAction.Platform != GingerCoreNET.SolutionRepositoryLib.RepositoryObjectsLib.PlatformsLib.ePlatformType.Web)
diff --git a/Ginger/Ginger/Ginger.csproj b/Ginger/Ginger/Ginger.csproj
index ef90153eb7..3e98dc02bf 100644
--- a/Ginger/Ginger/Ginger.csproj
+++ b/Ginger/Ginger/Ginger.csproj
@@ -704,6 +704,7 @@
+
diff --git a/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml b/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml
index 4f13abe2fe..2667cbf1a1 100644
--- a/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml
+++ b/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml
@@ -1,4 +1,4 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs b/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs
index 68f81b1a5f..c1af5cc61e 100644
--- a/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs
+++ b/Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs
@@ -16,6 +16,7 @@ limitations under the License.
*/
#endregion
+using AccountReport.Contracts.GraphQL.ResponseModels;
using amdocs.ginger.GingerCoreNET;
using Amdocs.Ginger.Common;
using Amdocs.Ginger.CoreNET;
@@ -26,16 +27,21 @@ limitations under the License.
using Amdocs.Ginger.CoreNET.Reports;
using Amdocs.Ginger.CoreNET.Run.RunListenerLib;
using Amdocs.Ginger.CoreNET.Utility;
+using DocumentFormat.OpenXml.Wordprocessing;
using Ginger.Reports;
using Ginger.Repository.AddItemToRepositoryWizard;
using Ginger.Repository.ItemToRepositoryWizard;
using Ginger.UserControls;
using GingerCore;
using GingerWPF.WizardLib;
+using GraphQL;
+using GraphQLClient.Clients;
+using MathNet.Numerics.LinearAlgebra.Factorization;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -45,15 +51,16 @@ limitations under the License.
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;
+using System.Windows.Media;
using static Amdocs.Ginger.CoreNET.BPMN.Exportation.RunSetExecutionHistoryToBPMNExporter;
namespace Ginger.Run
-{
+ {
///
/// Interaction logic for RunSetsExecutionsPage.xaml
///
public partial class RunSetsExecutionsHistoryPage : Page
- {
+ {
private const string BPMNExportPath = @"~\\Documents\BPMN";
private readonly RunsetFromReportLoader _runsetFromReportLoader;
@@ -62,21 +69,40 @@ public partial class RunSetsExecutionsHistoryPage : Page
ExecutionLoggerHelper executionLoggerHelper = new ExecutionLoggerHelper();
private HttpClient? _httpClient;
+ private Task> response;
+ private GraphQLResponse data;
+ private GraphQlClient graphQlClient = null;
+ private ExecutionReportGraphQLClient executionReportGraphQLClient;
+ private bool GaraphQLClientLoadFlag = false;
+ private bool isLoading = true;
+ private RadioButton remoteRadioButton;
+ private RadioButton localRadioButton;
+ private Button openExecutionFolder;
+ private Button deleteExecutionResults;
+ private Button deleteAllExecutionResults;
+
- public bool AutoLoadExecutionData = false;
public ObservableList ExecutionsHistoryList
- {
+ {
get { return mExecutionsHistoryList; }
- }
+ }
string mRunSetExecsRootFolder = string.Empty;
public RunSetConfig RunsetConfig { get; set; }
public enum eExecutionHistoryLevel
- {
+ {
Solution,
SpecificRunSet
- }
+ }
+
+ public enum ePageAction
+ {
+ firstPage,
+ lastPage,
+ nextPage,
+ previousPage
+ }
private eExecutionHistoryLevel mExecutionHistoryLevel;
@@ -85,462 +111,777 @@ public enum eExecutionHistoryLevel
public event LoadRunsetEventHandler? LoadRunset;
public RunSetsExecutionsHistoryPage(eExecutionHistoryLevel executionHistoryLevel, RunSetConfig runsetConfig = null)
- {
+ {
+ isLoading = true;
InitializeComponent();
mExecutionHistoryLevel = executionHistoryLevel;
RunsetConfig = runsetConfig;
_runsetFromReportLoader = new();
-
this.Unloaded += OnUnloaded;
SetGridView();
- LoadExecutionsHistoryData();
- }
+ ReloadData();
+
+ isLoading = false;
+
+
+ }
+
+ void AssignGraphQLObjectEndPoint()
+ {
+
+ try
+ {
+ string endPoint = GingerRemoteExecutionUtils.GetReportDataServiceUrl();
+ if (!string.IsNullOrEmpty(endPoint))
+ {
+ endPoint = endPoint + "api/graphql";
+ graphQlClient = new GraphQlClient(endPoint);
+ executionReportGraphQLClient = new ExecutionReportGraphQLClient(graphQlClient);
+ GaraphQLClientLoadFlag = true;
+ }
+
+ }
+ catch (Exception ex)
+ {
+ Reporter.ToLog(eLogLevel.ERROR, $"Error occurred while connecting remote.", ex);
+ Reporter.ToUser(eUserMsgKey.RemoteExecutionHistoryEndPoint);
+
+ }
+
+ }
+ ///
+ /// Checks the centralized execution logger configuration and sets the appropriate radio button and loads the executions history data.
+ ///
+ void CheckCentralizedExecutionLoggerConfig()
+ {
+ GraphQlLoadingVisible();
+ if (GaraphQLClientLoadFlag)
+ {
+ RadioButton_Remote(null, null);
+ }
+ else
+ {
+ RadioButton_Local(null, null);
+ }
+ GraphQlLoadingCollapsed();
+ }
+ ///
+ /// Event handler for the remote radio button. Shows the button panel and loads the executions history data using GraphQL.
+ ///
+ private async void RadioButton_Remote(object sender, RoutedEventArgs e)
+ {
+ xButtonPnl.Visibility = Visibility.Visible;
+ GraphQlLoadingVisible();
+ await LoadExecutionsHistoryDataGraphQl();
+ GraphQlLoadingCollapsed();
+ }
+ ///
+ /// Event handler for the local radio button. Hides the button panel and loads the executions history data using LiteDB.
+ ///
+ private void RadioButton_Local(object sender, RoutedEventArgs e)
+ {
+ xButtonPnl.Visibility = Visibility.Collapsed;
+ localRadioButton.IsChecked = true;
+ LoadExecutionsHistoryDataLiteDb();
+ }
+
+ ///
+ /// Refreshes the data based on the selected radio button.
+ ///
+ private async Task RefreshDataAsync()
+ {
+ GraphQlLoadingVisible();
+
+ if ((bool)remoteRadioButton.IsChecked)
+ {
+ await LoadExecutionsHistoryDataGraphQl();
+ }
+ else if ((bool)localRadioButton.IsChecked)
+ {
+ LoadExecutionsHistoryDataLiteDb();
+ }
+ GraphQlLoadingCollapsed();
+ }
private void OnUnloaded(object sender, RoutedEventArgs e)
- {
- if (_httpClient != null)
{
+ if (_httpClient != null)
+ {
_httpClient.Dispose();
_httpClient = null;
_runsetFromReportLoader.Dispose();
+ }
}
- }
+ ///
+ /// Reloads the data for the RunSetsExecutionsHistoryPage.
+ ///
public void ReloadData()
- {
- LoadExecutionsHistoryData();
- }
-
- private void SetGridView()
- {
- if (mExecutionHistoryLevel == eExecutionHistoryLevel.Solution)
{
- grdExecutionsHistory.SetGridEnhancedHeader(Amdocs.Ginger.Common.Enums.eImageType.History, GingerDicser.GetTermResValue(eTermResKey.RunSets, "All", "Executions History"), saveAllHandler: null, addHandler: null);
+ AssignGraphQLObjectEndPoint();
+ if (GaraphQLClientLoadFlag)
+ {
+ remoteRadioButton.IsChecked = true;
+ remoteRadioButton.IsEnabled = true;
+
+ }
+ else
+ {
+ remoteRadioButton.IsEnabled = false;
+ localRadioButton.IsChecked = true;
+ }
+ CheckCentralizedExecutionLoggerConfig();
}
+ ///
+ /// Sets up the GridView control for displaying the execution history.
+ ///
+ private void SetGridView()
+ {
+ if (mExecutionHistoryLevel == eExecutionHistoryLevel.Solution)
+ {
+ xGridExecutionsHistory.SetGridEnhancedHeader(Amdocs.Ginger.Common.Enums.eImageType.History, GingerDicser.GetTermResValue(eTermResKey.RunSets, "All", "Executions History"), saveAllHandler: null, addHandler: null);
+ }
+ xPageSizeComboBox.Items.Add(25);
+ xPageSizeComboBox.Items.Add(50);
+ xPageSizeComboBox.Items.Add(100);
GridViewDef view = new GridViewDef(GridViewDef.DefaultViewName);
view.GridColsView =
[
new() {
Field = nameof(RunSetReport.GUID),
Header = "Execution ID",
- WidthWeight = 15
+ WidthWeight = 25
},
new() {
Field = RunSetReport.Fields.Name,
- WidthWeight = 20,
- ReadOnly = true },
+ WidthWeight = 30,
+ ReadOnly = true
+ },
new()
{
- Field = RunSetReport.Fields.Description,
- WidthWeight = 20,
- ReadOnly = true
+ Field = RunSetReport.Fields.RunSetExecutionStatus,
+ Header = "Status",
+ WidthWeight = 8,
+ ReadOnly = true,
+ BindingMode = BindingMode.OneWay
},
new()
{
Field = RunSetReport.Fields.SourceApplication,
Header = "Requested From",
- WidthWeight = 10,
+ WidthWeight = 15,
ReadOnly = true,
},
new()
{
Field = RunSetReport.Fields.SourceApplicationUser,
Header = "Requested By",
- WidthWeight = 10,
+ WidthWeight = 15,
ReadOnly = true,
},
new()
{
Field = RunSetReport.Fields.StartTimeStamp,
- Header = "Execution Start Time",
- WidthWeight = 10,
+ Header = "Start Time",
+ WidthWeight = 15,
ReadOnly = true
},
new()
{
Field = RunSetReport.Fields.EndTimeStamp,
- Header = "Execution End Time",
- WidthWeight = 10,
+ Header = "End Time",
+ WidthWeight = 15,
ReadOnly = true
},
new()
{
Field = RunSetReport.Fields.ExecutionDurationHHMMSS,
- Header = "Execution Duration",
- WidthWeight = 10,
+ Header = "Duration",
+ WidthWeight = 15,
ReadOnly = true
},
new()
- {
- Field = RunSetReport.Fields.RunSetExecutionStatus,
- Header = "Execution Status",
- WidthWeight = 10,
- ReadOnly = true,
- BindingMode = BindingMode.OneWay
- },
- new()
- {
- Field = RunSetReport.Fields.DataRepMethod,
- Header = "Type",
- Visible = true,
- ReadOnly = true,
- WidthWeight = 5,
- BindingMode = BindingMode.OneWay
- },
- new()
{
Field = "Actions",
- WidthWeight = 24,
+ WidthWeight = 15,
StyleType = GridColView.eGridColStyleType.Template,
CellTemplate = GetActionsDataTemplate()
}
];
- grdExecutionsHistory.SetAllColumnsDefaultView(view);
- grdExecutionsHistory.InitViewItems();
+ xGridExecutionsHistory.SetAllColumnsDefaultView(view);
+ xGridExecutionsHistory.InitViewItems();
- grdExecutionsHistory.btnRefresh.AddHandler(Button.ClickEvent, new RoutedEventHandler(RefreshGrid));
- grdExecutionsHistory.AddToolbarTool("@Open_16x16.png", "Open Execution Results Main Folder", new RoutedEventHandler(GetExecutionResultsFolder));
- grdExecutionsHistory.AddToolbarTool("@Delete_16x16.png", "Delete Selected Execution Results", new RoutedEventHandler(DeleteSelectedExecutionResults));
- grdExecutionsHistory.AddToolbarTool("@Trash_16x16.png", "Delete All Execution Results", new RoutedEventHandler(DeleteAllSelectedExecutionResults));
- WeakEventManager.AddHandler(source: grdExecutionsHistory, eventName: nameof(ucGrid.RowDoubleClick), handler: OpenExecutionResultsFolder);
+ xGridExecutionsHistory.btnRefresh.AddHandler(Button.ClickEvent, new RoutedEventHandler(RefreshGrid));
- if (mExecutionHistoryLevel == eExecutionHistoryLevel.SpecificRunSet)
- {
- grdExecutionsHistory.AddCheckBox("Auto Load Execution History", new RoutedEventHandler(AutoLoadExecutionHistory));
+ xGridExecutionsHistory.AddToolbarTool("@Open_16x16.png", "Open Execution Results Main Folder", new RoutedEventHandler(GetExecutionResultsFolder));
+ xGridExecutionsHistory.AddToolbarTool("@Delete_16x16.png", "Delete Selected Execution Results", new RoutedEventHandler(DeleteSelectedExecutionResults));
+ xGridExecutionsHistory.AddToolbarTool("@Trash_16x16.png", "Delete All Execution Results", new RoutedEventHandler(DeleteAllSelectedExecutionResults));
+
+ WeakEventManager.AddHandler(source: xGridExecutionsHistory, eventName: nameof(ucGrid.RowDoubleClick), handler: OpenExecutionResultsFolder);
+ xGridExecutionsHistory.AddLabel("Load Execution History Data:");
+
+ string groupName = "ExecutionLoggerGroup";
+ if (GaraphQLClientLoadFlag)
+ {
+ remoteRadioButton = xGridExecutionsHistory.AddRadioButton("Remote ", groupName, new RoutedEventHandler(RadioButton_Remote), isChecked: true);
+ localRadioButton = xGridExecutionsHistory.AddRadioButton("Local", groupName, new RoutedEventHandler(RadioButton_Local));
+ }
+ else
+ {
+ remoteRadioButton = xGridExecutionsHistory.AddRadioButton("Remote ", groupName, new RoutedEventHandler(RadioButton_Remote), isEnabled: false);
+ localRadioButton = xGridExecutionsHistory.AddRadioButton("Local", groupName, new RoutedEventHandler(RadioButton_Local), isChecked: true);
+ }
}
- }
private DataTemplate GetActionsDataTemplate()
- {
- if (mExecutionHistoryLevel == eExecutionHistoryLevel.SpecificRunSet)
{
+ if (mExecutionHistoryLevel == eExecutionHistoryLevel.SpecificRunSet)
+ {
return (DataTemplate)pageGrid.Resources["ActionsDataTemplateWithoutLoadRunset"];
- }
+ }
else
- {
+ {
return (DataTemplate)pageGrid.Resources["ActionsDataTemplate"];
+ }
}
- }
- private string GetContentXAMLFromDataTemplate(DataTemplate dataTemplate)
- {
- using StringWriter stringWriter = new();
- XamlWriter.Save(dataTemplate.LoadContent(), stringWriter);
- return stringWriter.ToString();
- }
- private void AutoLoadExecutionHistory(object sender, RoutedEventArgs e)
- {
- if (((System.Windows.Controls.Primitives.ToggleButton)sender).IsChecked == true)
- {
- AutoLoadExecutionData = true;
- }
- else
- {
- AutoLoadExecutionData = false;
- }
- }
public string NameInDb()
- {
+ {
var name = typeof(T).Name + "s";
return name;
- }
- private async void LoadExecutionsHistoryData()
- {
- grdExecutionsHistory.Visibility = Visibility.Collapsed;
+ }
+ ///
+ /// Loads the execution history data from LiteDB.
+ ///
+ private async Task LoadExecutionsHistoryDataLiteDb()
+ {
+ xGridExecutionsHistory.Visibility = Visibility.Collapsed;
Loading.Visibility = Visibility.Visible;
mExecutionsHistoryList.Clear();
await System.Threading.Tasks.Task.Run(() =>
{
try
- {
- if (WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
{
+ if (WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
+ {
mRunSetExecsRootFolder = executionLoggerHelper.GetLoggerDirectory(WorkSpace.Instance.Solution.LoggerConfigurations.CalculatedLoggerFolder);
//pull all RunSets JSON files from it
string[] runSetsfiles = Directory.GetFiles(mRunSetExecsRootFolder, "RunSet.txt", SearchOption.AllDirectories);
foreach (string runSetFile in runSetsfiles)
- {
+ {
RunSetReport runSetReport = (RunSetReport)JsonLib.LoadObjFromJSonFile(runSetFile, typeof(RunSetReport));
runSetReport.DataRepMethod = ExecutionLoggerConfiguration.DataRepositoryMethod.TextFile;
runSetReport.LogFolder = System.IO.Path.GetDirectoryName(runSetFile);
runSetReport.RunSetGuid = Guid.Parse(runSetReport.GUID);
if (mExecutionHistoryLevel == eExecutionHistoryLevel.SpecificRunSet)
- {
+ {
//filer the run sets by GUID
if (RunsetConfig != null && string.IsNullOrEmpty(runSetReport.GUID) == false)
- {
+ {
Guid runSetReportGuid = Guid.Empty;
Guid.TryParse(runSetReport.GUID, out runSetReportGuid);
if (RunsetConfig.Guid.Equals(runSetReportGuid))
- {
+ {
mExecutionsHistoryList.Add(runSetReport);
+ }
}
}
- }
else
- {
+ {
mExecutionsHistoryList.Add(runSetReport);
+ }
}
- }
LiteDbConnector dbConnector = new LiteDbConnector(Path.Combine(mRunSetExecsRootFolder, "GingerExecutionResults.db"));
var rsLiteColl = dbConnector.GetCollection(NameInDb());
IEnumerable runSetDataColl = null;
if (RunsetConfig != null)
- {
+ {
runSetDataColl = rsLiteColl.Find(x => x.GUID == RunsetConfig.Guid);
- }
+ }
else
- {
+ {
runSetDataColl = rsLiteColl.FindAll();
- }
+ }
foreach (var runSet in runSetDataColl)
- {
+ {
RunSetReport runSetReport = new RunSetReport();
runSetReport.DataRepMethod = ExecutionLoggerConfiguration.DataRepositoryMethod.LiteDB;
runSetReport.SetLiteDBData(runSet);
mExecutionsHistoryList.Add(runSetReport);
+ }
}
- AddRemoteExucationRunsetData();
}
- }
catch (Exception ex)
- {
+ {
Reporter.ToLog(eLogLevel.ERROR, "Error Occurred during LoadExecutionHistory.", ex);
- }
+ }
});
+ SetContentInGrid();
+ }
+ ///
+ /// Loads the execution history data using GraphQL.
+ ///
+ private async Task LoadExecutionsHistoryDataGraphQl()
+ {
+ xGridExecutionsHistory.Visibility = Visibility.Collapsed;
+ Loading.Visibility = Visibility.Visible;
+ mExecutionsHistoryList.Clear();
+ int recordLimit = (int)xPageSizeComboBox.SelectedItem;
+ graphQlClient.ResetPagination();
+ await LoadRemoteDataFromGraphQL(recordLimit, ePageAction.firstPage);
+ SetContentInGrid();
+
+
+ }
+ ///
+ /// Sets the content in the grid by populating the data source list with sorted and filtered execution history.
+ ///
+ void SetContentInGrid()
+ {
ObservableList executionsHistoryListSortedByDate = new ObservableList();
if (mExecutionsHistoryList != null && mExecutionsHistoryList.Count > 0)
- {
+ {
IEnumerable sortedAndFilteredExecutionHistoryList = mExecutionsHistoryList
- .Where(report => report.RunSetExecutionStatus != eRunStatus.Automated)
- .OrderByDescending(item => item.StartTimeStamp);
+ .Where(report => report.RunSetExecutionStatus != eRunStatus.Automated)
+ .OrderByDescending(item => item.StartTimeStamp);
foreach (RunSetReport runSetReport in sortedAndFilteredExecutionHistoryList)
- {
+ {
runSetReport.StartTimeStamp = runSetReport.StartTimeStamp.ToLocalTime();
runSetReport.EndTimeStamp = runSetReport.EndTimeStamp.ToLocalTime();
executionsHistoryListSortedByDate.Add(runSetReport);
+ }
}
- }
- grdExecutionsHistory.DataSourceList = executionsHistoryListSortedByDate;
- grdExecutionsHistory.Visibility = Visibility.Visible;
+ xGridExecutionsHistory.DataSourceList = executionsHistoryListSortedByDate;
+ xGridExecutionsHistory.Visibility = Visibility.Visible;
Loading.Visibility = Visibility.Collapsed;
- }
+ }
- private void AddRemoteExucationRunsetData()
- {
- List runsetsReport = new List();
- if (RunsetConfig != null)
+
+ ///
+ /// Handles pagination button click events.
+ ///
+ private async Task LoadRemoteDataFromGraphQL(int recordLimit, ePageAction pageButton, string endCursor = null, string startCursor = null, bool firstPage = false, bool lastPage = false, bool afterOrBefore = true)
{
- runsetsReport = new GingerRemoteExecutionUtils().GetRunsetExecutionInfo(WorkSpace.Instance.Solution.Guid, RunsetConfig.Guid);
+ try
+ {
+ if (mExecutionHistoryLevel == eExecutionHistoryLevel.Solution)
+ {
+ response = executionReportGraphQLClient.ExecuteReportQuery(recordLimit, WorkSpace.Instance.Solution.Guid, endCursor: endCursor, startCursor: startCursor, firstPage: firstPage, lastPage: lastPage, afterOrBefore: afterOrBefore);
+ }
+ else
+ {
+ response = executionReportGraphQLClient.ExecuteReportQuery(recordLimit, WorkSpace.Instance.Solution.Guid, RunsetConfig.Guid, endCursor: endCursor, startCursor: startCursor, firstPage: firstPage, lastPage: lastPage, afterOrBefore: afterOrBefore);
+ }
+
+
+ AddRemoteDataToList(await response);
+ UpdatePageInfo(pageButton);
+ UpdateButtonStates();
+ }
+ catch (Exception ex)
+ {
+ Reporter.ToLog(eLogLevel.ERROR, $"Error occurred while connecting remote.", ex);
+ Reporter.ToUser(eUserMsgKey.RemoteExecutionHistoryEndPoint);
+ RadioButton_Local(null, null);
+
+
+
+ }
}
- else
+
+ ///
+ /// Updates the pagination information displayed to the user.
+ ///
+ private void UpdatePageInfo(ePageAction pageAction)
{
- runsetsReport = new GingerRemoteExecutionUtils().GetSolutionRunsetsExecutionInfo(WorkSpace.Instance.Solution.Guid);
+ int recordCount = (int)xPageSizeComboBox.SelectedItem;
+ int totalEntries = graphQlClient.TotalCount;
+ int itemsFetched = graphQlClient.ItemsFetchedSoFar;
+ int currentCount = graphQlClient.CurrentRecordCount;
+ int start, end;
+
+ // Calculate the record range (start and end)
+ CalculatePageRange(pageAction, recordCount, totalEntries, itemsFetched, currentCount, out start, out end);
+
+ // Calculate the page number
+ int pageNumber = CalculatePageNumber(pageAction, recordCount, totalEntries, itemsFetched, start);
+ if (pageAction == ePageAction.lastPage)
+ {
+ graphQlClient.ItemsFetchedSoFar = totalEntries;
+ }
+
+ // Update the UI with the calculated range and page number
+ xRangelbl.Content = $"Showing {start} to {end} of {totalEntries} entries";
+ xPageNumber.Content = $"Page {pageNumber}";
}
- foreach (var item in runsetsReport)
+
+ ///
+ /// Calculates the range of page numbers based on the given page action, record count, total entries, items fetched, and current count.
+ ///
+ /// The page action (e.g., "firstPage", "lastPage", "nextPage", "previousPage").
+ /// The number of records per page.
+ /// The total number of entries.
+ /// The number of items fetched.
+ /// The current count of items.
+ /// The start page number of the range.
+ /// The end page number of the range.
+ public static void CalculatePageRange(ePageAction pageAction, int recordCount, int totalEntries, int itemsFetched, int currentCount, out int start, out int end)
{
- mExecutionsHistoryList.Add(item);
+ start = itemsFetched - recordCount + 1;
+ if (start < 1)
+ {
+ start = 1;
+ }
+ end = itemsFetched;
+
+ switch (pageAction)
+ {
+ case ePageAction.firstPage:
+ start = 1;
+ end = Math.Min(recordCount, totalEntries);
+ break;
+
+ case ePageAction.lastPage:
+ float result = MathF.Floor((float)totalEntries / recordCount);
+ int remainingRecords = totalEntries - (int)result * recordCount;
+ recordCount = remainingRecords == 0 ? recordCount : remainingRecords;
+
+ start = totalEntries - recordCount + 1;
+ if (start < 1)
+ {
+ start = 1;
+ }
+ end = totalEntries;
+
+ break;
+
+ case ePageAction.nextPage:
+ if (currentCount < recordCount)
+ {
+ start = totalEntries - currentCount + 1;
+ }
+ end = Math.Min(itemsFetched, totalEntries);
+ break;
+
+ case ePageAction.previousPage:
+ start = itemsFetched - recordCount + 1;
+ end = itemsFetched;
+ if (end < 1)
+ {
+ end = recordCount;
+ }
+ break;
+ default:
+ return;
+
+ }
}
- }
+
+ ///
+ /// Calculates the page number based on the page action and other parameters.
+ ///
+ /// The action performed on the page (firstPage, lastPage, nextPage, previousPage).
+ /// The number of records per page.
+ /// The total number of entries.
+ /// The number of items fetched.
+ /// The starting index of the current page.
+ /// The calculated page number.
+ public static int CalculatePageNumber(ePageAction pageAction, int recordCount, int totalEntries, int itemsFetched, int start)
+ {
+ int pageNumber = 1;
+
+ switch (pageAction)
+ {
+ case ePageAction.firstPage:
+ pageNumber = 1;
+ break;
+
+ case ePageAction.lastPage:
+ float result = MathF.Floor((float)totalEntries / recordCount);
+ int remainingRecords = totalEntries - (int)result * recordCount;
+ pageNumber = (int)result + (remainingRecords == 0 ? 0 : 1);
+ break;
+
+ case ePageAction.nextPage:
+ if (itemsFetched % recordCount == 0)
+ {
+ pageNumber = (itemsFetched / recordCount);
+ }
+ else
+ {
+ pageNumber = (itemsFetched / recordCount) + 1;
+ }
+ break;
+
+ case ePageAction.previousPage:
+ pageNumber = (start - 1) / recordCount + 1;
+ break;
+ default:
+ return 0;
+ }
+
+ return pageNumber;
+ }
+
+ ///
+ /// Updates the enabled/disabled state of pagination buttons based on current pagination state.
+ ///
+ private void UpdateButtonStates()
+ {
+ btnFirst.IsEnabled = graphQlClient.HasPreviousPage;
+ btnPrevious.IsEnabled = graphQlClient.HasPreviousPage;
+ btnNext.IsEnabled = graphQlClient.HasNextPage;
+ btnLast.IsEnabled = graphQlClient.HasNextPage;
+ xPageSizeComboBox.IsEnabled = graphQlClient.HasNextPage || graphQlClient.HasPreviousPage;
+ }
+
+ ///
+ /// Adds the data fetched from GraphQL to the list.
+ ///
+ private void AddRemoteDataToList(GraphQLResponse data)
+ {
+ mExecutionsHistoryList.Clear();
+
+ foreach (var node in data.Data.Runsets.Nodes)
+ {
+ var runSetReport = new RunSetReport
+ {
+ GUID = node.ExecutionId.ToString(),
+ RunSetGuid = node.EntityId.Value,
+ Name = node.Name,
+ Description = node.Description,
+ SourceApplication = node.SourceApplication,
+ SourceApplicationUser = node.SourceApplicationUser,
+ StartTimeStamp = DateTime.Parse(node.StartTime.ToString(), CultureInfo.InvariantCulture).ToUniversalTime(),
+ EndTimeStamp = DateTime.Parse(node.EndTime.ToString(), CultureInfo.InvariantCulture).ToUniversalTime(),
+ Elapsed = node.ElapsedEndTimeStamp,
+ DataRepMethod = ExecutionLoggerConfiguration.DataRepositoryMethod.Remote
+ };
+
+ if (node.ElapsedEndTimeStamp != null)
+ {
+ runSetReport.ExecutionDurationHHMMSS = GingerCoreNET.GeneralLib.General.TimeConvert((node.ElapsedEndTimeStamp / 1000).ToString());
+ }
+
+ if (Enum.TryParse(node.Status, out eRunStatus runStatus))
+ {
+ runSetReport.RunSetExecutionStatus = runStatus;
+ }
+
+ mExecutionsHistoryList.Add(runSetReport);
+ }
+
+ SetContentInGrid();
+ }
+
private void DeleteSelectedExecutionResults(object sender, RoutedEventArgs e)
- {
- if (Reporter.ToUser(eUserMsgKey.ExecutionsResultsToDelete) == eUserMsgSelection.Yes)
{
- DeleteExecutionReports(grdExecutionsHistory.Grid.SelectedItems);
+ if (Reporter.ToUser(eUserMsgKey.ExecutionsResultsToDelete) == eUserMsgSelection.Yes)
+ {
+ DeleteExecutionReports(xGridExecutionsHistory.Grid.SelectedItems);
+ }
}
- }
private void DeleteAllSelectedExecutionResults(object sender, RoutedEventArgs e)
- {
- if (Reporter.ToUser(eUserMsgKey.AllExecutionsResultsToDelete) == eUserMsgSelection.Yes)
{
- DeleteExecutionReports(grdExecutionsHistory.Grid.Items);
+ if (Reporter.ToUser(eUserMsgKey.AllExecutionsResultsToDelete) == eUserMsgSelection.Yes)
+ {
+ DeleteExecutionReports(xGridExecutionsHistory.Grid.Items);
+ }
}
- }
private void DeleteExecutionReports(System.Collections.IList runSetReports)
- {
+ {
bool remoteDeletionFlag = false;
foreach (RunSetReport runSetReport in runSetReports)
- {
- if (runSetReport.DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.LiteDB)
{
+ if (runSetReport.DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.LiteDB)
+ {
LiteDbManager dbManager = new LiteDbManager(executionLoggerHelper.GetLoggerDirectory(WorkSpace.Instance.Solution.LoggerConfigurations.CalculatedLoggerFolder));
var result = dbManager.GetRunSetLiteData();
List filterData = LiteDbRunSet.IncludeAllReferences(result).Find(a => a._id.Equals(new LiteDB.ObjectId(runSetReport.GUID))).ToList();
LiteDbConnector dbConnector = new LiteDbConnector(Path.Combine(mRunSetExecsRootFolder, "GingerExecutionResults.db"));
dbConnector.DeleteDocumentByLiteDbRunSet(filterData[0]);
- }
+ }
else if (runSetReport.DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.TextFile)
- {
+ {
string runSetFolder = executionLoggerHelper.GetLoggerDirectory(runSetReport.LogFolder);
TextFileRepository.DeleteLocalData(runSetFolder);
- }
- else if (runSetReport.DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.Remote && !remoteDeletionFlag)
- {
+ }
+ else if ((bool)remoteRadioButton.IsChecked)
+ {
Reporter.ToUser(eUserMsgKey.RemoteExecutionResultsCannotBeAccessed);
remoteDeletionFlag = true;
+ }
}
- }
- if (grdExecutionsHistory.Grid.SelectedItems.Count > 0)
- {
- LoadExecutionsHistoryData();
+ if (xGridExecutionsHistory.Grid.SelectedItems.Count > 0)
+ {
+ RefreshDataAsync();
+ }
}
- }
private void RefreshGrid(object sender, RoutedEventArgs e)
- {
- ReloadData();
- }
+ {
+ RefreshDataAsync();
+ }
private void GetExecutionResultsFolder(object sender, RoutedEventArgs e)
- {
- if (WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
{
+
+
+ if ((bool)remoteRadioButton.IsChecked)
+ {
+ Reporter.ToUser(eUserMsgKey.RemoteExecutionReportFolder);
+ return;
+ }
+
+
+ if (WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
+ {
System.Diagnostics.Process.Start(new ProcessStartInfo() { FileName = executionLoggerHelper.GetLoggerDirectory(WorkSpace.Instance.Solution.LoggerConfigurations.CalculatedLoggerFolder), UseShellExecute = true });
- }
+ }
else
- {
+ {
return;
+ }
}
- }
private void OpenExecutionResultsFolder()
- {
- if (grdExecutionsHistory.CurrentItem == null)
{
+ if (xGridExecutionsHistory.CurrentItem == null)
+ {
Reporter.ToUser(eUserMsgKey.NoItemWasSelected);
return;
- }
+ }
- string runSetFolder = ((RunSetReport)grdExecutionsHistory.CurrentItem).LogFolder;
+ string runSetFolder = ((RunSetReport)xGridExecutionsHistory.CurrentItem).LogFolder;
if (string.IsNullOrEmpty(runSetFolder))
- {
+ {
return;
- }
+ }
if (!Directory.Exists(runSetFolder))
- {
+ {
Directory.CreateDirectory(runSetFolder);
- }
+ }
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() { FileName = runSetFolder, UseShellExecute = true });
- }
+ }
private void OpenExecutionResultsFolder(object sender, RoutedEventArgs e)
- {
+ {
OpenExecutionResultsFolder();
- }
+ }
private void OpenExecutionResultsFolder(object sender, EventArgs e)
- {
+ {
OpenExecutionResultsFolder();
- }
+ }
private void ReportBtnClicked(object sender, RoutedEventArgs e)
- {
- HTMLReportsConfiguration currentConf = WorkSpace.Instance.Solution.HTMLReportsConfigurationSetList.FirstOrDefault(x => (x.IsSelected == true));
- if (grdExecutionsHistory.CurrentItem == null)
{
+ HTMLReportsConfiguration currentConf = WorkSpace.Instance.Solution.HTMLReportsConfigurationSetList.FirstOrDefault(x => (x.IsSelected == true));
+ if (xGridExecutionsHistory.CurrentItem == null)
+ {
Reporter.ToUser(eUserMsgKey.NoItemWasSelected);
return;
- }
- if (((RunSetReport)grdExecutionsHistory.CurrentItem).DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.LiteDB)
- {
- var selectedGuid = ((RunSetReport)grdExecutionsHistory.CurrentItem).GUID;
+ }
+ if (((RunSetReport)xGridExecutionsHistory.CurrentItem).DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.LiteDB)
+ {
+ var selectedGuid = ((RunSetReport)xGridExecutionsHistory.CurrentItem).GUID;
WebReportGenerator webReporterRunner = new WebReportGenerator();
webReporterRunner.RunNewHtmlReport(string.Empty, selectedGuid);
- }
- else if (((RunSetReport)grdExecutionsHistory.CurrentItem).DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.Remote)
- {
- var executionGuid = ((RunSetReport)grdExecutionsHistory.CurrentItem).GUID;
+ }
+ else if (((RunSetReport)xGridExecutionsHistory.CurrentItem).DataRepMethod == ExecutionLoggerConfiguration.DataRepositoryMethod.Remote)
+ {
+ var executionGuid = ((RunSetReport)xGridExecutionsHistory.CurrentItem).GUID;
new GingerRemoteExecutionUtils().GenerateHTMLReport(executionGuid);
- }
+ }
else
- {
+ {
- string runSetFolder = executionLoggerHelper.GetLoggerDirectory(((RunSetReport)grdExecutionsHistory.CurrentItem).LogFolder);
+ string runSetFolder = executionLoggerHelper.GetLoggerDirectory(((RunSetReport)xGridExecutionsHistory.CurrentItem).LogFolder);
string reportsResultFolder = Ginger.Reports.GingerExecutionReport.ExtensionMethods.CreateGingerExecutionReport(new ReportInfo(runSetFolder), false, null, null, false, currentConf.HTMLReportConfigurationMaximalFolderSize);
if (reportsResultFolder == string.Empty)
- {
+ {
Reporter.ToUser(eUserMsgKey.NoItemWasSelected);
return;
- }
+ }
else
- {
+ {
System.Diagnostics.Process.Start(new ProcessStartInfo() { FileName = reportsResultFolder, UseShellExecute = true });
System.Diagnostics.Process.Start(new ProcessStartInfo() { FileName = reportsResultFolder + "\\" + "GingerExecutionReport.html", UseShellExecute = true });
+ }
}
}
- }
private void LoadRunsetButton_Click(object sender, RoutedEventArgs e)
- {
+ {
Button LoadRunsetButton = (Button)sender;
RunSetReport runsetReport = (RunSetReport)LoadRunsetButton.Tag;
_ = Task.Run(async () =>
{
try
- {
+ {
Reporter.ToStatus(eStatusMsgKey.LoadingRunSet, messageArgs: runsetReport.Name);
RunSetConfig? runset = await _runsetFromReportLoader.LoadAsync(runsetReport);
if (runset == null)
- {
+ {
Dispatcher.Invoke(() => Reporter.ToUser(eUserMsgKey.RunsetNotFoundForLoading));
return;
- }
+ }
Dispatcher.Invoke(() =>
{
LoadRunsetEventHandler? handler = LoadRunset;
handler?.Invoke(runset);
if (runset.IsVirtual)
- {
+ {
runset.DirtyStatus = Amdocs.Ginger.Common.Enums.eDirtyStatus.Modified;
- }
+ }
});
- }
- catch(Exception ex)
- {
+ }
+ catch (Exception ex)
+ {
Reporter.ToUser(eUserMsgKey.RunSetLoadFromReportError, ex.Message);
- }
+ }
finally
- {
+ {
Reporter.HideStatusMessage();
- }
+ }
});
- }
+ }
private void BPMNButton_Click(object sender, RoutedEventArgs e)
- {
+ {
Button BPMNButton = (Button)sender;
RunSetReport runSetReport = (RunSetReport)BPMNButton.Tag;
_ = ExportBPMNFromRunSetReportAsync(runSetReport);
- }
+ }
private async Task ExportBPMNFromRunSetReportAsync(RunSetReport runSetReport)
- {
- try
{
+ try
+ {
Dispatcher.Invoke(() => Reporter.ToStatus(eStatusMsgKey.ExportingToBPMNZIP));
RunSetExecutionHistoryToBPMNExporter exporter = new();
@@ -550,48 +891,48 @@ private async Task ExportBPMNFromRunSetReportAsync(RunSetReport runSetReport)
executedBusinessFlows = RemoveNonSharedRepositoryActivitiesFromExecutionData(executedBusinessFlows);
if (!executedBusinessFlows.Any())
- {
+ {
return;
- }
+ }
int exportedSuccessfullyCount = 0;
foreach (ExecutedBusinessFlow executedBusinessFlow in executedBusinessFlows)
- {
- try
{
+ try
+ {
exporter.Export(executedBusinessFlow, BPMNExportPath);
exportedSuccessfullyCount++;
- }
+ }
catch (Exception ex)
- {
+ {
Reporter.ToLog(eLogLevel.ERROR, $"Error occurred while exporting BPMN for business flow {executedBusinessFlow.Name}.", ex);
+ }
}
- }
if (exportedSuccessfullyCount > 0)
- {
+ {
Dispatcher.Invoke(() => Reporter.ToUser(eUserMsgKey.MultipleExportToBPMNSuccessful, exportedSuccessfullyCount));
- }
+ }
else
- {
+ {
Dispatcher.Invoke(() => Reporter.ToUser(eUserMsgKey.GingerEntityToBPMNConversionError, "Unexpected Error, check logs for more details."));
+ }
}
- }
catch (Exception ex)
- {
+ {
Dispatcher.Invoke(() => Reporter.ToUser(eUserMsgKey.GingerEntityToBPMNConversionError, "Unexpected Error, check logs for more details."));
Reporter.ToLog(eLogLevel.ERROR, "Exception occurred while exporting BPMN from execution history.", ex);
- }
+ }
finally
- {
+ {
Dispatcher.Invoke(() => Reporter.HideStatusMessage());
+ }
}
- }
private IEnumerable RemoveNonSharedRepositoryActivitiesFromExecutionData(IEnumerable executedBusinessFlows)
- {
+ {
List<(BusinessFlow, IEnumerable)> activitiesMissingFromSR = [];
foreach (ExecutedBusinessFlow executedBusinessFlow in executedBusinessFlows)
- {
+ {
activitiesMissingFromSR.Add((
executedBusinessFlow.BusinessFlow,
executedBusinessFlow
@@ -599,36 +940,36 @@ private IEnumerable RemoveNonSharedRepositoryActivitiesFro
.Where(executedActivity => !executedActivity.ExistInSharedRepository)
.Select(executedActivity => executedActivity.Activity)
.ToArray()));
- }
+ }
bool allItemsExistInSR = !activitiesMissingFromSR
.SelectMany(pair => pair.Item2)
.Any();
if (allItemsExistInSR)
- {
+ {
return executedBusinessFlows;
- }
+ }
//ask user if they want to add missing activities to Shared Repository
eUserMsgSelection userResponse = eUserMsgSelection.Cancel;
Dispatcher.Invoke(() => userResponse = Reporter.ToUser(eUserMsgKey.AddActivitiesToSharedRepositoryForBPMNConversion));
if (userResponse == eUserMsgSelection.Yes)
- {
+ {
bool wasAllAdded = TryAddActivitiesToSharedRepository(activitiesMissingFromSR);
if (!wasAllAdded)
- {
+ {
Dispatcher.Invoke(() => Reporter.ToUser(eUserMsgKey.AllActivitiesMustBeAddedToSharedRepositoryForBPMNExport));
return Array.Empty();
- }
+ }
return executedBusinessFlows;
- }
+ }
else if (userResponse == eUserMsgSelection.No)
- {
+ {
List filteredExecutedBusinessFlows = [];
foreach (ExecutedBusinessFlow executedBusinessFlow in executedBusinessFlows)
- {
+ {
IEnumerable activitiesExistingInSR = executedBusinessFlow
.ExecutedActivities
.Where(execitedActivity => execitedActivity.ExistInSharedRepository)
@@ -637,44 +978,44 @@ private IEnumerable RemoveNonSharedRepositoryActivitiesFro
filteredExecutedBusinessFlows.Add(new ExecutedBusinessFlow(
executedBusinessFlow.BusinessFlow,
activitiesExistingInSR));
- }
+ }
return filteredExecutedBusinessFlows;
- }
+ }
else
- {
+ {
return Array.Empty();
+ }
}
- }
private bool ActivityExistInSharedRepository(string name)
- {
+ {
return WorkSpace
.Instance
.SolutionRepository
.GetAllRepositoryItems()
.Any(activity => string.Equals(activity.ActivityName, name));
- }
+ }
private bool TryAddActivitiesToSharedRepository(IEnumerable<(BusinessFlow, IEnumerable)> bfActivities)
- {
+ {
bool wasAllAdded = false;
Dispatcher.Invoke(() =>
{
List uploadItems = new();
foreach (var bfActivitiesPair in bfActivities)
- {
+ {
BusinessFlow bf = bfActivitiesPair.Item1;
foreach (GingerCore.Activity activity in bfActivitiesPair.Item2)
- {
+ {
uploadItems.Add(UploadItemToRepositoryWizard.CreateUploadItem(
activity,
new Context()
- {
+ {
BusinessFlow = bf
- }));
+ }));
+ }
}
- }
UploadItemToRepositoryWizard uploadItemToRepositoryWizard = new(uploadItems);
WizardWindow.ShowWizard(uploadItemToRepositoryWizard);
@@ -683,6 +1024,100 @@ private bool TryAddActivitiesToSharedRepository(IEnumerable<(BusinessFlow, IEnum
.All(activity => ActivityExistInSharedRepository(activity.ActivityName));
});
return wasAllAdded;
+ }
+ private async void btnFirst_Click(object sender, RoutedEventArgs e)
+ {
+ GraphQlLoadingVisible();
+ btnFirst.IsEnabled = false;
+ LoadExecutionsHistoryDataGraphQl();
+ UpdatePageInfo(ePageAction.firstPage);
+ GraphQlLoadingCollapsed();
+ }
+
+ private async void btnPrevious_Click(object sender, RoutedEventArgs e)
+ {
+ GraphQlLoadingVisible();
+ btnPrevious.IsEnabled = false;
+
+ float result = MathF.Floor(graphQlClient.TotalCount / (int)xPageSizeComboBox.SelectedItem);
+ int remainingRecords = graphQlClient.TotalCount - (int)result * (int)xPageSizeComboBox.SelectedItem;
+ int recordCount;
+
+ if (graphQlClient.ItemsFetchedSoFar % (int)xPageSizeComboBox.SelectedItem == 0)
+ {
+ recordCount = (int)xPageSizeComboBox.SelectedItem;
+ }
+ else
+ {
+ recordCount = remainingRecords;
+ }
+ string endCursor = graphQlClient.EndCursor;
+ string startCursor = graphQlClient.StartCursor;
+ bool firstPage = false;
+ bool lastPage = false;
+ bool afterOrBefore = false;
+
+ if (graphQlClient.HasPreviousPage)
+ {
+ graphQlClient.DecreaseFetchedItemsCount(recordCount);
+ await LoadRemoteDataFromGraphQL((int)xPageSizeComboBox.SelectedItem, pageButton: ePageAction.previousPage, endCursor: endCursor, startCursor: startCursor, firstPage: firstPage, lastPage: lastPage, afterOrBefore: afterOrBefore);
+ }
+ GraphQlLoadingCollapsed();
+ }
+
+ private async void btnNext_Click(object sender, RoutedEventArgs e)
+ {
+ GraphQlLoadingVisible();
+ btnNext.IsEnabled = false;
+ string endCursor = graphQlClient.EndCursor;
+ string startCursor = graphQlClient.StartCursor;
+ bool firstPage = false;
+ bool lastPage = false;
+ bool afterOrBefore = true;
+
+ if (graphQlClient.HasNextPage)
+ {
+ await LoadRemoteDataFromGraphQL((int)xPageSizeComboBox.SelectedItem, pageButton: ePageAction.nextPage, endCursor: endCursor, startCursor: startCursor, firstPage: firstPage, lastPage: lastPage, afterOrBefore: afterOrBefore);
+ }
+ GraphQlLoadingCollapsed();
+ }
+
+ private async void btnLast_Click(object sender, RoutedEventArgs e)
+ {
+ GraphQlLoadingVisible();
+ btnLast.IsEnabled = false;
+ float result = MathF.Floor(graphQlClient.TotalCount / (int)xPageSizeComboBox.SelectedItem);
+ int remainingRecords = graphQlClient.TotalCount - (int)result * (int)xPageSizeComboBox.SelectedItem;
+ int recordCount = remainingRecords == 0 ? (int)xPageSizeComboBox.SelectedItem : remainingRecords;
+
+ string endCursor = null;
+ string startCursor = null;
+ bool firstPage = false;
+ bool lastPage = true;
+ bool afterOrBefore = false;
+
+ await LoadRemoteDataFromGraphQL(recordLimit: recordCount, pageButton: ePageAction.lastPage, endCursor: endCursor, startCursor: startCursor, firstPage: firstPage, lastPage: lastPage, afterOrBefore: afterOrBefore);
+ GraphQlLoadingCollapsed();
+ }
+ void GraphQlLoadingVisible()
+ {
+ xGraphQlLoading.Visibility = Visibility.Visible;
+ }
+ void GraphQlLoadingCollapsed()
+ {
+ xGraphQlLoading.Visibility = Visibility.Hidden;
+ }
+
+ private void xPageSizeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (isLoading)
+ {
+ return; // Exit the method if still loading
+ }
+ GraphQlLoadingVisible();
+ CheckCentralizedExecutionLoggerConfig();
+ GraphQlLoadingCollapsed();
+ }
+
}
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/Ginger/Ginger/RunSetPageLib/NewRunSetPage.xaml.cs b/Ginger/Ginger/RunSetPageLib/NewRunSetPage.xaml.cs
index bed22d6770..1b04ce372e 100644
--- a/Ginger/Ginger/RunSetPageLib/NewRunSetPage.xaml.cs
+++ b/Ginger/Ginger/RunSetPageLib/NewRunSetPage.xaml.cs
@@ -2274,10 +2274,7 @@ private void TabControl_SelectionChanged(object sender, SelectionChangedEventArg
{
ExecutionBorder.BorderBrush = FindResource("$amdocsLogoLinarGradientBrush") as Brush;
- if (mRunSetsExecutionsPage.AutoLoadExecutionData)
- {
- InitExecutionHistorySection();
- }
+
}
}
}
diff --git a/Ginger/Ginger/SolutionWindows/SolutionPage.xaml b/Ginger/Ginger/SolutionWindows/SolutionPage.xaml
index 1a6d7ac6e0..5fed384636 100644
--- a/Ginger/Ginger/SolutionWindows/SolutionPage.xaml
+++ b/Ginger/Ginger/SolutionWindows/SolutionPage.xaml
@@ -1,8 +1,9 @@
-
+
+
+
diff --git a/Ginger/Ginger/SolutionWindows/SolutionPage.xaml.cs b/Ginger/Ginger/SolutionWindows/SolutionPage.xaml.cs
index 602cd0550c..8600e525c2 100644
--- a/Ginger/Ginger/SolutionWindows/SolutionPage.xaml.cs
+++ b/Ginger/Ginger/SolutionWindows/SolutionPage.xaml.cs
@@ -47,19 +47,19 @@ public SolutionPage()
WorkSpace.Instance.PropertyChanged += WorkSpacePropertyChanged;
WeakEventManager.AddHandler(source: UCEncryptionKey.UpdateKey, eventName: nameof(UIElement.PreviewMouseDown), handler: ReplaceKeyBtn_Click);
- Init();
+ BindElement();
}
private void WorkSpacePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(WorkSpace.Solution))
{
- Init();
+ BindElement();
}
}
- private void Init(Solution solution = null)
+ private void BindElement(Solution solution = null)
{
if (WorkSpace.Instance.Solution != null)
{
@@ -79,6 +79,7 @@ private void Init(Solution solution = null)
xLoadSolutionlbl.Visibility = Visibility.Collapsed;
xSolutionDetailsStack.Visibility = Visibility.Visible;
GingerCore.GeneralLib.BindingHandler.ObjFieldBinding(SolutionNameTextBox, TextBox.TextProperty, mSolution, nameof(Solution.Name));
+ xShowIDUC.Init(mSolution);
GingerCore.GeneralLib.BindingHandler.ObjFieldBinding(SolutionFolderTextBox, TextBox.TextProperty, mSolution, nameof(Solution.Folder));
GingerCore.GeneralLib.BindingHandler.ObjFieldBinding(AccountTextBox, TextBox.TextProperty, mSolution, nameof(Solution.Account));
UCEncryptionKey.EncryptionKeyPasswordBox.Password = mSolution.EncryptionKey;
@@ -149,7 +150,7 @@ private void SaveBtn_Click(object sender, RoutedEventArgs e)
public bool ShowAsWindow(Solution solution, eWindowShowStyle windowStyle = eWindowShowStyle.Dialog, bool startupLocationWithOffset = false)
{
- Init(solution);
+ BindElement(solution);
UCEncryptionKey.mSolution = solution;
IsEncrytedStrAvailableOnSol = !string.IsNullOrEmpty(mSolution.EncryptedValidationString);
diff --git a/Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs b/Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs
index b9ca88a3b1..6811cb0271 100644
--- a/Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs
+++ b/Ginger/Ginger/UserControlsLib/ImageMakerLib/ImageMakerControl.xaml.cs
@@ -623,6 +623,12 @@ private void SetImage()
case eImageType.NormalUser:
SetAsFontAwesomeIcon(EFontAwesomeIcon.Solid_UserGear);
break;
+ case eImageType.AnglesArrowLeft:
+ SetAsFontAwesomeIcon(EFontAwesomeIcon.Solid_AnglesLeft);
+ break;
+ case eImageType.AnglesArrowRight:
+ SetAsFontAwesomeIcon(EFontAwesomeIcon.Solid_AnglesRight);
+ break;
#endregion
diff --git a/Ginger/Ginger/UserControlsLib/ucGridView/ucGrid.xaml.cs b/Ginger/Ginger/UserControlsLib/ucGridView/ucGrid.xaml.cs
index add772da8b..c561dd8721 100644
--- a/Ginger/Ginger/UserControlsLib/ucGridView/ucGrid.xaml.cs
+++ b/Ginger/Ginger/UserControlsLib/ucGridView/ucGrid.xaml.cs
@@ -1175,6 +1175,46 @@ public CheckBox AddCheckBox(string txt, RoutedEventHandler? handler)
toolbar.Items.Add(pnl);
return b;
}
+ public RadioButton AddRadioButton(string content, string groupName, RoutedEventHandler? handler, bool isEnabled = true, bool isChecked = false)
+ {
+ DockPanel pnl = new DockPanel();
+ pnl.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
+ pnl.VerticalAlignment = System.Windows.VerticalAlignment.Center;
+ pnl.LastChildFill = false;
+
+ if (string.IsNullOrEmpty(content))
+ {
+ throw new ArgumentException("Content cannot be null or empty", nameof(content));
+ }
+ if (string.IsNullOrEmpty(groupName))
+ {
+ throw new ArgumentException("GroupName cannot be null or empty", nameof(groupName));
+ }
+
+ RadioButton b = new RadioButton();
+ b.Margin = new Thickness(3, 0, 0, 0);
+ b.Height = Double.NaN;
+ b.Width = Double.NaN;
+ b.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
+ b.VerticalAlignment = System.Windows.VerticalAlignment.Center;
+ b.Padding = new Thickness(2, 0, 0, 0);
+ b.Content = content;
+ b.GroupName = groupName; // Set the group name for grouping radio buttons together
+ b.IsEnabled = isEnabled; // Set the enabled/disabled state of the radio button
+ b.IsChecked = isChecked; // Set the checked/unchecked state of the radio button
+
+
+ if (handler != null)
+ {
+ b.AddHandler(RadioButton.ClickEvent, handler);
+ }
+
+ pnl.Children.Add(b); // using dock panel for getting regular check box design
+ toolbar.Items.Add(pnl);
+ return b;
+ }
+
+
#endregion ##### External Methods
diff --git a/Ginger/GingerCoreCommon/Actions/Act.cs b/Ginger/GingerCoreCommon/Actions/Act.cs
index 24ce0e2bf0..5c300a156a 100644
--- a/Ginger/GingerCoreCommon/Actions/Act.cs
+++ b/Ginger/GingerCoreCommon/Actions/Act.cs
@@ -138,6 +138,7 @@ public static partial class Fields
public static string OutDataSourceTableName = "OutDataSourceTableName";
public static string OutDSParamMapType = "OutDSParamMapType";
public static string SupportSimulation = "SupportSimulation";
+ public static string AutoScreenShotOnFailure = "AutoScreenShotOnFailure";
}
// Being set by GingerRunner in PrepAction
@@ -174,7 +175,9 @@ public static partial class Fields
public bool SupportSimulation
{
get
- { return mSupportSimulation; }
+ {
+ return mSupportSimulation;
+ }
set
{
if (mSupportSimulation != value)
@@ -185,6 +188,26 @@ public bool SupportSimulation
}
}
+ ///
+ /// Gets a value indicating whether automatic screenshot capture is enabled on failure.
+ ///
+ private bool mAutoScreenShotOnFailure = true;
+ [IsSerializedForLocalRepository]
+ public bool AutoScreenShotOnFailure
+ {
+ get {
+ return mAutoScreenShotOnFailure;
+ }
+ set {
+
+ if (mAutoScreenShotOnFailure != value)
+ {
+ mAutoScreenShotOnFailure = value;
+ OnPropertyChanged(Fields.AutoScreenShotOnFailure);
+ }
+ }
+ }
+
public virtual eLocateBy LocateBy
{
get
diff --git a/Ginger/GingerCoreCommon/Actions/ActWithoutDriver.cs b/Ginger/GingerCoreCommon/Actions/ActWithoutDriver.cs
index 9542e40d47..bbbd9321c6 100644
--- a/Ginger/GingerCoreCommon/Actions/ActWithoutDriver.cs
+++ b/Ginger/GingerCoreCommon/Actions/ActWithoutDriver.cs
@@ -1,4 +1,4 @@
-#region License
+#region License
/*
Copyright © 2014-2024 European Support Limited
@@ -29,5 +29,11 @@ public abstract class ActWithoutDriver : Act
public ProjEnvironment RunOnEnvironment;
public ObservableList DSList;
public abstract void Execute();
+
+ protected ActWithoutDriver()
+ {
+ //Disable Auto Screenshot on failure by default. User can override it if needed
+ AutoScreenShotOnFailure = false;
+ }
}
}
diff --git a/Ginger/GingerCoreCommon/Actions/Webservices/ActSoapUI.cs b/Ginger/GingerCoreCommon/Actions/Webservices/ActSoapUI.cs
index 20e0bb3b51..a24c80e793 100644
--- a/Ginger/GingerCoreCommon/Actions/Webservices/ActSoapUI.cs
+++ b/Ginger/GingerCoreCommon/Actions/Webservices/ActSoapUI.cs
@@ -1,4 +1,4 @@
-#region License
+#region License
/*
Copyright © 2014-2024 European Support Limited
@@ -29,6 +29,12 @@ namespace GingerCore.Actions
{
public class ActSoapUI : Act
{
+ public ActSoapUI()
+ {
+ //Disable Auto Screenshot on failure by default. User can override it if needed
+ AutoScreenShotOnFailure = false;
+ }
+
public override string ActionDescription { get { return "SoapUI Wrapper Action"; } }
public override string ActionUserDescription { get { return "Run SoapUI commands on Dos/Unix system"; } }
diff --git a/Ginger/GingerCoreCommon/EnumsLib/eImageType.cs b/Ginger/GingerCoreCommon/EnumsLib/eImageType.cs
index 952a04c3d9..44478e9b54 100644
--- a/Ginger/GingerCoreCommon/EnumsLib/eImageType.cs
+++ b/Ginger/GingerCoreCommon/EnumsLib/eImageType.cs
@@ -355,6 +355,8 @@ public enum eImageType
DataTable,
Robot,
Accessibility,
+ AnglesArrowLeft,
+ AnglesArrowRight,
#region Comparison Status Images
Unchanged,
diff --git a/Ginger/GingerCoreCommon/EnumsLib/eStatus.cs b/Ginger/GingerCoreCommon/EnumsLib/eStatus.cs
index 7bacb8b9ad..e60df68fa1 100644
--- a/Ginger/GingerCoreCommon/EnumsLib/eStatus.cs
+++ b/Ginger/GingerCoreCommon/EnumsLib/eStatus.cs
@@ -1,4 +1,4 @@
-#region License
+#region License
/*
Copyright © 2014-2024 European Support Limited
@@ -33,6 +33,7 @@ public enum eRunStatus
FailIgnored,
Blocked,
Completed,
- Automated
+ Automated,
+ Canceled
}
}
diff --git a/Ginger/GingerCoreCommon/InterfacesLib/IAct.cs b/Ginger/GingerCoreCommon/InterfacesLib/IAct.cs
index da99ecd3c0..9b56148844 100644
--- a/Ginger/GingerCoreCommon/InterfacesLib/IAct.cs
+++ b/Ginger/GingerCoreCommon/InterfacesLib/IAct.cs
@@ -1,4 +1,4 @@
-#region License
+#region License
/*
Copyright © 2014-2024 European Support Limited
@@ -72,5 +72,11 @@ public interface IAct
bool EnableActionLogConfig { get; set; }
ActionLogConfig ActionLogConfig { get; set; }
Single? ElapsedSecs { get; }
+
+ ///
+ /// Gets a value indicating whether automatic screenshot capture is enabled on failure.
+ ///
+ bool AutoScreenShotOnFailure { get; }
+
}
}
diff --git a/Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs b/Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs
index 79f0e37fd1..e842239fdf 100644
--- a/Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs
+++ b/Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs
@@ -194,7 +194,9 @@ public enum eUserMsgKey
ShareApplicationToEnvironment,
SaveSolution,
LocatorTestInProgress,
- DeleteSelectedDB
+ DeleteSelectedDB,
+ RemoteExecutionReportFolder,
+ RemoteExecutionHistoryEndPoint,
}
public static class UserMsgsPool
@@ -878,6 +880,8 @@ public static void LoadUserMsgsPool()
Reporter.UserMsgsPool.Add(eUserMsgKey.DeleteRecoverFolderWarn, new UserMsg(eUserMsgType.WARN, "Delete Unrecovered files?",
"Unrecovered items will be deleted. Do you want to continue?",
eUserMsgOption.YesNo, eUserMsgSelection.No));
+ Reporter.UserMsgsPool.Add(eUserMsgKey.RemoteExecutionReportFolder, new UserMsg(eUserMsgType.INFO, "Remote Execution History", "Open execution folder not supported for Remote Execution History source.", eUserMsgOption.OK, eUserMsgSelection.OK));
+ Reporter.UserMsgsPool.Add(eUserMsgKey.RemoteExecutionHistoryEndPoint, new UserMsg(eUserMsgType.INFO, "Remote Execution History", "Unable to reach server, Please check your Endpoint URL or Internet Connection.\nLoading Local Execution History.", eUserMsgOption.OK, eUserMsgSelection.OK));
}
}
diff --git a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIBase.cs b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIBase.cs
index ccd099aadc..3aa6ca30e2 100644
--- a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIBase.cs
+++ b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIBase.cs
@@ -36,7 +36,12 @@ namespace GingerCore.Actions.WebServices
{
public class ActWebAPIBase : Act, IActPluginPostRun
{
- public override string ActionDescription { get { return "WebAPI Action"; } }
+ public ActWebAPIBase()
+ {
+ //Disable Auto Screenshot on failure by default. User can override it if needed
+ AutoScreenShotOnFailure = false;
+ }
+ public override string ActionDescription { get { return "Web API Action"; } }
public override eImageType Image { get { return eImageType.Exchange; } }
diff --git a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIModel.cs b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIModel.cs
index ebc467319f..c84c3d72e4 100644
--- a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIModel.cs
+++ b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIModel.cs
@@ -33,6 +33,12 @@ namespace GingerCore.Actions.WebServices.WebAPI
{
public class ActWebAPIModel : Act, IActPluginExecution, IActPluginPostRun
{
+ public ActWebAPIModel()
+ {
+ //Disable Auto Screenshot on failure by default. User can override it if needed
+ AutoScreenShotOnFailure = false;
+ }
+
public override String ActionType
{
get
@@ -101,7 +107,7 @@ public Guid APImodelGUID
public override List> GetInputValueListForVEProcessing()
{
- List> list = new List>();
+ List> list = [];
List AIVList = APIModelParamsValue.Cast().ToList();
list.Add(General.ConvertListToObservableList(AIVList));
return list;
diff --git a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIRest.cs b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIRest.cs
index 855e07b27e..f45c857141 100644
--- a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIRest.cs
+++ b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPIRest.cs
@@ -29,7 +29,7 @@ namespace GingerCore.Actions.WebServices
{
public class ActWebAPIRest : ActWebAPIBase, IActPluginExecution
{
- public override string ActionDescription { get { return "WebAPI REST Action"; } }
+ public override string ActionDescription { get { return "Web API REST Action"; } }
public override string ActionUserDescription { get { return "Performs REST action"; } }
public override string ActionEditPage { get { return "WebServices.ActWebAPIEditPage"; } }
public override bool ValueConfigsNeeded { get { return false; } }
diff --git a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPISoap.cs b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPISoap.cs
index 21b7b2e358..2909fac11f 100644
--- a/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPISoap.cs
+++ b/Ginger/GingerCoreNET/ActionsLib/Webservices/ActWebAPISoap.cs
@@ -27,7 +27,7 @@ namespace GingerCore.Actions.WebServices
{
public class ActWebAPISoap : ActWebAPIBase, IActPluginExecution
{
- public override string ActionDescription { get { return "WebAPI SOAP Action"; } }
+ public override string ActionDescription { get { return "Web API SOAP Action"; } }
public override string ActionUserDescription { get { return "Performs SOAP action"; } }
public override string ActionEditPage { get { return "WebServices.ActWebAPIEditPage"; } }
public override bool ValueConfigsNeeded { get { return false; } }
diff --git a/Ginger/GingerCoreNET/ActionsLib/Webservices/Diameter/ActDiameter.cs b/Ginger/GingerCoreNET/ActionsLib/Webservices/Diameter/ActDiameter.cs
index 7ca25f854e..74f517ea6b 100644
--- a/Ginger/GingerCoreNET/ActionsLib/Webservices/Diameter/ActDiameter.cs
+++ b/Ginger/GingerCoreNET/ActionsLib/Webservices/Diameter/ActDiameter.cs
@@ -30,6 +30,12 @@ namespace Amdocs.Ginger.CoreNET.ActionsLib.Webservices.Diameter
{
public class ActDiameter : Act
{
+ public ActDiameter()
+ {
+ //Disable Auto Screenshot on failure by default. User can override it if needed
+ AutoScreenShotOnFailure = false;
+ }
+
public override string ActionType { get { return ActionDescription; } }
public override string ActionDescription { get { return "Diameter Action"; } }
diff --git a/Ginger/GingerCoreNET/Clients/Extentions/GraphQLClientExtensions.cs b/Ginger/GingerCoreNET/Clients/Extentions/GraphQLClientExtensions.cs
new file mode 100644
index 0000000000..32735482ce
--- /dev/null
+++ b/Ginger/GingerCoreNET/Clients/Extentions/GraphQLClientExtensions.cs
@@ -0,0 +1,27 @@
+using AccountReport.Contracts.GraphQL.ResponseModels;
+using GraphQL;
+using System;
+
+namespace GraphQLClient.Extensions
+{
+ public static class GraphQLClientExtensions
+ {
+ ///
+ /// Extracts pagination information from the GraphQL response.
+ ///
+ public static PageInfo GetPageInfo(GraphQLResponse response)
+ {
+ if (response?.Data?.Runsets?.PageInfo == null)
+ {
+ throw new ArgumentNullException(nameof(response), "The response or its PageInfo is null.");
+ }
+ return new PageInfo
+ {
+ EndCursor = response.Data.Runsets.PageInfo.EndCursor,
+ HasNextPage = response.Data.Runsets.PageInfo.HasNextPage,
+ HasPreviousPage = response.Data.Runsets.PageInfo.HasPreviousPage,
+ StartCursor = response.Data.Runsets.PageInfo.StartCursor
+ };
+ }
+ }
+}
diff --git a/Ginger/GingerCoreNET/Clients/GraphQLClients/ExecutionReportGraphQLClient.cs b/Ginger/GingerCoreNET/Clients/GraphQLClients/ExecutionReportGraphQLClient.cs
new file mode 100644
index 0000000000..21effd4361
--- /dev/null
+++ b/Ginger/GingerCoreNET/Clients/GraphQLClients/ExecutionReportGraphQLClient.cs
@@ -0,0 +1,87 @@
+using AccountReport.Contracts.GraphQL.Helpers;
+using AccountReport.Contracts.GraphQL.RequestModels;
+using AccountReport.Contracts.GraphQL.ResponseModels;
+using GraphQL;
+using GraphQLClient.Clients;
+using System;
+using System.Collections.Generic;
+
+using System.Threading.Tasks;
+
+///
+/// Handles execution of GraphQL queries for execution reports.
+///
+public class ExecutionReportGraphQLClient
+{
+ private readonly GraphQlClient graphQlClient;
+
+ public ExecutionReportGraphQLClient(GraphQlClient graphQlClient)
+ {
+ this.graphQlClient = graphQlClient;
+ }
+
+ ///
+ /// Executes the report query with specified parameters.
+ ///
+ public async Task> ExecuteReportQuery(int recordLimit, Guid solutionId, Guid? runSetId = null, string endCursor = null, string startCursor = null, bool firstPage = false, bool lastPage = false, bool afterOrBefore = true)
+ {
+ const string paraList = "executionId, entityId, name, description, sourceApplication, sourceApplicationUser, startTime, endTime, elapsedEndTimeStamp, status";
+
+ if (recordLimit <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(recordLimit), "Record limit must be greater than zero.");
+ }
+ if (solutionId == Guid.Empty)
+ {
+ throw new ArgumentException("Solution ID cannot be empty.", nameof(solutionId));
+ }
+
+ var queryInfo = new GraphQLQueryInfo
+ {
+ PageInfo = new PageRequestInfo
+ {
+ FirstPage = firstPage,
+ LastPage = lastPage,
+ StartCursor = startCursor,
+ EndCursor = endCursor,
+ RecordLimit = recordLimit,
+ RequestNextPage = afterOrBefore
+ },
+ SortingInfo = new SortColumn
+ {
+ Field = "startTime",
+ Order = "DESC"
+ },
+ Filters = new List
+ {
+ new Filter
+ {
+ Field = "solutionId",
+ Operator = "eq",
+ Value = solutionId
+ }
+ }
+ };
+
+ if (runSetId.HasValue)
+ {
+ queryInfo.Filters.Add(new Filter
+ {
+ Field = "entityId",
+ Operator = "eq",
+ Value = runSetId.Value
+ });
+ }
+
+ var generatedQuery = RunsetQueryBuilder.CreateQuery(queryInfo, paraList);
+ try
+ {
+ return await graphQlClient.GetRunsets(generatedQuery);
+ }
+ catch (Exception ex)
+ {
+ throw new ArgumentException("Error executing the GraphQL query.", ex);
+ }
+
+ }
+}
diff --git a/Ginger/GingerCoreNET/Clients/GraphQLClients/GraphQLClient.cs b/Ginger/GingerCoreNET/Clients/GraphQLClients/GraphQLClient.cs
new file mode 100644
index 0000000000..417b57296e
--- /dev/null
+++ b/Ginger/GingerCoreNET/Clients/GraphQLClients/GraphQLClient.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Threading.Tasks;
+using AccountReport.Contracts.GraphQL.ResponseModels;
+using GraphQL;
+using GraphQL.Client.Http;
+using GraphQL.Client.Serializer.Newtonsoft;
+using GraphQLClient.Extensions;
+
+namespace GraphQLClient.Clients
+{
+ ///
+ /// Handles GraphQL client operations for fetching data and managing pagination.
+ ///
+ public class GraphQlClient
+ {
+ private readonly GraphQLHttpClient client;
+
+ public PageInfo PageInfo { get; private set; }
+ public string EndCursor { get; private set; }
+ public bool HasNextPage { get; private set; }
+ public bool HasPreviousPage { get; private set; }
+ public string StartCursor { get; private set; }
+ public int TotalCount { get; set; }
+ public int ItemsFetchedSoFar { get; set; }
+ public int CurrentRecordCount { get; set; }
+
+ public GraphQlClient(string endpoint)
+ {
+ try
+ {
+ client = new GraphQLHttpClient(endpoint, new NewtonsoftJsonSerializer());
+ ResetPagination();
+ }
+ catch (UriFormatException ex)
+ {
+ throw new ArgumentException("Invalid URL format", nameof(endpoint), ex);
+ }
+ }
+
+ ///
+ /// Resets the pagination state.
+ ///
+ public void ResetPagination()
+ {
+ EndCursor = null;
+ HasNextPage = true;
+ ItemsFetchedSoFar = 0;
+ }
+
+ ///
+ /// Decreases the count of fetched items, used when paginating backward.
+ ///
+ public void DecreaseFetchedItemsCount(int count)
+ {
+ ItemsFetchedSoFar -= count;
+ }
+
+ ///
+ /// Fetches runsets data using the provided GraphQL query.
+ ///
+ public async Task> GetRunsets(string query)
+ {
+ var request = new GraphQLRequest { Query = query };
+ try
+ {
+ var response = await client.SendQueryAsync(request);
+ var pageInfo = GraphQLClientExtensions.GetPageInfo(response);
+
+ EndCursor = pageInfo.EndCursor;
+ HasNextPage = pageInfo.HasNextPage;
+ HasPreviousPage = pageInfo.HasPreviousPage;
+ StartCursor = pageInfo.StartCursor;
+ TotalCount = response.Data.Runsets.TotalCount;
+
+ if (pageInfo.StartCursor == EndCursor)
+ {
+ HasPreviousPage = false;
+ ItemsFetchedSoFar = 0;
+ }
+ var beforePage = query.IndexOf("before") >= 0;
+ if (!beforePage)
+ {
+ ItemsFetchedSoFar += response.Data.Runsets.Nodes.Count;
+ }
+ CurrentRecordCount = response.Data.Runsets.Nodes.Count;
+
+
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ throw new ArgumentException("Error fetching runsets", ex);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ginger/GingerCoreNET/GingerCoreNET.csproj b/Ginger/GingerCoreNET/GingerCoreNET.csproj
index 6d6ebc66be..d82b9538aa 100644
--- a/Ginger/GingerCoreNET/GingerCoreNET.csproj
+++ b/Ginger/GingerCoreNET/GingerCoreNET.csproj
@@ -31,10 +31,13 @@
+
+
-
-
+
+
+
@@ -261,9 +264,15 @@
-
+
+
+
+
+
+
+
diff --git a/Ginger/GingerCoreNET/Run/GingerExecutionEngine.cs b/Ginger/GingerCoreNET/Run/GingerExecutionEngine.cs
index bd97977060..eca517bdbf 100644
--- a/Ginger/GingerCoreNET/Run/GingerExecutionEngine.cs
+++ b/Ginger/GingerCoreNET/Run/GingerExecutionEngine.cs
@@ -272,13 +272,13 @@ public GingerExecutionEngine(GingerRunner GingerRunner)
InitializeAccountReportExecutionLogger();
InitializeSealightReportExecutionLogger();
- if (WorkSpace.Instance!=null && WorkSpace.Instance.Solution!=null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
+ if (WorkSpace.Instance != null && WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.LoggerConfigurations != null)
{
WorkSpace.Instance.Solution.LoggerConfigurations.PublishToCentralizedDbChanged -= InitializeAccountReportExecutionLogger;
WorkSpace.Instance.Solution.LoggerConfigurations.PublishToCentralizedDbChanged += InitializeAccountReportExecutionLogger;
}
- if(WorkSpace.Instance != null && WorkSpace.Instance.Solution!=null && WorkSpace.Instance.Solution.SealightsConfiguration!=null)
+ if (WorkSpace.Instance != null && WorkSpace.Instance.Solution != null && WorkSpace.Instance.Solution.SealightsConfiguration != null)
{
WorkSpace.Instance.Solution.SealightsConfiguration.SealightsConfigChanged -= InitializeSealightReportExecutionLogger;
WorkSpace.Instance.Solution.SealightsConfiguration.SealightsConfigChanged += InitializeSealightReportExecutionLogger;
@@ -289,17 +289,17 @@ public void InitializeAccountReportExecutionLogger()
{
var accountReportExecutionLogger = RunListeners.Find((runListeners) => runListeners.GetType() == typeof(AccountReportExecutionLogger));
- if (mSelectedExecutionLoggerConfiguration != null
+ if (mSelectedExecutionLoggerConfiguration != null
&& mSelectedExecutionLoggerConfiguration.PublishLogToCentralDB == ePublishToCentralDB.Yes &&
accountReportExecutionLogger == null)
{
RunListeners.Add(new AccountReportExecutionLogger(mContext));
}
-
+
else if (
mSelectedExecutionLoggerConfiguration != null
&& mSelectedExecutionLoggerConfiguration.PublishLogToCentralDB == ePublishToCentralDB.No &&
- accountReportExecutionLogger!=null
+ accountReportExecutionLogger != null
)
{
RunListeners.Remove(accountReportExecutionLogger);
@@ -310,7 +310,7 @@ public void InitializeSealightReportExecutionLogger()
{
var seaLightReportExecutionLogger = RunListeners.Find((runListeners) => runListeners.GetType() == typeof(SealightsReportExecutionLogger));
- if(mSelectedExecutionLoggerConfiguration!=null &&
+ if (mSelectedExecutionLoggerConfiguration != null &&
WorkSpace.Instance.Solution.SealightsConfiguration.SealightsLog == Configurations.SealightsConfiguration.eSealightsLog.Yes &&
seaLightReportExecutionLogger == null
)
@@ -318,7 +318,7 @@ public void InitializeSealightReportExecutionLogger()
RunListeners.Add(new SealightsReportExecutionLogger(mContext));
}
- else if(
+ else if (
mSelectedExecutionLoggerConfiguration != null &&
WorkSpace.Instance.Solution.SealightsConfiguration.SealightsLog == Configurations.SealightsConfiguration.eSealightsLog.No &&
seaLightReportExecutionLogger != null
@@ -390,11 +390,11 @@ public Amdocs.Ginger.CoreNET.Execution.eRunStatus RunsetStatus
{
get
{
- if (!BusinessFlows.Any())
+ if (BusinessFlows.Count == 0)
{
return eRunStatus.Skipped;
}
- else if (BusinessFlows.Any(x=> x.RunStatus == eRunStatus.Stopped))
+ else if (BusinessFlows.Any(x => x.RunStatus == eRunStatus.Stopped))
{
return eRunStatus.Stopped;
}
@@ -406,11 +406,11 @@ public Amdocs.Ginger.CoreNET.Execution.eRunStatus RunsetStatus
{
return eRunStatus.Blocked;
}
- else if (BusinessFlows.Any() && BusinessFlows.Count(x=> x.RunStatus == eRunStatus.Skipped) == BusinessFlows.Count)
+ else if (BusinessFlows.Count != 0 && BusinessFlows.Count(x => x.RunStatus == eRunStatus.Skipped) == BusinessFlows.Count)
{
return eRunStatus.Skipped;
}
- else if (BusinessFlows.Any() && BusinessFlows.Count(x=> x.RunStatus == eRunStatus.Passed || x.RunStatus == eRunStatus.Skipped) == BusinessFlows.Count)
+ else if (BusinessFlows.Count != 0 && BusinessFlows.Count(x => x.RunStatus is eRunStatus.Passed or eRunStatus.Skipped) == BusinessFlows.Count)
{
return eRunStatus.Passed;
}
@@ -423,7 +423,7 @@ public Amdocs.Ginger.CoreNET.Execution.eRunStatus RunsetStatus
public void UpdateBusinessFlowsRunList()
{
List oldBFRuns = new(GingerRunner.BusinessFlowsRunList);
- List newBFRuns = new();
+ List newBFRuns = [];
foreach (BusinessFlow bf in BusinessFlows)
{
@@ -513,7 +513,7 @@ public void RunRunner(bool doContinueRun = false)
//Init
mGingerRunner.Status = eRunStatus.Started;
IsRunning = true;
- mStopRun = false;
+ mStopRun = false;
if (doContinueRun == false)
{
SetupVirtualAgents();
@@ -833,15 +833,15 @@ private void SetupVirtualAgents()
///
if (agent.SupportVirtualAgent() && runSetConfig.ActiveAgentListWithRunner.Where(entry => entry.Key != mGingerRunner.Guid).Select(y => y.Value).Where(y => y != null).Any(x => (x.Any(k => ((Agent)k).Guid == agent.Guid || (((Agent)k).ParentGuid != null && ((Agent)k).ParentGuid == agent.Guid)))))
{
- var virtualagent = agent.CreateCopy(true) as Agent;
- virtualagent.AgentOperations = new AgentOperations(virtualagent);
- virtualagent.ParentGuid = agent.Guid;
- virtualagent.Name = agent.Name + " Virtual";
- virtualagent.IsVirtual = true;
- virtualagent.DriverClass = agent.DriverClass;
- virtualagent.DriverType = agent.DriverType;
- applicationAgent.Agent = virtualagent;
- virtualagent.DriverConfiguration = agent.DriverConfiguration;
+ var virtualagent = agent.CreateCopy(true) as Agent;
+ virtualagent.AgentOperations = new AgentOperations(virtualagent);
+ virtualagent.ParentGuid = agent.Guid;
+ virtualagent.Name = agent.Name + " Virtual";
+ virtualagent.IsVirtual = true;
+ virtualagent.DriverClass = agent.DriverClass;
+ virtualagent.DriverType = agent.DriverType;
+ applicationAgent.Agent = virtualagent;
+ virtualagent.DriverConfiguration = agent.DriverConfiguration;
}
}
@@ -1119,11 +1119,11 @@ public List GetPossibleOutputVariables(RunSetConfig runSetConfig,
private BusinessFlowRun GetCurrenrtBusinessFlowRun()
{
- BusinessFlowRun businessFlowRun = GingerRunner.BusinessFlowsRunList.FirstOrDefault(x=> x.BusinessFlowInstanceGuid == CurrentBusinessFlow?.InstanceGuid);
+ BusinessFlowRun businessFlowRun = GingerRunner.BusinessFlowsRunList.FirstOrDefault(x => x.BusinessFlowInstanceGuid == CurrentBusinessFlow?.InstanceGuid);
if (businessFlowRun == null)
{
- businessFlowRun = GingerRunner.BusinessFlowsRunList.FirstOrDefault(x=> x.BusinessFlowGuid == CurrentBusinessFlow?.Guid);
+ businessFlowRun = GingerRunner.BusinessFlowsRunList.FirstOrDefault(x => x.BusinessFlowGuid == CurrentBusinessFlow?.Guid);
}
return businessFlowRun;
}
@@ -2002,7 +2002,7 @@ private static string EvaluateWebApiModelParameterValue(string valueToEvaluate,
if (item_toCompare.ValueForDriver != null)
{
return valueToEvaluate.Replace(item_toCompare.ItemName, item_toCompare.ValueForDriver);
- }
+ }
}
}
@@ -2267,7 +2267,7 @@ public void PrepActionValueExpression(Act act, BusinessFlow businessflow = null)
internal void PrepDynamicVariables()
{
- IEnumerable vars = CurrentBusinessFlow.GetAllHierarchyVariables().Where(v=>v.GetType() == typeof(VariableDynamic));
+ IEnumerable vars = CurrentBusinessFlow.GetAllHierarchyVariables().Where(v => v.GetType() == typeof(VariableDynamic));
foreach (VariableBase v in vars)
{
VariableDynamic vd = (VariableDynamic)v;
@@ -2277,17 +2277,23 @@ internal void PrepDynamicVariables()
private void ProcessScreenShot(Act act, GingerRunner.eActionExecutorType ActionExecutorType)
{
- string msg = string.Empty;
if (act.Status == Amdocs.Ginger.CoreNET.Execution.eRunStatus.Stopped)
{
- return;//user stopped it so no need screen shot
+ return;
+ }
+
+ // if action failed and user don't want screen shot on failure
+ if (act.Status == Amdocs.Ginger.CoreNET.Execution.eRunStatus.Failed && !act.AutoScreenShotOnFailure)
+ {
+ return;
}
if (ActionExecutorType == GingerRunner.eActionExecutorType.RunOnDriver)
{
if (act.TakeScreenShot || act.Status == Amdocs.Ginger.CoreNET.Execution.eRunStatus.Failed)
{
+ string msg;
try
{
if (act.WindowsToCapture == Act.eWindowsToCapture.DesktopScreen)
@@ -2312,9 +2318,6 @@ private void ProcessScreenShot(Act act, GingerRunner.eActionExecutorType ActionE
Reporter.ToLog(eLogLevel.WARN, msg);
act.ExInfo += msg;
}
-
-
-
else if (((AgentOperations)a.AgentOperations).Status != Agent.eStatus.Running)
{
msg = "Screen shot not captured because agent is not running for the action:'" + act.Description + "'";
@@ -2330,7 +2333,7 @@ private void ProcessScreenShot(Act act, GingerRunner.eActionExecutorType ActionE
{
foreach (string screenShot in screenShotAction.ScreenShots)
{
- act.ScreenShots.Add(screenShot);
+ act.ScreenShots.Add(screenShot);
}
foreach (string screenShotName in screenShotAction.ScreenShotsNames)
{
@@ -2365,8 +2368,7 @@ private void ProcessScreenShot(Act act, GingerRunner.eActionExecutorType ActionE
private void TakeDesktopScreenShotIntoAction(Act act)
{
- string msg = string.Empty;
-
+ string msg;
try
{
Dictionary screenShotsPaths = new Dictionary();
@@ -2655,7 +2657,7 @@ public void SetCurrentActivityAgent()
return;
}
- ApplicationAgent AA = (ApplicationAgent)mGingerRunner.ApplicationAgents.FirstOrDefault(x=> x.AppName.Equals(AppName));
+ ApplicationAgent AA = (ApplicationAgent)mGingerRunner.ApplicationAgents.FirstOrDefault(x => x.AppName.Equals(AppName));
if (AA == null || ((Agent)AA.Agent) == null)
{
@@ -3213,7 +3215,7 @@ private bool RunSharedRepositoryActivity(FlowControl fc)
sharedActivityInstance.AddDynamicly = true;
sharedActivityInstance.VariablesDependencies = CurrentBusinessFlow.CurrentActivity.VariablesDependencies;
eUserMsgSelection userSelection = eUserMsgSelection.None;
- CurrentBusinessFlow.MapTAToBF(userSelection, sharedActivityInstance, WorkSpace.Instance.Solution.ApplicationPlatforms,true);
+ CurrentBusinessFlow.MapTAToBF(userSelection, sharedActivityInstance, WorkSpace.Instance.Solution.ApplicationPlatforms, true);
int index = CurrentBusinessFlow.Activities.IndexOf(CurrentBusinessFlow.CurrentActivity) + 1;
ActivitiesGroup activitiesGroup = CurrentBusinessFlow.ActivitiesGroups.FirstOrDefault(x => x.Name == CurrentBusinessFlow.CurrentActivity.ActivitiesGroupID);
@@ -3319,7 +3321,7 @@ public void CalculateActionFinalStatus(Act act)
}
}
- int CountFail = act.ReturnValues.Count(x=>x.Status == ActReturnValue.eStatus.Failed);
+ int CountFail = act.ReturnValues.Count(x => x.Status == ActReturnValue.eStatus.Failed);
if (CountFail > 0)
{
act.Status = Amdocs.Ginger.CoreNET.Execution.eRunStatus.Failed;
@@ -3657,7 +3659,7 @@ private void SetMappedValuesToActivityVariables(Activity activity, Activity[] pr
Reporter.ToLog(eLogLevel.INFO, $"Mapping {GingerDicser.GetTermResValue(eTermResKey.Activity)} {GingerDicser.GetTermResValue(eTermResKey.Variables)} with customized values.");
- foreach(VariableBase mappedTargetVar in mappedTargetVars)
+ foreach (VariableBase mappedTargetVar in mappedTargetVars)
{
if (!Guid.TryParse(mappedTargetVar.MappedOutputValue, out Guid mappedSourceVarGuid))
{
@@ -3667,7 +3669,7 @@ private void SetMappedValuesToActivityVariables(Activity activity, Activity[] pr
Activity mappedSourceActivity = prevActivities
.FirstOrDefault(prevActivity => prevActivity.Guid == mappedTargetVar.VariableReferenceEntity);
-
+
if (mappedSourceActivity == null)
{
Reporter.ToLog(eLogLevel.ERROR, $"No Activity('{mappedTargetVar.VariableReferenceEntity}') found by id in {GingerDicser.GetTermResValue(eTermResKey.BusinessFlow)} before current {GingerDicser.GetTermResValue(eTermResKey.Activity)}({activity.Guid}-{activity.ActivityName}).");
@@ -3686,7 +3688,7 @@ private void SetMappedValuesToActivityVariables(Activity activity, Activity[] pr
}
Reporter.ToLog(eLogLevel.INFO, $"Setting value '{mappedSourceVar.Value}' from {GingerDicser.GetTermResValue(eTermResKey.Variable)}({mappedSourceVar.Guid}-{mappedSourceVar.Name}) to {GingerDicser.GetTermResValue(eTermResKey.Variable)}({mappedTargetVar.Guid}-{mappedTargetVar.Name}).");
-
+
bool wasValueSet = mappedTargetVar.SetValue(mappedSourceVar.Value);
if (!wasValueSet)
{
@@ -4946,7 +4948,7 @@ public void CloseAgents()
}
else
{
- foreach (ApplicationAgent p in mGingerRunner.ApplicationAgents.DistinctBy(x=>x.AgentID))
+ foreach (ApplicationAgent p in mGingerRunner.ApplicationAgents.DistinctBy(x => x.AgentID))
{
if (p.Agent != null)
{
@@ -5024,7 +5026,7 @@ public void UpdateApplicationAgents()
//we will trigger property change only if bTargetAppListModified=true
bool bTargetAppListModified = false;
- if (BusinessFlows.Any())// Run Tab
+ if (BusinessFlows.Count != 0)// Run Tab
{
foreach (BusinessFlow BF in BusinessFlows)
{
diff --git a/Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs b/Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs
index 3f17fb3426..d2ce467d6b 100644
--- a/Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs
+++ b/Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs
@@ -31,7 +31,7 @@ namespace Amdocs.Ginger.CoreNET
{
public class GingerRemoteExecutionUtils
{
- public List GetSolutionRunsetsExecutionInfo(Guid soluionGuid)
+ public List GetSolutionRunsetsExecutionInfo(Guid soluionGuid)
{
var runSetReports = new List();
var baseURI = GetReportDataServiceUrl();
@@ -61,8 +61,7 @@ public List GetSolutionRunsetsExecutionInfo(Guid soluionGuid)
}
return runSetReports;
}
-
- public List GetRunsetExecutionInfo(Guid soluionGuid, Guid runsetGuid)
+ public List GetRunsetExecutionInfo(Guid soluionGuid, Guid runsetGuid)
{
var runSetReports = new List();
var baseURI = GetReportDataServiceUrl();
@@ -93,7 +92,7 @@ public List GetRunsetExecutionInfo(Guid soluionGuid, Guid runsetGu
}
return runSetReports;
}
- private static string GetReportDataServiceUrl()
+ public static string GetReportDataServiceUrl()
{
var baseURI = WorkSpace.Instance.Solution.ExecutionLoggerConfigurationSetList.FirstOrDefault(x => (x.IsSelected)).CentralLoggerEndPointUrl;
@@ -103,7 +102,7 @@ private static string GetReportDataServiceUrl()
}
return baseURI;
}
- private List ConvertResponsInRunsetReport(string result)
+ private List ConvertResponsInRunsetReport(string result)
{
var runsetHLInfoResponses = JsonConvert.DeserializeObject>(result);
List runSetReports = new List();
@@ -143,7 +142,7 @@ public void GenerateHTMLReport(string executionGuid)
Reporter.ToUser(eUserMsgKey.StaticErrorMessage, "Centralized Html Report Service URL is missing in General Report Configurations.\nPlease go to Configurations > Reports > Execution Logger Configurations to configure the HTML Report URL");
}
}
- private static string GetReportHTMLServiceUrl()
+ public static string GetReportHTMLServiceUrl()
{
var baseURI = WorkSpace.Instance.Solution.ExecutionLoggerConfigurationSetList.FirstOrDefault(x => (x.IsSelected)).CentralizedHtmlReportServiceURL;
@@ -160,5 +159,5 @@ private static string GetReportHTMLServiceUrl()
}
return baseURI;
}
- }
+ }
}
diff --git a/Ginger/GingerCoreNETUnitTest/GingerCoreNETUnitTest.csproj b/Ginger/GingerCoreNETUnitTest/GingerCoreNETUnitTest.csproj
index 047a3a350c..9fd4e120e4 100644
--- a/Ginger/GingerCoreNETUnitTest/GingerCoreNETUnitTest.csproj
+++ b/Ginger/GingerCoreNETUnitTest/GingerCoreNETUnitTest.csproj
@@ -87,6 +87,7 @@
+
diff --git a/Ginger/GingerTest/GingerTest.csproj b/Ginger/GingerTest/GingerTest.csproj
index 8df5fc4fe6..b1629faf26 100644
--- a/Ginger/GingerTest/GingerTest.csproj
+++ b/Ginger/GingerTest/GingerTest.csproj
@@ -16,6 +16,7 @@
+
diff --git a/Ginger/GingerTest/Run/RunSetsExecutionsHistoryPageUnitTest.cs b/Ginger/GingerTest/Run/RunSetsExecutionsHistoryPageUnitTest.cs
new file mode 100644
index 0000000000..46252ea92e
--- /dev/null
+++ b/Ginger/GingerTest/Run/RunSetsExecutionsHistoryPageUnitTest.cs
@@ -0,0 +1,197 @@
+using Amdocs.Ginger.CoreNET.Application_Models.Execution.POM;
+using Ginger.Run;
+using GingerCore.Actions;
+using GingerCore.Drivers;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using static Ginger.Run.RunSetsExecutionsHistoryPage;
+
+namespace GingerTest.Run
+{
+ [TestClass]
+ public class RunSetsExecutionsHistoryPageUnitTest
+ {
+ ///
+ /// Test method to calculate the page range for the first page.
+ ///
+ [TestMethod]
+ public void CalculatePageRange_ShouldReturnCorrectRangeForFirstPage()
+ {
+ // Arrange
+ int start, end;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 25;
+ int currentCount = 25;
+ int expectedStart = 1;
+ int expectedEnd = 25;
+
+ // Act
+ RunSetsExecutionsHistoryPage.CalculatePageRange(ePageAction.firstPage, recordCount, totalEntries, itemsFetched, currentCount, out start, out end);
+
+ // Assert
+ Assert.AreEqual(expectedStart, start);
+ Assert.AreEqual(expectedEnd, end);
+ }
+
+ ///
+ /// Test method to calculate the page range for the next page.
+ ///
+ [TestMethod]
+ public void CalculatePageRange_ShouldReturnCorrectRangeForNextPage()
+ {
+ // Arrange
+ int start, end;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 50;
+ int currentCount = 25;
+ int expectedStart = 26;
+ int expectedEnd = 50;
+
+ // Act
+ RunSetsExecutionsHistoryPage.CalculatePageRange(ePageAction.nextPage, recordCount, totalEntries, itemsFetched, currentCount, out start, out end);
+
+ // Assert
+ Assert.AreEqual(expectedStart, start);
+ Assert.AreEqual(expectedEnd, end);
+ }
+
+ ///
+ /// Test method to calculate the page range for the previous page.
+ ///
+ [TestMethod]
+ public void CalculatePageRange_ShouldReturnCorrectRangeForPreviousPage()
+ {
+ // Arrange
+ int start, end;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 25;
+ int currentCount = 25;
+ int expectedStart = 1;
+ int expectedEnd = 25;
+
+ // Act
+ RunSetsExecutionsHistoryPage.CalculatePageRange(ePageAction.previousPage, recordCount, totalEntries, itemsFetched, currentCount, out start, out end);
+
+ // Assert
+ Assert.AreEqual(expectedStart, start);
+ Assert.AreEqual(expectedEnd, end);
+ }
+
+ ///
+ /// Test method to calculate the page range for the last page.
+ ///
+ [TestMethod]
+ public void CalculatePageRange_ShouldReturnCorrectRangeForLastPage()
+ {
+ // Arrange
+ int start, end;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 200;
+ int currentCount = 25;
+ int expectedStart = 176;
+ int expectedEnd = 200;
+
+ // Act
+ RunSetsExecutionsHistoryPage.CalculatePageRange(ePageAction.lastPage, recordCount, totalEntries, itemsFetched, currentCount, out start, out end);
+
+ // Assert
+ Assert.AreEqual(expectedStart, start);
+ Assert.AreEqual(expectedEnd, end);
+ }
+
+ ///
+ /// Test method to calculate the page number for the first page.
+ ///
+ [TestMethod]
+ public void CalculatePageNo_ShouldReturnCorrectRangeForFirstPage()
+ {
+ // Arrange
+ int start = 1;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 25;
+ int result;
+ int expectedPageNo = 1;
+
+ // Act
+ result = RunSetsExecutionsHistoryPage.CalculatePageNumber(ePageAction.firstPage, recordCount, totalEntries, itemsFetched, start);
+
+ // Assert
+ Assert.AreEqual(expectedPageNo, result);
+
+ }
+
+ ///
+ /// Test method to calculate the page number for the previous page.
+ ///
+ [TestMethod]
+ public void CalculatePageNo_ShouldReturnCorrectRangeForPreviousPage()
+ {
+ // Arrange
+ int start = 26;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 50;
+ int result;
+ int expectedPageNo = 2;
+
+ // Act
+ result = RunSetsExecutionsHistoryPage.CalculatePageNumber(ePageAction.previousPage, recordCount, totalEntries, itemsFetched, start);
+
+ // Assert
+ Assert.AreEqual(expectedPageNo, result);
+
+ }
+
+ ///
+ /// Test method to calculate the page number for the next page.
+ ///
+ [TestMethod]
+ public void CalculatePageNo_ShouldReturnCorrectRangeForNextPage()
+ {
+ // Arrange
+ int start = 51;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 75;
+ int result;
+ int expectedPageNo = 3;
+
+ // Act
+ result = RunSetsExecutionsHistoryPage.CalculatePageNumber(ePageAction.nextPage, recordCount, totalEntries, itemsFetched, start);
+
+ // Assert
+ Assert.AreEqual(expectedPageNo, result);
+
+ }
+
+ ///
+ /// Test method to calculate the page number for the last page.
+ ///
+ [TestMethod]
+ public void CalculatePageNo_ShouldReturnCorrectRangeForLastPage()
+ {
+ // Arrange
+ int start = 175;
+ int recordCount = 25;
+ int totalEntries = 200;
+ int itemsFetched = 200;
+ int result;
+ int expectedPageNo = 8;
+
+ // Act
+ result = RunSetsExecutionsHistoryPage.CalculatePageNumber(ePageAction.lastPage, recordCount, totalEntries, itemsFetched, start);
+
+ // Assert
+ Assert.AreEqual(expectedPageNo, result);
+
+ }
+
+ }
+}
+
+