commit b2937984a05b340dc5e07258946c9f5e24fa290f Author: Steve Sanderson Date: Tue Dec 5 16:38:47 2017 +0000 Simple E2E test for static site diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..4b82ccd914 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vs/ +bin/ +obj/ diff --git a/Blazor.sln b/Blazor.sln new file mode 100644 index 0000000000..435f95845b --- /dev/null +++ b/Blazor.sln @@ -0,0 +1,55 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2005 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA}" +EndProject +Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "HelloWorld", "samples\HelloWorld\", "{4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A}" + ProjectSection(WebsiteProperties) = preProject + TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0" + Debug.AspNetCompiler.VirtualPath = "/localhost_56836" + Debug.AspNetCompiler.PhysicalPath = "samples\HelloWorld\" + Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_56836\" + Debug.AspNetCompiler.Updateable = "true" + Debug.AspNetCompiler.ForceOverwrite = "true" + Debug.AspNetCompiler.FixedNames = "false" + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.VirtualPath = "/localhost_56836" + Release.AspNetCompiler.PhysicalPath = "samples\HelloWorld\" + Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_56836\" + Release.AspNetCompiler.Updateable = "true" + Release.AspNetCompiler.ForceOverwrite = "true" + Release.AspNetCompiler.FixedNames = "false" + Release.AspNetCompiler.Debug = "False" + VWDPort = "56836" + SlnRelativePath = "samples\HelloWorld\" + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor.E2ETest", "e2e\Blazor.E2ETest.csproj", "{A1A3AEB6-A832-477E-8D91-A672CFE53801}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A}.Release|Any CPU.Build.0 = Debug|Any CPU + {A1A3AEB6-A832-477E-8D91-A672CFE53801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1A3AEB6-A832-477E-8D91-A672CFE53801}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1A3AEB6-A832-477E-8D91-A672CFE53801}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1A3AEB6-A832-477E-8D91-A672CFE53801}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A} = {F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3} + EndGlobalSection +EndGlobal diff --git a/e2e/Blazor.E2ETest.csproj b/e2e/Blazor.E2ETest.csproj new file mode 100644 index 0000000000..9974024ab3 --- /dev/null +++ b/e2e/Blazor.E2ETest.csproj @@ -0,0 +1,18 @@ + + + + netcoreapp2.0 + false + + + + + + + + + + + + + diff --git a/e2e/Infrastructure/BrowserFixture.cs b/e2e/Infrastructure/BrowserFixture.cs new file mode 100644 index 0000000000..2067721cfd --- /dev/null +++ b/e2e/Infrastructure/BrowserFixture.cs @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using OpenQA.Selenium; +using OpenQA.Selenium.Chrome; +using OpenQA.Selenium.Remote; +using System; + +namespace Blazor.E2ETest.Infrastructure +{ + public class BrowserFixture : IDisposable + { + public IWebDriver Browser { get; } + + public BrowserFixture() + { + var opts = new ChromeOptions(); + opts.AddArgument("--headless"); + Browser = new RemoteWebDriver(opts); + } + + public void Dispose() + { + Browser.Dispose(); + } + } +} diff --git a/e2e/Infrastructure/StaticServerFixture.cs b/e2e/Infrastructure/StaticServerFixture.cs new file mode 100644 index 0000000000..e1a29dde8b --- /dev/null +++ b/e2e/Infrastructure/StaticServerFixture.cs @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Threading; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; + +namespace Blazor.E2ETest.Infrastructure +{ + public class StaticServerFixture : IDisposable + { + private IWebHost _host; + + public string Start(string path) + { + _host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(path) + .UseWebRoot(string.Empty) + .UseStartup() + .UseUrls("http://127.0.0.1:0") + .Build(); + StartWebHostInBackgroundThread(_host); + + return _host.ServerFeatures + .Get() + .Addresses.Single(); + } + + public void Dispose() + { + _host.StopAsync(); + } + + private static void StartWebHostInBackgroundThread(IWebHost host) + { + var serverStarted = new ManualResetEvent(false); + + new Thread(() => + { + host.Start(); + serverStarted.Set(); + }).Start(); + + serverStarted.WaitOne(); + } + + private class Startup + { + public void Configure(IApplicationBuilder app) + { + app.UseFileServer(); + } + } + } +} diff --git a/e2e/Infrastructure/StaticSiteTestBase.cs b/e2e/Infrastructure/StaticSiteTestBase.cs new file mode 100644 index 0000000000..f2d233a580 --- /dev/null +++ b/e2e/Infrastructure/StaticSiteTestBase.cs @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using OpenQA.Selenium; +using System; +using System.IO; +using Xunit; + +namespace Blazor.E2ETest.Infrastructure +{ + public class StaticSiteTestBase + : IClassFixture, IClassFixture + { + public IWebDriver Browser { get; } + + private Uri _serverRootUri; + + public StaticSiteTestBase( + BrowserFixture browserFixture, + StaticServerFixture serverFixture, + string staticSitePath) + { + Browser = browserFixture.Browser; + + // Start a static files web server for the specified directory + var staticSiteFullPath = Path.Combine(FindSolutionDir(), staticSitePath); + var serverRootUriString = serverFixture.Start(staticSiteFullPath); + _serverRootUri = new Uri(serverRootUriString); + } + + public void Navigate(string relativeUrl) + { + var absoluteUrl = new Uri(_serverRootUri, relativeUrl); + Browser.Navigate().GoToUrl(absoluteUrl); + } + + private string FindSolutionDir() + { + return FindClosestDirectoryContaining( + "Blazor.sln", + Path.GetDirectoryName(GetType().Assembly.Location)); + } + + private static string FindClosestDirectoryContaining( + string filename, + string startDirectory) + { + var dir = startDirectory; + while (true) + { + if (File.Exists(Path.Combine(dir, filename))) + { + return dir; + } + + dir = Directory.GetParent(dir)?.FullName; + if (string.IsNullOrEmpty(dir)) + { + throw new FileNotFoundException( + $"Could not locate a file called '{filename}' in " + + $"directory '{startDirectory}' or any parent directory."); + } + } + } + } +} diff --git a/e2e/Tests/HelloWorldTest.cs b/e2e/Tests/HelloWorldTest.cs new file mode 100644 index 0000000000..6f0e7dced6 --- /dev/null +++ b/e2e/Tests/HelloWorldTest.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Blazor.E2ETest.Infrastructure; +using OpenQA.Selenium; +using Xunit; + +namespace Blazor.E2ETest.Tests +{ + public class HelloWorldTest : StaticSiteTestBase + { + public HelloWorldTest(BrowserFixture browserFixture, StaticServerFixture serverFixture) + : base(browserFixture, serverFixture, @"samples\HelloWorld") + { + } + + [Fact] + public void HasTitle() + { + Navigate("/"); + Assert.Equal("Hello", Browser.Title); + } + + [Fact] + public void DisplaysMessage() + { + Navigate("/"); + Assert.Equal("Hello, world!", Browser.FindElement(By.TagName("h1")).Text); + } + } +} diff --git a/samples/HelloWorld/index.html b/samples/HelloWorld/index.html new file mode 100644 index 0000000000..aa16be5f86 --- /dev/null +++ b/samples/HelloWorld/index.html @@ -0,0 +1,8 @@ + + + Hello + + +

Hello, world!

+ +