Skip to content

Commit 42e72bb

Browse files
mialeskapaveliam
authored andcommitted
move IsClickable and IsEnabled with waitings to ElementStateProvider (#40)
* move IsClickable and IsEnabled with waitings to ElementStateProvider resolves #39 * renamed private methods and make ElementState private field * add WaitForNotClickable and WaitForNotEnabled to IElementStateProvider * remove ContainsClassAttribute method and IElementWithState interface (merged to IElement)
1 parent f79b743 commit 42e72bb

File tree

5 files changed

+91
-66
lines changed

5 files changed

+91
-66
lines changed

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

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ namespace Aquality.Selenium.Elements
1313
/// Defines base class for any UI element.
1414
/// </summary>
1515
public abstract class Element : IElement
16-
{
16+
{
17+
private readonly ElementState elementState;
18+
1719
protected Element(By locator, string name, ElementState state)
1820
{
1921
Locator = locator;
2022
Name = name;
21-
ElementState = state;
23+
elementState = state;
2224
}
2325

2426
public By Locator { get; }
2527

2628
public string Name { get; }
2729

28-
public ElementState ElementState { get; }
29-
3030
protected abstract string ElementType { get; }
3131

3232
public JsActions JsActions => new JsActions(this, ElementType);
@@ -43,17 +43,11 @@ protected Element(By locator, string name, ElementState state)
4343

4444
private IElementFactory ElementFactory => new ElementFactory();
4545

46-
public bool IsEnabled(TimeSpan? timeout = null)
47-
{
48-
bool isElementEnabled(IWebElement element) => element.Enabled && !element.GetAttribute(Attributes.Class).Contains(PopularClassNames.Disabled);
49-
return Finder.FindElements(Locator, isElementEnabled, timeout).Count != 0;
50-
}
51-
5246
public RemoteWebElement GetElement(TimeSpan? timeout = null)
5347
{
5448
try
5549
{
56-
return (RemoteWebElement)Finder.FindElement(Locator, ElementState, timeout);
50+
return (RemoteWebElement)Finder.FindElement(Locator, elementState, timeout);
5751
}
5852
catch (NoSuchElementException ex)
5953
{
@@ -70,7 +64,7 @@ public void ClickAndWait()
7064

7165
public void WaitAndClick()
7266
{
73-
WaitForElementIsClickable();
67+
State.WaitForClickable();
7468
Click();
7569
}
7670

@@ -127,20 +121,10 @@ public void SetInnerHtml(string value)
127121
Logger.InfoLoc("loc.send.text", value);
128122
Browser.ExecuteScript(JavaScript.SetInnerHTML, GetElement(), value);
129123
}
130-
131-
public void WaitForElementIsClickable(TimeSpan? timeout = null)
132-
{
133-
Finder.FindElements(Locator, element => element.Displayed && element.Enabled, timeout);
134-
}
135124

136125
public T FindChildElement<T>(By childLocator, ElementSupplier<T> supplier = null, ElementState state = ElementState.Displayed) where T : IElement
137126
{
138127
return ElementFactory.FindChildElement(this, childLocator, supplier, state);
139128
}
140-
141-
public bool ContainsClassAttribute(string className)
142-
{
143-
return GetAttribute(Attributes.Class).Contains(className.ToLower());
144-
}
145129
}
146130
}

Aquality.Selenium/src/Aquality.Selenium/Elements/ElementStateProvider.cs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Aquality.Selenium.Waitings;
33
using OpenQA.Selenium;
44
using System;
5-
using System.Collections.ObjectModel;
65
using System.Linq;
76

87
namespace Aquality.Selenium.Elements
@@ -19,30 +18,60 @@ internal ElementStateProvider(By elementLocator)
1918
public bool IsDisplayed => WaitForDisplayed(TimeSpan.Zero);
2019

2120
public bool IsExist => WaitForExist(TimeSpan.Zero);
22-
23-
public bool WaitForDisplayed(TimeSpan? timeout = null)
21+
22+
public bool IsClickable => WaitForClickable(TimeSpan.Zero);
23+
24+
public bool IsEnabled => WaitForEnabled(TimeSpan.Zero);
25+
26+
public bool WaitForClickable(TimeSpan? timeout = null)
2427
{
25-
return FindElements(timeout, ElementState.Displayed).Any();
28+
return IsAnyElementFound(timeout, element => element.Displayed && element.Enabled);
2629
}
2730

28-
public bool WaitForExist(TimeSpan? timeout = null)
31+
public bool WaitForNotClickable(TimeSpan? timeout = null)
2932
{
30-
return FindElements(timeout, ElementState.ExistsInAnyState).Any();
33+
return ConditionalWait.WaitForTrue(driver => !IsClickable, timeout);
34+
}
35+
36+
public bool WaitForDisplayed(TimeSpan? timeout = null)
37+
{
38+
return IsAnyElementFound(timeout, ElementState.Displayed);
3139
}
3240

3341
public bool WaitForNotDisplayed(TimeSpan? timeout = null)
3442
{
3543
return ConditionalWait.WaitForTrue(driver => !IsDisplayed, timeout);
3644
}
3745

46+
public bool WaitForEnabled(TimeSpan? timeout = null)
47+
{
48+
bool isElementEnabled(IWebElement element) => element.Enabled && !element.GetAttribute(Attributes.Class).Contains(PopularClassNames.Disabled);
49+
return IsAnyElementFound(timeout, isElementEnabled);
50+
}
51+
52+
public bool WaitForNotEnabled(TimeSpan? timeout = null)
53+
{
54+
return ConditionalWait.WaitForTrue(driver => !IsEnabled, timeout);
55+
}
56+
57+
public bool WaitForExist(TimeSpan? timeout = null)
58+
{
59+
return IsAnyElementFound(timeout, ElementState.ExistsInAnyState);
60+
}
61+
3862
public bool WaitForNotExist(TimeSpan? timeout = null)
3963
{
4064
return ConditionalWait.WaitForTrue(driver => !IsExist, timeout);
4165
}
4266

43-
private ReadOnlyCollection<IWebElement> FindElements(TimeSpan? timeout, ElementState state)
67+
private bool IsAnyElementFound(TimeSpan? timeout, ElementState state)
68+
{
69+
return ElementFinder.Instance.FindElements(elementLocator, state, timeout).Any();
70+
}
71+
72+
private bool IsAnyElementFound(TimeSpan? timeout, Func<IWebElement, bool> elementStateCondition)
4473
{
45-
return ElementFinder.Instance.FindElements(elementLocator, state, timeout);
74+
return ElementFinder.Instance.FindElements(elementLocator, elementStateCondition, timeout).Any();
4675
}
4776
}
4877
}

Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/IElement.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Aquality.Selenium.Elements.Interfaces
88
/// <summary>
99
/// Describes behavior of any UI element.
1010
/// </summary>
11-
public interface IElement : IParent, IElementWithState
11+
public interface IElement : IParent
1212
{
1313
/// <summary>
1414
/// Gets JavaScript actions that can be performed with an element.
@@ -22,6 +22,12 @@ public interface IElement : IParent, IElementWithState
2222
/// <value>Instance of <see cref="Aquality.Selenium.Elements.Actions.MouseActions"/></value>
2323
MouseActions MouseActions { get; }
2424

25+
/// <summary>
26+
/// Gets element state.
27+
/// </summary>
28+
/// <value>Instance of <see cref="Aquality.Selenium.Elements.Interfaces.IElementStateProvider"/></value>
29+
IElementStateProvider State { get; }
30+
2531
/// <summary>
2632
/// Unique locator of element.
2733
/// </summary>
@@ -41,13 +47,6 @@ public interface IElement : IParent, IElementWithState
4147
/// <returns>Instance of <see cref="OpenQA.Selenium.Remote.RemoteWebElement"/> if found.</returns>
4248
/// <exception cref="OpenQA.Selenium.NoSuchElementException">Thrown when no elements found.</exception>
4349
RemoteWebElement GetElement(TimeSpan? timeout = null);
44-
45-
/// <summary>
46-
/// Gets element Enabled state. Checks that element is Enabled and does not have "disabled" class.
47-
/// </summary>
48-
/// <param name="timeout">Timeout to get state. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
49-
/// <returns>True if enabled and false otherwise.</returns>
50-
bool IsEnabled(TimeSpan? timeout = null);
5150

5251
/// <summary>
5352
/// Gets element text.
@@ -69,13 +68,7 @@ public interface IElement : IParent, IElementWithState
6968
/// Sends keys to element.
7069
/// </summary>
7170
/// <param name="key">Key to send.</param>
72-
void SendKeys(string key);
73-
74-
/// <summary>
75-
/// Waits for element is clickable which means element is displayed and enabled.
76-
/// </summary>
77-
/// <param name="timeout">Timeout for wait. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
78-
void WaitForElementIsClickable(TimeSpan? timeout = null);
71+
void SendKeys(string key);
7972

8073
/// <summary>
8174
/// Clicks the element.

Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/IElementStateProvider.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ public interface IElementStateProvider
2020
/// <value>True if element exists in DOM (without visibility check) and false otherwise</value>
2121
bool IsExist { get; }
2222

23+
/// <summary>
24+
/// Gets element's clickable state, which means element is displayed and enabled.
25+
/// </summary>
26+
/// <value>True if element is clickable, false otherwise</value>
27+
bool IsClickable { get; }
28+
29+
/// <summary>
30+
/// Gets element's Enabled state, which means element is Enabled and does not have "disabled" class.
31+
/// </summary>
32+
/// <value>True if enabled, false otherwise.</value>
33+
bool IsEnabled { get; }
34+
2335
/// <summary>
2436
/// Waits for element is displayed on the page.
2537
/// </summary>
@@ -47,5 +59,33 @@ public interface IElementStateProvider
4759
/// <param name="timeout">Timeout for waiting. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
4860
/// <returns>true if element does not exist after waiting, false otherwise</returns>
4961
bool WaitForNotExist(TimeSpan? timeout = null);
62+
63+
/// <summary>
64+
/// Waits for element is clickable which means element is displayed and enabled.
65+
/// </summary>
66+
/// <param name="timeout">Timeout for wait. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
67+
/// <returns>true if element is clickable after waiting, false otherwise</returns>
68+
bool WaitForClickable(TimeSpan? timeout = null);
69+
70+
/// <summary>
71+
/// Waits for element is not clickable which means element is not displayed or not enabled.
72+
/// </summary>
73+
/// <param name="timeout">Timeout for wait. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
74+
/// <returns>true if element is not clickable after waiting, false otherwise</returns>
75+
bool WaitForNotClickable(TimeSpan? timeout = null);
76+
77+
/// <summary>
78+
/// Waits for element is enabled state which means element is Enabled and does not have "disabled" class.
79+
/// </summary>
80+
/// <param name="timeout">Timeout to get state. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
81+
/// <returns>True if enabled, false otherwise.</returns>
82+
bool WaitForEnabled(TimeSpan? timeout = null);
83+
84+
/// <summary>
85+
/// Waits for element is not enabled state which means element is not Enabled or does have "disabled" class.
86+
/// </summary>
87+
/// <param name="timeout">Timeout to get state. Default: <see cref="Aquality.Selenium.Configurations.ITimeoutConfiguration.Condition"/></param>
88+
/// <returns>True if not enabled, false otherwise.</returns>
89+
bool WaitForNotEnabled(TimeSpan? timeout = null);
5090
}
5191
}

Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/IElementWithState.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)