Skip to content

[WIP] Add EToE tests which is the PW version of E2E #31137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 55 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
0c1a690
Try splitting createbuildpublish from run
HaoK Mar 13, 2021
44cfcbf
Merge branch 'main' into haok/pworder
HaoK Mar 13, 2021
3f8f8df
Update BlazorWasmTemplateTest.cs
HaoK Mar 13, 2021
c4efe4b
Update BlazorWasmTemplateTest.cs
HaoK Mar 14, 2021
d5a4c14
Update BlazorServerTemplateTest.cs
HaoK Mar 14, 2021
78a4740
Update BlazorWasmTemplateTest.cs
HaoK Mar 15, 2021
24967f8
Try stop sharing playwright instance, create one per test
HaoK Mar 15, 2021
1da6a3f
Update BrowserManager.cs
HaoK Mar 15, 2021
a201a63
Update AssemblyInfo.AssemblyFixtures.cs
HaoK Mar 16, 2021
5c5d794
Update AssemblyInfo.AssemblyFixtures.cs
HaoK Mar 16, 2021
ccc0c10
Cleanup
HaoK Mar 16, 2021
d08ece3
Update BlazorTemplateTest.cs
HaoK Mar 16, 2021
38a926e
Update BlazorWasmTemplateTest.cs
HaoK Mar 16, 2021
e205d24
Update BlazorWasmTemplateTest.cs
HaoK Mar 16, 2021
e856f9e
Add logging
HaoK Mar 16, 2021
3d9921c
Merge branch 'haok/pworder' of https://github.com/dotnet/aspnetcore i…
HaoK Mar 16, 2021
778d568
Update BlazorWasmTemplateTest.cs
HaoK Mar 17, 2021
9b300b2
Update BlazorWasmTemplateTest.cs
HaoK Mar 17, 2021
c0aae25
Update BlazorTemplateTest.cs
HaoK Mar 17, 2021
9cbac95
Update AssemblyInfo.AssemblyFixtures.cs
HaoK Mar 17, 2021
488f245
Update BlazorWasmTemplateTest.cs
HaoK Mar 17, 2021
811ad99
Merge branch 'main' into haok/pworder
HaoK Mar 17, 2021
861afce
Update BlazorTemplateTest.cs
HaoK Mar 18, 2021
1569cb2
Update BlazorTemplateTest.cs
HaoK Mar 18, 2021
0e6f858
Update LoggedTestBase.cs
HaoK Mar 18, 2021
f2d395b
Update LoggedTestBase.cs
HaoK Mar 18, 2021
54d171e
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
e204476
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
d31198f
Update BlazorServerTemplateTest.cs
HaoK Mar 19, 2021
8b17ff6
Use correct logger
HaoK Mar 19, 2021
9ab5a85
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
d4b6365
Update BlazorServerTemplateTest.cs
HaoK Mar 19, 2021
ad3f974
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
9f47a47
Update BlazorWasmTemplateTest.cs
HaoK Mar 19, 2021
3dede55
Update src/Testing/src/LoggedTest/LoggedTestBase.cs
HaoK Mar 19, 2021
03c786f
Update LoggedTestBase.cs
HaoK Mar 19, 2021
d2c6bf8
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
e9d5124
Update MvcTemplateTest.cs
HaoK Mar 19, 2021
70a67c9
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
d6723c0
Update BlazorTemplateTest.cs
HaoK Mar 19, 2021
815ad0d
Hook testsink to actually do something!
HaoK Mar 20, 2021
2678751
Update BlazorTemplateTest.cs
HaoK Mar 20, 2021
968b57e
Pass output to project methods
HaoK Mar 20, 2021
e48461d
Fixup output helper in GetOrCreateProject
HaoK Mar 20, 2021
b7fadae
Merge branch 'main' into haok/pworder
HaoK Mar 20, 2021
c001819
Update Project.cs
HaoK Mar 20, 2021
5172e66
Update ProjectFactoryFixture.cs
HaoK Mar 20, 2021
69e6f31
Update Project.cs
HaoK Mar 21, 2021
f3f8317
Update MvcTemplateTest.cs
HaoK Mar 21, 2021
a050395
Update BlazorWasmTemplateTest.cs
HaoK Mar 22, 2021
495da51
Update BlazorServerTemplateTest.cs
HaoK Mar 22, 2021
a57281f
Add EToE for components + pw
HaoK Mar 22, 2021
dc03942
Add build magic
HaoK Mar 22, 2021
56e3216
Comment out test for now
HaoK Mar 22, 2021
83146eb
Merge branch 'haok/pworder' into haok/etoe
HaoK Mar 22, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions AspNetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorWinFormsApp", "src\Co
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Http.Abstractions.Microbenchmarks", "src\Http\Http.Abstractions\perf\Microbenchmarks\Microsoft.AspNetCore.Http.Abstractions.Microbenchmarks.csproj", "{3F752B48-2936-4FCA-B0DC-4AB0F788F897}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.EToETests", "src\Components\test\EToETest\Microsoft.AspNetCore.Components.EToETests.csproj", "{60B82C36-E613-496D-AD1B-0015DDAEFD96}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about PlayweightE2ETests so it's clear how they are different?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gamer in me can't help but think P2W with this particular combination of letters P2W.Tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not put other product names in test projects. Those things change and become stale. We can call them Components.FunctionalTests or Component.EndToEnd or a similar generic name. In the end, if/when the migration is successful we can delete the old project and name the new project Components.E2ETests again if we want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make a specific goal of eventually removing the old Components.E2ETests and having the new one take that name? That would make sense to me.

In the meantime, it would be great for the new project to have some name that indicates why it exists. It will be really hard for anyone coming fresh to the repo to understand why we have both E2ETests and EToETests. How about calling the new one E2ETestMigration or similar, with the goal that we eventually replace the old one and rename it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, will start a new PR since this has gotten stale, with rebased from main, with E2ETestMigration as the folder, and the csproj will be the same just with an additional Components.Migration.E2ETests.csproj

EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{F0849E7E-61DB-4849-9368-9E7BC125DCB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsTestApp", "src\Components\WebView\Platforms\WindowsForms\testassets\WinFormsTestApp\WinFormsTestApp.csproj", "{99EE7769-3C81-477B-B947-0A5CBCD5B27D}"
Expand Down Expand Up @@ -7663,6 +7665,18 @@ Global
{3F752B48-2936-4FCA-B0DC-4AB0F788F897}.Release|x64.Build.0 = Release|Any CPU
{3F752B48-2936-4FCA-B0DC-4AB0F788F897}.Release|x86.ActiveCfg = Release|Any CPU
{3F752B48-2936-4FCA-B0DC-4AB0F788F897}.Release|x86.Build.0 = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|x64.ActiveCfg = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|x64.Build.0 = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|x86.ActiveCfg = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Debug|x86.Build.0 = Debug|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|Any CPU.Build.0 = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|x64.ActiveCfg = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|x64.Build.0 = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|x86.ActiveCfg = Release|Any CPU
{60B82C36-E613-496D-AD1B-0015DDAEFD96}.Release|x86.Build.0 = Release|Any CPU
{99EE7769-3C81-477B-B947-0A5CBCD5B27D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99EE7769-3C81-477B-B947-0A5CBCD5B27D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99EE7769-3C81-477B-B947-0A5CBCD5B27D}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -8498,6 +8512,7 @@ Global
{3BA297F8-1CA1-492D-AE64-A60B825D8501} = {D4E9A2C5-0838-42DF-BC80-C829C4C9137E}
{CC740832-D268-47A3-9058-B9054F8397E2} = {D3B76F4E-A980-45BF-AEA1-EA3175B0B5A1}
{3F752B48-2936-4FCA-B0DC-4AB0F788F897} = {DCBBDB52-4A49-4141-8F4D-81C0FFFB7BD5}
{60B82C36-E613-496D-AD1B-0015DDAEFD96} = {0508E463-0269-40C9-B5C2-3B600FB2A28B}
{F0849E7E-61DB-4849-9368-9E7BC125DCB0} = {D4E9A2C5-0838-42DF-BC80-C829C4C9137E}
{99EE7769-3C81-477B-B947-0A5CBCD5B27D} = {F0849E7E-61DB-4849-9368-9E7BC125DCB0}
{94D0D6F3-8632-41DE-908B-47A787D570FF} = {5241CF68-66A0-4724-9BAA-36DB959A5B11}
Expand Down
2 changes: 2 additions & 0 deletions src/Components/Components.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"src\\Components\\benchmarkapps\\Wasm.Performance\\Driver\\Wasm.Performance.Driver.csproj",
"src\\Components\\benchmarkapps\\Wasm.Performance\\TestApp\\Wasm.Performance.TestApp.csproj",
"src\\Components\\test\\E2ETest\\Microsoft.AspNetCore.Components.E2ETests.csproj",
"src\\Components\\test\\EToETest\\Microsoft.AspNetCore.Components.EToETests.csproj",
"src\\Components\\test\\testassets\\BasicTestApp\\BasicTestApp.csproj",
"src\\Components\\test\\testassets\\ComponentsApp.Server\\ComponentsApp.Server.csproj",
"src\\Components\\test\\testassets\\GlobalizationWasmApp\\GlobalizationWasmApp.csproj",
Expand Down Expand Up @@ -100,6 +101,7 @@
"src\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj",
"src\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj",
"src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj",
"src\\Shared\\BrowserTesting\\src\\Microsoft.AspNetCore.BrowserTesting.csproj",
"src\\SignalR\\clients\\csharp\\Client.Core\\src\\Microsoft.AspNetCore.SignalR.Client.Core.csproj",
"src\\SignalR\\clients\\csharp\\Client\\src\\Microsoft.AspNetCore.SignalR.Client.csproj",
"src\\SignalR\\clients\\csharp\\Http.Connections.Client\\src\\Microsoft.AspNetCore.Http.Connections.Client.csproj",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// 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.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.BrowserTesting;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
{
public class PlaywrightTestBase : LoggedTest, IAsyncLifetime
{
private static readonly bool _isCIEnvironment =
!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("ContinuousIntegrationBuild"));

public PlaywrightTestBase(ITestOutputHelper output) : base(output) { }

public async Task InitializeAsync()
{
var testSink = new TestSink();
testSink.MessageLogged += LogMessage;
var factory = new TestLoggerFactory(testSink, enabled: true);
BrowserManager = await BrowserManager.CreateAsync(CreateConfiguration(), factory);
BrowserContextInfo = new ContextInformation(factory);

void LogMessage(WriteContext ctx)
{
TestOutputHelper.WriteLine($"{MapLogLevel(ctx)}: [Browser]{ctx.Message}");

static string MapLogLevel(WriteContext obj) => obj.LogLevel switch
{
LogLevel.Trace => "trace",
LogLevel.Debug => "dbug",
LogLevel.Information => "info",
LogLevel.Warning => "warn",
LogLevel.Error => "error",
LogLevel.Critical => "crit",
LogLevel.None => "info",
_ => "info"
};
}
}

private static IConfiguration CreateConfiguration()
{
var basePath = Path.GetDirectoryName(typeof(PlaywrightTestBase).Assembly.Location);
var os = Environment.OSVersion.Platform switch
{
PlatformID.Win32NT => "win",
PlatformID.Unix => "linux",
PlatformID.MacOSX => "osx",
_ => null
};

var builder = new ConfigurationBuilder()
.AddJsonFile(Path.Combine(basePath, "playwrightSettings.json"))
.AddJsonFile(Path.Combine(basePath, $"playwrightSettings.{os}.json"), optional: true);

if (_isCIEnvironment)
{
builder.AddJsonFile(Path.Combine(basePath, "playwrightSettings.ci.json"), optional: true)
.AddJsonFile(Path.Combine(basePath, $"playwrightSettings.ci.{os}.json"), optional: true);
}

if (Debugger.IsAttached)
{
builder.AddJsonFile(Path.Combine(basePath, "playwrightSettings.debug.json"), optional: true);
}

return builder.Build();
}

public Task DisposeAsync() => BrowserManager.DisposeAsync();

public ITestOutputHelper Output => TestOutputHelper;
public ContextInformation BrowserContextInfo { get; protected set; }
public BrowserManager BrowserManager { get; private set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// 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.

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
public enum AspNetEnvironment
{
Development,
Production
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
public class AspNetSiteServerFixture : WebHostServerFixture
{
public delegate IHost BuildWebHost(string[] args);

public Assembly ApplicationAssembly { get; set; }

public BuildWebHost BuildWebHostMethod { get; set; }

public AspNetEnvironment Environment { get; set; } = AspNetEnvironment.Production;

public List<string> AdditionalArguments { get; set; } = new List<string> { "--test-execution-mode", "server" };

protected override IHost CreateWebHost()
{
if (BuildWebHostMethod == null)
{
throw new InvalidOperationException(
$"No value was provided for {nameof(BuildWebHostMethod)}");
}

var assembly = ApplicationAssembly ?? BuildWebHostMethod.Method.DeclaringType.Assembly;
var sampleSitePath = FindSampleOrTestSitePath(assembly.FullName);

var host = "127.0.0.1";

return BuildWebHostMethod(new[]
{
"--urls", $"http://{host}:0",
"--contentroot", sampleSitePath,
"--environment", Environment.ToString(),
}.Concat(AdditionalArguments).ToArray());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
public class BasicTestAppServerSiteFixture<TStartup> : AspNetSiteServerFixture where TStartup : class
{
public BasicTestAppServerSiteFixture()
{
BuildWebHostMethod = TestServer.Program.BuildWebHost<TStartup>;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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.Extensions.Hosting;
using System.Collections.Generic;
using DevHostServerProgram = Microsoft.AspNetCore.Components.WebAssembly.DevServer.Server.Program;

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
public class DevHostServerFixture<TProgram> : WebHostServerFixture
{
public string Environment { get; set; }
public string PathBase { get; set; }
public string ContentRoot { get; private set; }

protected override IHost CreateWebHost()
{
ContentRoot = FindSampleOrTestSitePath(
typeof(TProgram).Assembly.FullName);

var host = "127.0.0.1";

var args = new List<string>
{
"--urls", $"http://{host}:0",
"--contentroot", ContentRoot,
"--pathbase", PathBase,
"--applicationpath", typeof(TProgram).Assembly.Location,
};

if (!string.IsNullOrEmpty(Environment))
{
args.Add("--environment");
args.Add(Environment);
}

return DevHostServerProgram.BuildWebHost(args.ToArray());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
public abstract class ServerFixture : IDisposable
{
private static readonly Lazy<Dictionary<string, string>> _projects = new Lazy<Dictionary<string, string>>(FindProjects);

public Uri RootUri => _rootUriInitializer.Value;

private readonly Lazy<Uri> _rootUriInitializer;

public ServerFixture()
{
_rootUriInitializer = new Lazy<Uri>(() =>
{
var uri = new Uri(StartAndGetRootUri());

return uri;
});
}

public abstract void Dispose();

protected abstract string StartAndGetRootUri();

private static Dictionary<string, string> FindProjects()
{
return typeof(ServerFixture).Assembly.GetCustomAttributes<AssemblyMetadataAttribute>()
.Where(m => m.Key.StartsWith("TestAssemblyApplication[", StringComparison.Ordinal))
.ToDictionary(m =>
m.Key.Replace("TestAssemblyApplication", "").TrimStart('[').TrimEnd(']'),
m => m.Value);
}

public static string FindSampleOrTestSitePath(string projectName)
{
var projects = _projects.Value;
if (projects.TryGetValue(projectName, out var dir))
{
return dir;
}

throw new ArgumentException($"Cannot find a sample or test site with name '{projectName}'.");
}

protected static void RunInBackgroundThread(Action action)
{
var isDone = new ManualResetEvent(false);

ExceptionDispatchInfo edi = null;
new Thread(() =>
{
try
{
action();
}
catch (Exception ex)
{
edi = ExceptionDispatchInfo.Capture(ex);
}

isDone.Set();
}).Start();

if (!isDone.WaitOne(TimeSpan.FromSeconds(10)))
{
throw new TimeoutException("Timed out waiting for: " + action);
}

if (edi != null)
{
throw edi.SourceException;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
{
// Although this is not used for anything meaningful related to Blazor yet, it
// will be used later when there's a mechanism for publishing standalone Blazor
// apps as a set of purely static files and we need E2E testing on the result.

public class StaticSiteServerFixture : WebHostServerFixture
{
public string SampleSiteName { get; set; }

protected override IHost CreateWebHost()
{
if (string.IsNullOrEmpty(SampleSiteName))
{
throw new InvalidOperationException($"No value was provided for {nameof(SampleSiteName)}");
}

var sampleSitePath = FindSampleOrTestSitePath(SampleSiteName);

var host = "127.0.0.1";

return new HostBuilder()
.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseKestrel()
.UseContentRoot(sampleSitePath)
.UseWebRoot(string.Empty)
.UseStartup<StaticSiteStartup>()
.UseUrls($"http://{host}:0"))
.Build();
}

private class StaticSiteStartup
{
public void Configure(IApplicationBuilder app)
{
app.UseFileServer();
}
}
}
}
Loading