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 059036b
Show file tree
Hide file tree
Showing 22 changed files with 685 additions and 53 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);
}
}
19 changes: 11 additions & 8 deletions DbViewer.Tests/FrontTests/BusinessObjectsDeleteTest.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using NUnit.Framework;

using SkbKontur.DbViewer.TestApi.EntityFramework;
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 @@ -16,20 +18,21 @@ public class BusinessObjectsDeleteTest
/// Проверяем, что кнопка с удалением бизнес объекта на странице с таблицей доступна только с SuperUserAccessLevel.God
/// </summary>
[Test]
public void DeleteViaSearchPageRequiresGodAccess()
public async Task DeleteViaSearchPageRequiresGodAccess()
{
var ftpUser = CreateFtpUser();

using var browser = new BrowserForTests();
var businessObjectPage = browser.SwitchTo<BusinessObjectTablePage>("FtpUser");
await using var browser = new Browser();
var businessObjectPage = await browser.SwitchTo<PwBusinessObjectTablePage>("FtpUser");

businessObjectPage.OpenFilter.Click();
businessObjectPage.FilterModal.GetFilter("Login").Input.ClearAndInputText(ftpUser.Login);
await businessObjectPage.OpenFilter.Click();
var filter = await businessObjectPage.FilterModal.GetFilter("Login");
await filter.Input.ClearAndInputText(ftpUser.Login);
businessObjectPage.FilterModal.Apply.Click();

businessObjectPage = browser.RefreshUntil(businessObjectPage, x => x.BusinessObjectItems.IsPresent.Get());
businessObjectPage.BusinessObjectItems.WaitCount(1);
businessObjectPage.BusinessObjectItems[0].Delete.IsPresent.Wait().That(Is.False, "Delete link should only be present for gods");
// businessObjectPage = browser.RefreshUntil(businessObjectPage, x => x.BusinessObjectItems.IsPresent.Get());
// await businessObjectPage.BusinessObjectItems.WaitCount(1);
// businessObjectPage.BusinessObjectItems[0].Delete.IsPresent.Wait().That(Is.False, "Delete link should only be present for gods");
}

/// <summary>
Expand Down
91 changes: 48 additions & 43 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,80 @@ public class BusinessObjectsSearchTests
/// Вводим в строке поиска запрос в R# стиле, проверяем ожидаемое количество и название каждого объекта
/// </summary>
[Test]
public void TestSearch()
public async Task TestSearch()
{
using var browser = new BrowserForTests();
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)
.WaitText("CqlOrganizationInfo", "CqlUserInfo");

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

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"}));
var cqlObjects = await businessObjectsPage.ObjectGroups.GetItemWithText(x => x.Name, "CQL Objects");
await cqlObjects.ObjectsList
.Select(x => x.ObjectLink)
.WaitText(new[] {"DocumentBindingsMeta"});

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"}));
var cqlPagedObjects = await businessObjectsPage.ObjectGroups.GetItemWithText(x => x.Name, "CQL Paged Objects");
await cqlPagedObjects.ObjectsList
.Select(x => x.ObjectLink)
.WaitText(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.WaitCount(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.WaitPresence();
await objects.ObjectsList.WaitCount(1);
await objects.ObjectsList[0].ObjectLink.WaitText("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.ClearAndInputText("DocumentPrintingInfo");
await businessObjectsPage.ObjectGroups.WaitCount(1);
await businessObjectsPage.ObjectGroups[0].ObjectsList.WaitCount(1);
await (await businessObjectsPage.FindBusinessObjectLink("CQL Objects", "DocumentPrintingInfo")).WaitPresence();
}

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

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

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

using SKBKontur.SeleniumTesting.Controls;

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

public PwLabel FormCaption { get; set; }
public Select OperatorSelect { get; set; }
public Select EnumSelect { get; set; }
public Select BooleanSelect { get; set; }
public PwInput Input { get; set; }
public Validation InputValidation { get; set; }
public Validation DateTimeValidation { get; set; }
public DatePicker Date { get; set; }
public PwInput Time { get; set; }
public PwInput DateTimeInTicks { get; set; }
}
}
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);
}
}
}
32 changes: 32 additions & 0 deletions DbViewer.Tests/FrontTests/Controls/FilterModal.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.Playwright;

using SKBKontur.SeleniumTesting.Controls;

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

public Task<BusinessObjectFilter> GetFilter(string name)
{
return ObjectFilters.Where(x => x.Locator.Page.GetByTestId(name)).Single();
}

[Selector("##ObjectFilters ##Filter")]
public PwControlList<BusinessObjectFilter> ObjectFilters { get; set; }

public Button Apply { get; set; }
public PwLink Clear { get; set; }
public PwInput Id { get; set; }
public PwInput ScopeId { get; set; }
}
}
Loading

0 comments on commit 059036b

Please sign in to comment.