Merge branch 'develop'

This commit is contained in:
2022-05-03 19:18:45 -04:00
19 changed files with 269 additions and 89 deletions
-8
View File
@@ -1,13 +1,5 @@
@page "/" @page "/"
@inject ITrackingNavigationState TrackingNavigationState
@inject IAnalytics GlobalTracking
@layout PageLayout @layout PageLayout
<DevOnlyComponent>
<LinkButtonComponent Href="https://github.com/JonathanMcCaffrey/IGP-Fan-Reference/blob/main/IGP/Pages/HarassCalculatorPage.razor">
View on GitHub <i class="fa-brands fa-github" style="font-size: 24px; margin-left: 5px;"></i>
</LinkButtonComponent>
</DevOnlyComponent>
<HomePage/> <HomePage/>
+1 -1
View File
@@ -14,7 +14,7 @@
} }
else else
{ {
<div class="content"> <div id="content" class="content">
@Body @Body
</div> </div>
@@ -23,6 +23,8 @@
<Title>Work In Progress and Not Fully Tested</Title> <Title>Work In Progress and Not Fully Tested</Title>
<Message> <Message>
Build Calculator hasn't been thoroughly tested. Bugs and inaccurate results assumed. Build Calculator hasn't been thoroughly tested. Bugs and inaccurate results assumed.
<br/>
Currently not considering running out of alloy and ether to harvest.
</Message> </Message>
</AlertComponent> </AlertComponent>
@@ -7,14 +7,14 @@
<div class="bankContainer"> <div class="bankContainer">
<FormDisplayComponent Label="Time"> <FormDisplayComponent Label="Time">
<Display>@BuildOrderService.GetLastRequestInterval() | T @Interval.ToTime(BuildOrderService.GetLastRequestInterval())</Display> <Display>@(BuildOrderService.GetLastRequestInterval() + 1) | T @Interval.ToTime(BuildOrderService.GetLastRequestInterval() + 1)</Display>
</FormDisplayComponent> </FormDisplayComponent>
<div class="bankRow"> <div class="bankRow">
<FormDisplayComponent Label="Alloy"> <FormDisplayComponent Label="Alloy">
<Display>@_economy.Alloy</Display> <Display>@_economy.Alloy +@_economy.AlloyIncome</Display>
</FormDisplayComponent> </FormDisplayComponent>
<FormDisplayComponent Label="Ether"> <FormDisplayComponent Label="Ether">
<Display>@_economy.Ether</Display> <Display>@Math.Round(_economy.Ether) +@Math.Round(_economy.EtherIncome)</Display>
</FormDisplayComponent> </FormDisplayComponent>
</div> </div>
<div class="bankRow"> <div class="bankRow">
@@ -77,6 +77,9 @@
{ {
base.OnInitialized(); base.OnInitialized();
BuildOrderService.Subscribe(OnBuildOrderChanged); BuildOrderService.Subscribe(OnBuildOrderChanged);
_economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval() + 1);
} }
protected override bool ShouldRender() protected override bool ShouldRender()
@@ -102,7 +105,7 @@
void OnBuildOrderChanged() void OnBuildOrderChanged()
{ {
_economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval()); _economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval() + 1);
var ordersOverTime = BuildOrderService.GetOrders(); var ordersOverTime = BuildOrderService.GetOrders();
+1 -1
View File
@@ -1 +1 @@
[{"Key":"GamePatch","Value":"v0.0.6.9553a"},{"Key":"LastUpdated","Value":"May 02, 2022"}] [{"Key":"GamePatch","Value":"v0.0.6.9553a"},{"Key":"LastUpdated","Value":"May 03, 2022"}]
+2
View File
@@ -7,7 +7,9 @@ public class EconomyModel
{ {
public int Interval { get; set; } = 0; public int Interval { get; set; } = 0;
public float Alloy { get; set; } = 0; public float Alloy { get; set; } = 0;
public float AlloyIncome { get; set; } = 0;
public float Ether { get; set; } = 0; public float Ether { get; set; } = 0;
public float EtherIncome { get; set; } = 0;
public float Pyre { get; set; } = 0; public float Pyre { get; set; } = 0;
public int Supply { get; set; } = 0; public int Supply { get; set; } = 0;
public int WorkerCount { get; set; } = 6; public int WorkerCount { get; set; } = 6;
+8
View File
@@ -173,6 +173,8 @@ public class EconomyService : IEconomyService
{ {
var usedWorkers = Math.Min(harvester.Slots, freeWorkers); var usedWorkers = Math.Min(harvester.Slots, freeWorkers);
economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers; economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers;
economyAtSecond.AlloyIncome += harvester.HarvestedPerInterval * usedWorkers;
freeWorkers -= usedWorkers; freeWorkers -= usedWorkers;
if (usedWorkers < harvester.Slots) workersNeeded += 1; if (usedWorkers < harvester.Slots) workersNeeded += 1;
@@ -181,10 +183,16 @@ public class EconomyService : IEconomyService
if (harvester.RequiresWorker == false) if (harvester.RequiresWorker == false)
{ {
if (harvester.Resource == ResourceType.Ether) if (harvester.Resource == ResourceType.Ether)
{
economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots; economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots;
economyAtSecond.EtherIncome += harvester.HarvestedPerInterval * harvester.Slots;
}
if (harvester.Resource == ResourceType.Alloy) if (harvester.Resource == ResourceType.Alloy)
{
economyAtSecond.Alloy += harvester.HarvestedPerInterval * harvester.Slots; economyAtSecond.Alloy += harvester.HarvestedPerInterval * harvester.Slots;
economyAtSecond.AlloyIncome += harvester.HarvestedPerInterval * harvester.Slots;
}
} }
} }
+4 -12
View File
@@ -10,20 +10,11 @@ public enum DeploymentType
public class BaseTest public class BaseTest
{ {
protected static readonly DeploymentType DeploymentType =
Environment.GetEnvironmentVariable("TEST_HOOK") != null
? DeploymentType.Dev
: DeploymentType.Local;
protected static readonly string WebsiteUrl =
DeploymentType.Equals(DeploymentType.Dev)
? "https://calm-mud-04916b210.1.azurestaticapps.net/"
: "https://localhost:7234";
protected static readonly TestReport TestReport = new(); protected static readonly TestReport TestReport = new();
protected static Website WebsiteInstance = default!; protected static Website WebsiteInstance = default!;
protected readonly HttpClient HttpClient = new();
protected static Website Website protected static Website Website
{ {
@@ -35,7 +26,7 @@ public class BaseTest
options.AcceptInsecureCertificates = true; options.AcceptInsecureCertificates = true;
if (DeploymentType.Equals(DeploymentType.Dev)) options.AddArgument("--headless"); if (Website.DeploymentType.Equals(DeploymentType.Dev)) options.AddArgument("--headless");
options.AddArgument("--ignore-certificate-errors"); options.AddArgument("--ignore-certificate-errors");
options.AddArgument("--start-maximized"); options.AddArgument("--start-maximized");
options.AddArgument("--test-type"); options.AddArgument("--test-type");
@@ -43,10 +34,11 @@ public class BaseTest
IWebDriver webDriver = new FirefoxDriver(Environment.CurrentDirectory, options); IWebDriver webDriver = new FirefoxDriver(Environment.CurrentDirectory, options);
WebsiteInstance = new Website(webDriver); WebsiteInstance = new Website(webDriver, TestReport);
} }
return WebsiteInstance; return WebsiteInstance;
} }
} }
} }
+29
View File
@@ -0,0 +1,29 @@
using TestAutomation.Shared;
using TestAutomation.Utils;
namespace TestAutomation.Pages;
public abstract class BasePage : BaseElement
{
protected BasePage(Website website) : base(website)
{
}
private IEnumerable<string> Links =>
Website.FindAllWithTag(Website.Find("content"), "a")
.Select(x => x.GetAttribute("href"));
public abstract string Url { get; set; }
public IEnumerable<string> GetLinks()
{
try
{
return Links;
}
catch (Exception e)
{
throw new Exception($"Couldn't get links on page {Url}");
}
}
}
+9 -2
View File
@@ -1,10 +1,9 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using TestAutomation.Shared;
using TestAutomation.Utils; using TestAutomation.Utils;
namespace TestAutomation.Pages; namespace TestAutomation.Pages;
public class DatabasePage : BaseElement public class DatabasePage : BasePage
{ {
public DatabasePage(Website website) : base(website) public DatabasePage(Website website) : base(website)
{ {
@@ -12,6 +11,8 @@ public class DatabasePage : BaseElement
private IWebElement FilterNameInput => Website.Find("filterName"); private IWebElement FilterNameInput => Website.Find("filterName");
public override string Url { get; set; } = "database";
private ReadOnlyCollection<IWebElement> EntityNames() private ReadOnlyCollection<IWebElement> EntityNames()
{ {
@@ -43,4 +44,10 @@ public class DatabasePage : BaseElement
result = EntityNames()[index].Text; result = EntityNames()[index].Text;
return this; return this;
} }
public DatabasePage Goto()
{
Website.Goto(Url);
return this;
}
} }
+10 -3
View File
@@ -1,9 +1,8 @@
using TestAutomation.Shared; using TestAutomation.Utils;
using TestAutomation.Utils;
namespace TestAutomation.Pages; namespace TestAutomation.Pages;
public class DatabaseSinglePage : BaseElement public class DatabaseSinglePage : BasePage
{ {
public DatabaseSinglePage(Website website) : base(website) public DatabaseSinglePage(Website website) : base(website)
{ {
@@ -15,6 +14,8 @@ public class DatabaseSinglePage : BaseElement
private IWebElement InvalidSearch => Website.Find("invalidSearch"); private IWebElement InvalidSearch => Website.Find("invalidSearch");
private IWebElement ValidSearch => Website.Find("validSearch"); private IWebElement ValidSearch => Website.Find("validSearch");
public override string Url { get; set; } = "database";
public DatabaseSinglePage GetEntityName(out string result) public DatabaseSinglePage GetEntityName(out string result)
{ {
@@ -39,4 +40,10 @@ public class DatabaseSinglePage : BaseElement
result = ValidSearch.Text; result = ValidSearch.Text;
return this; return this;
} }
public DatabaseSinglePage Goto(string searchText)
{
Website.Goto($"{Url}/{searchText}");
return this;
}
} }
+15 -3
View File
@@ -1,9 +1,8 @@
using TestAutomation.Shared; using TestAutomation.Utils;
using TestAutomation.Utils;
namespace TestAutomation.Pages; namespace TestAutomation.Pages;
public class HarassCalculatorPage : BaseElement public class HarassCalculatorPage : BasePage
{ {
public HarassCalculatorPage(Website website) : base(website) public HarassCalculatorPage(Website website) : base(website)
{ {
@@ -24,6 +23,8 @@ public class HarassCalculatorPage : BaseElement
private int ExampleTotalAlloyLossAccurate => Website.FindInt("exampleTotalAlloyLossAccurate"); private int ExampleTotalAlloyLossAccurate => Website.FindInt("exampleTotalAlloyLossAccurate");
private int ExampleTotalAlloyLossAccurateDifference => Website.FindInt("exampleTotalAlloyLossAccurateDifference"); private int ExampleTotalAlloyLossAccurateDifference => Website.FindInt("exampleTotalAlloyLossAccurateDifference");
public override string Url { get; set; } = "harass-calculator";
public HarassCalculatorPage SetWorkersLostToHarass(int number) public HarassCalculatorPage SetWorkersLostToHarass(int number)
{ {
Website.EnterInput(NumberOfWorkersLostToHarass, number); Website.EnterInput(NumberOfWorkersLostToHarass, number);
@@ -84,4 +85,15 @@ public class HarassCalculatorPage : BaseElement
result = ExampleTotalAlloyLossAccurateDifference; result = ExampleTotalAlloyLossAccurateDifference;
return this; return this;
} }
protected HarassCalculatorPage NavigateTo()
{
return this;
}
public HarassCalculatorPage Goto()
{
Website.Goto(Url);
return this;
}
} }
+1 -1
View File
@@ -2,7 +2,7 @@
namespace TestAutomation.Shared; namespace TestAutomation.Shared;
public class BaseElement public abstract class BaseElement
{ {
protected readonly Website Website; protected readonly Website Website;
+15 -12
View File
@@ -5,18 +5,28 @@ namespace TestAutomation;
[TestFixture] [TestFixture]
public class TestHarassCalculator : BaseTest public class TestHarassCalculator : BaseTest
{ {
[SetUp]
public void SetUp()
{
TestReport.CreateTest();
}
[TearDown]
public void TearDown()
{
TestReport.ThrowErrors();
}
[Test] [Test]
public void CalculatorInput() public void CalculatorInput()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/harass-calculator");
var expectedTotalAlloyHarassment = 240; var expectedTotalAlloyHarassment = 240;
try
{
Website.HarassCalculatorPage Website.HarassCalculatorPage
.Goto()
.SetWorkersLostToHarass(3) .SetWorkersLostToHarass(3)
.SetNumberOfTownHallsExisting(2) .SetNumberOfTownHallsExisting(2)
.SetTownHallTravelTime(0, 30) .SetTownHallTravelTime(0, 30)
@@ -27,19 +37,11 @@ public class TestHarassCalculator : BaseTest
"does not equal " + "does not equal " +
$"foundTotalAlloyHarassment of {foundTotalAlloyHarassment} ")); $"foundTotalAlloyHarassment of {foundTotalAlloyHarassment} "));
} }
catch (Exception e)
{
TestReport.CheckPassed(false,
TestMessage.CreateFailedMessage(e.StackTrace!));
}
}
[Test] [Test]
public void CalculatedExampleInformation() public void CalculatedExampleInformation()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/harass-calculator");
var expectedExampleTotalAlloyLoss = 720; var expectedExampleTotalAlloyLoss = 720;
var expectedExampleWorkerCost = 300; var expectedExampleWorkerCost = 300;
@@ -49,6 +51,7 @@ public class TestHarassCalculator : BaseTest
var expectedExampleTotalAlloyLossAccurateDifference = 270; var expectedExampleTotalAlloyLossAccurateDifference = 270;
Website.HarassCalculatorPage Website.HarassCalculatorPage
.Goto()
.GetExampleTotalAlloyLoss(out var foundTotalAlloyLoss) .GetExampleTotalAlloyLoss(out var foundTotalAlloyLoss)
.GetExampleWorkerCost(out var foundExampleWorkerCost) .GetExampleWorkerCost(out var foundExampleWorkerCost)
.GetExampleMiningTimeCost(out var foundExampleMiningTimeCost) .GetExampleMiningTimeCost(out var foundExampleMiningTimeCost)
+31
View File
@@ -0,0 +1,31 @@
namespace TestAutomation;
[TestFixture]
public class TestLinks : BaseTest
{
[SetUp]
public void SetUp()
{
TestReport.CreateTest();
}
[TearDown]
public void TearDown()
{
TestReport.ThrowErrors();
}
[Test]
public void VerifyPageLinks()
{
Website.HarassCalculatorPage.Goto();
TestReport.VerifyLinks(Website.HarassCalculatorPage).Wait();
Website.DatabasePage.Goto();
TestReport.VerifyLinks(Website.DatabasePage).Wait();
Website.DatabaseSinglePage.Goto("throne");
TestReport.VerifyLinks(Website.DatabaseSinglePage).Wait();
}
}
+28 -15
View File
@@ -5,14 +5,27 @@ namespace TestAutomation;
[TestFixture] [TestFixture]
public class TestSearchFeatures : BaseTest public class TestSearchFeatures : BaseTest
{ {
[SetUp]
public void SetUp()
{
TestReport.CreateTest();
}
[TearDown]
public void TearDown()
{
TestReport.ThrowErrors();
}
[Test] [Test]
public void DesktopOpenCloseSearchDialog() public void DesktopOpenCloseSearchDialog()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/");
Website.NavigationBar Website
.Goto()
.NavigationBar
.ClickSearchButton() .ClickSearchButton()
.CloseDialog() .CloseDialog()
.ClickHomeLink(); .ClickHomeLink();
@@ -21,12 +34,10 @@ public class TestSearchFeatures : BaseTest
[Test] [Test]
public void DesktopSearchForThrone() public void DesktopSearchForThrone()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/"); Website
.Goto()
Website.NavigationBar .NavigationBar.ClickSearchButton()
.ClickSearchButton()
.Search("Throne") .Search("Throne")
.SelectSearchEntity("Throne") .SelectSearchEntity("Throne")
.GetEntityName(out var name) .GetEntityName(out var name)
@@ -36,45 +47,47 @@ public class TestSearchFeatures : BaseTest
new TestMessage { Description = "Couldn't find Throne via search." }); new TestMessage { Description = "Couldn't find Throne via search." });
TestReport.CheckPassed(!health.Trim().Equals(""), TestReport.CheckPassed(!health.Trim().Equals(""),
new TestMessage { Description = "Throne has no visible health!" }); new TestMessage { Description = "Throne has no visible health!" });
} }
[Test] [Test]
public void DesktopFilterForThrone() public void DesktopFilterForThrone()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database");
Website.DatabasePage Website.DatabasePage
.Goto()
.FilterName("Throne") .FilterName("Throne")
.GetEntityName(0, out var name); .GetEntityName(0, out var name);
TestReport.CheckPassed(name.Equals("Throne"), TestReport.CheckPassed(name.Equals("Throne"),
new TestMessage { Description = "Couldn't find Throne via filter." }); new TestMessage { Description = "Couldn't find Throne via filter." });
} }
[Test] [Test]
public void SeeThroneByDefault() public void SeeThroneByDefault()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database");
Website.DatabasePage Website.DatabasePage
.Goto()
.GetEntityName("army", "throne", out var name); .GetEntityName("army", "throne", out var name);
TestReport.CheckPassed(name.Equals("Throne"), TestReport.CheckPassed(name.Equals("Throne"),
new TestMessage { Description = "Couldn't find Throne on the page by default." }); new TestMessage { Description = "Couldn't find Throne on the page by default." });
} }
[Test] [Test]
public void DirectLinkNotThroneFailure() public void DirectLinkNotThroneFailure()
{ {
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database/not throne");
Website.DatabaseSinglePage Website.DatabaseSinglePage
.Goto("not throne")
.GetInvalidSearch(out var invalidSearch) .GetInvalidSearch(out var invalidSearch)
.GetValidSearch(out var validSearch); .GetValidSearch(out var validSearch);
@@ -83,6 +96,6 @@ public class TestSearchFeatures : BaseTest
TestReport.CheckPassed(validSearch.Equals("Throne"), TestReport.CheckPassed(validSearch.Equals("Throne"),
new TestMessage { Description = "Couldn't find valid search text on the page." }); new TestMessage { Description = "Couldn't find valid search text on the page." });
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database/not throne");
} }
} }
+49 -4
View File
@@ -11,18 +11,63 @@ public class TestReport
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
public Test CreateTest() public Test CreateTest()
{ {
var testName = new StackTrace().GetFrame(1)!.GetMethod()!.Name!; Tests.Add(new Test
Tests.Add(new Test { Name = testName }); {
Name = TestContext.CurrentContext.Test.Name
});
return Tests.Last(); return Tests.Last();
} }
public void ThrowErrors()
{
if (!Tests.Last().Result)
{
string messages = string.Join("\n", Tests.Last().Messages.Select(x => x.Description).ToList());
throw new Exception(
$"{Tests.Last().Name} test failed with {Tests.Last().Messages.Count} messages.\n\n{messages}");
}
}
public async Task VerifyLinks(BasePage page)
{
foreach (var link in page.GetLinks())
try
{
if(link.StartsWith("mailto")) continue;
using var client = new HttpClient();
var response = await client.GetAsync(link);
if (!response.IsSuccessStatusCode)
{
CheckPassed(false,
new TestMessage
{
Color = "red", Title = "Bad Link",
Description = $"{link} failed on page {page.Url} with status code {response.StatusCode}"
});
Console.WriteLine(response.StatusCode.ToString());
}
}
catch (Exception e)
{
CheckPassed(false,
new TestMessage
{
Color = "red", Title = "Bad Link",
Description = $"{link} failed on page {page.Url} with stacktrace {e.StackTrace}"
});
}
}
public void CheckPassed(bool passed, TestMessage message) public void CheckPassed(bool passed, TestMessage message)
{ {
if (passed) return; if (passed) return;
Tests.Last().Result = false; Tests.Last().Result = false;
Tests.Last().Messages.Add(message); Tests.Last().Messages.Add(message);
throw new Exception(message.Description);
} }
public bool DidTestsPass() public bool DidTestsPass()
+37 -1
View File
@@ -7,11 +7,24 @@ namespace TestAutomation.Utils;
public class Website public class Website
{ {
public static readonly DeploymentType DeploymentType =
Environment.GetEnvironmentVariable("TEST_HOOK")!.Contains("localhost")
? DeploymentType.Local
: DeploymentType.Dev;
public static readonly string Url =
DeploymentType.Equals(DeploymentType.Dev)
? "https://calm-mud-04916b210.1.azurestaticapps.net"
: "https://localhost:7234";
public readonly ScreenType ScreenType = ScreenType.Desktop; public readonly ScreenType ScreenType = ScreenType.Desktop;
public Website(IWebDriver webDriver) public TestReport TestReport { get; set; }
public Website(IWebDriver webDriver, TestReport testReport)
{ {
WebDriver = webDriver; WebDriver = webDriver;
TestReport = testReport;
// Pages // Pages
HarassCalculatorPage = new HarassCalculatorPage(this); HarassCalculatorPage = new HarassCalculatorPage(this);
@@ -100,6 +113,16 @@ public class Website
} }
} }
public ReadOnlyCollection<IWebElement> FindAllWithTag(string tag)
{
return WebDriver.FindElements(By.TagName(tag));
}
public ReadOnlyCollection<IWebElement> FindAllWithTag(IWebElement parent, string tag)
{
return parent.FindElements(By.TagName(tag));
}
public IWebElement FindButtonWithLabel(string label) public IWebElement FindButtonWithLabel(string label)
{ {
@@ -177,4 +200,17 @@ public class Website
{ {
return Find(byId).Text; return Find(byId).Text;
} }
public Website Goto()
{
WebDriver.Navigate().GoToUrl($"{Url}");
return this;
}
public void Goto(string path)
{
var url = $"{Url}/{path}";
WebDriver.Navigate().GoToUrl($"{url}");
}
} }
+1 -3
View File
@@ -9,15 +9,13 @@ public class Tests : BaseTest
[OneTimeSetUp] [OneTimeSetUp]
public void Setup() public void Setup()
{ {
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl); Website.Goto();
Website.WebDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15); Website.WebDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15);
} }
[OneTimeTearDown] [OneTimeTearDown]
public void TearDown() public void TearDown()
{ {
HttpClient HttpClient = new();
Website.WebDriver.Quit(); Website.WebDriver.Quit();
var message = new var message = new