Skip to content

Commit ae0f6be

Browse files
committed
[Infrastructure improvements]
* Improved selenium start and tear down * Selenium is set up and torn down in an assembly fixture. * Selenium is initialized lazily and in a non-blocking way. * Selenium processes are tracked as part of the build and their pids written to a file on disk for cleanup in the event of unexpected termination of the test process. * Browser fixture retries with linear backoff to create a remote driver. Under heavy load (like when we are doing a simultaneous NPM restore) the selenium server can become unresponsive so we retry three times, with a longer comand timeout allowance each time up to a max of 3 minutes. * Moved test project setup to build time instead of runtime. * Added target PrepareForTest to create the required files for testing * The template creation folder. * The template props file to use our built packages. * The folder for the custom hive. * Added assembly metadata attributes to find all the data we need to run the tests. * Path to the artifacts shipping packages folder. * Path to the artifacts non-shipping packages folder. * Path to the test templates creation folder. * Path to use for the custom templating hive used in tests. * Proper cleanup as part of the build * Remove the test templates creation folder. * Remove the test packages restore path. * Recreate the test templates creation folder. * Recreate the test packages restore path. * Generated Directory.Build.Props and Directory.Build.Targets in the test templates creation folder. * Cleaned up potentially stale templatetestsprops. * Improved test flows * Initialization is done lazily and asynchronously. * Selenium * Browser fixture * Template initialization. * Flattened test flows to avoid assertions inside deep callstacks. * All assertions happen at the test level with improved error messages. * With the exception of the migrations assertions. * Assertions contain information about which step failed, for what project and what failure details. * Broke down tests to perform individual steps instead of mixing build and publish. * Publish project. * Build project. (Debug) * Run built project. * Run published project. * Concentrated build logic into the Project class. * Context between the different steps of a test is maintained in this class. * All operations that require coordination are performed within this class. * There is a lock for dotnet and a lock for nodejs. When building SPAs we acquire the nodejs lock to correctly prevent multiple runs of nodejs in parallel. [ApiAuthorization template cleanups] * Fix preview3 issues with breaking changes on Entity framework by manually configuring the model in ApiAuthorizationDbContext. * Add app.db to the project file when using local db. * Fix linting errors on angular template. * Fix react tests * Add tests to cover new auth options in the SPA templates.
1 parent f303a55 commit ae0f6be

File tree

74 files changed

+3330
-1512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+3330
-1512
lines changed

.azure/pipelines/jobs/default-build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ jobs:
125125
displayName: Install JDK 11
126126
- powershell: Write-Host "##vso[task.prependpath]$env:JAVA_HOME\bin"
127127
displayName: Prepend JAVA bin folder to the PATH.
128+
- powershell: Write-Host "##vso[task.setvariable variable=SeleniumProcessTrackingFolder]$(BuildDirectory)\obj\selenium\"
129+
displayName: Add Selenium process tracking folder environment variable
128130
- powershell: ./eng/scripts/InstallGoogleChrome.ps1
129131
displayName: Install chrome
130132
- ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.agentOs, 'Windows'), eq(parameters.codeSign, 'true')) }}:

eng/scripts/KillProcesses.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ function _killJavaInstances() {
2222
}
2323
}
2424

25+
function _killSeleniumTrackedProcesses() {
26+
$files = Get-ChildItem $env:SeleniumProcessTrackingFolder -ErrorAction SilentlyContinue;
27+
# PID files have a format of <<pid>>.<<guid>>.pid
28+
$pids = $files |
29+
Where-Object { $_.Name -match "([0-9]+)\..*?.pid"; } |
30+
Foreach-Object { $Matches[1] };
31+
32+
foreach ($pid in $pids) {
33+
try {
34+
& cmd /c "taskkill /T /F /PID $pid 2>&1"
35+
} catch {
36+
Write-Host "Failed to kill process: $pid"
37+
}
38+
}
39+
}
40+
2541
_kill dotnet.exe
2642
_kill testhost.exe
2743
_kill iisexpress.exe
@@ -35,6 +51,7 @@ _kill chrome.exe
3551
_kill h2spec.exe
3652
_kill WerFault.exe
3753
_killJavaInstances
54+
_killSeleniumTrackedProcesses
3855

3956
if (Get-Command iisreset -ErrorAction ignore) {
4057
iisreset /restart
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.E2ETesting;
5+
using Xunit;
6+
7+
[assembly: TestFramework("Microsoft.AspNetCore.E2ETesting.XunitTestFrameworkWithAssemblyFixture", "Microsoft.AspNetCore.Components.E2ETests")]
8+
[assembly: AssemblyFixture(typeof(SeleniumStandaloneServer))]

src/Components/test/E2ETest/ServerExecutionTests/ServerComponentRenderingTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void ThrowsIfRenderIsRequestedOutsideSyncContext()
3232

3333
appElement.FindElement(By.Id("run-without-dispatch")).Click();
3434

35-
WaitAssert.Contains(
35+
Browser.Contains(
3636
$"{typeof(InvalidOperationException).FullName}: The current thread is not associated with the renderer's synchronization context",
3737
() => result.Text);
3838
}

src/Components/test/E2ETest/ServerExecutionTests/ServerSideAppTest.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using OpenQA.Selenium.Support.UI;
99
using System;
1010
using System.Linq;
11+
using System.Threading.Tasks;
1112
using Xunit;
1213
using Xunit.Abstractions;
1314

@@ -23,12 +24,16 @@ public ServerSideAppTest(
2324
{
2425
_serverFixture.Environment = AspNetEnvironment.Development;
2526
_serverFixture.BuildWebHostMethod = ComponentsApp.Server.Program.BuildWebHost;
27+
}
28+
29+
public override async Task InitializeAsync()
30+
{
31+
await base.InitializeAsync();
2632

2733
Navigate("/", noReload: false);
2834
WaitUntilLoaded();
2935
}
3036

31-
3237
[Fact]
3338
public void HasTitle()
3439
{
@@ -56,13 +61,13 @@ public void NavMenuHighlightsCurrentLocation()
5661
Browser.FindElement(By.LinkText("Counter")).Click();
5762

5863
// Verify we're now on the counter page, with that nav link (only) highlighted
59-
WaitAssert.Equal("Counter", () => Browser.FindElement(mainHeaderSelector).Text);
64+
Browser.Equal("Counter", () => Browser.FindElement(mainHeaderSelector).Text);
6065
Assert.Collection(Browser.FindElements(activeNavLinksSelector),
6166
item => Assert.Equal("Counter", item.Text));
6267

6368
// Verify we can navigate back to home too
6469
Browser.FindElement(By.LinkText("Home")).Click();
65-
WaitAssert.Equal("Hello, world!", () => Browser.FindElement(mainHeaderSelector).Text);
70+
Browser.Equal("Hello, world!", () => Browser.FindElement(mainHeaderSelector).Text);
6671
Assert.Collection(Browser.FindElements(activeNavLinksSelector),
6772
item => Assert.Equal("Home", item.Text));
6873
}
@@ -72,7 +77,7 @@ public void HasCounterPage()
7277
{
7378
// Navigate to "Counter"
7479
Browser.FindElement(By.LinkText("Counter")).Click();
75-
WaitAssert.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
80+
Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
7681

7782
// Observe the initial value is zero
7883
var countDisplayElement = Browser.FindElement(By.CssSelector("h1 + p"));
@@ -81,19 +86,19 @@ public void HasCounterPage()
8186
// Click the button; see it counts
8287
var button = Browser.FindElement(By.CssSelector(".main button"));
8388
button.Click();
84-
WaitAssert.Equal("Current count: 1", () => countDisplayElement.Text);
89+
Browser.Equal("Current count: 1", () => countDisplayElement.Text);
8590
button.Click();
86-
WaitAssert.Equal("Current count: 2", () => countDisplayElement.Text);
91+
Browser.Equal("Current count: 2", () => countDisplayElement.Text);
8792
button.Click();
88-
WaitAssert.Equal("Current count: 3", () => countDisplayElement.Text);
93+
Browser.Equal("Current count: 3", () => countDisplayElement.Text);
8994
}
9095

9196
[Fact]
9297
public void HasFetchDataPage()
9398
{
9499
// Navigate to "Fetch Data"
95100
Browser.FindElement(By.LinkText("Fetch data")).Click();
96-
WaitAssert.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
101+
Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
97102

98103
// Wait until loaded
99104
var tableSelector = By.CssSelector("table.table");

src/Components/test/E2ETest/Tests/BinaryHttpClientTest.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using OpenQA.Selenium;
99
using OpenQA.Selenium.Support.UI;
1010
using System;
11+
using System.Threading.Tasks;
1112
using Xunit;
1213
using Xunit.Abstractions;
1314

@@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
1617
public class BinaryHttpClientTest : BasicTestAppTestBase, IClassFixture<AspNetSiteServerFixture>
1718
{
1819
readonly ServerFixture _apiServerFixture;
19-
readonly IWebElement _appElement;
20+
IWebElement _appElement;
2021
IWebElement _responseStatus;
2122
IWebElement _responseStatusText;
2223
IWebElement _testOutcome;
@@ -30,11 +31,16 @@ public BinaryHttpClientTest(
3031
{
3132
apiServerFixture.BuildWebHostMethod = TestServer.Program.BuildWebHost;
3233
_apiServerFixture = apiServerFixture;
34+
}
35+
36+
public override async Task InitializeAsync()
37+
{
38+
await base.InitializeAsync();
3339

3440
Navigate(ServerPathBase, noReload: true);
3541
_appElement = MountTestComponent<BinaryHttpRequestsComponent>();
3642
}
37-
43+
3844
[Fact]
3945
public void CanSendAndReceiveBytes()
4046
{

0 commit comments

Comments
 (0)