Enforce E2E test prerequisites when building individual solutions only (#11642)
* Fixes multiple issues that happened due to the E2E tests not running on the CI * Enforces prerequisites for E2E tests on the CI and when building projects with E2E tests. * Re-enables the E2E tests for templates.
This commit is contained in:
parent
f7de3da7a1
commit
1480b99866
|
|
@ -28,7 +28,7 @@
|
|||
<PropertyGroup>
|
||||
<RunCommand>dotnet</RunCommand>
|
||||
<_BlazorCliLocation>$(MSBuildThisFileDirectory)../../DevServer/src/bin/$(Configuration)/netcoreapp3.0/blazor-devserver.dll</_BlazorCliLocation>
|
||||
<RunArguments>exec "$(_BlazorCliLocation)" serve "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)" $(AdditionalRunArguments)</RunArguments>
|
||||
<RunArguments>exec "$(_BlazorCliLocation)" serve --applicationpath "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)" $(AdditionalRunArguments)</RunArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
// 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.IO;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.DevServer.Commands
|
||||
{
|
||||
|
|
@ -23,28 +21,11 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Commands
|
|||
|
||||
HelpOption("-?|-h|--help");
|
||||
|
||||
ApplicationPath = new CommandArgument()
|
||||
{
|
||||
Description = "Path to the client application dll",
|
||||
MultipleValues = false,
|
||||
Name = "<PATH>",
|
||||
ShowInHelpText = true
|
||||
};
|
||||
Arguments.Add(ApplicationPath);
|
||||
|
||||
OnExecute(Execute);
|
||||
}
|
||||
|
||||
public CommandArgument ApplicationPath { get; private set; }
|
||||
|
||||
private int Execute()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ApplicationPath.Value))
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid value for parameter '{nameof(ApplicationPath)}'. Value supplied: '{ApplicationPath.Value}'");
|
||||
}
|
||||
|
||||
Server.Startup.ApplicationAssembly = ApplicationPath.Value;
|
||||
Server.Program.BuildWebHost(RemainingArguments.ToArray()).Run();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<Reference Include="Microsoft.AspNetCore.ResponseCompression" />
|
||||
<Reference Include="Microsoft.AspNetCore" />
|
||||
<Reference Include="Microsoft.Extensions.CommandLineUtils.Sources" />
|
||||
<Reference Include="Microsoft.Extensions.Hosting" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Pack settings -->
|
||||
|
|
|
|||
|
|
@ -1,8 +1,15 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.DevServer.Server
|
||||
{
|
||||
|
|
@ -18,12 +25,24 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Server
|
|||
/// <summary>
|
||||
/// Intended for framework test use only.
|
||||
/// </summary>
|
||||
public static IWebHost BuildWebHost(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseConfiguration(new ConfigurationBuilder()
|
||||
.AddCommandLine(args)
|
||||
.Build())
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
public static IHost BuildWebHost(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureHostConfiguration(cb => {
|
||||
var applicationPath = args.SkipWhile(a => a != "--applicationpath").Skip(1).FirstOrDefault();
|
||||
var name = Path.ChangeExtension(applicationPath,".StaticWebAssets.xml");
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
cb.AddInMemoryCollection(new Dictionary<string, string>
|
||||
{
|
||||
[WebHostDefaults.StaticWebAssetsKey] = name
|
||||
});
|
||||
}
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStaticWebAssets();
|
||||
webBuilder.UseStartup<Startup>();
|
||||
}).Build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Server
|
|||
{
|
||||
internal class Startup
|
||||
{
|
||||
public static string ApplicationAssembly { get; set; }
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
|
@ -35,7 +40,7 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Server
|
|||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, IConfiguration configuration)
|
||||
{
|
||||
var applicationAssemblyFullPath = ResolveApplicationAssemblyFullPath(environment);
|
||||
var applicationAssemblyFullPath = ResolveApplicationAssemblyFullPath();
|
||||
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseResponseCompression();
|
||||
|
|
@ -54,15 +59,22 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Server
|
|||
});
|
||||
}
|
||||
|
||||
private static string ResolveApplicationAssemblyFullPath(IWebHostEnvironment environment)
|
||||
private string ResolveApplicationAssemblyFullPath()
|
||||
{
|
||||
var applicationAssemblyFullPath = Path.Combine(environment.ContentRootPath, ApplicationAssembly);
|
||||
if (!File.Exists(applicationAssemblyFullPath))
|
||||
const string applicationPathKey = "applicationpath";
|
||||
var configuredApplicationPath = Configuration.GetValue<string>(applicationPathKey);
|
||||
if (string.IsNullOrEmpty(configuredApplicationPath))
|
||||
{
|
||||
throw new InvalidOperationException($"Application assembly not found at {applicationAssemblyFullPath}.");
|
||||
throw new InvalidOperationException($"No value was supplied for the required option '{applicationPathKey}'.");
|
||||
}
|
||||
|
||||
return applicationAssemblyFullPath;
|
||||
var resolvedApplicationPath = Path.GetFullPath(configuredApplicationPath);
|
||||
if (!File.Exists(resolvedApplicationPath))
|
||||
{
|
||||
throw new InvalidOperationException($"Application assembly not found at {resolvedApplicationPath}.");
|
||||
}
|
||||
|
||||
return resolvedApplicationPath;
|
||||
}
|
||||
|
||||
private static void EnableConfiguredPathbase(IApplicationBuilder app, IConfiguration configuration)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
<PropertyGroup>
|
||||
<_BlazorDevServerDll>$(MSBuildThisFileDirectory)../tools/blazor-devserver.dll</_BlazorDevServerDll>
|
||||
<RunCommand>dotnet</RunCommand>
|
||||
<RunArguments>"$(_BlazorDevServerDll)" serve "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)"</RunArguments>
|
||||
<RunArguments>"$(_BlazorDevServerDll)" serve --applicationpath "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)"</RunArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
@ECHO OFF
|
||||
SET RepoRoot=%~dp0..\..
|
||||
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %*
|
||||
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj "/p:EnforceE2ETestPrerequisites=true" %*
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ set -euo pipefail
|
|||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
repo_root="$DIR/../.."
|
||||
"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "$@"
|
||||
"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "/p:EnforceE2ETestPrerequisites=true" "$@"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@
|
|||
// 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;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DevHostServerProgram = Microsoft.AspNetCore.Blazor.DevServer.Server.Program;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
|
||||
|
|
@ -22,7 +28,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
|
|||
{
|
||||
"--urls", "http://127.0.0.1:0",
|
||||
"--contentroot", ContentRoot,
|
||||
"--pathbase", PathBase
|
||||
"--pathbase", PathBase,
|
||||
"--applicationpath", typeof(TProgram).Assembly.Location,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(Environment))
|
||||
|
|
@ -31,7 +38,29 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
|
|||
args.Add(Environment);
|
||||
}
|
||||
|
||||
return DevHostServerProgram.BuildWebHost(args.ToArray());
|
||||
return new FakeWebHost(DevHostServerProgram.BuildWebHost(args.ToArray()));
|
||||
}
|
||||
|
||||
private class FakeWebHost : IWebHost
|
||||
{
|
||||
private readonly IHost _realHost;
|
||||
|
||||
public FakeWebHost(IHost realHost)
|
||||
{
|
||||
_realHost = realHost;
|
||||
}
|
||||
|
||||
public IFeatureCollection ServerFeatures => ((IServer)_realHost.Services.GetService(typeof(IServer))).Features;
|
||||
|
||||
public IServiceProvider Services => _realHost.Services;
|
||||
|
||||
public void Dispose() => _realHost.Dispose();
|
||||
|
||||
public void Start() => _realHost.Start();
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken = default) => _realHost.StartAsync();
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken = default) => _realHost.StopAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@
|
|||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TestGroupName>Components.E2ETests</TestGroupName>
|
||||
|
||||
<!--
|
||||
Temporarily disabled until this runs on macOS
|
||||
-->
|
||||
<SkipTests Condition="'$(SeleniumE2ETestsSupported)' != 'true'">true</SkipTests>
|
||||
<SkipTests>true</SkipTests>
|
||||
<!-- https://github.com/aspnet/AspNetCore/issues/6857 -->
|
||||
<BuildHelixPayload>false</BuildHelixPayload>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,33 +5,39 @@
|
|||
<title>Basic test app</title>
|
||||
<base href="/subdir/" />
|
||||
<link href="style.css" rel="stylesheet" />
|
||||
|
||||
<!-- Used by ExternalContentPackage -->
|
||||
<link href="_content/TestContentPackage/styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<root>Loading...</root>
|
||||
<root>Loading...</root>
|
||||
|
||||
<!-- Used for testing interop scenarios between JS and .NET -->
|
||||
<script src="js/jsinteroptests.js"></script>
|
||||
<!-- Used for testing interop scenarios between JS and .NET -->
|
||||
<script src="js/jsinteroptests.js"></script>
|
||||
|
||||
<script>
|
||||
// Used by ElementRefComponent
|
||||
function setElementValue(element, newValue) {
|
||||
element.value = newValue;
|
||||
return element.value;
|
||||
}
|
||||
<script>
|
||||
// Used by ElementRefComponent
|
||||
function setElementValue(element, newValue) {
|
||||
element.value = newValue;
|
||||
return element.value;
|
||||
}
|
||||
|
||||
function uriHelperNavigate() {
|
||||
Blazor.navigateTo('/subdir/some-path');
|
||||
}
|
||||
function uriHelperNavigate() {
|
||||
Blazor.navigateTo('/subdir/some-path');
|
||||
}
|
||||
|
||||
(function () {
|
||||
// Load either blazor.webassembly.js or blazor.server.js depending
|
||||
// on the hash part of the URL. This is just to give a way for the
|
||||
// test runner to make the selection.
|
||||
var src = location.hash === '#server'
|
||||
? 'blazor.server.js'
|
||||
: 'blazor.webassembly.js';
|
||||
document.write('<script src="_framework/' + src + '"><' + '/script>');
|
||||
})();
|
||||
</script>
|
||||
(function () {
|
||||
// Load either blazor.webassembly.js or blazor.server.js depending
|
||||
// on the hash part of the URL. This is just to give a way for the
|
||||
// test runner to make the selection.
|
||||
var src = location.hash === '#server'
|
||||
? 'blazor.server.js'
|
||||
: 'blazor.webassembly.js';
|
||||
document.write('<script src="_framework/' + src + '"><' + '/script>');
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Used by ExternalContentPackage -->
|
||||
<script src="_content/TestContentPackage/prompt.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -4,19 +4,9 @@
|
|||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<OutputType>library</OutputType>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<StaticWebAssetBasePath>_content/TestContentPackage</StaticWebAssetBasePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- .js files will be referenced via <script> tags -->
|
||||
<EmbeddedResource Include="content\**\*.js" LogicalName="blazor:js:%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
||||
<!-- .css files will be referenced via <link rel='Stylesheet'> tags -->
|
||||
<EmbeddedResource Include="content\**\*.css" LogicalName="blazor:css:%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
||||
<!-- Any other files will be included in the 'dist' output but without any tags referencing them -->
|
||||
<EmbeddedResource Include="content\**" Exclude="**\*.js;**\*.css" LogicalName="blazor:file:%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore.Components" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
|
@ -19,6 +19,7 @@ namespace TestServer
|
|||
.AddCommandLine(args)
|
||||
.Build())
|
||||
.UseStartup<TStartup>()
|
||||
.UseStaticWebAssets()
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
using BasicTestApp;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Components.Server;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
|
@ -63,6 +60,7 @@ namespace TestServer
|
|||
// Mount the server-side Blazor app on /subdir
|
||||
app.Map("/subdir", subdirApp =>
|
||||
{
|
||||
subdirApp.UseStaticFiles();
|
||||
subdirApp.UseClientSideBlazorFiles<BasicTestApp.Startup>();
|
||||
|
||||
subdirApp.UseRouting();
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ namespace Microsoft.AspNetCore
|
|||
{
|
||||
if (ctx.HostingEnvironment.IsDevelopment())
|
||||
{
|
||||
StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment);
|
||||
StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);
|
||||
}
|
||||
});
|
||||
builder.UseKestrel((builderContext, options) =>
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
public static readonly string ServerUrlsKey;
|
||||
public static readonly string ShutdownTimeoutKey;
|
||||
public static readonly string StartupAssemblyKey;
|
||||
public static readonly string StaticWebAssetsKey;
|
||||
public static readonly string SuppressStatusMessagesKey;
|
||||
public static readonly string WebRootKey;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,5 +21,6 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
public static readonly string SuppressStatusMessagesKey = "suppressStatusMessages";
|
||||
|
||||
public static readonly string ShutdownTimeoutKey = "shutdownTimeoutSeconds";
|
||||
public static readonly string StaticWebAssetsKey = "staticWebAssets";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
|||
public partial class StaticWebAssetsLoader
|
||||
{
|
||||
public StaticWebAssetsLoader() { }
|
||||
public static void UseStaticWebAssets(Microsoft.AspNetCore.Hosting.IWebHostEnvironment environment) { }
|
||||
public static void UseStaticWebAssets(Microsoft.AspNetCore.Hosting.IWebHostEnvironment environment, Microsoft.Extensions.Configuration.IConfiguration configuration) { }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.Extensions.Hosting
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
||||
|
|
@ -21,10 +22,11 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
|||
/// <summary>
|
||||
/// Configure the <see cref="IWebHostEnvironment"/> to use static web assets.
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public static void UseStaticWebAssets(IWebHostEnvironment environment)
|
||||
/// <param name="environment">The application <see cref="IWebHostEnvironment"/>.</param>
|
||||
/// <param name="configuration">The host <see cref="IConfiguration"/>.</param>
|
||||
public static void UseStaticWebAssets(IWebHostEnvironment environment, IConfiguration configuration)
|
||||
{
|
||||
using (var manifest = ResolveManifest(environment))
|
||||
using (var manifest = ResolveManifest(environment, configuration))
|
||||
{
|
||||
if (manifest != null)
|
||||
{
|
||||
|
|
@ -54,13 +56,13 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
|||
}
|
||||
}
|
||||
|
||||
internal static Stream ResolveManifest(IWebHostEnvironment environment)
|
||||
internal static Stream ResolveManifest(IWebHostEnvironment environment, IConfiguration configuration)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var assembly = Assembly.Load(environment.ApplicationName);
|
||||
var filePath = Path.Combine(Path.GetDirectoryName(GetAssemblyLocation(assembly)), $"{environment.ApplicationName}.StaticWebAssets.xml");
|
||||
var manifestPath = configuration.GetValue<string>(WebHostDefaults.StaticWebAssetsKey);
|
||||
var filePath = manifestPath ?? ResolveRelativeToAssembly(environment);
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
return File.OpenRead(filePath);
|
||||
|
|
@ -79,6 +81,12 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
|||
}
|
||||
}
|
||||
|
||||
private static string ResolveRelativeToAssembly(IWebHostEnvironment environment)
|
||||
{
|
||||
var assembly = Assembly.Load(environment.ApplicationName);
|
||||
return Path.Combine(Path.GetDirectoryName(GetAssemblyLocation(assembly)), $"{environment.ApplicationName}.StaticWebAssets.xml");
|
||||
}
|
||||
|
||||
internal static string GetAssemblyLocation(Assembly assembly)
|
||||
{
|
||||
if (Uri.TryCreate(assembly.CodeBase, UriKind.Absolute, out var result) &&
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
builder.ConfigureAppConfiguration((context, configBuilder) =>
|
||||
{
|
||||
StaticWebAssetsLoader.UseStaticWebAssets(context.HostingEnvironment);
|
||||
StaticWebAssetsLoader.UseStaticWebAssets(context.HostingEnvironment, context.Configuration);
|
||||
});
|
||||
|
||||
return builder;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
||||
|
|
@ -72,12 +75,39 @@ namespace Microsoft.AspNetCore.Hosting.StaticWebAssets
|
|||
};
|
||||
|
||||
// Act
|
||||
var manifest = StaticWebAssetsLoader.ResolveManifest(environment);
|
||||
var manifest = StaticWebAssetsLoader.ResolveManifest(environment, new ConfigurationBuilder().Build());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedManifest, new StreamReader(manifest).ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveManifest_UsesConfigurationKey_WhenProvided()
|
||||
{
|
||||
// Arrange
|
||||
var expectedManifest = @"<StaticWebAssets Version=""1.0"">
|
||||
<ContentRoot Path=""/Path"" BasePath=""/BasePath"" />
|
||||
</StaticWebAssets>
|
||||
";
|
||||
var path = Path.ChangeExtension(new Uri(typeof(StaticWebAssetsLoader).Assembly.CodeBase).LocalPath, ".StaticWebAssets.xml");
|
||||
var environment = new HostingEnvironment()
|
||||
{
|
||||
ApplicationName = "NonExistingDll"
|
||||
};
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string>() {
|
||||
[WebHostDefaults.StaticWebAssetsKey] = path
|
||||
}).Build();
|
||||
|
||||
// Act
|
||||
var manifest = StaticWebAssetsLoader.ResolveManifest(environment, configuration);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedManifest, new StreamReader(manifest).ReadToEnd());
|
||||
}
|
||||
|
||||
|
||||
private Stream CreateManifest(string manifestContent)
|
||||
{
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(manifestContent));
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ export class FetchData extends Component {
|
|||
</thead>
|
||||
<tbody>
|
||||
{forecasts.map(forecast =>
|
||||
<tr key={forecast.dateFormatted}>
|
||||
<td>{forecast.dateFormatted}</td>
|
||||
<tr key={forecast.date}>
|
||||
<td>{forecast.date}</td>
|
||||
<td>{forecast.temperatureC}</td>
|
||||
<td>{forecast.temperatureF}</td>
|
||||
<td>{forecast.summary}</td>
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ class FetchData extends React.PureComponent<WeatherForecastProps> {
|
|||
</thead>
|
||||
<tbody>
|
||||
{this.props.forecasts.map((forecast: WeatherForecastsStore.WeatherForecast) =>
|
||||
<tr key={forecast.dateFormatted}>
|
||||
<td>{forecast.dateFormatted}</td>
|
||||
<tr key={forecast.date}>
|
||||
<td>{forecast.date}</td>
|
||||
<td>{forecast.temperatureC}</td>
|
||||
<td>{forecast.temperatureF}</td>
|
||||
<td>{forecast.summary}</td>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export interface WeatherForecastsState {
|
|||
}
|
||||
|
||||
export interface WeatherForecast {
|
||||
dateFormatted: string;
|
||||
date: string;
|
||||
temperatureC: number;
|
||||
temperatureF: number;
|
||||
summary: string;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
@ECHO OFF
|
||||
SET RepoRoot=%~dp0..\..
|
||||
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %*
|
||||
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj "/p:EnforceE2ETestPrerequisites=true" %*
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ set -euo pipefail
|
|||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
repo_root="$DIR/../.."
|
||||
"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "$@"
|
||||
"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "/p:EnforceE2ETestPrerequisites=true" "$@"
|
||||
|
|
|
|||
|
|
@ -184,7 +184,8 @@ namespace Templates.Test.Helpers
|
|||
var environment = new Dictionary<string, string>
|
||||
{
|
||||
["ASPNETCORE_URLS"] = _urls,
|
||||
["ASPNETCORE_ENVIRONMENT"] = "Development"
|
||||
["ASPNETCORE_ENVIRONMENT"] = "Development",
|
||||
["ASPNETCORE_Kestrel__EndpointDefaults__Protocols"] = "Http1"
|
||||
};
|
||||
|
||||
var projectDll = Path.Combine(TemplateBuildDir, $"{ProjectName}.dll");
|
||||
|
|
@ -196,6 +197,7 @@ namespace Templates.Test.Helpers
|
|||
var environment = new Dictionary<string, string>
|
||||
{
|
||||
["ASPNETCORE_URLS"] = _urls,
|
||||
["ASPNETCORE_Kestrel__EndpointDefaults__Protocols"] = "Http1"
|
||||
};
|
||||
|
||||
var projectDll = $"{ProjectName}.dll";
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -78,7 +79,10 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
var opts = new ChromeOptions();
|
||||
|
||||
// Comment this out if you want to watch or interact with the browser (e.g., for debugging)
|
||||
opts.AddArgument("--headless");
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
opts.AddArgument("--headless");
|
||||
}
|
||||
|
||||
// Log errors
|
||||
opts.SetLoggingPreference(LogType.Browser, LogLevel.All);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,16 @@
|
|||
<_DefaultProjectFilter>$(MSBuildProjectDirectory)\..\..</_DefaultProjectFilter>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);node_modules\**</DefaultItemExcludes>
|
||||
<SeleniumProcessTrackingFolder Condition="'$(SeleniumProcessTrackingFolder)' == ''">$([MSBuild]::EnsureTrailingSlash('$(RepoRoot)'))artifacts\tmp\selenium\</SeleniumProcessTrackingFolder>
|
||||
<SeleniumE2ETestsSupported Condition="'$(SeleniumE2ETestsSupported)' == '' and '$(TargetArchitecture)' != 'arm' and '$(OS)' == 'Windows_NT' and '$(BuildJava)' == 'true'">true</SeleniumE2ETestsSupported>
|
||||
<EnforcePrerequisites Condition="'$(SeleniumE2ETestsSupported)' == 'true' and '$(EnforcePrerequisites)' == ''">true</EnforcePrerequisites>
|
||||
<SeleniumE2ETestsSupported Condition="'$(SeleniumE2ETestsSupported)' == '' and '$(TargetArchitecture)' != 'arm' and '$(OS)' == 'Windows_NT'">true</SeleniumE2ETestsSupported>
|
||||
|
||||
<!-- We want to enforce prerequisites when we build from the CI or within Visual Studio -->
|
||||
<EnforcedE2EBuildEnvironment Condition="'$(ContinuousIntegrationBuild)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true'">true</EnforcedE2EBuildEnvironment>
|
||||
|
||||
<!-- If not explicitly set, enforce E2E test prerequisites when the platform is supported and we are building on the CI or visual studio -->
|
||||
<EnforceE2ETestPrerequisites Condition="'$(SeleniumE2ETestsSupported)' == 'true' and $(EnforcedE2EBuildEnvironment) == 'true' and '$(EnforceE2ETestPrerequisites)' == ''">true</EnforceE2ETestPrerequisites>
|
||||
|
||||
<!-- Never enforce E2E test prerequisites if the platform is not supported -->
|
||||
<EnforceE2ETestPrerequisites Condition="'$(SeleniumE2ETestsSupported)' != 'true'">false</EnforceE2ETestPrerequisites>
|
||||
|
||||
<!-- WebDriver is not strong-named, so this test project cannot be strong named either. -->
|
||||
<SignAssembly>false</SignAssembly>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<Target Name="EnsureNodeJSRestored" Condition="'$(SeleniumE2ETestsSupported)' == 'true'" BeforeTargets="Build">
|
||||
<Message Text="Running yarn install on $(MSBuildProjectFile)" Importance="High" />
|
||||
|
||||
<Message Condition="'$(EnforcePrerequisites)' == ''"
|
||||
<Message Condition="'$(EnforceE2ETestPrerequisites)' != 'true'"
|
||||
Importance="High"
|
||||
Text="Prerequisites were not enforced at build time. Running Yarn or the E2E tests might fail as a result. Check /src/Shared/E2ETesting/Readme.md for instructions." />
|
||||
|
||||
|
|
@ -17,13 +17,13 @@
|
|||
<Target
|
||||
Name="WarnSeleniumNotSupported"
|
||||
BeforeTargets="Build"
|
||||
Condition="'$(SeleniumE2ETestsSupported)' == ''">
|
||||
Condition="'$(SeleniumE2ETestsSupported)' != 'true'">
|
||||
<Message Importance="High" Text="Selenium tests are not supported for OS '$(OS)' and architecture '$(TargetArchitecture)'." />
|
||||
</Target>
|
||||
|
||||
<!-- Running prerequisites -->
|
||||
|
||||
<Target Name="EnsurePrerequisites" Condition="'$(EnforcePrerequisites)' == 'true'" BeforeTargets="EnsureNodeJSRestored">
|
||||
<Target Name="EnsurePrerequisites" Condition="'$(EnforceE2ETestPrerequisites)' == 'true'" BeforeTargets="EnsureNodeJSRestored">
|
||||
<PropertyGroup>
|
||||
<_PackageJson>$(MSBuildProjectDirectory)\package.json</_PackageJson>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
private static IMessageSink _diagnosticsMessageSink;
|
||||
|
||||
// 1h 30 min
|
||||
private static int SeleniumProcessTimeout = 5400;
|
||||
private static int SeleniumProcessTimeout = 3600;
|
||||
|
||||
public SeleniumStandaloneServer(IMessageSink diagnosticsMessageSink)
|
||||
{
|
||||
|
|
@ -64,13 +64,9 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
|
||||
public static async Task<SeleniumStandaloneServer> GetInstanceAsync(ITestOutputHelper output)
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
|
||||
}
|
||||
await _semaphore.WaitAsync();
|
||||
if (Instance._process == null)
|
||||
{
|
||||
// No process was started, meaning the instance wasn't initialized.
|
||||
|
|
@ -139,7 +135,7 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
process.BeginErrorReadLine();
|
||||
|
||||
// The Selenium sever has to be up for the entirety of the tests and is only shutdown when the application (i.e. the test) exits.
|
||||
AppDomain.CurrentDomain.ProcessExit += (sender, args) => ProcessCleanup(process, pidFilePath);
|
||||
// AppDomain.CurrentDomain.ProcessExit += (sender, args) => ProcessCleanup(process, pidFilePath);
|
||||
|
||||
// Log
|
||||
void LogOutput(object sender, DataReceivedEventArgs e)
|
||||
|
|
@ -183,7 +179,7 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
output = null;
|
||||
logOutput.CompleteAdding();
|
||||
var exitCodeString = process.HasExited ? process.ExitCode.ToString() : "Process has not yet exited.";
|
||||
var message = @$"Failed to launch the server.
|
||||
var message = $@"Failed to launch the server.
|
||||
ExitCode: {exitCodeString}
|
||||
Captured output lines:
|
||||
{string.Join(Environment.NewLine, logOutput.GetConsumingEnumerable())}.";
|
||||
|
|
@ -211,19 +207,20 @@ Captured output lines:
|
|||
|
||||
private static void ProcessCleanup(Process process, string pidFilePath)
|
||||
{
|
||||
if (process?.HasExited == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
process?.KillTree(TimeSpan.FromSeconds(10));
|
||||
process?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
if (process?.HasExited == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
process?.KillTree(TimeSpan.FromSeconds(10));
|
||||
process?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors here since we can't do anything
|
||||
}
|
||||
}
|
||||
if (pidFilePath != null && File.Exists(pidFilePath))
|
||||
{
|
||||
File.Delete(pidFilePath);
|
||||
|
|
@ -231,6 +228,7 @@ Captured output lines:
|
|||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors here since we can't do anything
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue