Add basic browser automation tests for SPA templates (Windows only)

This commit is contained in:
Steve Sanderson 2017-09-05 16:19:04 +01:00
parent 95f2b8d375
commit 12a8e29288
4 changed files with 125 additions and 6 deletions

View File

@ -1,10 +1,12 @@
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Reflection;
using Xunit;
namespace Templates.Test.Helpers
@ -53,13 +55,13 @@ namespace Templates.Test.Helpers
_listeningUri = new Uri(listeningUrlString, UriKind.Absolute);
}
internal void AssertOk(string requestUrl)
public void AssertOk(string requestUrl)
=> AssertStatusCode(requestUrl, HttpStatusCode.OK);
internal void AssertNotFound(string requestUrl)
public void AssertNotFound(string requestUrl)
=> AssertStatusCode(requestUrl, HttpStatusCode.NotFound);
internal void AssertStatusCode(string requestUrl, HttpStatusCode statusCode)
public void AssertStatusCode(string requestUrl, HttpStatusCode statusCode)
{
var request = new HttpRequestMessage(
HttpMethod.Get,
@ -69,6 +71,14 @@ namespace Templates.Test.Helpers
Assert.Equal(statusCode, response.StatusCode);
}
public IWebDriver VisitInBrowser()
{
var driver = new EdgeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
driver.Navigate().GoToUrl(_listeningUri);
return driver;
}
public void Dispose()
{
_httpClient.Dispose();

View File

@ -0,0 +1,70 @@
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Support.UI;
using System;
namespace Templates.Test.Helpers
{
public static class WebDriverExtensions
{
public static string GetText(this ISearchContext driver, string cssSelector)
{
return driver.FindElement(By.CssSelector(cssSelector)).Text;
}
public static void Click(this IWebDriver driver, By by)
{
Click(driver, null, by);
}
public static void Click(this IWebDriver driver, ISearchContext searchContext, By by)
{
// This elaborate way of clicking is a workaround for https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/5238133/
new Actions(driver)
.MoveToElement((searchContext ?? driver).FindElement(by))
.Click()
.Perform();
}
public static void Click(this IWebDriver driver, string cssSelector)
{
Click(driver, null, cssSelector);
}
public static void Click(this IWebDriver driver, ISearchContext searchContext, string cssSelector)
{
Click(driver, searchContext, By.CssSelector(cssSelector));
}
public static IWebElement FindElement(this ISearchContext searchContext, string cssSelector)
{
return searchContext.FindElement(By.CssSelector(cssSelector));
}
public static IWebElement Parent(this IWebElement webElement)
{
return webElement.FindElement(By.XPath(".."));
}
public static IWebElement FindElement(this IWebDriver driver, string cssSelector, int timeoutSeconds)
{
return FindElement(driver, null, cssSelector, timeoutSeconds);
}
public static IWebElement FindElement(this IWebDriver driver, ISearchContext searchContext, string cssSelector, int timeoutSeconds)
{
return FindElement(driver, searchContext, By.CssSelector(cssSelector), timeoutSeconds);
}
public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutSeconds)
{
return FindElement(driver, null, by, timeoutSeconds);
}
public static IWebElement FindElement(this IWebDriver driver, ISearchContext searchContext, By by, int timeoutSeconds)
{
return new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutSeconds))
.Until(drv => searchContext.FindElement(by));
}
}
}

View File

@ -1,4 +1,6 @@
using Xunit;
using OpenQA.Selenium;
using Templates.Test.Helpers;
using Xunit;
namespace Templates.Test
{
@ -22,7 +24,40 @@ namespace Templates.Test
using (var aspNetProcess = StartAspNetProcess(targetFrameworkOverride))
{
aspNetProcess.AssertOk("/");
using (var browser = aspNetProcess.VisitInBrowser())
{
TestBasicNavigation(browser);
}
}
}
private void TestBasicNavigation(IWebDriver browser)
{
// <title> element gets project ID injected into it during template execution
Assert.Contains(ProjectName, browser.Title);
// Initially displays the home page
Assert.Equal("Hello, world!", browser.GetText("h1"));
// Can navigate to the counter page
browser.Click(By.PartialLinkText("Counter"));
Assert.Equal("Counter", browser.GetText("h1"));
// Clicking the counter button works
var counterComponent = browser.FindElement("h1").Parent();
Assert.Equal("0", counterComponent.GetText("strong"));
browser.Click(counterComponent, "button");
Assert.Equal("1", counterComponent.GetText("strong"));
// Can navigate to the 'fetch data' page
browser.Click(By.PartialLinkText("Fetch data"));
Assert.Equal("Weather forecast", browser.GetText("h1"));
// Loads and displays the table of weather forecasts
var fetchDataComponent = browser.FindElement("h1").Parent();
var table = browser.FindElement(fetchDataComponent, "table", 5);
Assert.Equal(5, table.FindElements(By.CssSelector("tbody tr")).Count);
}
}
}

View File

@ -5,8 +5,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Security.Permissions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" />
<PackageReference Include="Selenium.WebDriver.MicrosoftDriver" Version="15.15063.0" NoWarn="KRB4002" />
<PackageReference Include="Selenium.Support" Version="3.4.0" NoWarn="NU1701" />
<PackageReference Include="Selenium.WebDriver" Version="3.4.0" NoWarn="NU1701" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.analyzers" />
<PackageReference Include="xunit.runner.visualstudio" />