diff --git a/AOW4.Client/AOW4.Client.csproj b/AOW4.Client/AOW4.Client.csproj
index ab51c0e..91750a3 100644
--- a/AOW4.Client/AOW4.Client.csproj
+++ b/AOW4.Client/AOW4.Client.csproj
@@ -1,16 +1,16 @@
-
- net10.0
- enable
- enable
- true
- Default
- true
-
+
+ net10.0
+ enable
+ enable
+ true
+ Default
+ true
+
-
-
-
+
+
+
diff --git a/AOW4.Client/Pages/Counter.razor b/AOW4.Client/Pages/Counter.razor
index 6b9e8cb..22e3468 100644
--- a/AOW4.Client/Pages/Counter.razor
+++ b/AOW4.Client/Pages/Counter.razor
@@ -10,10 +10,11 @@
@code {
- private int currentCount = 0;
+ private int currentCount;
private void IncrementCount()
{
currentCount++;
}
+
}
diff --git a/AOW4.Client/Program.cs b/AOW4.Client/Program.cs
index 519269f..91db88a 100644
--- a/AOW4.Client/Program.cs
+++ b/AOW4.Client/Program.cs
@@ -2,4 +2,4 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
-await builder.Build().RunAsync();
+await builder.Build().RunAsync();
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/AOW4.SeleniumTests.csproj b/AOW4.SeleniumTests/AOW4.SeleniumTests.csproj
index ae70d08..47ceaaf 100644
--- a/AOW4.SeleniumTests/AOW4.SeleniumTests.csproj
+++ b/AOW4.SeleniumTests/AOW4.SeleniumTests.csproj
@@ -1,18 +1,18 @@
-
- net10.0
- false
- enable
- enable
-
+
+ net10.0
+ false
+ enable
+ enable
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/AOW4.SeleniumTests/Driver/DriverFactory.cs b/AOW4.SeleniumTests/Driver/DriverFactory.cs
index aa2643a..fcc922e 100644
--- a/AOW4.SeleniumTests/Driver/DriverFactory.cs
+++ b/AOW4.SeleniumTests/Driver/DriverFactory.cs
@@ -1,4 +1,3 @@
-using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
@@ -10,10 +9,9 @@ public static class DriverFactory
{
var options = new ChromeOptions();
var headless = Environment.GetEnvironmentVariable("HEADLESS");
- if (!string.IsNullOrEmpty(headless) && (headless == "1" || headless.Equals("true", StringComparison.OrdinalIgnoreCase)))
- {
+ if (!string.IsNullOrEmpty(headless) &&
+ (headless == "1" || headless.Equals("true", StringComparison.OrdinalIgnoreCase)))
options.AddArgument("--headless=new");
- }
options.AddArgument("--disable-gpu");
options.AddArgument("--no-sandbox");
@@ -24,4 +22,4 @@ public static class DriverFactory
return new ChromeDriver(service, options);
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Pages/CounterPage.cs b/AOW4.SeleniumTests/Pages/CounterPage.cs
index 877e249..59159f8 100644
--- a/AOW4.SeleniumTests/Pages/CounterPage.cs
+++ b/AOW4.SeleniumTests/Pages/CounterPage.cs
@@ -5,11 +5,15 @@ namespace AOW4.SeleniumTests.Pages;
public class CounterPage
{
private readonly IWebDriver _driver;
- public CounterPage(IWebDriver driver) => _driver = driver;
+
+ public CounterPage(IWebDriver driver)
+ {
+ _driver = driver;
+ }
public bool IsAt()
{
var url = _driver.Url ?? string.Empty;
- return url.Contains("counter", System.StringComparison.OrdinalIgnoreCase) || _driver.PageSource.Contains("Counter");
+ return url.Contains("counter", StringComparison.OrdinalIgnoreCase) || _driver.PageSource.Contains("Counter");
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Pages/HomePage.cs b/AOW4.SeleniumTests/Pages/HomePage.cs
index 8f571d2..c6617d2 100644
--- a/AOW4.SeleniumTests/Pages/HomePage.cs
+++ b/AOW4.SeleniumTests/Pages/HomePage.cs
@@ -5,11 +5,16 @@ namespace AOW4.SeleniumTests.Pages;
public class HomePage
{
private readonly IWebDriver _driver;
- public HomePage(IWebDriver driver) => _driver = driver;
+
+ public HomePage(IWebDriver driver)
+ {
+ _driver = driver;
+ }
public bool IsAt()
{
var url = _driver.Url ?? string.Empty;
- return url.EndsWith("/") || url.Contains("/index", System.StringComparison.OrdinalIgnoreCase) || _driver.PageSource.Contains("Home");
+ return url.EndsWith("/") || url.Contains("/index", StringComparison.OrdinalIgnoreCase) ||
+ _driver.PageSource.Contains("Home");
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Pages/NavMenuPage.cs b/AOW4.SeleniumTests/Pages/NavMenuPage.cs
index 9b3a599..e27bdf2 100644
--- a/AOW4.SeleniumTests/Pages/NavMenuPage.cs
+++ b/AOW4.SeleniumTests/Pages/NavMenuPage.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using OpenQA.Selenium;
namespace AOW4.SeleniumTests.Pages;
@@ -15,13 +14,12 @@ public class NavMenuPage
public void ClickLinkByText(string linkText)
{
var link = _driver.FindElements(By.CssSelector("a[href]"))
- .FirstOrDefault(e => !string.IsNullOrWhiteSpace(e.Text) && e.Text.Trim().Equals(linkText, System.StringComparison.OrdinalIgnoreCase));
+ .FirstOrDefault(e =>
+ !string.IsNullOrWhiteSpace(e.Text) &&
+ e.Text.Trim().Equals(linkText, StringComparison.OrdinalIgnoreCase));
- if (link == null)
- {
- throw new NoSuchElementException($"Link with text '{linkText}' not found in the page.");
- }
+ if (link == null) throw new NoSuchElementException($"Link with text '{linkText}' not found in the page.");
link.Click();
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Pages/WeatherPage.cs b/AOW4.SeleniumTests/Pages/WeatherPage.cs
deleted file mode 100644
index e482da8..0000000
--- a/AOW4.SeleniumTests/Pages/WeatherPage.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using OpenQA.Selenium;
-
-namespace AOW4.SeleniumTests.Pages;
-
-public class WeatherPage
-{
- private readonly IWebDriver _driver;
- public WeatherPage(IWebDriver driver) => _driver = driver;
-
- public bool IsAt()
- {
- var url = _driver.Url ?? string.Empty;
- return url.Contains("weather", System.StringComparison.OrdinalIgnoreCase) || _driver.PageSource.Contains("Weather");
- }
-}
diff --git a/AOW4.SeleniumTests/README.md b/AOW4.SeleniumTests/README.md
index 9ac5807..9de8599 100644
--- a/AOW4.SeleniumTests/README.md
+++ b/AOW4.SeleniumTests/README.md
@@ -1,6 +1,7 @@
# AOW4 Selenium Tests
Requirements:
+
- .NET 10 SDK
- Google Chrome installed (compatible with ChromeDriver package)
- The AOW4 web app running locally (by default at `http://localhost:5000`) or set `BASE_URL` env var.
@@ -16,5 +17,6 @@ dotnet test AOW4.SeleniumTests\AOW4.SeleniumTests.csproj
```
Notes:
+
- Navigation tests use the UI nav links — ensure the app is running before executing tests.
- Broken links scanner sends HTTP HEAD requests and falls back to GET if needed.
diff --git a/AOW4.SeleniumTests/Tests/BaseTest.cs b/AOW4.SeleniumTests/Tests/BaseTest.cs
index 1dd2e86..5f0443d 100644
--- a/AOW4.SeleniumTests/Tests/BaseTest.cs
+++ b/AOW4.SeleniumTests/Tests/BaseTest.cs
@@ -1,15 +1,12 @@
+using AOW4.SeleniumTests.Driver;
using NUnit.Framework;
using OpenQA.Selenium;
-using AOW4.SeleniumTests.Driver;
namespace AOW4.SeleniumTests.Tests;
[TestFixture]
public abstract class BaseTest
{
- protected IWebDriver Driver = null!;
- protected string BaseUrl => "http://localhost:5212/";
-
[OneTimeSetUp]
public void GlobalSetup()
{
@@ -29,8 +26,11 @@ public abstract class BaseTest
}
}
+ protected IWebDriver Driver = null!;
+ protected string BaseUrl => "http://localhost:5212/";
+
protected void GoHome()
{
Driver.Navigate().GoToUrl(BaseUrl);
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Tests/BrokenLinksTest.cs b/AOW4.SeleniumTests/Tests/BrokenLinksTest.cs
index 87d57d3..9db6177 100644
--- a/AOW4.SeleniumTests/Tests/BrokenLinksTest.cs
+++ b/AOW4.SeleniumTests/Tests/BrokenLinksTest.cs
@@ -1,7 +1,4 @@
using NUnit.Framework;
-using System.Net.Http;
-using System.Collections.Generic;
-using System.Linq;
using OpenQA.Selenium;
namespace AOW4.SeleniumTests.Tests;
@@ -25,19 +22,16 @@ public class BrokenLinksTest : BaseTest
foreach (var raw in anchors)
{
- if (raw.StartsWith("javascript:", System.StringComparison.OrdinalIgnoreCase))
+ if (raw.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase))
continue;
- if (raw.StartsWith("mailto:", System.StringComparison.OrdinalIgnoreCase))
+ if (raw.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase))
continue;
- System.Uri uri;
+ Uri uri;
try
{
- uri = new System.Uri(raw, System.UriKind.RelativeOrAbsolute);
- if (!uri.IsAbsoluteUri)
- {
- uri = new System.Uri(new System.Uri(BaseUrl), raw);
- }
+ uri = new Uri(raw, UriKind.RelativeOrAbsolute);
+ if (!uri.IsAbsoluteUri) uri = new Uri(new Uri(BaseUrl), raw);
}
catch
{
@@ -54,21 +48,15 @@ public class BrokenLinksTest : BaseTest
// try GET as fallback
using var greq = new HttpRequestMessage(HttpMethod.Get, uri);
var gresp = client.Send(greq);
- if (!gresp.IsSuccessStatusCode)
- {
- failures.Add($"{(int)gresp.StatusCode} {uri}");
- }
+ if (!gresp.IsSuccessStatusCode) failures.Add($"{(int)gresp.StatusCode} {uri}");
}
}
- catch (System.Exception ex)
+ catch (Exception ex)
{
failures.Add($"Error checking {uri}: {ex.Message}");
}
}
- if (failures.Any())
- {
- Assert.Fail("Broken links found:\n" + string.Join("\n", failures));
- }
+ if (failures.Any()) Assert.Fail("Broken links found:\n" + string.Join("\n", failures));
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.SeleniumTests/Tests/NavigationTests.cs b/AOW4.SeleniumTests/Tests/NavigationTests.cs
index 01d4168..0dfc1e9 100644
--- a/AOW4.SeleniumTests/Tests/NavigationTests.cs
+++ b/AOW4.SeleniumTests/Tests/NavigationTests.cs
@@ -1,5 +1,4 @@
using NUnit.Framework;
-using AOW4.SeleniumTests.Pages;
namespace AOW4.SeleniumTests.Tests;
@@ -11,7 +10,9 @@ public class NavigationTests : BaseTest
{
GoHome();
- Assert.IsTrue(Driver.Url.Contains(expectedPath, System.StringComparison.OrdinalIgnoreCase) || Driver.PageSource.Contains(linkText),
+ Assert.IsTrue(
+ Driver.Url.Contains(expectedPath, StringComparison.OrdinalIgnoreCase) ||
+ Driver.PageSource.Contains(linkText),
$"Expected to be on route containing '{expectedPath}' after clicking '{linkText}', but was '{Driver.Url}'");
}
-}
+}
\ No newline at end of file
diff --git a/AOW4.slnx b/AOW4.slnx
index 6361106..2892bf2 100644
--- a/AOW4.slnx
+++ b/AOW4.slnx
@@ -1,5 +1,5 @@
-
-
-
+
+
+
diff --git a/AOW4/AOW4.csproj b/AOW4/AOW4.csproj
index a6a657c..90888a0 100644
--- a/AOW4/AOW4.csproj
+++ b/AOW4/AOW4.csproj
@@ -1,15 +1,15 @@
-
- net10.0
- enable
- enable
- true
-
+
+ net10.0
+ enable
+ enable
+ true
+
-
-
-
-
+
+
+
+
diff --git a/AOW4/Components/App.razor b/AOW4/Components/App.razor
index f6d3139..3085cd7 100644
--- a/AOW4/Components/App.razor
+++ b/AOW4/Components/App.razor
@@ -2,21 +2,21 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/AOW4/Components/Layout/MainLayout.razor.css b/AOW4/Components/Layout/MainLayout.razor.css
index 38d1f25..0847203 100644
--- a/AOW4/Components/Layout/MainLayout.razor.css
+++ b/AOW4/Components/Layout/MainLayout.razor.css
@@ -21,20 +21,20 @@ main {
align-items: center;
}
- .top-row ::deep a, .top-row ::deep .btn-link {
- white-space: nowrap;
- margin-left: 1.5rem;
- text-decoration: none;
- }
+.top-row ::deep a, .top-row ::deep .btn-link {
+ white-space: nowrap;
+ margin-left: 1.5rem;
+ text-decoration: none;
+}
- .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
- text-decoration: underline;
- }
+.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
+ text-decoration: underline;
+}
- .top-row ::deep a:first-child {
- overflow: hidden;
- text-overflow: ellipsis;
- }
+.top-row ::deep a:first-child {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
@media (max-width: 640.98px) {
.top-row {
@@ -90,9 +90,9 @@ main {
z-index: 1000;
}
- #blazor-error-ui .dismiss {
- cursor: pointer;
- position: absolute;
- right: 0.75rem;
- top: 0.5rem;
- }
+#blazor-error-ui .dismiss {
+ cursor: pointer;
+ position: absolute;
+ right: 0.75rem;
+ top: 0.5rem;
+}
diff --git a/AOW4/Components/Layout/NavMenu.razor b/AOW4/Components/Layout/NavMenu.razor
deleted file mode 100644
index b2c4ea8..0000000
--- a/AOW4/Components/Layout/NavMenu.razor
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
diff --git a/AOW4/Components/Layout/NavMenu.razor.css b/AOW4/Components/Layout/NavMenu.razor.css
deleted file mode 100644
index a2aeace..0000000
--- a/AOW4/Components/Layout/NavMenu.razor.css
+++ /dev/null
@@ -1,105 +0,0 @@
-.navbar-toggler {
- appearance: none;
- cursor: pointer;
- width: 3.5rem;
- height: 2.5rem;
- color: white;
- position: absolute;
- top: 0.5rem;
- right: 1rem;
- border: 1px solid rgba(255, 255, 255, 0.1);
- background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
-}
-
-.navbar-toggler:checked {
- background-color: rgba(255, 255, 255, 0.5);
-}
-
-.top-row {
- min-height: 3.5rem;
- background-color: rgba(0,0,0,0.4);
-}
-
-.navbar-brand {
- font-size: 1.1rem;
-}
-
-.bi {
- display: inline-block;
- position: relative;
- width: 1.25rem;
- height: 1.25rem;
- margin-right: 0.75rem;
- top: -1px;
- background-size: cover;
-}
-
-.bi-house-door-fill-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
-}
-
-.bi-plus-square-fill-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
-}
-
-.bi-list-nested-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
-}
-
-.nav-item {
- font-size: 0.9rem;
- padding-bottom: 0.5rem;
-}
-
- .nav-item:first-of-type {
- padding-top: 1rem;
- }
-
- .nav-item:last-of-type {
- padding-bottom: 1rem;
- }
-
- .nav-item ::deep .nav-link {
- color: #d7d7d7;
- background: none;
- border: none;
- border-radius: 4px;
- height: 3rem;
- display: flex;
- align-items: center;
- line-height: 3rem;
- width: 100%;
- }
-
-.nav-item ::deep a.active {
- background-color: rgba(255,255,255,0.37);
- color: white;
-}
-
-.nav-item ::deep .nav-link:hover {
- background-color: rgba(255,255,255,0.1);
- color: white;
-}
-
-.nav-scrollable {
- display: none;
-}
-
-.navbar-toggler:checked ~ .nav-scrollable {
- display: block;
-}
-
-@media (min-width: 641px) {
- .navbar-toggler {
- display: none;
- }
-
- .nav-scrollable {
- /* Never collapse the sidebar for wide screens */
- display: block;
-
- /* Allow sidebar to scroll for tall menus */
- height: calc(100vh - 3.5rem);
- overflow-y: auto;
- }
-}
diff --git a/AOW4/Components/Pages/BuildingCalculator.razor b/AOW4/Components/Pages/BuildingCalculator.razor
index 0e8536e..38cdfca 100644
--- a/AOW4/Components/Pages/BuildingCalculator.razor
+++ b/AOW4/Components/Pages/BuildingCalculator.razor
@@ -10,23 +10,23 @@
Build Order
-
- | Turn Requested |
- Building |
- Finish Turn |
- Industry Remaining |
-
+
+ | Turn Requested |
+ Building |
+ Finish Turn |
+ Industry Remaining |
+
- @foreach (var entry in Result.BuildOrder)
- {
-
- | @entry.RequestedTurn |
- @entry.Name |
- @(entry.BuiltFinishTurn == 0 ? "Starting" : entry.BuiltFinishTurn.ToString()) |
- @entry.IndustryCostRemaining |
-
- }
+ @foreach (var entry in Result.BuildOrder)
+ {
+
+ | @entry.RequestedTurn |
+ @entry.Name |
+ @(entry.BuiltFinishTurn == 0 ? "Starting" : entry.BuiltFinishTurn.ToString()) |
+ @entry.IndustryCostRemaining |
+
+ }
@@ -35,23 +35,23 @@
Gold Over Time
-
- | Turn |
- Stored Gold |
- Income |
- Upkeep |
-
+
+ | Turn |
+ Stored Gold |
+ Income |
+ Upkeep |
+
- @foreach (var snapshot in Result.ResourceHistory)
- {
-
- | @snapshot.Turn |
- @snapshot.Stored.Gold |
- @snapshot.TotalIncome.Gold |
- @snapshot.TotalUpkeep.Gold |
-
- }
+ @foreach (var snapshot in Result.ResourceHistory)
+ {
+
+ | @snapshot.Turn |
+ @snapshot.Stored.Gold |
+ @snapshot.TotalIncome.Gold |
+ @snapshot.TotalUpkeep.Gold |
+
+ }
@@ -68,12 +68,13 @@
protected override void OnInitialized()
{
- Result = BuildingPlanCalculator.CreateSampleBuildPlan(60);
+ Result = BuildingPlanCalculator.CreateSampleBuildPlan();
Json = JsonSerializer.Serialize(Result, new JsonSerializerOptions
{
WriteIndented = true
});
}
+
}