Skip to content

Commit

Permalink
playwright playground
Browse files Browse the repository at this point in the history
  • Loading branch information
fakefeik committed Jan 15, 2024
1 parent 008fe98 commit ecd557f
Show file tree
Hide file tree
Showing 21 changed files with 577 additions and 47 deletions.
1 change: 1 addition & 0 deletions DbViewer.Tests/DbViewer.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.2.0" />
<PackageReference Include="Kontur.ReactUI.SeleniumTesting" Version="3.6.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.40.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
Expand Down
60 changes: 60 additions & 0 deletions DbViewer.Tests/FrontTests/AutoFill/PwAutoFill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Linq;
using System.Reflection;

using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests.AutoFill
{
public class PwAutoFill
{
public static TPage InitializePage<TPage>(IPage page)
where TPage : PwPageBase
{
var newPage = (TPage)Activator.CreateInstance(typeof(TPage), page)!;
InitializeControls(newPage, newPage.Page, null);
return newPage;
}

public static void InitializeControls(object instance, IPage page, ILocator? parent)
{
var properties = instance
.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite && typeof(PwControlBase).IsAssignableFrom(p.PropertyType) && !p.GetCustomAttributes<SkipAutoFillAttribute>().Any());

foreach (var property in properties)
{
var locator = LocatorForProperty(property, page, parent);
var value = Activator.CreateInstance(property.PropertyType, locator)!;
InitializeControls(value, page, locator);
property.SetValue(instance, value);
}
}

public static ILocator LocatorForProperty(PropertyInfo property, IPage page, ILocator? parent)
{
var selector = property
.GetCustomAttributes<SelectorAttribute>()
.Select(x => x.Selector.ToString())
.FirstOrDefault();

if (string.IsNullOrEmpty(selector))
return GetByTestId(page, parent, property.Name);

var selectors = selector.Split(" ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
return selectors
.Aggregate(
parent,
(current, s) => s.StartsWith("##")
? GetByTestId(page, current, s[2..])
: GetLocator(page, current, s)
)!;
}

private static ILocator GetByTestId(IPage page, ILocator? parent, string tid) => parent == null ? page.GetByTestId(tid) : parent.GetByTestId(tid);
private static ILocator GetLocator(IPage page, ILocator? parent, string loc) => parent == null ? page.Locator(loc) : parent.Locator(loc);
}
}
99 changes: 54 additions & 45 deletions DbViewer.Tests/FrontTests/BusinessObjectsSearchTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using NUnit.Framework;
using System.Threading.Tasks;

using NUnit.Framework;

using SkbKontur.DbViewer.Tests.FrontTests.Helpers;
using SkbKontur.DbViewer.Tests.FrontTests.Pages;
using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests
{
Expand All @@ -12,77 +14,84 @@ public class BusinessObjectsSearchTests
/// Вводим в строке поиска запрос в R# стиле, проверяем ожидаемое количество и название каждого объекта
/// </summary>
[Test]
public void TestSearch()
public async Task TestSearch()
{
using var browser = new BrowserForTests();

var businessObjectsPage = browser.SwitchTo<BusinessObjectsPage>();
businessObjectsPage.FilterInput.ClearAndInputText("CI");
businessObjectsPage.ObjectGroups.WaitCount(1);
businessObjectsPage.ObjectGroups
.GetItemWithText(x => x.Name.Text, "CQL Paged Objects").ObjectsList
.Wait(x => x.ObjectLink.Text)
.That(Is.EqualTo(new[] {"CqlOrganizationInfo", "CqlUserInfo"}));

businessObjectsPage.FilterInput.ClearAndInputText("DocMe");
businessObjectsPage.ObjectGroups.WaitCount(2);
businessObjectsPage.ObjectGroups
.GetItemWithText(x => x.Name.Text, "CQL Objects").ObjectsList
.Wait(x => x.ObjectLink.Text)
.That(Is.EqualTo(new[] {"DocumentBindingsMeta"}));
businessObjectsPage.ObjectGroups
.GetItemWithText(x => x.Name.Text, "CQL Paged Objects").ObjectsList
.Wait(x => x.ObjectLink.Text)
.That(Is.EqualTo(new[] {"CqlDocumentMeta"}));
await using var browser = new Browser();

var businessObjectsPage = await browser.SwitchTo<PwBusinessObjectsPage>();
await businessObjectsPage.FilterInput.ClearAndInputText("CI");
await businessObjectsPage.ObjectGroups.WaitCount(1);

var pagedObjects = await businessObjectsPage.ObjectGroups.GetItemWithText(x => x.Name, "CQL Paged Objects");
await pagedObjects.ObjectsList
.Select(x => x.ObjectLink)
.Expect()
.ToHaveTextAsync(new[] {"CqlOrganizationInfo", "CqlUserInfo"});

await businessObjectsPage.FilterInput.ClearAndInputText("DocMe");
await businessObjectsPage.ObjectGroups.WaitCount(2);

var cqlObjects = await businessObjectsPage.ObjectGroups.GetItemWithText(x => x.Name, "CQL Objects");
await cqlObjects.ObjectsList
.Select(x => x.ObjectLink)
.Expect()
.ToHaveTextAsync(new[] {"DocumentBindingsMeta"});

var cqlPagedObjects = await businessObjectsPage.ObjectGroups.GetItemWithText(x => x.Name, "CQL Paged Objects");
await cqlPagedObjects.ObjectsList
.Select(x => x.ObjectLink)
.Expect()
.ToHaveTextAsync(new[] {"CqlDocumentMeta"});
}

/// <summary>
/// Проверяем, что у таблицы FtpUser есть плашка indexed
/// </summary>
[Test]
public void TestSearchIndexedField()
public async Task TestSearchIndexedField()
{
using var browser = new BrowserForTests();
await using var browser = new Browser();

var businessObjects = browser.SwitchTo<BusinessObjectsPage>();
businessObjects.FilterInput.ClearAndInputText("UsersTable");
businessObjects.ObjectGroups.WaitCount(1);
var businessObjects = await browser.SwitchTo<PwBusinessObjectsPage>();
await businessObjects.FilterInput.ClearAndInputText("UsersTable");
await businessObjects.ObjectGroups.Expect().ToHaveCountAsync(1);

var objects = businessObjects.ObjectGroups.GetItemWithText(x => x.Name.Text, "Postgres Objects");
objects.IndexedLabel.WaitPresence();
objects.ObjectsList.WaitCount(1);
objects.ObjectsList[0].ObjectLink.WaitText("UsersTable");
var objects = await businessObjects.ObjectGroups.GetItemWithText(x => x.Name, "Postgres Objects");
await objects.IndexedLabel.Expect().ToBeVisibleAsync();
await objects.ObjectsList.Expect().ToHaveCountAsync(1);
await objects.ObjectsList[0].ObjectLink.Expect().ToHaveTextAsync("UsersTable");
}

/// <summary>
/// Вводим в поиск CqlDocumentPrintingInfo.
/// Проверяем что нам выдает ровно одну ссылку
/// </summary>
[Test]
public void TestSearchLink()
public async Task TestSearchLink()
{
using var browser = new BrowserForTests();
await using var browser = new Browser();

var businessObjectsPage = browser.SwitchTo<BusinessObjectsPage>();
businessObjectsPage.FilterInput.ClearAndInputText("DocumentPrintingInfo");
businessObjectsPage.ObjectGroups.WaitCount(1);
businessObjectsPage.ObjectGroups[0].ObjectsList.WaitCount(1);
businessObjectsPage.FindBusinessObjectLink("CQL Objects", "DocumentPrintingInfo").WaitPresence();
var businessObjectsPage = await browser.SwitchTo<PwBusinessObjectsPage>();
await businessObjectsPage.FilterInput.Locator.FillAsync("DocumentPrintingInfo");
await businessObjectsPage.ObjectGroups.Expect().ToHaveCountAsync(1);
await businessObjectsPage.ObjectGroups[0].ObjectsList.Expect().ToHaveCountAsync(1);
await (await businessObjectsPage.FindBusinessObjectLink("CQL Objects", "DocumentPrintingInfo")).Expect().ToBeVisibleAsync();
}

/// <summary>
/// Переходим по ссылке на CqlDocumentPrintingInfo
/// Проверяем, что ссылка ведет туда, куда нам нужно
/// </summary>
[Test]
public void TestLinkShouldReferToShowTablePage()
public async Task TestLinkShouldReferToShowTablePage()
{
using var browser = new BrowserForTests();
await using var browser = new Browser();

var businessObjectsPage = await browser.SwitchTo<PwBusinessObjectsPage>();

var businessObjectsPage = browser.SwitchTo<BusinessObjectsPage>();
var link = businessObjectsPage.FindBusinessObjectLink("CQL Objects", "DocumentPrintingInfo");
var page = link.ClickAndGoTo<BusinessObjectTablePage>();
page.Header.WaitText("DocumentPrintingInfo");
var link = await businessObjectsPage.FindBusinessObjectLink("CQL Objects", "DocumentPrintingInfo");
var page = await link.ClickAndGoTo<PwBusinessObjectTablePage>();
await page.Header.Expect().ToHaveTextAsync("DocumentPrintingInfo");
}
}
}
21 changes: 21 additions & 0 deletions DbViewer.Tests/FrontTests/Controls/BusinessObjectGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.AutoFill;
using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests.Controls
{
public class BusinessObjectGroup : PwControlBase
{
public BusinessObjectGroup(ILocator locator)
: base(locator)
{
}

public PwLabel Name { get; set; }
public PwLabel IndexedLabel { get; set; }

[Selector("##ObjectsList ##ObjectItem")]
public PwControlList<BusinessObjectItem> ObjectsList { get; set; }
}
}
16 changes: 16 additions & 0 deletions DbViewer.Tests/FrontTests/Controls/BusinessObjectItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests.Controls
{
public class BusinessObjectItem : PwControlBase
{
public BusinessObjectItem(ILocator locator)
: base(locator)
{
}

public PwLink ObjectLink { get; set; }
}
}
25 changes: 25 additions & 0 deletions DbViewer.Tests/FrontTests/Controls/BusinessObjectTableRow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests.Controls
{
public class BusinessObjectTableRow : PwControlBase
{
public BusinessObjectTableRow(ILocator locator)
: base(locator)
{
}

public PwLink Details { get; set; }
public PwLink Delete { get; set; }
public PwLabel Id { get; set; }
public PwLabel ScopeId { get; set; }

public PwLabel FindColumn(string tid)
{
return null;
// return this.Find<Label>().ByTid(tid);
}
}
}
48 changes: 48 additions & 0 deletions DbViewer.Tests/FrontTests/Pages/PwBusinessObjectTablePage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.AutoFill;
using SkbKontur.DbViewer.Tests.FrontTests.Helpers;
using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

using SKBKontur.SeleniumTesting.Controls;

namespace SkbKontur.DbViewer.Tests.FrontTests.Pages
{
[PageRoute("BusinessObjects/{id}")]
public class PwBusinessObjectTablePage : PwPageBase
{
public PwBusinessObjectTablePage(IPage page)
: base(page)
{
}

public PwLabel Header { get; set; }

public PwLink GoBack { get; set; }
public PwLabel NothingFound { get; set; }

public PwLabel ItemsCountInfo { get; set; }

public PwLink OpenFilter { get; set; }
public FilterModal FilterModal { get; set; }
public DownloadLimitModal DownloadLimitModal { get; set; }

public CountDropdown CountDropdown { get; set; }
public PwLink ClearFilter { get; set; }
public PwLink FieldSettings { get; set; }
public PwLink DownloadLink { get; set; }

[Selector("Portal:portal ##ColumnSelector")]
public ColumnSelector ColumnSelector { get; set; }

public ConfirmDeleteObjectModal ConfirmDeleteObjectModal { get; set; }

public BusinessObjectTableHeader TableHeader { get; set; }

[Selector("##Body")]
[ChildSelector("##Row")]
public PwControlList<Controls.BusinessObjectTableRow> BusinessObjectItems { get; set; }

public Paging Paging { get; set; }
}
}
32 changes: 32 additions & 0 deletions DbViewer.Tests/FrontTests/Pages/PwBusinessObjectsPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Threading.Tasks;

using Microsoft.Playwright;

using SkbKontur.DbViewer.Tests.FrontTests.AutoFill;
using SkbKontur.DbViewer.Tests.FrontTests.Helpers;
using SkbKontur.DbViewer.Tests.FrontTests.Playwright;

namespace SkbKontur.DbViewer.Tests.FrontTests.Pages
{
[PageRoute("BusinessObjects")]
public class PwBusinessObjectsPage : PwPageBase
{
public PwBusinessObjectsPage(IPage page)
: base(page)
{
}

public PwLabel Header { get; set; }
public PwLink BackLink { get; set; }
public PwInput FilterInput { get; set; }

[Selector("##ObjectGroups ##ObjectGroup")]
public PwControlList<Controls.BusinessObjectGroup> ObjectGroups { get; set; }

public async Task<PwLink> FindBusinessObjectLink(string groupName, string objectName)
{
var businessObjectsList = (await ObjectGroups.GetItemWithText(x => x.Name, groupName)).ObjectsList;
return (await businessObjectsList.GetItemWithText(x => x.ObjectLink, objectName)).ObjectLink;
}
}
}
Loading

0 comments on commit ecd557f

Please sign in to comment.