Fail faster in Blazor E2E tests
This change adds a fail-fast mechanism to our E2E tests based on the browser console. This will fail super hard if an unhandled exception is thrown. I think it would be interesting to also see if we could do the same thing for 404s. The goal of this change is to make it so that the E2E tests can fail faster (3-4s) than the 30s timeout in the case that something catastrophic happens. As a nice side benefit you get to see the exception message.
This commit is contained in:
parent
40e268f59e
commit
3cc6e8373b
|
|
@ -1,13 +1,12 @@
|
|||
// 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.Linq;
|
||||
using BasicTestApp;
|
||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
|
||||
|
|
@ -38,18 +37,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure
|
|||
protected SelectElement WaitUntilTestSelectorReady()
|
||||
{
|
||||
var elemToFind = By.CssSelector("#test-selector > select");
|
||||
WaitUntilExists(elemToFind, timeoutSeconds: 30);
|
||||
WaitUntilExists(elemToFind, timeoutSeconds: 30, throwOnError: true);
|
||||
return new SelectElement(Browser.FindElement(elemToFind));
|
||||
}
|
||||
|
||||
protected IWebElement WaitUntilExists(By findBy, int timeoutSeconds = 10)
|
||||
{
|
||||
IWebElement result = null;
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(timeoutSeconds))
|
||||
.Until(driver => (result = driver.FindElement(findBy)) != null);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void SignInAs(string usernameOrNull, string rolesOrNull, bool useSeparateTab = false)
|
||||
{
|
||||
const string authenticationPageUrl = "/Authentication";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
// 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.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.E2ETesting
|
||||
{
|
||||
|
|
@ -55,6 +60,66 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
|
||||
protected virtual void InitializeAsyncCore()
|
||||
{
|
||||
// Clear logs - we check these during tests in some cases.
|
||||
// Make sure each test starts clean.
|
||||
((IJavaScriptExecutor)Browser).ExecuteScript("console.clear()");
|
||||
}
|
||||
|
||||
protected IWebElement WaitUntilExists(By findBy, int timeoutSeconds = 10, bool throwOnError = false)
|
||||
{
|
||||
List<LogEntry> errors = null;
|
||||
IWebElement result = null;
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(timeoutSeconds)).Until(driver =>
|
||||
{
|
||||
if (throwOnError && Browser.Manage().Logs.AvailableLogTypes.Contains(LogType.Browser))
|
||||
{
|
||||
// Fail-fast if any errors were logged to the console.
|
||||
var log = Browser.Manage().Logs.GetLog(LogType.Browser);
|
||||
errors = log.Where(IsError).ToList();
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (result = driver.FindElement(findBy)) != null;
|
||||
});
|
||||
|
||||
if (errors?.Count > 0)
|
||||
{
|
||||
var message =
|
||||
$"Encountered errors while looking for '{findBy}'." + Environment.NewLine +
|
||||
string.Join(Environment.NewLine, errors);
|
||||
throw new XunitException(message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsError(LogEntry entry)
|
||||
{
|
||||
if (entry.Level < LogLevel.Severe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't fail if we're missing the favicon, that's not super important.
|
||||
if (entry.Message.Contains("favicon.ico"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// These two messages appear sometimes, but it doesn't actually block the tests.
|
||||
if (entry.Message.Contains("WASM: wasm streaming compile failed: TypeError: Could not download wasm module"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (entry.Message.Contains("WASM: falling back to ArrayBuffer instantiation"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue