Browse Source

test(BrokenLinks) Now checking for broken links on a few pages

main
Jonathan McCaffrey 4 years ago
parent
commit
c16c0172bc
  1. 8
      IGP/Index.razor
  2. 2
      IGP/PageLayout.razor
  3. 16
      TestAutomation/BaseTest.cs
  4. 29
      TestAutomation/Pages/BasePage.cs
  5. 11
      TestAutomation/Pages/DatabasePage.cs
  6. 13
      TestAutomation/Pages/DatabaseSinglePage.cs
  7. 18
      TestAutomation/Pages/HarassCalculatorPage.cs
  8. 2
      TestAutomation/Shared/BaseElement.cs
  9. 51
      TestAutomation/TestHarassCalculator.cs
  10. 31
      TestAutomation/TestLinks.cs
  11. 55
      TestAutomation/TestSearchFeatures.cs
  12. 53
      TestAutomation/Utils/TestReport.cs
  13. 38
      TestAutomation/Utils/Website.cs
  14. 4
      TestAutomation/_Tests.cs

8
IGP/Index.razor

@ -1,13 +1,5 @@
@page "/"
@inject ITrackingNavigationState TrackingNavigationState
@inject IAnalytics GlobalTracking
@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/>

2
IGP/PageLayout.razor

@ -14,7 +14,7 @@
}
else
{
<div class="content">
<div id="content" class="content">
@Body
</div>

16
TestAutomation/BaseTest.cs

@ -10,20 +10,11 @@ public enum DeploymentType
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 Website WebsiteInstance = default!;
protected readonly HttpClient HttpClient = new();
protected static Website Website
{
@ -35,7 +26,7 @@ public class BaseTest
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("--start-maximized");
options.AddArgument("--test-type");
@ -43,10 +34,11 @@ public class BaseTest
IWebDriver webDriver = new FirefoxDriver(Environment.CurrentDirectory, options);
WebsiteInstance = new Website(webDriver);
WebsiteInstance = new Website(webDriver, TestReport);
}
return WebsiteInstance;
}
}
}

29
TestAutomation/Pages/BasePage.cs

@ -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}");
}
}
}

11
TestAutomation/Pages/DatabasePage.cs

@ -1,10 +1,9 @@
using System.Collections.ObjectModel;
using TestAutomation.Shared;
using TestAutomation.Utils;
namespace TestAutomation.Pages;
public class DatabasePage : BaseElement
public class DatabasePage : BasePage
{
public DatabasePage(Website website) : base(website)
{
@ -12,6 +11,8 @@ public class DatabasePage : BaseElement
private IWebElement FilterNameInput => Website.Find("filterName");
public override string Url { get; set; } = "database";
private ReadOnlyCollection<IWebElement> EntityNames()
{
@ -43,4 +44,10 @@ public class DatabasePage : BaseElement
result = EntityNames()[index].Text;
return this;
}
public DatabasePage Goto()
{
Website.Goto(Url);
return this;
}
}

13
TestAutomation/Pages/DatabaseSinglePage.cs

@ -1,9 +1,8 @@
using TestAutomation.Shared;
using TestAutomation.Utils;
using TestAutomation.Utils;
namespace TestAutomation.Pages;
public class DatabaseSinglePage : BaseElement
public class DatabaseSinglePage : BasePage
{
public DatabaseSinglePage(Website website) : base(website)
{
@ -15,6 +14,8 @@ public class DatabaseSinglePage : BaseElement
private IWebElement InvalidSearch => Website.Find("invalidSearch");
private IWebElement ValidSearch => Website.Find("validSearch");
public override string Url { get; set; } = "database";
public DatabaseSinglePage GetEntityName(out string result)
{
@ -39,4 +40,10 @@ public class DatabaseSinglePage : BaseElement
result = ValidSearch.Text;
return this;
}
public DatabaseSinglePage Goto(string searchText)
{
Website.Goto($"{Url}/{searchText}");
return this;
}
}

18
TestAutomation/Pages/HarassCalculatorPage.cs

@ -1,9 +1,8 @@
using TestAutomation.Shared;
using TestAutomation.Utils;
using TestAutomation.Utils;
namespace TestAutomation.Pages;
public class HarassCalculatorPage : BaseElement
public class HarassCalculatorPage : BasePage
{
public HarassCalculatorPage(Website website) : base(website)
{
@ -24,6 +23,8 @@ public class HarassCalculatorPage : BaseElement
private int ExampleTotalAlloyLossAccurate => Website.FindInt("exampleTotalAlloyLossAccurate");
private int ExampleTotalAlloyLossAccurateDifference => Website.FindInt("exampleTotalAlloyLossAccurateDifference");
public override string Url { get; set; } = "harass-calculator";
public HarassCalculatorPage SetWorkersLostToHarass(int number)
{
Website.EnterInput(NumberOfWorkersLostToHarass, number);
@ -84,4 +85,15 @@ public class HarassCalculatorPage : BaseElement
result = ExampleTotalAlloyLossAccurateDifference;
return this;
}
protected HarassCalculatorPage NavigateTo()
{
return this;
}
public HarassCalculatorPage Goto()
{
Website.Goto(Url);
return this;
}
}

2
TestAutomation/Shared/BaseElement.cs

@ -2,7 +2,7 @@
namespace TestAutomation.Shared;
public class BaseElement
public abstract class BaseElement
{
protected readonly Website Website;

51
TestAutomation/TestHarassCalculator.cs

@ -5,41 +5,43 @@ namespace TestAutomation;
[TestFixture]
public class TestHarassCalculator : BaseTest
{
[Test]
public void CalculatorInput()
[SetUp]
public void SetUp()
{
TestReport.CreateTest();
}
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/harass-calculator");
[TearDown]
public void TearDown()
{
TestReport.ThrowErrors();
}
[Test]
public void CalculatorInput()
{
var expectedTotalAlloyHarassment = 240;
try
{
Website.HarassCalculatorPage
.SetWorkersLostToHarass(3)
.SetNumberOfTownHallsExisting(2)
.SetTownHallTravelTime(0, 30)
.GetTotalAlloyHarassment(out var foundTotalAlloyHarassment);
TestReport.CheckPassed(expectedTotalAlloyHarassment.Equals(foundTotalAlloyHarassment),
TestMessage.CreateFailedMessage($"expectTotalAlloyHarassment of {expectedTotalAlloyHarassment} " +
"does not equal " +
$"foundTotalAlloyHarassment of {foundTotalAlloyHarassment} "));
}
catch (Exception e)
{
TestReport.CheckPassed(false,
TestMessage.CreateFailedMessage(e.StackTrace!));
}
Website.HarassCalculatorPage
.Goto()
.SetWorkersLostToHarass(3)
.SetNumberOfTownHallsExisting(2)
.SetTownHallTravelTime(0, 30)
.GetTotalAlloyHarassment(out var foundTotalAlloyHarassment);
TestReport.CheckPassed(expectedTotalAlloyHarassment.Equals(foundTotalAlloyHarassment),
TestMessage.CreateFailedMessage($"expectTotalAlloyHarassment of {expectedTotalAlloyHarassment} " +
"does not equal " +
$"foundTotalAlloyHarassment of {foundTotalAlloyHarassment} "));
}
[Test]
public void CalculatedExampleInformation()
{
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/harass-calculator");
var expectedExampleTotalAlloyLoss = 720;
var expectedExampleWorkerCost = 300;
@ -49,6 +51,7 @@ public class TestHarassCalculator : BaseTest
var expectedExampleTotalAlloyLossAccurateDifference = 270;
Website.HarassCalculatorPage
.Goto()
.GetExampleTotalAlloyLoss(out var foundTotalAlloyLoss)
.GetExampleWorkerCost(out var foundExampleWorkerCost)
.GetExampleMiningTimeCost(out var foundExampleMiningTimeCost)

31
TestAutomation/TestLinks.cs

@ -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();
}
}

55
TestAutomation/TestSearchFeatures.cs

@ -5,14 +5,27 @@ namespace TestAutomation;
[TestFixture]
public class TestSearchFeatures : BaseTest
{
[Test]
public void DesktopOpenCloseSearchDialog()
[SetUp]
public void SetUp()
{
TestReport.CreateTest();
}
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/");
[TearDown]
public void TearDown()
{
TestReport.ThrowErrors();
}
[Test]
public void DesktopOpenCloseSearchDialog()
{
Website.NavigationBar
Website
.Goto()
.NavigationBar
.ClickSearchButton()
.CloseDialog()
.ClickHomeLink();
@ -21,12 +34,10 @@ public class TestSearchFeatures : BaseTest
[Test]
public void DesktopSearchForThrone()
{
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/");
Website.NavigationBar
.ClickSearchButton()
Website
.Goto()
.NavigationBar.ClickSearchButton()
.Search("Throne")
.SelectSearchEntity("Throne")
.GetEntityName(out var name)
@ -36,45 +47,47 @@ public class TestSearchFeatures : BaseTest
new TestMessage { Description = "Couldn't find Throne via search." });
TestReport.CheckPassed(!health.Trim().Equals(""),
new TestMessage { Description = "Throne has no visible health!" });
}
[Test]
public void DesktopFilterForThrone()
{
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database");
Website.DatabasePage
.Goto()
.FilterName("Throne")
.GetEntityName(0, out var name);
TestReport.CheckPassed(name.Equals("Throne"),
new TestMessage { Description = "Couldn't find Throne via filter." });
}
[Test]
public void SeeThroneByDefault()
{
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database");
Website.DatabasePage
.Goto()
.GetEntityName("army", "throne", out var name);
TestReport.CheckPassed(name.Equals("Throne"),
new TestMessage { Description = "Couldn't find Throne on the page by default." });
}
[Test]
public void DirectLinkNotThroneFailure()
{
TestReport.CreateTest();
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database/not throne");
Website.DatabaseSinglePage
.Goto("not throne")
.GetInvalidSearch(out var invalidSearch)
.GetValidSearch(out var validSearch);
@ -82,7 +95,7 @@ public class TestSearchFeatures : BaseTest
new TestMessage { Description = "Couldn't find invalid search text on the page." });
TestReport.CheckPassed(validSearch.Equals("Throne"),
new TestMessage { Description = "Couldn't find valid search text on the page." });
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl + "/database/not throne");
}
}

53
TestAutomation/Utils/TestReport.cs

@ -11,18 +11,63 @@ public class TestReport
[MethodImpl(MethodImplOptions.NoInlining)]
public Test CreateTest()
{
var testName = new StackTrace().GetFrame(1)!.GetMethod()!.Name!;
Tests.Add(new Test { Name = testName });
Tests.Add(new Test
{
Name = TestContext.CurrentContext.Test.Name
});
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)
{
if (passed) return;
Tests.Last().Result = false;
Tests.Last().Messages.Add(message);
throw new Exception(message.Description);
}
public bool DidTestsPass()

38
TestAutomation/Utils/Website.cs

@ -7,11 +7,24 @@ namespace TestAutomation.Utils;
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 Website(IWebDriver webDriver)
public TestReport TestReport { get; set; }
public Website(IWebDriver webDriver, TestReport testReport)
{
WebDriver = webDriver;
TestReport = testReport;
// Pages
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)
{
@ -177,4 +200,17 @@ public class Website
{
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}");
}
}

4
TestAutomation/_Tests.cs

@ -9,15 +9,13 @@ public class Tests : BaseTest
[OneTimeSetUp]
public void Setup()
{
Website.WebDriver.Navigate().GoToUrl(WebsiteUrl);
Website.Goto();
Website.WebDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15);
}
[OneTimeTearDown]
public void TearDown()
{
HttpClient HttpClient = new();
Website.WebDriver.Quit();
var message = new

Loading…
Cancel
Save