Agent Tests for API, MAUI, and Slop Features
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using NUnit.Framework;
|
||||
using Tests.Helpers;
|
||||
|
||||
namespace Tests;
|
||||
|
||||
@@ -9,10 +8,7 @@ public class GlobalSetup
|
||||
[OneTimeSetUp]
|
||||
public async Task GlobalStart()
|
||||
{
|
||||
if (Environment.GetEnvironmentVariable("RUN_AGAINST_PRODUCTION") != "true")
|
||||
{
|
||||
await LocalServer.StartAsync();
|
||||
}
|
||||
if (Environment.GetEnvironmentVariable("RUN_AGAINST_PRODUCTION") != "true") await LocalServer.StartAsync();
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
@@ -20,4 +16,4 @@ public class GlobalSetup
|
||||
{
|
||||
LocalServer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,18 +32,15 @@ public static class LocalServer
|
||||
};
|
||||
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
|
||||
|
||||
_process.OutputDataReceived += (s, e) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.Data)) return;
|
||||
Console.WriteLine($"[SERVER] {e.Data}");
|
||||
var match = Regex.Match(e.Data, @"Now listening on:\s+(http://127.0.0.1:\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
tcs.TrySetResult(match.Groups[1].Value);
|
||||
}
|
||||
if (match.Success) tcs.TrySetResult(match.Groups[1].Value);
|
||||
};
|
||||
|
||||
|
||||
_process.ErrorDataReceived += (s, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
@@ -55,8 +52,8 @@ public static class LocalServer
|
||||
_process.BeginErrorReadLine();
|
||||
|
||||
// Wait for the URL to be parsed from output
|
||||
BaseUrl = await Task.WhenAny(tcs.Task, Task.Delay(30000)) == tcs.Task
|
||||
? tcs.Task.Result
|
||||
BaseUrl = await Task.WhenAny(tcs.Task, Task.Delay(30000)) == tcs.Task
|
||||
? tcs.Task.Result
|
||||
: null;
|
||||
|
||||
if (BaseUrl == null)
|
||||
@@ -64,7 +61,7 @@ public static class LocalServer
|
||||
Stop();
|
||||
throw new Exception("Timeout waiting for local server to start and provide a URL.");
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine($"[DEBUG_LOG] Local server started at: {BaseUrl}");
|
||||
}
|
||||
|
||||
@@ -88,7 +85,7 @@ public static class LocalServer
|
||||
if (parent == current) break;
|
||||
current = parent;
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(current) || !File.Exists(Path.Combine(current, "IGP.sln")))
|
||||
{
|
||||
// Fallback to searching up from current directory if BaseDirectory fails
|
||||
@@ -103,4 +100,4 @@ public static class LocalServer
|
||||
|
||||
return current ?? throw new Exception("Could not find project root containing IGP.sln");
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-10
@@ -1,4 +1,3 @@
|
||||
using Microsoft.Playwright;
|
||||
using Tests.Pages;
|
||||
using Tests.Shared;
|
||||
|
||||
@@ -6,16 +5,12 @@ namespace Tests.Helpers;
|
||||
|
||||
public class Website
|
||||
{
|
||||
public IPage Page { get; }
|
||||
public bool RunAgainstProduction { get; }
|
||||
public string BaseUrl { get; }
|
||||
|
||||
public Website(IPage page)
|
||||
{
|
||||
Page = page;
|
||||
RunAgainstProduction = Environment.GetEnvironmentVariable("RUN_AGAINST_PRODUCTION") == "true";
|
||||
|
||||
BaseUrl = RunAgainstProduction ? "https://igpfanreference.ca" : (LocalServer.BaseUrl ?? "http://localhost:5234");
|
||||
BaseUrl = RunAgainstProduction ? "https://igpfanreference.ca" : LocalServer.BaseUrl ?? "http://localhost:5234";
|
||||
|
||||
NavigationBar = new NavigationBar(this);
|
||||
SearchDialog = new SearchDialog(this);
|
||||
@@ -25,8 +20,10 @@ public class Website
|
||||
DatabaseSinglePage = new DatabaseSinglePage(this);
|
||||
}
|
||||
|
||||
public ILocator Locator(string selector) => Page.Locator(selector);
|
||||
public ILocator FindById(string id) => Page.Locator($"#{id}");
|
||||
public IPage Page { get; }
|
||||
public bool RunAgainstProduction { get; }
|
||||
public string BaseUrl { get; }
|
||||
|
||||
public NavigationBar NavigationBar { get; }
|
||||
public SearchDialog SearchDialog { get; }
|
||||
public BuildCalculatorPage BuildCalculatorPage { get; }
|
||||
@@ -34,17 +31,30 @@ public class Website
|
||||
public DatabasePage DatabasePage { get; }
|
||||
public DatabaseSinglePage DatabaseSinglePage { get; }
|
||||
|
||||
public ILocator Locator(string selector)
|
||||
{
|
||||
return Page.Locator(selector);
|
||||
}
|
||||
|
||||
public ILocator FindById(string id)
|
||||
{
|
||||
return Page.Locator($"#{id}");
|
||||
}
|
||||
|
||||
public async Task GotoAsync(string? path = null)
|
||||
{
|
||||
var url = path is null ? BaseUrl : $"{BaseUrl}/{path}";
|
||||
await Page.GotoAsync(url);
|
||||
}
|
||||
|
||||
public async Task ClickElementAsync(ILocator locator) => await locator.ClickAsync();
|
||||
public async Task ClickElementAsync(ILocator locator)
|
||||
{
|
||||
await locator.ClickAsync();
|
||||
}
|
||||
|
||||
public async Task EnterInputAsync(ILocator locator, string value)
|
||||
{
|
||||
await locator.FillAsync(value);
|
||||
await locator.PressAsync("Enter");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,14 @@
|
||||
using Tests.Helpers;
|
||||
|
||||
namespace Tests.Pages;
|
||||
|
||||
public abstract class BasePage
|
||||
{
|
||||
protected Website Website { get; }
|
||||
|
||||
protected BasePage(Website website)
|
||||
{
|
||||
Website = website;
|
||||
}
|
||||
|
||||
protected Website Website { get; }
|
||||
|
||||
public abstract string Url { get; }
|
||||
|
||||
public virtual async Task GotoAsync()
|
||||
@@ -22,7 +20,8 @@ public abstract class BasePage
|
||||
{
|
||||
var content = Website.FindById("content");
|
||||
var links = content.Locator("a");
|
||||
var hrefs = await links.EvaluateAllAsync<string[]>("els => els.map(el => el.getAttribute('href')).filter(Boolean)");
|
||||
var hrefs = await links.EvaluateAllAsync<string[]>(
|
||||
"els => els.map(el => el.getAttribute('href')).filter(Boolean)");
|
||||
return hrefs.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,35 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Tests.Pages.BuildCalculator;
|
||||
|
||||
public class ArmyComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public ArmyComponent(Website website) => _website = website;
|
||||
|
||||
public ArmyComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator ArmyView => _website.Locator(".armyView");
|
||||
|
||||
public ILocator DisplayValue(string label) =>
|
||||
_website.Locator(".displayContainer").Filter(new() { HasText = label }).Locator(".displayContent");
|
||||
|
||||
public ILocator ArmyCards => ArmyView.Locator(".armyCard");
|
||||
|
||||
public async Task<string> GetArmyCompletedAtAsync() =>
|
||||
(await DisplayValue("Army Completed At").TextContentAsync())?.Trim() ?? "";
|
||||
public ILocator DisplayValue(string label)
|
||||
{
|
||||
return _website.Locator(".displayContainer").Filter(new LocatorFilterOptions { HasText = label })
|
||||
.Locator(".displayContent");
|
||||
}
|
||||
|
||||
public async Task<string> GetArmyAttackingAtAsync() =>
|
||||
(await DisplayValue("Army Attacking At").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetArmyCompletedAtAsync()
|
||||
{
|
||||
return (await DisplayValue("Army Completed At").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetArmyAttackingAtAsync()
|
||||
{
|
||||
return (await DisplayValue("Army Attacking At").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetArmyUnitNamesAsync()
|
||||
{
|
||||
@@ -25,9 +38,10 @@ public class ArmyComponent
|
||||
foreach (var card in cards)
|
||||
{
|
||||
var text = (await card.InnerTextAsync()).Trim();
|
||||
var match = System.Text.RegularExpressions.Regex.Match(text, @"\d+x\s*(.+)");
|
||||
var match = Regex.Match(text, @"\d+x\s*(.+)");
|
||||
names.Add(match.Success ? match.Groups[1].Value.Trim() : text);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
@@ -43,6 +57,7 @@ public class ArmyComponent
|
||||
var name = (await nameEl.TextContentAsync())?.Trim() ?? "";
|
||||
counts.Add((name, int.Parse(count)));
|
||||
}
|
||||
|
||||
return counts;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,25 +3,60 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class BankComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public BankComponent(Website website) => _website = website;
|
||||
|
||||
public BankComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator BankContainer => _website.Locator(".bankContainer");
|
||||
|
||||
public ILocator DisplayValue(string label) =>
|
||||
BankContainer.Locator(".displayContainer").Filter(new() { HasText = label }).Locator(".displayContent");
|
||||
public ILocator DisplayValue(string label)
|
||||
{
|
||||
return BankContainer.Locator(".displayContainer").Filter(new LocatorFilterOptions { HasText = label })
|
||||
.Locator(".displayContent");
|
||||
}
|
||||
|
||||
public async Task<string> GetTimeAsync() => (await DisplayValue("Time").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetAlloyAsync() => (await DisplayValue("Alloy").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetEtherAsync() => (await DisplayValue("Ether").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetPyreAsync() => (await DisplayValue("Pyre").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetSupplyAsync() => (await DisplayValue("Supply").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetTimeAsync()
|
||||
{
|
||||
return (await DisplayValue("Time").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetWorkerCountAsync() =>
|
||||
(await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(0).TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetAlloyAsync()
|
||||
{
|
||||
return (await DisplayValue("Alloy").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetBusyWorkerCountAsync() =>
|
||||
(await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(1).TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetEtherAsync()
|
||||
{
|
||||
return (await DisplayValue("Ether").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetCreatingWorkerCountAsync() =>
|
||||
(await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(2).TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
public async Task<string> GetPyreAsync()
|
||||
{
|
||||
return (await DisplayValue("Pyre").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetSupplyAsync()
|
||||
{
|
||||
return (await DisplayValue("Supply").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetWorkerCountAsync()
|
||||
{
|
||||
return (await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(0).TextContentAsync())
|
||||
?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetBusyWorkerCountAsync()
|
||||
{
|
||||
return (await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(1).TextContentAsync())
|
||||
?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetCreatingWorkerCountAsync()
|
||||
{
|
||||
return (await BankContainer.Locator(".workerText").Locator(".displayContent").Nth(2).TextContentAsync())
|
||||
?.Trim() ?? "";
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,42 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class BuildChartComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public BuildChartComponent(Website website) => _website = website;
|
||||
|
||||
public BuildChartComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator ChartsContainer => _website.Locator(".chartsContainer");
|
||||
|
||||
public ILocator DisplayValue(string label) =>
|
||||
_website.Locator(".displayContainer").Filter(new() { HasText = label }).Locator(".displayContent");
|
||||
public ILocator DisplayValue(string label)
|
||||
{
|
||||
return _website.Locator(".displayContainer").Filter(new LocatorFilterOptions { HasText = label })
|
||||
.Locator(".displayContent");
|
||||
}
|
||||
|
||||
public async Task<string> GetHighestAlloyAsync() => (await DisplayValue("Highest Alloy").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetHighestEtherAsync() => (await DisplayValue("Highest Ether").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetHighestPyreAsync() => (await DisplayValue("Highest Pyre").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetHighestArmyAsync() => (await DisplayValue("Highest Army").TextContentAsync())?.Trim() ?? "";
|
||||
public async Task<string> GetHighestAlloyAsync()
|
||||
{
|
||||
return (await DisplayValue("Highest Alloy").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<int> GetChartCountAsync() =>
|
||||
await ChartsContainer.Locator("> div").CountAsync();
|
||||
}
|
||||
public async Task<string> GetHighestEtherAsync()
|
||||
{
|
||||
return (await DisplayValue("Highest Ether").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetHighestPyreAsync()
|
||||
{
|
||||
return (await DisplayValue("Highest Pyre").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<string> GetHighestArmyAsync()
|
||||
{
|
||||
return (await DisplayValue("Highest Army").TextContentAsync())?.Trim() ?? "";
|
||||
}
|
||||
|
||||
public async Task<int> GetChartCountAsync()
|
||||
{
|
||||
return await ChartsContainer.Locator("> div").CountAsync();
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,16 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class BuildOrderComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public BuildOrderComponent(Website website) => _website = website;
|
||||
|
||||
public BuildOrderComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator JsonTextarea => _website.Locator("textarea");
|
||||
|
||||
public async Task<string> GetJsonDataAsync() =>
|
||||
await JsonTextarea.InputValueAsync();
|
||||
}
|
||||
public async Task<string> GetJsonDataAsync()
|
||||
{
|
||||
return await JsonTextarea.InputValueAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Tests.Pages.BuildCalculator;
|
||||
|
||||
public class EntityClickViewComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public EntityClickViewComponent(Website website) => _website = website;
|
||||
|
||||
public EntityClickViewComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator EntityClickView => _website.Locator(".entityClickView");
|
||||
|
||||
@@ -16,16 +22,21 @@ public class EntityClickViewComponent
|
||||
|
||||
public async Task<string?> GetEntityHealthAsync()
|
||||
{
|
||||
var healthText = EntityClickView.Locator("div").Filter(new() { HasTextRegex = new System.Text.RegularExpressions.Regex("Health", System.Text.RegularExpressions.RegexOptions.IgnoreCase) }).First;
|
||||
var healthText = EntityClickView.Locator("div").Filter(new LocatorFilterOptions
|
||||
{ HasTextRegex = new Regex("Health", RegexOptions.IgnoreCase) }).First;
|
||||
if (await healthText.CountAsync() == 0) return null;
|
||||
var text = (await healthText.TextContentAsync()) ?? "";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(text, @"(\d+)");
|
||||
var text = await healthText.TextContentAsync() ?? "";
|
||||
var match = Regex.Match(text, @"(\d+)");
|
||||
return match.Success ? match.Groups[1].Value : null;
|
||||
}
|
||||
|
||||
public async Task ClickDetailedViewAsync() =>
|
||||
await EntityClickView.Locator("button").Filter(new() { HasText = "Detailed" }).ClickAsync();
|
||||
public async Task ClickDetailedViewAsync()
|
||||
{
|
||||
await EntityClickView.Locator("button").Filter(new LocatorFilterOptions { HasText = "Detailed" }).ClickAsync();
|
||||
}
|
||||
|
||||
public async Task ClickPlainViewAsync() =>
|
||||
await EntityClickView.Locator("button").Filter(new() { HasText = "Plain" }).ClickAsync();
|
||||
}
|
||||
public async Task ClickPlainViewAsync()
|
||||
{
|
||||
await EntityClickView.Locator("button").Filter(new LocatorFilterOptions { HasText = "Plain" }).ClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -3,26 +3,45 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class FilterComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public FilterComponent(Website website) => _website = website;
|
||||
|
||||
public FilterComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
private ILocator FactionSelect =>
|
||||
_website.Locator("select").Filter(new() { Has = _website.Locator("option:has-text('Aru'), option:has-text(\"Q'Rath\")") });
|
||||
_website.Locator("select").Filter(new LocatorFilterOptions
|
||||
{ Has = _website.Locator("option:has-text('Aru'), option:has-text(\"Q'Rath\")") });
|
||||
|
||||
private ILocator ImmortalSelect =>
|
||||
_website.Locator("select").Filter(new() { Has = _website.Locator("option:has-text('Orzum'), option:has-text('Ajari'), option:has-text('Atzlan'), option:has-text('Mala'), option:has-text('Xol')") });
|
||||
_website.Locator("select").Filter(new LocatorFilterOptions
|
||||
{
|
||||
Has = _website.Locator(
|
||||
"option:has-text('Orzum'), option:has-text('Ajari'), option:has-text('Atzlan'), option:has-text('Mala'), option:has-text('Xol')")
|
||||
});
|
||||
|
||||
public async Task SelectFactionAsync(string faction) =>
|
||||
public async Task SelectFactionAsync(string faction)
|
||||
{
|
||||
await FactionSelect.SelectOptionAsync(faction);
|
||||
}
|
||||
|
||||
public async Task SelectImmortalAsync(string immortal) =>
|
||||
public async Task SelectImmortalAsync(string immortal)
|
||||
{
|
||||
await ImmortalSelect.SelectOptionAsync(immortal);
|
||||
}
|
||||
|
||||
public async Task<string> GetSelectedFactionAsync() =>
|
||||
await FactionSelect.InputValueAsync();
|
||||
public async Task<string> GetSelectedFactionAsync()
|
||||
{
|
||||
return await FactionSelect.InputValueAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetSelectedImmortalAsync() =>
|
||||
await ImmortalSelect.InputValueAsync();
|
||||
public async Task<string> GetSelectedImmortalAsync()
|
||||
{
|
||||
return await ImmortalSelect.InputValueAsync();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetAvailableImmortalsAsync() =>
|
||||
await ImmortalSelect.Locator("option").AllTextContentsAsync();
|
||||
}
|
||||
public async Task<IReadOnlyList<string>> GetAvailableImmortalsAsync()
|
||||
{
|
||||
return await ImmortalSelect.Locator("option").AllTextContentsAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,45 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Tests.Pages.BuildCalculator;
|
||||
|
||||
public class HighlightsComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public HighlightsComponent(Website website) => _website = website;
|
||||
|
||||
public HighlightsComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator HighlightsContainer => _website.Locator(".highlightsContainer");
|
||||
public ILocator RequestedColumn => HighlightsContainer.Locator("div").Filter(new() { HasText = "Requested" }).Locator("+ div");
|
||||
public ILocator FinishedColumn => HighlightsContainer.Locator("div").Filter(new() { HasText = "Finished" }).Locator("+ div");
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetRequestedItemsAsync() =>
|
||||
await GetHighlightItemsAsync();
|
||||
public ILocator RequestedColumn => HighlightsContainer.Locator("div")
|
||||
.Filter(new LocatorFilterOptions { HasText = "Requested" }).Locator("+ div");
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetFinishedItemsAsync() =>
|
||||
await GetHighlightItemsAsync();
|
||||
public ILocator FinishedColumn => HighlightsContainer.Locator("div")
|
||||
.Filter(new LocatorFilterOptions { HasText = "Finished" }).Locator("+ div");
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetRequestedItemsAsync()
|
||||
{
|
||||
return await GetHighlightItemsAsync();
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<string>> GetFinishedItemsAsync()
|
||||
{
|
||||
return await GetHighlightItemsAsync();
|
||||
}
|
||||
|
||||
private async Task<IReadOnlyList<string>> GetHighlightItemsAsync()
|
||||
{
|
||||
var items = await _website.Locator(".highlightsContainer").Locator("div").Filter(new() { HasTextRegex = new System.Text.RegularExpressions.Regex(@"^\d+\s*\|") }).AllAsync();
|
||||
var items = await _website.Locator(".highlightsContainer").Locator("div")
|
||||
.Filter(new LocatorFilterOptions { HasTextRegex = new Regex(@"^\d+\s*\|") }).AllAsync();
|
||||
var result = new List<string>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
var text = (await item.TextContentAsync())?.Trim();
|
||||
if (text is not null) result.Add(text);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class HotkeyViewerComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public HotkeyViewerComponent(Website website) => _website = website;
|
||||
|
||||
public HotkeyViewerComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator KeyContainer => _website.Locator(".keyContainer");
|
||||
|
||||
@@ -12,12 +16,13 @@ public class HotkeyViewerComponent
|
||||
var upper = keyLabel.ToUpperInvariant();
|
||||
var buttons = KeyContainer.Locator("> div > div");
|
||||
var count = await buttons.CountAsync();
|
||||
for (int i = 0; i < count; i++)
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var btn = buttons.Nth(i);
|
||||
var text = (await btn.TextContentAsync())?.Trim().ToUpperInvariant() ?? "";
|
||||
if (text.StartsWith(upper)) return btn;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -25,7 +30,7 @@ public class HotkeyViewerComponent
|
||||
{
|
||||
var btn = await FindKeyButtonAsync(keyText);
|
||||
if (btn is null) throw new InvalidOperationException($"Key \"{keyText}\" not found");
|
||||
await btn.ClickAsync(new() { Force = true });
|
||||
await btn.ClickAsync(new LocatorClickOptions { Force = true });
|
||||
}
|
||||
|
||||
public async Task<string?> GetFirstEntityNameAsync(string keyText)
|
||||
@@ -44,11 +49,12 @@ public class HotkeyViewerComponent
|
||||
var entities = btn.Locator("> div");
|
||||
var count = await entities.CountAsync();
|
||||
var names = new List<string>();
|
||||
for (int i = 0; i < count; i++)
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var text = (await entities.Nth(i).TextContentAsync())?.Trim();
|
||||
if (!string.IsNullOrEmpty(text)) names.Add(text);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class OptionsComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public OptionsComponent(Website website) => _website = website;
|
||||
|
||||
private ILocator FormNumberInput(string label) =>
|
||||
_website.Locator(".formNumberContainer").Filter(new() { HasText = label }).Locator("input[type='number']");
|
||||
|
||||
private ILocator ButtonWithLabel(string label) =>
|
||||
_website.Locator("button").Filter(new() { HasText = label });
|
||||
public OptionsComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator BuildingInputDelayInput => FormNumberInput("Building Input Delay");
|
||||
public ILocator WaitTimeInput => FormNumberInput("Wait Time");
|
||||
@@ -17,22 +15,55 @@ public class OptionsComponent
|
||||
public ILocator AddWaitButton => ButtonWithLabel("Add Wait").First;
|
||||
public ILocator AddWaitToButton => ButtonWithLabel("Add Wait").Last;
|
||||
|
||||
private ILocator FormNumberInput(string label)
|
||||
{
|
||||
return _website.Locator(".formNumberContainer").Filter(new LocatorFilterOptions { HasText = label })
|
||||
.Locator("input[type='number']");
|
||||
}
|
||||
|
||||
private ILocator ButtonWithLabel(string label)
|
||||
{
|
||||
return _website.Locator("button").Filter(new LocatorFilterOptions { HasText = label });
|
||||
}
|
||||
|
||||
public async Task SetBuildingInputDelayAsync(int value)
|
||||
{
|
||||
await BuildingInputDelayInput.FillAsync(value.ToString());
|
||||
await BuildingInputDelayInput.PressAsync("Enter");
|
||||
}
|
||||
|
||||
public async Task SetWaitTimeAsync(int value) =>
|
||||
public async Task SetWaitTimeAsync(int value)
|
||||
{
|
||||
await WaitTimeInput.FillAsync(value.ToString());
|
||||
}
|
||||
|
||||
public async Task SetWaitToAsync(int value) =>
|
||||
public async Task SetWaitToAsync(int value)
|
||||
{
|
||||
await WaitToInput.FillAsync(value.ToString());
|
||||
}
|
||||
|
||||
public async Task ClickAddWaitAsync() => await AddWaitButton.ClickAsync();
|
||||
public async Task ClickAddWaitToAsync() => await AddWaitToButton.ClickAsync();
|
||||
public async Task ClickAddWaitAsync()
|
||||
{
|
||||
await AddWaitButton.ClickAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetBuildingInputDelayAsync() => await BuildingInputDelayInput.InputValueAsync();
|
||||
public async Task<string> GetWaitTimeAsync() => await WaitTimeInput.InputValueAsync();
|
||||
public async Task<string> GetWaitToAsync() => await WaitToInput.InputValueAsync();
|
||||
}
|
||||
public async Task ClickAddWaitToAsync()
|
||||
{
|
||||
await AddWaitToButton.ClickAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetBuildingInputDelayAsync()
|
||||
{
|
||||
return await BuildingInputDelayInput.InputValueAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetWaitTimeAsync()
|
||||
{
|
||||
return await WaitTimeInput.InputValueAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetWaitToAsync()
|
||||
{
|
||||
return await WaitToInput.InputValueAsync();
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,18 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class TimelineComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public TimelineComponent(Website website) => _website = website;
|
||||
|
||||
public TimelineComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator Container =>
|
||||
_website.Locator(".calculatorGrid > div").Filter(new() { HasText = "Timeline highlights" });
|
||||
_website.Locator(".calculatorGrid > div").Filter(new LocatorFilterOptions { HasText = "Timeline highlights" });
|
||||
|
||||
public async Task<bool> ContainsEntityAsync(string name)
|
||||
{
|
||||
var text = (await Container.TextContentAsync()) ?? "";
|
||||
var text = await Container.TextContentAsync() ?? "";
|
||||
return text.Contains(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,21 @@ namespace Tests.Pages.BuildCalculator;
|
||||
public class TimingComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public TimingComponent(Website website) => _website = website;
|
||||
|
||||
private ILocator FormNumberInput(string label) =>
|
||||
_website.Locator(".formNumberContainer").Filter(new() { HasText = label }).Locator("input[type='number']");
|
||||
public TimingComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator AttackTimeInput => FormNumberInput("Attack Time");
|
||||
public ILocator TravelTimeInput => FormNumberInput("Travel Time");
|
||||
|
||||
private ILocator FormNumberInput(string label)
|
||||
{
|
||||
return _website.Locator(".formNumberContainer").Filter(new LocatorFilterOptions { HasText = label })
|
||||
.Locator("input[type='number']");
|
||||
}
|
||||
|
||||
public async Task SetAttackTimeAsync(int value)
|
||||
{
|
||||
await AttackTimeInput.FillAsync(value.ToString());
|
||||
@@ -23,6 +30,13 @@ public class TimingComponent
|
||||
await TravelTimeInput.PressAsync("Enter");
|
||||
}
|
||||
|
||||
public async Task<string> GetAttackTimeAsync() => await AttackTimeInput.InputValueAsync();
|
||||
public async Task<string> GetTravelTimeAsync() => await TravelTimeInput.InputValueAsync();
|
||||
}
|
||||
public async Task<string> GetAttackTimeAsync()
|
||||
{
|
||||
return await AttackTimeInput.InputValueAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetTravelTimeAsync()
|
||||
{
|
||||
return await TravelTimeInput.InputValueAsync();
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,12 @@ public class BuildCalculatorPage : BasePage
|
||||
public ToastComponent Toast { get; }
|
||||
|
||||
public ILocator CalculatorGrid => Website.Locator(".calculatorGrid");
|
||||
public ILocator ClearBuildOrderButton => Website.Locator("button").Filter(new() { HasText = "Clear Build Order" });
|
||||
|
||||
public async Task ClickClearBuildOrderAsync() => await ClearBuildOrderButton.ClickAsync();
|
||||
}
|
||||
public ILocator ClearBuildOrderButton =>
|
||||
Website.Locator("button").Filter(new LocatorFilterOptions { HasText = "Clear Build Order" });
|
||||
|
||||
public async Task ClickClearBuildOrderAsync()
|
||||
{
|
||||
await ClearBuildOrderButton.ClickAsync();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ namespace Tests.Pages;
|
||||
|
||||
public class DatabasePage : BasePage
|
||||
{
|
||||
public DatabasePage(Website website) : base(website) { }
|
||||
public DatabasePage(Website website) : base(website)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Url => "database";
|
||||
|
||||
@@ -23,4 +25,4 @@ public class DatabasePage : BasePage
|
||||
var el = Website.FindById("entityName").Nth(index);
|
||||
return (await el.InnerTextAsync()).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ namespace Tests.Pages;
|
||||
|
||||
public class DatabaseSinglePage : BasePage
|
||||
{
|
||||
public DatabaseSinglePage(Website website) : base(website) { }
|
||||
public DatabaseSinglePage(Website website) : base(website)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Url => "database";
|
||||
|
||||
@@ -11,15 +13,23 @@ public class DatabaseSinglePage : BasePage
|
||||
await Website.GotoAsync($"{Url}/{searchText}");
|
||||
}
|
||||
|
||||
public async Task<string> GetEntityNameAsync() =>
|
||||
(await Website.FindById("entityName").InnerTextAsync()).Trim();
|
||||
public async Task<string> GetEntityNameAsync()
|
||||
{
|
||||
return (await Website.FindById("entityName").InnerTextAsync()).Trim();
|
||||
}
|
||||
|
||||
public async Task<string> GetEntityHealthAsync() =>
|
||||
(await Website.FindById("entityHealth").InnerTextAsync()).Trim();
|
||||
public async Task<string> GetEntityHealthAsync()
|
||||
{
|
||||
return (await Website.FindById("entityHealth").InnerTextAsync()).Trim();
|
||||
}
|
||||
|
||||
public async Task<string> GetInvalidSearchAsync() =>
|
||||
(await Website.FindById("invalidSearch").InnerTextAsync()).Trim();
|
||||
public async Task<string> GetInvalidSearchAsync()
|
||||
{
|
||||
return (await Website.FindById("invalidSearch").InnerTextAsync()).Trim();
|
||||
}
|
||||
|
||||
public async Task<string> GetValidSearchAsync() =>
|
||||
(await Website.FindById("validSearch").InnerTextAsync()).Trim();
|
||||
}
|
||||
public async Task<string> GetValidSearchAsync()
|
||||
{
|
||||
return (await Website.FindById("validSearch").InnerTextAsync()).Trim();
|
||||
}
|
||||
}
|
||||
@@ -2,29 +2,76 @@ namespace Tests.Pages;
|
||||
|
||||
public class HarassCalculatorPage : BasePage
|
||||
{
|
||||
public HarassCalculatorPage(Website website) : base(website) { }
|
||||
public HarassCalculatorPage(Website website) : base(website)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Url => "harass-calculator";
|
||||
|
||||
public async Task SetWorkersLostToHarassAsync(int number) =>
|
||||
public async Task SetWorkersLostToHarassAsync(int number)
|
||||
{
|
||||
await EnterAndPressAsync("numberOfWorkersLostToHarass", number);
|
||||
}
|
||||
|
||||
public async Task SetNumberOfTownHallsExistingAsync(int number) =>
|
||||
public async Task SetNumberOfTownHallsExistingAsync(int number)
|
||||
{
|
||||
await EnterAndPressAsync("numberOfTownHallsExisting", number);
|
||||
}
|
||||
|
||||
public async Task SetTownHallTravelTimeAsync(int index, int seconds) =>
|
||||
public async Task SetTownHallTravelTimeAsync(int index, int seconds)
|
||||
{
|
||||
await EnterInputAtIndexAsync("numberOfTownHallTravelTimes", index, seconds);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalAlloyHarassmentAsync() => await ReadIntAsync("totalAlloyHarassment");
|
||||
public async Task<int> GetWorkerReplacementCostAsync() => await ReadIntAsync("workerReplacementCost");
|
||||
public async Task<int> GetDelayedMiningCostAsync() => await ReadIntAsync("delayedMiningCost");
|
||||
public async Task<int> GetAverageTravelTimeAsync() => await ReadIntAsync("getAverageTravelTime");
|
||||
public async Task<int> GetExampleTotalAlloyLossAsync() => await ReadIntAsync("exampleTotalAlloyLoss");
|
||||
public async Task<int> GetExampleWorkerCostAsync() => await ReadIntAsync("exampleWorkerCost");
|
||||
public async Task<int> GetExampleMiningTimeCostAsync() => await ReadIntAsync("exampleMiningTimeCost");
|
||||
public async Task<int> GetExampleTotalAlloyLossAccurateAsync() => await ReadIntAsync("exampleTotalAlloyLossAccurate");
|
||||
public async Task<int> GetExampleTotalAlloyLossDifferenceAsync() => await ReadIntAsync("exampleTotalAlloyLossDifference");
|
||||
public async Task<int> GetExampleTotalAlloyLossAccurateDifferenceAsync() => await ReadIntAsync("exampleTotalAlloyLossAccurateDifference");
|
||||
public async Task<int> GetTotalAlloyHarassmentAsync()
|
||||
{
|
||||
return await ReadIntAsync("totalAlloyHarassment");
|
||||
}
|
||||
|
||||
public async Task<int> GetWorkerReplacementCostAsync()
|
||||
{
|
||||
return await ReadIntAsync("workerReplacementCost");
|
||||
}
|
||||
|
||||
public async Task<int> GetDelayedMiningCostAsync()
|
||||
{
|
||||
return await ReadIntAsync("delayedMiningCost");
|
||||
}
|
||||
|
||||
public async Task<int> GetAverageTravelTimeAsync()
|
||||
{
|
||||
return await ReadIntAsync("getAverageTravelTime");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleTotalAlloyLossAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleTotalAlloyLoss");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleWorkerCostAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleWorkerCost");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleMiningTimeCostAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleMiningTimeCost");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleTotalAlloyLossAccurateAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleTotalAlloyLossAccurate");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleTotalAlloyLossDifferenceAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleTotalAlloyLossDifference");
|
||||
}
|
||||
|
||||
public async Task<int> GetExampleTotalAlloyLossAccurateDifferenceAsync()
|
||||
{
|
||||
return await ReadIntAsync("exampleTotalAlloyLossAccurateDifference");
|
||||
}
|
||||
|
||||
private async Task EnterAndPressAsync(string id, int value)
|
||||
{
|
||||
@@ -45,4 +92,4 @@ public class HarassCalculatorPage : BasePage
|
||||
var text = await Website.FindById(id).TextContentAsync() ?? "";
|
||||
return int.Parse(text.Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@ namespace Tests.Shared;
|
||||
public class NavigationBar
|
||||
{
|
||||
private readonly Website _website;
|
||||
public NavigationBar(Website website) => _website = website;
|
||||
|
||||
public NavigationBar(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator SearchButton => _website.Locator("#desktop-searchButton");
|
||||
|
||||
@@ -17,4 +21,4 @@ public class NavigationBar
|
||||
await SearchButton.ClickAsync();
|
||||
return _website.SearchDialog;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@ namespace Tests.Shared;
|
||||
public class SearchDialog
|
||||
{
|
||||
private readonly Website _website;
|
||||
public SearchDialog(Website website) => _website = website;
|
||||
|
||||
public SearchDialog(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator SearchBackground => _website.FindById("searchBackground");
|
||||
public ILocator SearchInput => _website.FindById("searchInput");
|
||||
@@ -23,4 +27,4 @@ public class SearchDialog
|
||||
{
|
||||
await _website.ClickElementAsync(_website.Locator($"button[label=\"{label}\"]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@ namespace Tests.Shared;
|
||||
public class ToastComponent
|
||||
{
|
||||
private readonly Website _website;
|
||||
public ToastComponent(Website website) => _website = website;
|
||||
|
||||
public ToastComponent(Website website)
|
||||
{
|
||||
_website = website;
|
||||
}
|
||||
|
||||
public ILocator Container => _website.Locator(".toastsContainer");
|
||||
public ILocator Toasts => _website.Locator(".toastsContainer .toastContainer");
|
||||
@@ -24,7 +28,7 @@ public class ToastComponent
|
||||
return Array.from(titles).some(t => t.textContent.trim().includes(expected));
|
||||
}",
|
||||
text,
|
||||
new() { Timeout = 3000 }
|
||||
new PageWaitForFunctionOptions { Timeout = 3000 }
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@@ -33,4 +37,4 @@ public class ToastComponent
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@ namespace Tests.Specs;
|
||||
[FixtureLifeCycle(LifeCycle.SingleInstance)]
|
||||
public class BuildCalculatorTests : PageTest
|
||||
{
|
||||
private Helpers.Website _website = null!;
|
||||
private Website _website = null!;
|
||||
|
||||
[SetUp]
|
||||
public void CreateWebsite() => _website = new Helpers.Website(Page);
|
||||
public void CreateWebsite()
|
||||
{
|
||||
_website = new Website(Page);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AddEntitiesViaKeyboardQWE()
|
||||
@@ -112,4 +115,4 @@ public class BuildCalculatorTests : PageTest
|
||||
var hasToast = await calc.Toast.HasToastContainingAsync("Not Enough Ether");
|
||||
Assert.That(hasToast, Is.True);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@ namespace Tests.Specs;
|
||||
[FixtureLifeCycle(LifeCycle.SingleInstance)]
|
||||
public class HarassCalculatorTests : PageTest
|
||||
{
|
||||
private Helpers.Website _website = null!;
|
||||
private Website _website = null!;
|
||||
|
||||
[SetUp]
|
||||
public void CreateWebsite() => _website = new Helpers.Website(Page);
|
||||
public void CreateWebsite()
|
||||
{
|
||||
_website = new Website(Page);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CalculatorInput()
|
||||
@@ -40,4 +43,4 @@ public class HarassCalculatorTests : PageTest
|
||||
Assert.That(await page.GetExampleTotalAlloyLossAccurateDifferenceAsync(), Is.EqualTo(270));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,18 @@ namespace Tests.Specs;
|
||||
[FixtureLifeCycle(LifeCycle.SingleInstance)]
|
||||
public class LinksTests : PageTest
|
||||
{
|
||||
private Helpers.Website _website = null!;
|
||||
private Website _website = null!;
|
||||
|
||||
[SetUp]
|
||||
public void CreateWebsite() => _website = new Helpers.Website(Page);
|
||||
public void CreateWebsite()
|
||||
{
|
||||
_website = new Website(Page);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task VerifyPageLinks()
|
||||
{
|
||||
_website = new Helpers.Website(Page);
|
||||
_website = new Website(Page);
|
||||
|
||||
await _website.HarassCalculatorPage.GotoAsync();
|
||||
var harassLinks = await _website.HarassCalculatorPage.GetLinksAsync();
|
||||
@@ -34,8 +37,8 @@ public class LinksTests : PageTest
|
||||
{
|
||||
if (link.StartsWith("mailto")) return;
|
||||
|
||||
using var client = new System.Net.Http.HttpClient();
|
||||
using var client = new HttpClient();
|
||||
var response = await client.GetAsync(link);
|
||||
Assert.That(response.IsSuccessStatusCode, Is.True, $"Link '{link}' returned {response.StatusCode}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@ namespace Tests.Specs;
|
||||
[FixtureLifeCycle(LifeCycle.SingleInstance)]
|
||||
public class SearchFeaturesTests : PageTest
|
||||
{
|
||||
private Helpers.Website _website = null!;
|
||||
private Website _website = null!;
|
||||
|
||||
[SetUp]
|
||||
public void CreateWebsite() => _website = new Helpers.Website(Page);
|
||||
public void CreateWebsite()
|
||||
{
|
||||
_website = new Website(Page);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DesktopOpenCloseSearchDialog()
|
||||
@@ -65,4 +68,4 @@ public class SearchFeaturesTests : PageTest
|
||||
Assert.That(invalidSearch, Is.EqualTo("not throne"));
|
||||
Assert.That(validSearch, Is.EqualTo("Throne"));
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageReference Include="NUnit" Version="4.3.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Playwright.NUnit" Version="1.52.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.0"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
<PackageReference Include="Microsoft.Playwright.NUnit" Version="1.52.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Microsoft.Playwright" />
|
||||
<Using Include="Tests.Helpers" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="Microsoft.Playwright"/>
|
||||
<Using Include="Tests.Helpers"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user