Skip to content

Commit

Permalink
Feature - Extend Window from Element (#17)
Browse files Browse the repository at this point in the history
* Implemented relative search against window locator.

* Fix codesmell issue at ElementExtensions

* Extend ApplicationManager tests. Fix issue with ApplicationFactory registration in DI container

+semver: feature
  • Loading branch information
mialeska authored Sep 23, 2019
1 parent 43f86a9 commit 16f724c
Show file tree
Hide file tree
Showing 22 changed files with 207 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private static IServiceCollection RegisterServices(Func<IServiceProvider, Applic
services.AddSingleton(serviceProvider => new LocalizationManager(serviceProvider.GetRequiredService<ILoggerConfiguration>(), serviceProvider.GetRequiredService<Logger>(), Assembly.GetExecutingAssembly()));
services.AddSingleton<IKeyboardActions>(serviceProvider => new KeyboardActions(serviceProvider.GetRequiredService<LocalizationLogger>(), () => Application.WindowsDriver));
services.AddSingleton<IMouseActions>(serviceProvider => new MouseActions(serviceProvider.GetRequiredService<LocalizationLogger>(), () => Application.WindowsDriver));
services.AddSingleton(serviceProvider => ApplicationFactory);
services.AddTransient(serviceProvider => ApplicationFactory);
return services;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

<ItemGroup>
<PackageReference Include="Appium.WebDriver" Version="4.0.0" />
<PackageReference Include="Aquality.Selenium.Core" Version="0.1.5" />
<PackageReference Include="Aquality.Selenium.Core" Version="0.1.6" />
</ItemGroup>

</Project>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Aquality.WinAppDriver.Elements
/// </summary>
public class Button : Element, IButton
{
public Button(By locator, string name) : base(locator, name)
protected internal Button(By locator, string name) : base(locator, name)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
using Aquality.Selenium.Core.Localization;
using Aquality.Selenium.Core.Waitings;
using Aquality.WinAppDriver.Elements.Interfaces;
using Aquality.WinAppDriver.Extensions;
using Aquality.WinAppDriver.Windows;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using CoreFactory = Aquality.Selenium.Core.Elements.ElementFactory;
using IElement = Aquality.WinAppDriver.Elements.Interfaces.IElement;
using IElementFactory = Aquality.WinAppDriver.Elements.Interfaces.IElementFactory;

namespace Aquality.WinAppDriver.Elements
Expand Down Expand Up @@ -36,6 +40,12 @@ public ITextBox GetTextBox(By locator, string name)
return GetCustomElement(ResolveSupplier<ITextBox>(null), locator, name);
}

public T FindChildElement<T>(Window parentWindow, By childLocator, string childName, ElementSupplier<T> supplier = null) where T : IElement
{
var elementSupplier = ResolveSupplier(supplier);
return elementSupplier(new ByChained(parentWindow.Locator, childLocator), $"{childName}' - {parentWindow.GetElementType()} '{parentWindow.Name}", ElementState.Displayed);
}

protected override ElementSupplier<T> ResolveSupplier<T>(ElementSupplier<T> supplier)
{
if (supplier != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using OpenQA.Selenium;
using Aquality.Selenium.Core.Elements;
using Aquality.WinAppDriver.Windows;
using OpenQA.Selenium;
using CoreElementFactory = Aquality.Selenium.Core.Elements.Interfaces.IElementFactory;

namespace Aquality.WinAppDriver.Elements.Interfaces
Expand Down Expand Up @@ -32,5 +34,15 @@ public interface IElementFactory : CoreElementFactory
/// <returns>Instance of element that implements ITextBox interface</returns>
ITextBox GetTextBox(By locator, string name);

/// <summary>
/// Finds element relative to parent window.
/// </summary>
/// <typeparam name="T">Type of the target element.</typeparam>
/// <param name="parentWindow">Parent window for the element.</param>
/// <param name="childLocator">Locator of the element relative to parent window.</param>
/// <param name="childName">Name of the element.</param>
/// <param name="supplier">Delegate that defines constructor of element in case of custom element.</param>
/// <returns>Instance of element.</returns>
T FindChildElement<T>(Window parentWindow, By childLocator, string childName, ElementSupplier<T> supplier = null) where T : IElement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static class ElementExtensions
internal static string GetElementType(this IElement element)
{
string elementType = null;
if (typeof(Element).IsAssignableFrom(element.GetType()))
if (element is Element)
{
elementType = element.GetType().GetProperty("ElementType", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(element).ToString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"loc.application.driver.service.remote": "Працуем з сэрвісам драйвера па адрасе '{0}'",
"loc.button": "Кнопка",
"loc.label": "Надпіс",
"loc.window": "Акно",
"loc.text.field": "Тэкставае поле",
"loc.text.clearing": "Aчышчаем",
"loc.text.typing": "Уводзім значэнне '{0}'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"loc.application.driver.service.remote": "Using driver service running on '{0}'",
"loc.button": "Button",
"loc.label": "Label",
"loc.window": "Window",
"loc.text.field": "Text Field",
"loc.text.clearing": "Clearing",
"loc.text.typing": "Typing '{0}'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"loc.application.driver.service.remote": "Работаем с сервисом драйвера по адресу '{0}'",
"loc.button": "Кнопка",
"loc.label": "Надпись",
"loc.window": "Окно",
"loc.text.field": "Текстовое поле",
"loc.text.clearing": "Очищаем",
"loc.text.typing": "Вводим значение '{0}'",
Expand Down
44 changes: 20 additions & 24 deletions Aquality.WinAppDriver/src/Aquality.WinAppDriver/Windows/Window.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,58 @@
using Aquality.Selenium.Core.Logging;
using Aquality.Selenium.Core.Elements;
using Aquality.WinAppDriver.Applications;
using Aquality.WinAppDriver.Elements.Interfaces;
using OpenQA.Selenium;
using System.Drawing;
using Element = Aquality.WinAppDriver.Elements.Element;
using IElementFactory = Aquality.WinAppDriver.Elements.Interfaces.IElementFactory;

namespace Aquality.WinAppDriver.Windows
{
/// <summary>
/// Defines base class for any application's window.
/// </summary>
public abstract class Window
public abstract class Window : Element
{
/// <summary>
/// Constructor with parameters.
/// </summary>
/// <param name="locator">Unique locator of the window.</param>
/// <param name="name">Name of the window.</param>
protected Window(By locator, string name)
protected Window(By locator, string name) : base(locator, name)
{
Locator = locator;
Name = name;
}

/// <summary>
/// Locator of specified window.
/// </summary>
public By Locator { get; }

/// <summary>
/// Name of specified window.
/// </summary>
public string Name { get; }

/// <summary>
/// Instance of logger <see cref="Selenium.Core.Logging.Logger"/>
/// </summary>
/// <value>Logger instance.</value>
protected Logger Logger => ApplicationManager.GetRequiredService<Logger>();

/// <summary>
/// Element factory <see cref="IElementFactory"/>
/// </summary>
/// <value>Element factory.</value>
protected IElementFactory ElementFactory => ApplicationManager.GetRequiredService<IElementFactory>();

/// <summary>
/// Finds element relative to current window.
/// </summary>
/// <typeparam name="T">Type of the target element.</typeparam>
/// <param name="childLocator">Locator of the element relative to current window.</param>
/// <param name="childName">Name of the element.</param>
/// <param name="supplier">Delegate that defines constructor of element in case of custom element.</param>
/// <returns>Instance of element.</returns>
public T FindChildElement<T>(By childLocator, string childName, ElementSupplier<T> supplier = null) where T : IElement
{
return ElementFactory.FindChildElement(this, childLocator, childName, supplier);
}

/// <summary>
/// Return window state for window locator
/// </summary>
/// <value>True - window is opened,
/// False - window is not opened.</value>
public bool IsDisplayed => WindowLabel.State.WaitForDisplayed();
public bool IsDisplayed => State.WaitForDisplayed();

/// <summary>
/// Gets size of window element defined by its locator.
/// </summary>
public Size Size => WindowLabel.GetElement().Size;
public Size Size => GetElement().Size;

private ILabel WindowLabel => ElementFactory.GetLabel(Locator, Name);
protected override string ElementType => LocalizationManager.GetLocalizedMessage("loc.window");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Aquality.WinAppDriver.Actions;
using Aquality.WinAppDriver.Applications;
using Aquality.WinAppDriver.Elements.Interfaces;
using Aquality.WinAppDriver.Tests.Applications.Locators;
using Aquality.WinAppDriver.Tests.Windows;
using NUnit.Framework;
using System;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Aquality.WinAppDriver.Actions;
using Aquality.WinAppDriver.Applications;
using Aquality.WinAppDriver.Elements.Interfaces;
using Aquality.WinAppDriver.Tests.Applications.Locators;
using Aquality.WinAppDriver.Tests.Windows;
using NUnit.Framework;

namespace Aquality.WinAppDriver.Tests.Actions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using Aquality.Selenium.Core.Applications;
using Aquality.Selenium.Core.Elements.Interfaces;
using Aquality.WinAppDriver.Applications;
using Aquality.WinAppDriver.Tests.Windows;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;

namespace Aquality.WinAppDriver.Tests.Applications
{
public class ApplicationManagerTests : TestWithApplication
{
private readonly CalculatorWindow calculatorWindow = new CalculatorWindow();

[Test]
public void Should_WorkWithCalculator()
{
ApplicationManager.Application.Driver.FindElement(calculatorWindow.OneButton.Locator).Click();
ApplicationManager.Application.Driver.FindElement(calculatorWindow.PlusButton.Locator).Click();
ApplicationManager.Application.Driver.FindElement(calculatorWindow.TwoButton.Locator).Click();
ApplicationManager.Application.Driver.FindElement(calculatorWindow.EqualsButton.Locator).Click();
var result = ApplicationManager.Application.Driver.FindElement(calculatorWindow.ResultsLabel.Locator).Text;
StringAssert.Contains("3", result);
}

[Test]
public void Should_WorkWithCalculator_ViaElementFinder()
{
ApplicationManager.GetRequiredService<IElementFinder>().FindElement(calculatorWindow.OneButton.Locator).Click();
ApplicationManager.GetRequiredService<IElementFinder>().FindElement(calculatorWindow.PlusButton.Locator).Click();
ApplicationManager.GetRequiredService<IElementFinder>().FindElement(calculatorWindow.TwoButton.Locator).Click();
ApplicationManager.GetRequiredService<IElementFinder>().FindElement(calculatorWindow.EqualsButton.Locator).Click();
var result = ApplicationManager.GetRequiredService<IElementFinder>().FindElement(calculatorWindow.ResultsLabel.Locator).Text;
StringAssert.Contains("3", result);
}

[Test]
public void Should_GetCurrentApplicationFactory_AfterSetDefaultFactory()
{
var firstFactory = ApplicationManager.GetRequiredService<IApplicationFactory>();
ApplicationManager.SetDefaultFactory();
var secondFactory = ApplicationManager.GetRequiredService<IApplicationFactory>();
Assert.AreNotSame(firstFactory, secondFactory);
ApplicationManager.ApplicationFactory = firstFactory;
Assert.AreSame(firstFactory, ApplicationManager.GetRequiredService<IApplicationFactory>());
Assert.AreNotSame(secondFactory, ApplicationManager.GetRequiredService<IApplicationFactory>());
}

[Test]
public void Should_GetCurrentApplication_AfterSetApplication()
{
IApplication firstApplication;
using(var scope = ApplicationManager.ServiceProvider.CreateScope())
{
firstApplication = scope.ServiceProvider.GetRequiredService<IApplication>();
}

// Creating a second instance of Application
ApplicationManager.Application = ApplicationManager.ApplicationFactory.Application;

using (var scope = ApplicationManager.ServiceProvider.CreateScope())
{
var secondApplication = scope.ServiceProvider.GetRequiredService<IApplication>();
Assert.AreNotSame(firstApplication, secondApplication);
secondApplication.Driver.Quit();
}

// Switching back to a first instance of Application
ApplicationManager.Application = firstApplication as Application;

using (var scope = ApplicationManager.ServiceProvider.CreateScope())
{
Assert.AreSame(firstApplication, scope.ServiceProvider.GetRequiredService<IApplication>());
}
}

[Test]
public void Should_GetCurrentApplication_AfterQuit()
{
var firstApplication = ApplicationManager.Application;
firstApplication.Quit();
var secondApplication = ApplicationManager.Application;
Assert.AreNotSame(firstApplication, secondApplication);
using (var scope = ApplicationManager.ServiceProvider.CreateScope())
{
var secondApplicationFromServiceProvider = scope.ServiceProvider.GetRequiredService<IApplication>();
Assert.AreNotSame(firstApplication, secondApplicationFromServiceProvider);
Assert.AreSame(secondApplication, secondApplicationFromServiceProvider);
}
}
}
}

This file was deleted.

Loading

0 comments on commit 16f724c

Please sign in to comment.