diff --git a/Blazor.sln b/Blazor.sln index ec562e142a..4786973eeb 100644 --- a/Blazor.sln +++ b/Blazor.sln @@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mono", "mono", "{7B5CAAB1-A EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Blazor.Mono", "runtime\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj", "{39FEC72D-AF52-47A3-B63D-7BF0E4335248}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoSanity", "samples\MonoSanity\MonoSanity.csproj", "{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,6 +57,10 @@ Global {39FEC72D-AF52-47A3-B63D-7BF0E4335248}.Debug|Any CPU.Build.0 = Debug|Any CPU {39FEC72D-AF52-47A3-B63D-7BF0E4335248}.Release|Any CPU.ActiveCfg = Release|Any CPU {39FEC72D-AF52-47A3-B63D-7BF0E4335248}.Release|Any CPU.Build.0 = Release|Any CPU + {7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -63,6 +69,7 @@ Global {4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A} = {F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA} {7B5CAAB1-A3EB-44F7-87E3-A13ED89FC17D} = {B867E038-B3CE-43E3-9292-61568C46CDEB} {39FEC72D-AF52-47A3-B63D-7BF0E4335248} = {B867E038-B3CE-43E3-9292-61568C46CDEB} + {7C53BB6B-5906-4753-B507-C9FCC2F7E5B7} = {F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3} diff --git a/e2e/Blazor.E2ETest.csproj b/e2e/Blazor.E2ETest.csproj index 9974024ab3..846c134a70 100644 --- a/e2e/Blazor.E2ETest.csproj +++ b/e2e/Blazor.E2ETest.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/e2e/Infrastructure/AspNetServerFixture.cs b/e2e/Infrastructure/AspNetServerFixture.cs new file mode 100644 index 0000000000..6797baa849 --- /dev/null +++ b/e2e/Infrastructure/AspNetServerFixture.cs @@ -0,0 +1,29 @@ +// 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 Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using System; +using System.IO; + +namespace Blazor.E2ETest.Infrastructure +{ + public class AspNetServerFixture : ServerFixture + { + public string StartAndGetUrl(Type startupType) + { + var sampleSitePath = Path.Combine( + FindSolutionDir(), + "samples", + startupType.Assembly.GetName().Name); + + var host = WebHost.CreateDefaultBuilder() + .UseStartup(startupType) + .UseContentRoot(sampleSitePath) + .UseUrls("http://127.0.0.1:0") + .Build(); + + return StartAndGetUrl(host); + } + } +} \ No newline at end of file diff --git a/e2e/Infrastructure/AspNetSiteTestBase.cs b/e2e/Infrastructure/AspNetSiteTestBase.cs new file mode 100644 index 0000000000..74aef3b2bb --- /dev/null +++ b/e2e/Infrastructure/AspNetSiteTestBase.cs @@ -0,0 +1,33 @@ +// 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 Xunit; + +namespace Blazor.E2ETest.Infrastructure +{ + public class AspNetSiteTestBase + : IClassFixture, IClassFixture + { + public IWebDriver Browser { get; } + + private Uri _serverRootUri; + + public AspNetSiteTestBase( + BrowserFixture browserFixture, + AspNetServerFixture serverFixture) + { + Browser = browserFixture.Browser; + + var serverRootUriString = serverFixture.StartAndGetUrl(typeof(TStartup)); + _serverRootUri = new Uri(serverRootUriString); + } + + public void Navigate(string relativeUrl) + { + var absoluteUrl = new Uri(_serverRootUri, relativeUrl); + Browser.Navigate().GoToUrl(absoluteUrl); + } + } +} diff --git a/e2e/Infrastructure/ServerFixture.cs b/e2e/Infrastructure/ServerFixture.cs new file mode 100644 index 0000000000..976d4b2f88 --- /dev/null +++ b/e2e/Infrastructure/ServerFixture.cs @@ -0,0 +1,74 @@ +// 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 Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using System; +using System.IO; +using System.Linq; +using System.Threading; + +namespace Blazor.E2ETest.Infrastructure +{ + public abstract class ServerFixture : IDisposable + { + private IWebHost _host; + + public void Dispose() + { + _host.StopAsync(); + } + + protected string StartAndGetUrl(IWebHost host) + { + _host = host; + return StartWebHostInBackgroundThread(); + } + + protected static string FindSolutionDir() + { + return FindClosestDirectoryContaining( + "Blazor.sln", + Path.GetDirectoryName(typeof(ServerFixture).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."); + } + } + } + + private string StartWebHostInBackgroundThread() + { + var serverStarted = new ManualResetEvent(false); + + new Thread(() => + { + _host.Start(); + serverStarted.Set(); + }).Start(); + + serverStarted.WaitOne(); + + return _host.ServerFeatures + .Get() + .Addresses.Single(); + } + } +} diff --git a/e2e/Infrastructure/StaticServerFixture.cs b/e2e/Infrastructure/StaticServerFixture.cs index e1a29dde8b..0432bb4a40 100644 --- a/e2e/Infrastructure/StaticServerFixture.cs +++ b/e2e/Infrastructure/StaticServerFixture.cs @@ -1,51 +1,30 @@ // 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 System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Server.Features; namespace Blazor.E2ETest.Infrastructure { - public class StaticServerFixture : IDisposable + public class StaticServerFixture : ServerFixture { - private IWebHost _host; - - public string Start(string path) + public string StartAndGetUrl(string sampleSiteName) { - _host = new WebHostBuilder() + var sampleSitePath = Path.Combine( + FindSolutionDir(), + "samples", + sampleSiteName); + + var host = new WebHostBuilder() .UseKestrel() - .UseContentRoot(path) + .UseContentRoot(sampleSitePath) .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(); + return StartAndGetUrl(host); } private class Startup diff --git a/e2e/Infrastructure/StaticSiteTestBase.cs b/e2e/Infrastructure/StaticSiteTestBase.cs index f2d233a580..f5f019d5dc 100644 --- a/e2e/Infrastructure/StaticSiteTestBase.cs +++ b/e2e/Infrastructure/StaticSiteTestBase.cs @@ -18,13 +18,12 @@ namespace Blazor.E2ETest.Infrastructure public StaticSiteTestBase( BrowserFixture browserFixture, StaticServerFixture serverFixture, - string staticSitePath) + string sampleSiteName) { Browser = browserFixture.Browser; // Start a static files web server for the specified directory - var staticSiteFullPath = Path.Combine(FindSolutionDir(), staticSitePath); - var serverRootUriString = serverFixture.Start(staticSiteFullPath); + var serverRootUriString = serverFixture.StartAndGetUrl(sampleSiteName); _serverRootUri = new Uri(serverRootUriString); } @@ -33,34 +32,5 @@ namespace Blazor.E2ETest.Infrastructure 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 index 6f0e7dced6..5342ac398f 100644 --- a/e2e/Tests/HelloWorldTest.cs +++ b/e2e/Tests/HelloWorldTest.cs @@ -10,7 +10,7 @@ namespace Blazor.E2ETest.Tests public class HelloWorldTest : StaticSiteTestBase { public HelloWorldTest(BrowserFixture browserFixture, StaticServerFixture serverFixture) - : base(browserFixture, serverFixture, @"samples\HelloWorld") + : base(browserFixture, serverFixture, "HelloWorld") { } diff --git a/e2e/Tests/MonoSanityTest.cs b/e2e/Tests/MonoSanityTest.cs new file mode 100644 index 0000000000..9658cd2a0f --- /dev/null +++ b/e2e/Tests/MonoSanityTest.cs @@ -0,0 +1,23 @@ +// 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 Xunit; + +namespace Blazor.E2ETest.Tests +{ + public class MonoSanityTest : AspNetSiteTestBase + { + public MonoSanityTest(BrowserFixture browserFixture, AspNetServerFixture serverFixture) + : base(browserFixture, serverFixture) + { + } + + [Fact] + public void HasTitle() + { + Navigate("/"); + Assert.Equal("Mono sanity check", Browser.Title); + } + } +} diff --git a/samples/MonoSanity/MonoSanity.csproj b/samples/MonoSanity/MonoSanity.csproj new file mode 100644 index 0000000000..d7c2e491fc --- /dev/null +++ b/samples/MonoSanity/MonoSanity.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.0 + + + + + + + diff --git a/samples/MonoSanity/Program.cs b/samples/MonoSanity/Program.cs new file mode 100644 index 0000000000..c445914645 --- /dev/null +++ b/samples/MonoSanity/Program.cs @@ -0,0 +1,21 @@ +// 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 Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; + +namespace MonoSanity +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build(); + } +} diff --git a/samples/MonoSanity/Properties/launchSettings.json b/samples/MonoSanity/Properties/launchSettings.json new file mode 100644 index 0000000000..ef6819c0df --- /dev/null +++ b/samples/MonoSanity/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:50885/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "MonoSanity": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:50886/" + } + } +} diff --git a/samples/MonoSanity/Startup.cs b/samples/MonoSanity/Startup.cs new file mode 100644 index 0000000000..286fb20173 --- /dev/null +++ b/samples/MonoSanity/Startup.cs @@ -0,0 +1,17 @@ +// 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 Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; + +namespace MonoSanity +{ + public class Startup + { + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + app.UseDeveloperExceptionPage(); + app.UseFileServer(); + } + } +} diff --git a/samples/MonoSanity/wwwroot/index.html b/samples/MonoSanity/wwwroot/index.html new file mode 100644 index 0000000000..0600c266b8 --- /dev/null +++ b/samples/MonoSanity/wwwroot/index.html @@ -0,0 +1,8 @@ + + + Mono sanity check + + +

Hello, world!

+ +