Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public void ClearInput()
new AssertionBehavior(AssertionType.Continuous, false),
$"{Caption} is not enabled");

Element.Clear();
while (Element.GetAttribute("value").Length > 0)
{
Element.SendKeys(Keys.Backspace);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,72 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.RegularExpressions;

namespace Behavioral.Automation.Template.Bindings.ElementWrappers
{
public class WebElementWrapper : IWebElementWrapper
{
private readonly Func<IWebElement> _elementSelector;
private readonly IDriverService _driverService;

public WebElementWrapper([NotNull] Func<IWebElement> elementSelector, [NotNull] string caption, [NotNull] IDriverService driverService)
public WebElementWrapper([NotNull] Func<IWebElement> elementSelector, [NotNull] string caption,
[NotNull] IDriverService driverService)
{
_elementSelector = elementSelector;
_driverService = driverService;
Driver = driverService;
Caption = caption;
}

public string Caption { get; }

public IWebElement Element => _elementSelector();

public string Text => Element.Text;
public string Text
{
get
{
try
{
return Regex.Replace(Element.Text, @"\t|\n|\r", " ").Replace(" ", " ");
}
catch (Exception e) when (e is NullReferenceException or StaleElementReferenceException)
{
return string.Empty;
}
}
}

public string GetAttribute(string attribute) => Element.GetAttribute(attribute);
public string GetAttribute(string attribute)
{
try
{
return Element.GetAttribute(attribute);
}
catch (Exception e) when (e is NullReferenceException or StaleElementReferenceException)
{
return null;
}
}

public void Click()
{
MouseHover();
Assert.ShouldGet(() => Enabled);
_driverService.MouseClick();
Assert.ShouldBecome(() => Enabled, true, $"Unable to click on {Caption}. The element was disabled");
try
{
Element.Click();
}
catch (ElementClickInterceptedException)
{
MouseHover();
Driver.MouseClick();
}
}

public void MouseHover()
{
Assert.ShouldBecome(() => Enabled, true, $"{Caption} is disabled");
_driverService.ScrollTo(Element);
Assert.ShouldBecome(() => Displayed, true, $"{Caption} is not visible");
Driver.ScrollTo(Element);
}

public void SendKeys(string text)
Expand All @@ -47,29 +79,25 @@ public void SendKeys(string text)
Element.SendKeys(text);
}

public bool Displayed => Element != null && Element.Displayed;

public bool Enabled => Displayed && Element.Enabled && AriaEnabled;

public string Tooltip
public bool Displayed
{
get
{
var matTooltip = GetAttribute("matTooltip");
if (matTooltip != null)
try
{
return matTooltip;
return Element is not null && Element.Displayed;
}
var ngReflectTip = GetAttribute("ng-reflect-message"); //some elements have their tooltips' texts stored inside 'ng-reflect-message' attribute
if (ngReflectTip != null)
catch (Exception e) when (e is NullReferenceException or StaleElementReferenceException)
{
return ngReflectTip;
return false;
}

return GetAttribute("aria-label"); //some elements have their tooltips' texts stored inside 'aria-label' attribute
}
}

public bool Enabled => Displayed && Element.Enabled;

public string Tooltip => GetAttribute("data-test-tooltip-text");

public bool Stale
{
get
Expand All @@ -80,7 +108,7 @@ public bool Stale
var elementEnabled = Element.Enabled;
return false;
}
catch (StaleElementReferenceException)
catch (Exception e) when (e is NullReferenceException or StaleElementReferenceException)
{
return true;
}
Expand All @@ -89,34 +117,22 @@ public bool Stale

public IEnumerable<IWebElementWrapper> FindSubElements(By locator, string caption)
{
var elements = Assert.ShouldGet(() => Element.FindElements(locator));
return ElementsToWrappers(elements, caption);
}

private IEnumerable<IWebElementWrapper> ElementsToWrappers(IEnumerable<IWebElement> elements, string caption)
{
foreach (var element in elements)
try
{
var wrapper = new WebElementWrapper(() => element, caption, _driverService);
yield return wrapper;
return ElementsToWrappers(Assert.ShouldGet(() => Element.FindElements(locator)), caption);
}
catch (Exception e) when (e is NullReferenceException or InvalidOperationException)
{
NUnit.Framework.Assert.Fail($"Couldn't find elements with {caption}");
return null;
}
}

protected IDriverService Driver => _driverService;

private bool AriaEnabled
private IEnumerable<IWebElementWrapper> ElementsToWrappers(IEnumerable<IWebElement> elements, string caption)
{
get
{
switch (Element.GetAttribute("aria-disabled"))
{
case null:
case "false":
return true;
}

return false;
}
return elements.Select(element => new WebElementWrapper(() => element, caption, Driver));
}

protected IDriverService Driver { get; }
}
}
10 changes: 2 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,5 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

[1.8.6] - 2022-01-25
### Fixed
- Error when calling Aggregate() to generate message for DropdownWrapper

[1.8.5] - 2022-01-27
### Changed
- Bindings code refactoring
- Updated Specflow package version
[1.8.7] - 2022-02-25
- Moved tooltip attribute to separate interface
2 changes: 1 addition & 1 deletion src/Behavioral.Automation/Behavioral.Automation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The whole automation code is divided into the following parts:
- UI structure descriptive code
- Supportive code</Description>
<Copyright>Quantori Inc.</Copyright>
<PackageVersion>1.8.6</PackageVersion>
<PackageVersion>1.8.7</PackageVersion>
<RepositoryUrl>https://github.com/quantori/Behavioral.Automation</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
24 changes: 12 additions & 12 deletions src/Behavioral.Automation/Bindings/LabelBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

namespace Behavioral.Automation.Bindings
{
/// <summary>
/// Bindings for labels or other text elements testing
/// <summary>
/// Bindings for labels or other text elements testing
/// </summary>
[Binding]
public sealed class LabelBinding
Expand All @@ -23,18 +23,18 @@ public LabelBinding([NotNull] RunnerService runnerService, [NotNull] ScenarioCon
_scenarioContext = scenarioContext;
}

/// <summary>
/// Check that element's text is equal to the expected one
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <param name="behavior">Assertion behavior (instant or continuous)</param>
/// <summary>
/// Check that element's text is equal to the expected one
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <param name="behavior">Assertion behavior (instant or continuous)</param>
/// <param name="value">Expected value</param>
/// <example>Then "Test" element text should be "expected text"</example>
[Given("the (.*?) text (is|is not|become|become not) \"(.*)\"")]
[Then("the (.*?) text should (be|be not|become|become not) \"(.*)\"")]
public void CheckSelectedText(
[NotNull] IWebElementWrapper element,
[NotNull] AssertionBehavior behavior,
[NotNull] IWebElementWrapper element,
[NotNull] AssertionBehavior behavior,
[NotNull] string value)
{
Assert.ShouldBecome(() => StringExtensions.GetElementTextOrValue(element), value, behavior,
Expand Down Expand Up @@ -68,7 +68,7 @@ public void CheckSelectedTextContain(
/// <example>Then the "Test" element should have tooltip with text "expected string"</example>
[Then("the (.*?) should (have|not have) tooltip with text \"(.*)\"")]
public void CheckElementTooltip(
[NotNull] IWebElementWrapper element,
[NotNull] ITooltipElementWrapper element,
[NotNull] AssertionBehavior behavior,
[NotNull] string value)
{
Expand All @@ -88,8 +88,8 @@ public void CheckElementIsEmpty([NotNull] IWebElementWrapper element, AssertionB
{
Assert.ShouldBecome(() => StringExtensions.GetElementTextOrValue(element), string.Empty, behavior,
$"{element.Caption} text is \"{StringExtensions.GetElementTextOrValue(element)}\"");
}
}

/// <summary>
/// Check that multiple elements' texts are empty
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/Behavioral.Automation/Elements/ITooltipElementWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Behavioral.Automation.Elements
{
public interface ITooltipElementWrapper : IWebElementWrapper
{
/// <summary>
/// Message that appears when mouse is hovered over element
/// </summary>
public string Tooltip { get; }
}
}
5 changes: 0 additions & 5 deletions src/Behavioral.Automation/Elements/IWebElementWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ public interface IWebElementWrapper
/// </summary>
public bool Enabled { get; }

/// <summary>
/// Message that appears when mouse is hovered over element
/// </summary>
public string Tooltip { get; }

/// <summary>
/// Element staleness. See <seealso cref="StaleElementReferenceException"/>
/// </summary>
Expand Down