Skip to content

Commit

Permalink
Merge branch 'Releases/Beta' into BugFix/EmptyGuid
Browse files Browse the repository at this point in the history
  • Loading branch information
Maheshkale447 authored Jun 26, 2024
2 parents bf0ff0e + 9c3616c commit 3379d94
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 27 deletions.
4 changes: 2 additions & 2 deletions Ginger/Ginger/Actions/ActionEditPages/ValidationDBPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
<Label x:Name="FreeSQLLabel" Style="{StaticResource @LabelStyle}" FontWeight="SemiBold" VerticalAlignment="Center" HorizontalAlignment="Left">Free SQL:</Label>
<usercontrols:ImageMakerControl x:Name="imgHelpSql" ToolTip="SELECT COUNT(1) FROM {Table} - Enter only Table name below (+optional WHERE clause)" Visibility="Collapsed" SetAsFontImageWithSize="12" ImageType="Info" Width="12" Height="12" FontWeight="SemiBold" Foreground="{StaticResource $BackgroundColor_DarkGray}" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="5,0,0,0">
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="0,0,0,0">
<Actions:UCValueExpression x:Name="SQLUCValueExpression" Width="550"/>
</StackPanel>
</Grid>
Expand Down Expand Up @@ -185,7 +185,7 @@
</Grid.ColumnDefinitions>
<Label Grid.Column="0" x:Name="lblWhere" Style="{StaticResource @LabelStyle}" FontWeight="SemiBold" VerticalAlignment="Center" HorizontalAlignment="Left">Where:</Label>

<TextBox Grid.Column="1" x:Name="txtWhere" Width="550" HorizontalAlignment="Left"></TextBox>
<TextBox Grid.Column="1" x:Name="txtWhere" Style="{StaticResource @TextBoxStyle}" Width="550" HorizontalAlignment="Left"></TextBox>
</Grid>
</StackPanel>
</StackPanel>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Amdocs.Ginger.Common.UIElement;
using amdocs.ginger.GingerCoreNET;
using Amdocs.Ginger.Common.UIElement;
using Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.Exceptions;
using Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.POM;
using Amdocs.Ginger.Repository;
using Applitools.Utils;
using GingerCore;
using GingerCore.Actions;
Expand Down Expand Up @@ -183,8 +185,12 @@ private Task<IEnumerable<IBrowserElement>> GetAllMatchingElementsAsync()
private async Task<IEnumerable<IBrowserElement>> GetAllMatchingElementsFromPOMAsync()
{
string locateValue = _act.ElementLocateValueForDriver;

POMLocatorParser pomLocatorParser = POMLocatorParser.Create(locateValue);
Func<Guid, ApplicationPOMModel> pomByIdProvider = WorkSpace
.Instance
.SolutionRepository
.GetRepositoryItemByGuid<ApplicationPOMModel>;

POMLocatorParser pomLocatorParser = POMLocatorParser.Create(locateValue, pomByIdProvider);
if (pomLocatorParser.ElementInfo == null)
{
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,62 @@
#nullable enable
namespace Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.POM
{
/// <summary>
/// Locate <see cref="ApplicationPOMModel"/> elements.
/// </summary>
/// <typeparam name="TElement">The type of elements to locate.</typeparam>
internal sealed class POMElementLocator<TElement>
{
/// <summary>
/// Delegate for locating elements based on primitive locators.
/// <br/><br/>
/// <b>NOTE</b><br/>
/// Only primitive locators like <see cref="eLocateBy.ByID"/>, <see cref="eLocateBy.ByXPath"/> etc. will be passed to this delegate. <br/>
/// Complex locators like <see cref="eLocateBy.POMElement"/> will not be passed.
/// </summary>
/// <param name="locateBy">The primitive locator type. </param>
/// <param name="locateValue">The value to locate the element.</param>
/// <returns>The located elements.</returns>
internal delegate Task<IEnumerable<TElement>> ElementsProvider(eLocateBy locateBy, string locateValue);

internal sealed class LocateResult
{
/// <summary>
/// Get or initialize the located elements.
/// </summary>
internal required IEnumerable<TElement> Elements { get; init; }

/// <summary>
/// Get or initialize a value indicating whether the POM was auto-updated during the locate operation.
/// </summary>
internal required bool WasAutoUpdated { get; init; }
}

internal sealed class Args
{
/// <summary>
/// Get or initialize the information about the element to locate.
/// </summary>
internal required ElementInfo ElementInfo { get; init; }

/// <summary>
/// Get or initialize the provider for locating elements.
/// </summary>
internal required ElementsProvider ElementsProvider { get; init; }

/// <summary>
/// Get or initialize the current business flow.
/// </summary>
internal required BusinessFlow BusinessFlow { get; init; }

/// <summary>
/// Get or initialize the current project environment.
/// </summary>
internal required ProjEnvironment Environment { get; init; }

/// <summary>
/// Get or initialize a value indicating whether the POM should be auto-updated during the locate operation.
/// </summary>
internal required bool AutoUpdatePOM { get; init; }
}

Expand All @@ -44,6 +83,10 @@ internal sealed class Args
private readonly BusinessFlow _businessFlow;
private readonly ProjEnvironment _environment;

/// <summary>
/// Initializes a new instance of <see cref="POMElementLocator{TElement}"/>.
/// </summary>
/// <param name="args">The arguments for initializing <see cref="POMElementLocator{TElement}"/>.</param>
internal POMElementLocator(Args args)
{
_autoUpdatePOM = args.AutoUpdatePOM;
Expand All @@ -53,20 +96,24 @@ internal POMElementLocator(Args args)
_environment = args.Environment;
}

/// <summary>
/// Locate POM elements. This method also tries to modify the POM if no elements are found initially and appropriate configurations are set via <see cref="Args"/>.
/// </summary>
/// <returns><see cref="LocateResult"/> containing the result of the locate operation.</returns>
internal async Task<LocateResult> LocateAsync()
{
IEnumerable<TElement>? elements = null;
bool wasAutoUpdated = false;

elements = await LocateAsync(_elementInfo.Locators);
elements = await GetElementsByLocators(_elementInfo.Locators);

bool noElementFound = elements == null || !elements.Any();

if (noElementFound && _autoUpdatePOM)
{
UpdatePOM();
wasAutoUpdated = true;
elements = await LocateAsync(_elementInfo.Locators);
elements = await GetElementsByLocators(_elementInfo.Locators);
}

if (elements == null)
Expand All @@ -81,7 +128,12 @@ internal async Task<LocateResult> LocateAsync()
};
}

private async Task<IEnumerable<TElement>> LocateAsync(IEnumerable<ElementLocator> locators)
/// <summary>
/// Get collection of <typeparamref name="TElement"/> matching any of the provided locators.
/// </summary>
/// <param name="locators">Collection of <see cref="ElementLocator"/> to search for.</param>
/// <returns>Collection of <typeparamref name="TElement"/> matching any of the provided locators</returns>
private async Task<IEnumerable<TElement>> GetElementsByLocators(IEnumerable<ElementLocator> locators)
{
IEnumerable<TElement>? elements = null;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
using amdocs.ginger.GingerCoreNET;
using Amdocs.Ginger.Common;
using Amdocs.Ginger.Common.SelfHealingLib;
using Amdocs.Ginger.Common.UIElement;
using Amdocs.Ginger.Common.UIElement;
using Amdocs.Ginger.Repository;
using GingerCore.Drivers.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

#nullable enable
namespace Amdocs.Ginger.CoreNET.Drivers.CoreDrivers.Web.POM
{
/// <summary>
/// Parses the POM locator value and provides access to the POM and element information.
/// </summary>
internal sealed class POMLocatorParser
{
/// <summary>
/// Id of the POM.
/// </summary>
internal Guid POMId { get; }

/// <summary>
/// POM model.
/// </summary>
internal ApplicationPOMModel? POM { get; }

/// <summary>
/// Id of the element.
/// </summary>
internal Guid ElementId { get; }

/// <summary>
/// Information about the identified element.
/// </summary>
internal ElementInfo? ElementInfo { get; }

internal static POMLocatorParser Create(string locatorValue)
{
Func<Guid, ApplicationPOMModel> pomProvider = WorkSpace.Instance.SolutionRepository.GetRepositoryItemByGuid<ApplicationPOMModel>;

return Create(locatorValue, pomProvider);
}

internal static POMLocatorParser Create(string locatorValue, Func<Guid, ApplicationPOMModel> pomProvider)
/// <summary>
/// Creates a new instance of <see cref="POMLocatorParser"/>.
/// </summary>
/// <param name="locatorValue">The POM element locator value.</param>
/// <param name="pomByIdProvider">The function to provide the <see cref="ApplicationPOMModel"/> based on the given id.</param>
/// <returns>A new instance of <see cref="POMLocatorParser"/>.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="locatorValue"/> is null or empty.</exception>
/// <exception cref="FormatException">Thrown when <paramref name="locatorValue"/> is an invalid POM locator or the POM id or element id is not valid.</exception>
internal static POMLocatorParser Create(string locatorValue, Func<Guid, ApplicationPOMModel?> pomByIdProvider)
{
if (string.IsNullOrEmpty(locatorValue))
{
Expand All @@ -48,7 +57,7 @@ internal static POMLocatorParser Create(string locatorValue, Func<Guid, Applicat
throw new FormatException($"'{ids[0]}' is not a valid POM id");
}

ApplicationPOMModel? pom = pomProvider(pomId);
ApplicationPOMModel? pom = pomByIdProvider(pomId);

if (!Guid.TryParse(ids[1], out Guid elementId))
{
Expand All @@ -61,7 +70,7 @@ internal static POMLocatorParser Create(string locatorValue, Func<Guid, Applicat
element = pom.MappedUIElements.FirstOrDefault(e => e != null && e.Guid == elementId);
}

return new(pomId, pom, elementId, element);
return new POMLocatorParser(pomId, pom, elementId, element);
}

private POMLocatorParser(Guid pomId, ApplicationPOMModel? pom, Guid elementId, ElementInfo? element)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace GingerCoreNETUnitTest.Drivers.CoreDrivers.Web.ActionHandlers
{
[TestClass]
[TestCategory(TestCategory.UnitTest)]
public class ActScreenShotHandlerUnitTests
public class ActScreenShotHandlerTests
{
[TestMethod]
public async Task HandleAsync_OnlyActiveWindow_OneScreenShotAddedToAction()
Expand Down
Loading

0 comments on commit 3379d94

Please sign in to comment.