Skip to content

Commit ad787d6

Browse files
authored
Add optional parameter to Factory methods to set custom element's name (#42)
1 parent 02b4f40 commit ad787d6

File tree

7 files changed

+118
-63
lines changed

7 files changed

+118
-63
lines changed

Aquality.Selenium.Core/src/Aquality.Selenium.Core/Aquality.Selenium.Core.xml

Lines changed: 28 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Aquality.Selenium.Core/src/Aquality.Selenium.Core/Elements/Element.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public void Click()
5252
DoWithRetry(() => GetElement().Click());
5353
}
5454

55-
public T FindChildElement<T>(By childLocator, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement
55+
public T FindChildElement<T>(By childLocator, string name = null, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement
5656
{
57-
return Factory.FindChildElement(this, childLocator, supplier, state);
57+
return Factory.FindChildElement(this, childLocator, name, supplier, state);
5858
}
5959

6060
public string GetAttribute(string attr)
@@ -71,11 +71,24 @@ public virtual RemoteWebElement GetElement(TimeSpan? timeout = null)
7171
}
7272
catch (NoSuchElementException ex)
7373
{
74-
Logger.Debug($"Page source:{Environment.NewLine}{Application.Driver.PageSource}", ex);
74+
LogPageSource(ex);
7575
throw;
7676
}
7777
}
7878

79+
private void LogPageSource(WebDriverException exception)
80+
{
81+
try
82+
{
83+
Logger.Debug($"Page source:{Environment.NewLine}{Application.Driver.PageSource}", exception);
84+
}
85+
catch (WebDriverException e)
86+
{
87+
Logger.Error(exception.Message);
88+
Logger.Fatal("An exception occured while tried to save the page source", e);
89+
}
90+
}
91+
7992
public string Text
8093
{
8194
get

Aquality.Selenium.Core/src/Aquality.Selenium.Core/Elements/ElementFactory.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ public ElementFactory(ConditionalWait conditionalWait, IElementFinder elementFin
3737
/// <returns>Dictionary where key is interface and value is its implementation.</returns>
3838
protected virtual IDictionary<Type, Type> ElementTypesMap => new Dictionary<Type, Type>();
3939

40-
public virtual T FindChildElement<T>(IElement parentElement, By childLocator, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement
40+
public virtual T FindChildElement<T>(IElement parentElement, By childLocator, string name = null, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement
4141
{
4242
var elementSupplier = ResolveSupplier(supplier);
43-
return elementSupplier(new ByChained(parentElement.Locator, childLocator), $"Child element of {parentElement.Name}", state);
43+
return elementSupplier(new ByChained(parentElement.Locator, childLocator), name ?? $"Child element of {parentElement.Name}", state);
4444
}
4545

46-
public virtual IList<T> FindElements<T>(By locator, ElementSupplier<T> supplier = null, ElementsCount expectedCount = ElementsCount.Any, ElementState state = ElementState.Displayed) where T : IElement
46+
public virtual IList<T> FindElements<T>(By locator, string name = null, ElementSupplier<T> supplier = null, ElementsCount expectedCount = ElementsCount.Any, ElementState state = ElementState.Displayed) where T : IElement
4747
{
4848
var elementSupplier = ResolveSupplier(supplier);
4949
switch (expectedCount)
@@ -67,7 +67,8 @@ public virtual IList<T> FindElements<T>(By locator, ElementSupplier<T> supplier
6767
IEnumerable<T> elements = webElements.Select((webElement, index) =>
6868
{
6969
var elementIndex = index + 1;
70-
return elementSupplier(GenerateXpathLocator(locator, webElement, elementIndex), $"element {elementIndex}", state);
70+
var elementName = $"{name ?? "element"} {elementIndex}";
71+
return elementSupplier(GenerateXpathLocator(locator, webElement, elementIndex), elementName, state);
7172
});
7273
return elements.ToList();
7374
}
Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using OpenQA.Selenium;
2+
using System;
23
using System.Collections.Generic;
34

45
namespace Aquality.Selenium.Core.Elements.Interfaces
@@ -9,38 +10,40 @@ namespace Aquality.Selenium.Core.Elements.Interfaces
910
public interface IElementFactory
1011
{
1112
/// <summary>
12-
/// Create custom element according to passed parameters
13+
/// Create custom element according to passed parameters.
1314
/// </summary>
14-
/// <typeparam name="T">Type of the target element</typeparam>
15-
/// <param name="elementSupplier">Delegate that defines constructor of element</param>
16-
/// <param name="locator">Locator of the target element</param>
17-
/// <param name="name">Name of the target element</param>
18-
/// <param name="state">State of the target element</param>
19-
/// <returns>Instance of custom element</returns>
15+
/// <typeparam name="T">Type of the target element.</typeparam>
16+
/// <param name="elementSupplier">Delegate that defines constructor of element.</param>
17+
/// <param name="locator">Locator of the target element.</param>
18+
/// <param name="name">Name of the target element.</param>
19+
/// <param name="state">State of the target element.</param>
20+
/// <returns>Instance of custom element.</returns>
2021
T GetCustomElement<T>(ElementSupplier<T> elementSupplier, By locator, string name, ElementState state = ElementState.Displayed) where T : IElement;
2122

2223
/// <summary>
2324
/// Finds child element by its locator relative to parent element.
2425
/// </summary>
25-
/// <typeparam name="T">Type of child element that has to implement IElement</typeparam>
26-
/// <param name="parentElement">Parent element</param>
27-
/// <param name="childLocator">Locator of child element relative to its parent</param>
28-
/// <param name="supplier">Delegate that defines constructor of element in case of custom element</param>
29-
/// <param name="state">Child element state</param>
30-
/// <exception cref="System.InvalidOperationException">Thrown when the supplier is null, and no constructor with required arguments was found.</exception>
26+
/// <typeparam name="T">Type of child element that has to implement IElement.</typeparam>
27+
/// <param name="parentElement">Parent element.</param>
28+
/// <param name="childLocator">Locator of child element relative to its parent.</param>
29+
/// <param name="supplier">Delegate that defines constructor of element in case of custom element.</param>
30+
/// <param name="state">Child element state.</param>
31+
/// <param name="name">Child element name.</param>
32+
/// <exception cref="InvalidOperationException">Thrown when the supplier is null, and no constructor with required arguments was found.</exception>
3133
/// <returns>Instance of child element</returns>
32-
T FindChildElement<T>(IElement parentElement, By childLocator, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement;
34+
T FindChildElement<T>(IElement parentElement, By childLocator, string name = null, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement;
3335

3436
/// <summary>
3537
/// Finds list of elements by base locator.
3638
/// </summary>
37-
/// <typeparam name="T">Type of elements that have to implement IElement</typeparam>
38-
/// <param name="locator">Base elements locator</param>
39-
/// <param name="supplier">Delegate that defines constructor of element in case of custom elements</param>
40-
/// <param name="expectedCount">Expected number of elements that have to be found (zero, more then zero, any)</param>
41-
/// <param name="state">Elements state</param>
42-
/// <exception cref="System.InvalidOperationException">Thrown when the supplier is null, and no constructor with required arguments was found.</exception>
43-
/// <returns>List of elements that found by locator</returns>
44-
IList<T> FindElements<T>(By locator, ElementSupplier<T> supplier = null, ElementsCount expectedCount = ElementsCount.Any, ElementState state = ElementState.Displayed) where T : IElement;
39+
/// <typeparam name="T">Type of elements that have to implement IElement.</typeparam>
40+
/// <param name="locator">Base elements locator.</param>
41+
/// <param name="supplier">Delegate that defines constructor of element in case of custom elements.</param>
42+
/// <param name="expectedCount">Expected number of elements that have to be found (zero, more then zero, any).</param>
43+
/// <param name="state">Elements state.</param>
44+
/// <param name="name">Elements name.</param>
45+
/// <exception cref="InvalidOperationException">Thrown when the supplier is null, and no constructor with required arguments was found.</exception>
46+
/// <returns>List of elements that found by locator.</returns>
47+
IList<T> FindElements<T>(By locator, string name = null, ElementSupplier<T> supplier = null, ElementsCount expectedCount = ElementsCount.Any, ElementState state = ElementState.Displayed) where T : IElement;
4548
}
4649
}

Aquality.Selenium.Core/src/Aquality.Selenium.Core/Elements/Interfaces/IParent.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ public interface IParent
1010
/// <summary>
1111
/// Finds child element of current element by its locator.
1212
/// </summary>
13-
/// <typeparam name="T">Type of child element that has to implement IElement</typeparam>
13+
/// <typeparam name="T">Type of child element that has to implement IElement.</typeparam>
1414
/// <param name="childLocator">Locator of child element.</param>
15-
/// <param name="supplier">Delegate that defines constructor of child element in case of custom element</param>
16-
/// <param name="state">Child element state</param>
17-
/// <returns>Instance of child element</returns>
18-
T FindChildElement<T>(By childLocator, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement;
15+
/// <param name="name">Child element name.</param>
16+
/// <param name="supplier">Delegate that defines constructor of child element in case of custom element.</param>
17+
/// <param name="state">Child element state.</param>
18+
/// <returns>Instance of child element.</returns>
19+
T FindChildElement<T>(By childLocator, string name = null, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement;
1920
}
2021
}

Aquality.Selenium.Core/tests/Aquality.Selenium.Core.Tests/Applications/WindowsApp/ElementFactoryTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,40 @@ public void Should_FindElements_ViaElementFactory()
3737
Assert.IsTrue(Factory.FindButtons(By.XPath("//*")).Count > 1);
3838
}
3939

40+
[Test]
41+
public void Should_FindElements_WithCustomName_ViaElementFactory()
42+
{
43+
const string name = "Custom Name";
44+
var buttons = Factory.FindButtons(By.XPath("//*"), name);
45+
Assert.Multiple(() =>
46+
{
47+
Assert.IsTrue(buttons.Count > 1);
48+
for (var i = 0; i < buttons.Count; i++)
49+
{
50+
var button = buttons[i];
51+
StringAssert.StartsWith(name, button.Name);
52+
StringAssert.EndsWith((i + 1).ToString(), button.Name);
53+
}
54+
});
55+
}
56+
57+
[Test]
58+
public void Should_FindElements_WithDefaultName_ViaElementFactory()
59+
{
60+
var buttons = Factory.FindButtons(By.XPath("//*"));
61+
Assert.Multiple(() =>
62+
{
63+
Assert.IsTrue(buttons.Count > 1);
64+
for (var i = 0; i < buttons.Count; i++)
65+
{
66+
var button = buttons[i];
67+
var endOfName = (i + 1).ToString();
68+
StringAssert.AreNotEqualIgnoringCase(endOfName, button.Name);
69+
StringAssert.EndsWith(endOfName, button.Name);
70+
}
71+
});
72+
}
73+
4074
[Test]
4175
public void Should_ThrowInvalidOperationException_WhenConstructorIsNotDefined_ForFindChildElement()
4276
{

Aquality.Selenium.Core/tests/Aquality.Selenium.Core.Tests/Applications/WindowsApp/Elements/ElementFactoryExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ public static Button GetButton(this IElementFactory elementFactory, By elementLo
1212
return elementFactory.GetCustomElement(GetButtonSupplier(), elementLocator, elementName);
1313
}
1414

15-
public static Button FindChildButton(this IElementFactory elementFactory, IElement parentElement, By elementLocator)
15+
public static Button FindChildButton(this IElementFactory elementFactory, IElement parentElement, By elementLocator, string name = null)
1616
{
17-
return elementFactory.FindChildElement(parentElement, elementLocator, GetButtonSupplier());
17+
return elementFactory.FindChildElement(parentElement, elementLocator, name, GetButtonSupplier());
1818
}
1919

20-
public static IList<Button> FindButtons(this IElementFactory elementFactory, By elementLocator, ElementsCount elementsCount = ElementsCount.MoreThenZero)
20+
public static IList<Button> FindButtons(this IElementFactory elementFactory, By elementLocator, string name = null, ElementsCount elementsCount = ElementsCount.MoreThenZero)
2121
{
22-
return elementFactory.FindElements(elementLocator, GetButtonSupplier(), elementsCount);
22+
return elementFactory.FindElements(elementLocator, name: name, GetButtonSupplier(), elementsCount);
2323
}
2424

2525
private static ElementSupplier<Button> GetButtonSupplier()

0 commit comments

Comments
 (0)