Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Infra/splitting libraries #6

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
11 changes: 5 additions & 6 deletions VacationTests/DiExample/Container.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System;

namespace DiExample
namespace DiExample;

public class Container
{
public class Container
public IServiceProvider BuildServiceProvider()
{
public IServiceProvider BuildServiceProvider()
{
throw new NotImplementedException();
}
throw new NotImplementedException();
}
}
5 changes: 3 additions & 2 deletions VacationTests/DiExample/DiExample.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand All @@ -16,6 +17,6 @@
<PackageReference Include="NUnitLite" Version="3.13.3" />
<PackageReference Include="coverlet.collector" Version="3.0.2" />
<PackageReference Include="Selenium.WebDriver" Version="4.8.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="113.0.5672.6300" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="118.0.5993.7000" />
</ItemGroup>
</Project>
19 changes: 9 additions & 10 deletions VacationTests/DiExample/PageObjects/Pages/KonturPage.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
using DiExample.Selenium.Page;
using OpenQA.Selenium;

namespace DiExample.PageObjects.Pages
namespace DiExample.PageObjects.Pages;

public class KonturPage : IPage
{
public class KonturPage : IPage
{
private readonly IWebDriver _driver;
private readonly IWebDriver _driver;

public KonturPage(IWebDriver driver) => _driver = driver;
public KonturPage(IWebDriver driver) => _driver = driver;

public string Url => "https://kontur.ru/";
public string Title => _driver.Title;
public string CompositeUrl(string path) => Url + path;
public string Url => "https://kontur.ru/";
public string Title => _driver.Title;
public string CompositeUrl(string path) => Url + path;

public IWebElement FirstNew => _driver.FindElement(By.ClassName("tm-article-body"));
}
public IWebElement FirstNew => _driver.FindElement(By.ClassName("tm-article-body"));
}
13 changes: 6 additions & 7 deletions VacationTests/DiExample/Selenium/Page/IPage.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace DiExample.Selenium.Page
namespace DiExample.Selenium.Page;

public interface IPage
{
public interface IPage
{
string Url { get; }
string Title { get; }
string CompositeUrl(string path);
}
string Url { get; }
string Title { get; }
string CompositeUrl(string path);
}
43 changes: 21 additions & 22 deletions VacationTests/DiExample/Selenium/Page/IPageFactory.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
using System;
using OpenQA.Selenium;

namespace DiExample.Selenium.Page
namespace DiExample.Selenium.Page;

public interface IPageFactory
{
TPage Create<TPage>(IWebDriver webDriver) where TPage : class, IPage;
TPage Create<TPage>(IWebDriver webDriver, string path) where TPage : class, IPage;
}

public class PageFactory : IPageFactory
{
public interface IPageFactory
#region Реализация

public TPage Create<TPage>(IWebDriver webDriver) where TPage : class, IPage
{
TPage Create<TPage>(IWebDriver webDriver) where TPage : class, IPage;
TPage Create<TPage>(IWebDriver webDriver, string path) where TPage : class, IPage;
var page = (TPage) Activator.CreateInstance(typeof(TPage), webDriver);
webDriver.Navigate().GoToUrl(page.Url);
return page;
}

public class PageFactory : IPageFactory
public TPage Create<TPage>(IWebDriver webDriver, string path) where TPage : class, IPage
{
#region Реализация

public TPage Create<TPage>(IWebDriver webDriver) where TPage : class, IPage
{
var page = (TPage) Activator.CreateInstance(typeof(TPage), webDriver);
webDriver.Navigate().GoToUrl(page.Url);
return page;
}

public TPage Create<TPage>(IWebDriver webDriver, string path) where TPage : class, IPage
{
var page = (TPage) Activator.CreateInstance(typeof(TPage), webDriver);
webDriver.Navigate().GoToUrl(page.CompositeUrl(path));
return page;
}

#endregion
var page = (TPage) Activator.CreateInstance(typeof(TPage), webDriver);
webDriver.Navigate().GoToUrl(page.CompositeUrl(path));
return page;
}

#endregion
}
21 changes: 10 additions & 11 deletions VacationTests/DiExample/SmokyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;

namespace DiExample
namespace DiExample;

public class SmokyTests
{
public class SmokyTests
{
private readonly IServiceProvider _serviceProvider = new Container().BuildServiceProvider();
private IBrowser Browser => _serviceProvider.GetRequiredService<IBrowser>();
private readonly IServiceProvider _serviceProvider = new Container().BuildServiceProvider();
private IBrowser Browser => _serviceProvider.GetRequiredService<IBrowser>();

[TestCase("Контур"), TestCase("экосистема"), TestCase("бизнеса")]
public void BrowserShould_BeOpenAndReturn_KonturPage(string substring)
{
var page = Browser.GoToPage<KonturPage>();
[TestCase("Контур"), TestCase("экосистема"), TestCase("бизнеса")]
public void BrowserShould_BeOpenAndReturn_KonturPage(string substring)
{
var page = Browser.GoToPage<KonturPage>();

Assert.That(page.Title, Contains.Substring(substring));
}
Assert.That(page.Title, Contains.Substring(substring));
}
}
17 changes: 17 additions & 0 deletions VacationTests/SeloneCore/Controls/BaseWebElements/Button.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Kontur.Selone.Extensions;
using Kontur.Selone.Properties;
using Kontur.Selone.Selectors.Context;

namespace SeloneCore.Controls.BaseWebElements;

// Об интерфейсах https://ulearn.me/course/basicprogramming/Interfeysy_3df89dfb-7f0f-4123-82ac-364c3a426396
// О наследовании https://ulearn.me/course/basicprogramming/Nasledovanie_ac2b8cb6-8d63-4b81-9083-eaa77ab0c89c
public class Button : ControlBase, ICanClickAndOpenPage
{
public Button(IContextBy contextBy, IPageObjectFactory pageObjectFactory) : base(contextBy, pageObjectFactory)
{
}

public IProp<string> Text => Container.Text();
public IPageObjectFactory PageObjectFactory => base.PageObjectFactory;
}
30 changes: 30 additions & 0 deletions VacationTests/SeloneCore/Controls/BaseWebElements/Checkbox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Kontur.Selone.Extensions;
using Kontur.Selone.Properties;
using Kontur.Selone.Selectors.Context;
using SeloneCore.Props;

namespace SeloneCore.Controls.BaseWebElements;

public class Checkbox : ControlBase
{
public Checkbox(IContextBy contextBy, IPageObjectFactory pageObjectFactory) : base(contextBy, pageObjectFactory)
{
}

public IProp<string> Text => Container.Text();
public IProp<bool> Checked => Container.Checked();

public void SetChecked()
{
Checked.Wait().EqualTo(false);
Click();
Checked.Wait().EqualTo(true);
}

public void SetUnchecked()
{
Checked.Wait().EqualTo(true);
Click();
Checked.Wait().EqualTo(false);
}
}
50 changes: 50 additions & 0 deletions VacationTests/SeloneCore/Controls/BaseWebElements/Combobox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Kontur.Selone.Elements;
using Kontur.Selone.Extensions;
using Kontur.Selone.Properties;
using Kontur.Selone.Selectors.Context;
using Kontur.Selone.Selectors.XPath;
using NUnit.Framework;
using SeloneCore.Props;

namespace SeloneCore.Controls.BaseWebElements;

public class Combobox : ControlBase
{
private readonly Input input;

public Combobox(IContextBy contextBy, IPageObjectFactory pageObjectFactory) : base(contextBy, pageObjectFactory)
{
input = pageObjectFactory.CreateControl<Input>(Container.Search(x =>
x.XPath(".//*[contains(@data-comp-name,'CommonWrapper Input')]")));
MenuItems = pageObjectFactory.CreateElementsCollection<Button>(
Container.Root(),
x => x.WithTid("ComboBoxMenu__item").FixedByIndex()
);
}

public IProp<string> Text => Container.Text();
public IProp<bool> HasError => Container.HasError();
public ElementsCollection<Button> MenuItems { get; }

public void SelectValue(string value)
{
Open();
MenuItems.Wait().Single(x => x.Text, Contains.Substring(value)).Click();
}

public void InputValue(string text)
{
Container.Click();
input.ClearAndInputText(text);
}

public void WaitValue(string text)
{
input.Value.Wait().EqualTo(text);
}

public void Open()
{
Container.Click();
}
}
40 changes: 40 additions & 0 deletions VacationTests/SeloneCore/Controls/BaseWebElements/ControlBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Kontur.Selone.Extensions;
using Kontur.Selone.Properties;
using Kontur.Selone.Selectors.Context;
using OpenQA.Selenium;
using SeloneCore.Props;

namespace SeloneCore.Controls.BaseWebElements;

public abstract class ControlBase : IHaveContainer
{
protected IPageObjectFactory PageObjectFactory { get; }
public IWebElement Container { get; }

protected ControlBase(IContextBy contextBy, IPageObjectFactory pageObjectFactory)
{
PageObjectFactory = pageObjectFactory;
Container = contextBy.SearchContext.SearchElement(contextBy.By);
}

public IProp<bool> Present => Container.Present(); // Typo IsPreset. Expression reflection
public IProp<bool> Visible => Container.Visible();
public IProp<bool> Disabled => Container.Disabled();

public void Click()
{
Container.Click();
}

public override string ToString()
{
try
{
return $"{Container.TagName} {Container.Text}";
}
catch (StaleElementReferenceException)
{
return "StaleElement (not found in DOM)";
}
}
}
50 changes: 50 additions & 0 deletions VacationTests/SeloneCore/Controls/BaseWebElements/DatePicker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Globalization;
using Kontur.Selone.Extensions;
using Kontur.Selone.Properties;
using Kontur.Selone.Selectors.Context;
using OpenQA.Selenium;
using SeloneCore.Props;

namespace SeloneCore.Controls.BaseWebElements;

public class DatePicker : ControlBase
{
private readonly IWebElement dateInput;

public DatePicker(IContextBy contextBy, IPageObjectFactory pageObjectFactory) : base(contextBy, pageObjectFactory)
{
dateInput = Container.SearchElement(By.XPath(".//*[contains(@data-comp-name, 'DateInput')]"));
}

public IProp<DateTime> Date => Container.Date();
public IProp<bool> HasError => Container.HasError();

public void SetValue(DateTime date)
{
SetValue(date.ToString("d", new CultureInfo("ru-RU")).Replace(".", string.Empty));
}

/// <summary>
/// Сейчас поведение контрола с датой такое, что каленарик остается открытым, пока в нём не кликнешь конкретную дату
/// Esc и Enter не закрывают календарик.
/// Каледарик может перекрывать нужный в тесте элемент, соответственно тест не сможет с ним взаимодейсвтовать
/// Возможные решения:
/// 1) Послать Tab. Нюанс: следующий контрол может быть тоже календарик и снова перекроются элементы.
/// 2) Кликнуть по другому элементу. Может выглядеть нелогично в тесте без комментариев. И надо думать в каждом тесте
/// отдельно.
/// 3) Сделать универсальный клик в любое место. В каком-то из интерфейсов в этом месте может быть что-то.
/// 4) Сделать на фронте так, чтобы в режиме для тестов календарик не раскрывался.
/// 5) (используется в проекте) Посылать с помощью js blur() - убирание фокуса с элемента.
/// 6) По-честному кликать в дату. Возможно непросто в реализации обвязки.
/// </summary>
public void SetValue(string text)
{
dateInput.SendKeys(text);
Blur();
}

private void Blur()
{
dateInput.ExecuteJs("x.blur();");
}
}
Loading