Skip to content

Commit 308abff

Browse files
authored
Enhanced logging of elements search failure (#91)
* Enhanced logging of elements search failure
1 parent 95d6a61 commit 308abff

File tree

13 files changed

+89
-55
lines changed

13 files changed

+89
-55
lines changed

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

Lines changed: 10 additions & 5 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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected virtual IElementCacheHandler Cache
4545
{
4646
if (elementCacheHandler == null)
4747
{
48-
elementCacheHandler = new ElementCacheHandler(Locator, elementState, Finder);
48+
elementCacheHandler = new ElementCacheHandler(Locator, Name, elementState, Finder);
4949
}
5050

5151
return elementCacheHandler;
@@ -124,7 +124,7 @@ public virtual RemoteWebElement GetElement(TimeSpan? timeout = null)
124124
{
125125
return CacheConfiguration.IsEnabled
126126
? Cache.GetElement(timeout)
127-
: (RemoteWebElement) Finder.FindElement(Locator, elementState, timeout);
127+
: (RemoteWebElement) Finder.FindElement(Locator, elementState, timeout, Name);
128128
}
129129
catch (NoSuchElementException ex) when (LoggerConfiguration.LogPageSource)
130130
{

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ namespace Aquality.Selenium.Core.Elements
88
public class ElementCacheHandler : IElementCacheHandler
99
{
1010
private readonly By locator;
11+
private readonly string name;
1112
private readonly ElementState state;
1213
private readonly IElementFinder elementFinder;
1314

1415
private RemoteWebElement remoteElement;
1516

16-
public ElementCacheHandler(By locator, ElementState state, IElementFinder finder)
17+
public ElementCacheHandler(By locator, string name, ElementState state, IElementFinder finder)
1718
{
1819
this.locator = locator;
20+
this.name = name;
1921
this.state = state;
2022
elementFinder = finder;
2123
}
@@ -46,7 +48,7 @@ public RemoteWebElement GetElement(TimeSpan? timeout = null, ElementState? custo
4648

4749
if (IsRefreshNeeded(customState))
4850
{
49-
remoteElement = (RemoteWebElement)elementFinder.FindElement(locator, customState ?? state, timeout);
51+
remoteElement = (RemoteWebElement)elementFinder.FindElement(locator, customState ?? state, timeout, name);
5052
}
5153

5254
return remoteElement;

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,21 @@ public virtual IList<T> FindElements<T>(By locator, string name = null, ElementS
5656
switch (expectedCount)
5757
{
5858
case ElementsCount.Zero:
59-
ConditionalWait.WaitForTrue(() => !ElementFinder.FindElements(locator, state, TimeSpan.Zero).Any(),
60-
message: LocalizationManager.GetLocalizedMessage("loc.elements.found.but.should.not", locator.ToString(), state.ToString()));
59+
ConditionalWait.WaitForTrue(() => !ElementFinder.FindElements(locator, state, TimeSpan.Zero, name).Any(),
60+
message: LocalizationManager.GetLocalizedMessage("loc.elements.with.name.found.but.should.not", name, locator.ToString(), state.ToString()));
6161
break;
6262
case ElementsCount.MoreThenZero:
63-
ConditionalWait.WaitForTrue(() => ElementFinder.FindElements(locator, state, TimeSpan.Zero).Any(),
64-
message: LocalizationManager.GetLocalizedMessage("loc.no.elements.found.by.locator", locator.ToString()));
63+
ConditionalWait.WaitForTrue(() => ElementFinder.FindElements(locator, state, TimeSpan.Zero, name).Any(),
64+
message: LocalizationManager.GetLocalizedMessage("loc.no.elements.with.name.found.by.locator", name, locator.ToString()));
6565
break;
6666
case ElementsCount.Any:
67-
ConditionalWait.WaitFor(() => ElementFinder.FindElements(locator, state, TimeSpan.Zero) != null);
67+
ConditionalWait.WaitFor(() => ElementFinder.FindElements(locator, state, TimeSpan.Zero, name) != null);
6868
break;
6969
default:
7070
throw new ArgumentOutOfRangeException($"No such expected value: {expectedCount}");
7171
}
7272

73-
var webElements = ElementFinder.FindElements(locator, state, TimeSpan.Zero);
73+
var webElements = ElementFinder.FindElements(locator, state, TimeSpan.Zero, name);
7474
IEnumerable<T> elements = webElements.Select((webElement, index) =>
7575
{
7676
var elementIndex = index + 1;

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,44 @@ public ElementFinder(ILocalizedLogger logger, IConditionalWait conditionalWait)
2424

2525
private IConditionalWait ConditionalWait { get; }
2626

27-
public virtual IWebElement FindElement(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null)
27+
public virtual IWebElement FindElement(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null, string name = null)
2828
{
2929
var desiredState = ResolveState(state);
30-
return FindElement(locator, desiredState.ElementStateCondition, desiredState.StateName, timeout);
30+
return FindElement(locator, desiredState.ElementStateCondition, desiredState.StateName, timeout, name);
3131
}
3232

33-
public virtual IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null)
33+
public virtual IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null, string name = null)
3434
{
35-
return FindElement(locator, elementStateCondition, "desired", timeout);
35+
return FindElement(locator, elementStateCondition, "desired", timeout, name);
3636
}
3737

38-
public virtual IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, string stateName, TimeSpan? timeout = null)
38+
public virtual IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, string stateName, TimeSpan? timeout = null, string name = null)
3939
{
4040
var desiredState = new DesiredState(elementStateCondition, stateName)
4141
{
4242
IsCatchingTimeoutException = false,
4343
IsThrowingNoSuchElementException = true
4444
};
45-
return FindElements(locator, desiredState, timeout).First();
45+
return FindElements(locator, desiredState, timeout, name).First();
4646
}
4747

48-
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null)
48+
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null, string name = null)
4949
{
5050
var elementStateCondition = ResolveState(state);
5151
elementStateCondition.IsCatchingTimeoutException = true;
52-
return FindElements(locator, elementStateCondition, timeout);
52+
return FindElements(locator, elementStateCondition, timeout, name);
5353
}
5454

55-
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null)
55+
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null, string name = null)
5656
{
5757
var desiredState = new DesiredState(elementStateCondition, "desired")
5858
{
59-
IsCatchingTimeoutException = true
59+
IsCatchingTimeoutException = true,
6060
};
61-
return FindElements(locator, desiredState, timeout);
61+
return FindElements(locator, desiredState, timeout, name);
6262
}
6363

64-
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null)
64+
public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null, string name = null)
6565
{
6666
var foundElements = new List<IWebElement>();
6767
var resultElements = new List<IWebElement>();
@@ -76,14 +76,16 @@ public virtual ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredS
7676
}
7777
catch (WebDriverTimeoutException ex)
7878
{
79-
HandleTimeoutException(ex, desiredState, locator, foundElements);
79+
HandleTimeoutException(ex, desiredState, locator, foundElements, name);
8080
}
8181
return resultElements.AsReadOnly();
8282
}
8383

84-
protected virtual void HandleTimeoutException(WebDriverTimeoutException ex, DesiredState desiredState, By locator, List<IWebElement> foundElements)
84+
protected virtual void HandleTimeoutException(WebDriverTimeoutException ex, DesiredState desiredState, By locator, List<IWebElement> foundElements, string name = null)
8585
{
86-
var message = $"No elements with locator '{locator.ToString()}' were found in {desiredState.StateName} state";
86+
var message = string.IsNullOrEmpty(name)
87+
? $"No elements with locator '{locator}' were found in {desiredState.StateName} state"
88+
: $"Element [{name}] was not found by locator '{locator}' in {desiredState.StateName} state";
8789
if (desiredState.IsCatchingTimeoutException)
8890
{
8991
if (!foundElements.Any())
@@ -101,12 +103,11 @@ protected virtual void HandleTimeoutException(WebDriverTimeoutException ex, Desi
101103
}
102104
else
103105
{
104-
var combinedMessage = $"{ex.Message}: {message}";
105106
if (desiredState.IsThrowingNoSuchElementException && !foundElements.Any())
106107
{
107-
throw new NoSuchElementException(combinedMessage);
108+
throw new NoSuchElementException($"{message}: {ex.Message}");
108109
}
109-
throw new WebDriverTimeoutException(combinedMessage);
110+
throw new WebDriverTimeoutException($"{ex.Message}: {message}");
110111
}
111112
}
112113

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,50 @@ public interface IElementFinder
1616
/// <param name="locator">element locator</param>
1717
/// <param name="state">desired ElementState</param>
1818
/// <param name="timeout">timeout for search</param>
19+
/// <param name="name">element name to be used for logging and exception message</param>
1920
/// <exception cref="NoSuchElementException">Thrown if element was not found in time in desired state</exception>
2021
/// <returns>Found element</returns>
21-
IWebElement FindElement(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null);
22+
IWebElement FindElement(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null, string name = null);
2223

2324
/// <summary>
2425
/// Finds element in state defined by predicate.
2526
/// </summary>
2627
/// <param name="locator">elements locator</param>
2728
/// <param name="elementStateCondition">predicate to define element state</param>
2829
/// <param name="timeout">timeout for search</param>
30+
/// <param name="name">element name to be used for logging and exception message</param>
2931
/// <exception cref="NoSuchElementException">Thrown if element was not found in time in desired state</exception>
3032
/// <returns>Found element</returns>
31-
IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null);
33+
IWebElement FindElement(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null, string name = null);
3234

3335
/// <summary>
3436
/// Finds elements in desired ElementState.
3537
/// </summary>
3638
/// <param name="locator">elements locator</param>
3739
/// <param name="state">desired ElementState</param>
3840
/// <param name="timeout">timeout for search</param>
41+
/// <param name="name">elements' name to be used for logging and exception message</param>
3942
/// <returns>List of found elements</returns>
40-
ReadOnlyCollection<IWebElement> FindElements(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null);
43+
ReadOnlyCollection<IWebElement> FindElements(By locator, ElementState state = ElementState.ExistsInAnyState, TimeSpan? timeout = null, string name = null);
4144

4245
/// <summary>
4346
/// Finds elements in state defined by predicate.
4447
/// </summary>
4548
/// <param name="locator">elements locator</param>
4649
/// <param name="elementStateCondition">predicate to define elements state</param>
4750
/// <param name="timeout">timeout for search</param>
51+
/// <param name="name">elements' name to be used for logging and exception message</param>
4852
/// <returns>List of found elements</returns>
49-
ReadOnlyCollection<IWebElement> FindElements(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null);
53+
ReadOnlyCollection<IWebElement> FindElements(By locator, Func<IWebElement, bool> elementStateCondition, TimeSpan? timeout = null, string name = null);
5054

5155
/// <summary>
5256
/// Finds elements in state defined by desired state.
5357
/// </summary>
5458
/// <param name="locator">elements locator</param>
5559
/// <param name="desiredState">desired elements state</param>
5660
/// <param name="timeout">timeout for search</param>
61+
/// <param name="name">elements' name to be used for logging and exception message</param>
5762
/// <returns>List of found elements</returns>
58-
ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null);
63+
ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null, string name = null);
5964
}
6065
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public RelativeElementFinder(ILocalizedLogger logger, IConditionalWait condition
2525

2626
private Func<ISearchContext> SearchContextSupplier { get; }
2727

28-
public override ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null)
28+
public override ReadOnlyCollection<IWebElement> FindElements(By locator, DesiredState desiredState, TimeSpan? timeout = null, string name = null)
2929
{
3030
var foundElements = new List<IWebElement>();
3131
var resultElements = new List<IWebElement>();
@@ -40,7 +40,7 @@ public override ReadOnlyCollection<IWebElement> FindElements(By locator, Desired
4040
}
4141
catch (TimeoutException ex)
4242
{
43-
HandleTimeoutException(new WebDriverTimeoutException(ex.Message, ex), desiredState, locator, foundElements);
43+
HandleTimeoutException(new WebDriverTimeoutException(ex.Message, ex), desiredState, locator, foundElements, name);
4444
}
4545
return resultElements.AsReadOnly();
4646
}

0 commit comments

Comments
 (0)