Attempt to read the logs from the browser (#26289)
* Attempt to read the logs from the browser Seleniunm currently does not return log messages (See https://github.com/SeleniumHQ/selenium/issues/8229). This making figuring out blazor WASM test failures a lot harder. This change adds some JS to the test apps to read the console output. * WIP
This commit is contained in:
parent
90f4cdad9e
commit
0e5d7ef1d4
|
|
@ -6,6 +6,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<app>Loading...</app>
|
||||
<script src="seleniumworkaround.js"></script>
|
||||
<script src="customJsFileForTests.js"></script>
|
||||
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
(function () {
|
||||
// Note: there are multiple copies of this file throughout the repo. If you're editing it, please look for
|
||||
// other seleniumworkaround.js files and keep them all in sync.
|
||||
const logs = [];
|
||||
|
||||
const defaultLog = console.log;
|
||||
console.log = function () {
|
||||
defaultLog.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultError = console.error;
|
||||
console.error = function () {
|
||||
defaultError.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultWarn = console.warn;
|
||||
console.warn = function () {
|
||||
defaultWarn.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
window.getBrowserLogs = () => logs;
|
||||
})();
|
||||
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="seleniumworkaround.js"></script>
|
||||
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
(function () {
|
||||
// Note: there are multiple copies of this file throughout the repo. If you're editing it, please look for
|
||||
// other seleniumworkaround.js files and keep them all in sync.
|
||||
const logs = [];
|
||||
|
||||
const defaultLog = console.log;
|
||||
console.log = function () {
|
||||
defaultLog.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultError = console.error;
|
||||
console.error = function () {
|
||||
defaultError.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultWarn = console.warn;
|
||||
console.warn = function () {
|
||||
defaultWarn.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
window.getBrowserLogs = () => logs;
|
||||
})();
|
||||
|
||||
|
|
@ -62,8 +62,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
|
|||
((IJavaScriptExecutor)Browser).ExecuteScript("Blazor._internal.forceCloseConnection()");
|
||||
|
||||
// Wait until the reconnection dialog has been shown but is now hidden
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(10))
|
||||
.Until(driver => driver.FindElement(By.Id("components-reconnect-modal"))?.GetCssValue("display") == "none");
|
||||
var reconnectModel = Browser.Exists(By.Id("components-reconnect-modal"));
|
||||
Browser.Equal("none", () => reconnectModel.GetCssValue("display"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
|
|||
var interopButton = Browser.FindElement(By.Id("btn-interop"));
|
||||
interopButton.Click();
|
||||
|
||||
var wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(10))
|
||||
.Until(d => d.FindElement(By.Id("done-with-interop")));
|
||||
Browser.Exists(By.Id("done-with-interop"));
|
||||
|
||||
foreach (var expectedValue in expectedValues)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using BasicTestApp;
|
||||
using BasicTestApp.HttpClientTest;
|
||||
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
|
||||
using Microsoft.AspNetCore.E2ETesting;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using TestServer;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
|
@ -61,9 +59,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
_appElement.FindElement(By.Id("send-request")).Click();
|
||||
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.Id("response-status")) != null);
|
||||
_responseStatus = _appElement.FindElement(By.Id("response-status"));
|
||||
_responseStatus = Browser.Exists(By.Id("response-status"));
|
||||
_responseStatusText = _appElement.FindElement(By.Id("response-status-text"));
|
||||
_testOutcome = _appElement.FindElement(By.Id("test-outcome"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
private void WaitUntilLoaded()
|
||||
{
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.TagName("h1")).Text == "Hello, world!");
|
||||
var element = Browser.Exists(By.TagName("h1"));
|
||||
Browser.Equal("Hello, world!", () => element.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
Assert.NotNull(Browser.FindElement(By.Id("test-selector")));
|
||||
}
|
||||
|
||||
|
||||
private void WaitUntilLoaded()
|
||||
{
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.TagName("app")).Text != "Loading...");
|
||||
var app = Browser.Exists(By.TagName("app"));
|
||||
Browser.NotEqual("Loading...", () => app.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
private void WaitUntilLoaded()
|
||||
{
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.TagName("app")).Text != "Loading...");
|
||||
var app = Browser.Exists(By.TagName("app"));
|
||||
Browser.NotEqual("Loading...", () => app.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,9 +134,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
string WaitAndGetResponseText()
|
||||
{
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.Id("response-text")) != null);
|
||||
return app.FindElement(By.Id("response-text")).Text;
|
||||
return Browser.Exists(By.Id("response-text")).Text;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,9 +148,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
_appElement.FindElement(By.Id("send-request")).Click();
|
||||
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.Id("response-status")) != null);
|
||||
_responseStatus = _appElement.FindElement(By.Id("response-status"));
|
||||
_responseStatus = Browser.Exists(By.Id("response-status"));
|
||||
_responseBody = _appElement.FindElement(By.Id("response-body"));
|
||||
_responseHeaders = _appElement.FindElement(By.Id("response-headers"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,8 +135,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
var interopButton = Browser.FindElement(By.Id("btn-interop"));
|
||||
interopButton.Click();
|
||||
|
||||
var wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(10))
|
||||
.Until(d => d.FindElement(By.Id("done-with-interop")));
|
||||
Browser.Exists(By.Id("done-with-interop"));
|
||||
|
||||
foreach (var expectedValue in expectedValues)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -546,10 +546,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
SetUrlViaPushState("/LongPage1");
|
||||
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(2)).Until(
|
||||
driver => driver.FindElement(By.Id("loading-banner")) != null);
|
||||
|
||||
Assert.True(app.FindElement(By.Id("loading-banner")) != null);
|
||||
Browser.Exists(By.Id("loading-banner"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -96,8 +96,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
// Wait until loaded
|
||||
var tableSelector = By.CssSelector("table.table");
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(10)).Until(
|
||||
driver => driver.FindElement(tableSelector) != null);
|
||||
Browser.Exists(tableSelector);
|
||||
|
||||
// Check the table is displayed correctly
|
||||
var rows = Browser.FindElements(By.CssSelector("table.table tbody tr"));
|
||||
|
|
@ -111,8 +110,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
|
||||
private void WaitUntilLoaded()
|
||||
{
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(
|
||||
driver => driver.FindElement(By.TagName("app")).Text != "Loading...");
|
||||
var app = Browser.Exists(By.TagName("app"));
|
||||
Browser.NotEqual("Loading...", () => app.Text);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -66,13 +66,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
{
|
||||
// Navigate to a page with lazy loaded assemblies for the first time
|
||||
SetUrlViaPushState("/WithLazyAssembly");
|
||||
var app = Browser.MountTestComponent<TestRouterWithLazyAssembly>();
|
||||
Browser.MountTestComponent<TestRouterWithLazyAssembly>();
|
||||
|
||||
// Wait for the page to finish loading
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(2)).Until(
|
||||
driver => driver.FindElement(By.Id("use-package-button")) != null);
|
||||
|
||||
var button = app.FindElement(By.Id("use-package-button"));
|
||||
var button = Browser.Exists(By.Id("use-package-button"));
|
||||
|
||||
// We should have requested the DLL
|
||||
Assert.True(HasLoadedAssembly("Newtonsoft.Json.dll"));
|
||||
|
|
@ -98,8 +95,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
|
|||
SetUrlViaPushState("/WithLazyLoadedRoutes");
|
||||
|
||||
// Wait for the page to finish loading
|
||||
new WebDriverWait(Browser, TimeSpan.FromSeconds(2)).Until(
|
||||
driver => driver.FindElement(By.Id("lazy-load-msg")) != null);
|
||||
Browser.Exists(By.Id("lazy-load-msg"));
|
||||
|
||||
// Now the assembly has been loaded
|
||||
Assert.True(HasLoadedAssembly("LazyTestContentPackage.dll"));
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Used for specific test cases -->
|
||||
<script src="js/seleniumworkaround.js"></script>
|
||||
<script src="js/jsinteroptests.js"></script>
|
||||
<script src="js/renderattributestest.js"></script>
|
||||
<script src="js/webComponentPerformingJsInterop.js"></script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
(function () {
|
||||
// Note: there are multiple copies of this file throughout the repo. If you're editing it, please look for
|
||||
// other seleniumworkaround.js files and keep them all in sync.
|
||||
const logs = [];
|
||||
|
||||
const defaultLog = console.log;
|
||||
console.log = function () {
|
||||
defaultLog.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultError = console.error;
|
||||
console.error = function () {
|
||||
defaultError.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
const defaultWarn = console.warn;
|
||||
console.warn = function () {
|
||||
defaultWarn.apply(console, arguments);
|
||||
logs.push(Array.from(arguments).join(' '));
|
||||
}
|
||||
|
||||
window.getBrowserLogs = () => logs;
|
||||
})();
|
||||
|
||||
|
|
@ -14,12 +14,12 @@ namespace OpenQA.Selenium
|
|||
// case.
|
||||
public class BrowserAssertFailedException : XunitException
|
||||
{
|
||||
public BrowserAssertFailedException(IReadOnlyList<LogEntry> logs, Exception innerException, string screenShotPath, string innerHTML)
|
||||
public BrowserAssertFailedException(IReadOnlyCollection<string> logs, Exception innerException, string screenShotPath, string innerHTML)
|
||||
: base(BuildMessage(innerException, logs, screenShotPath, innerHTML), innerException)
|
||||
{
|
||||
}
|
||||
|
||||
private static string BuildMessage(Exception exception, IReadOnlyList<LogEntry> logs, string screenShotPath, string innerHTML)
|
||||
private static string BuildMessage(Exception exception, IReadOnlyCollection<string> logs, string screenShotPath, string innerHTML)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine(exception.ToString());
|
||||
|
|
|
|||
|
|
@ -5,8 +5,11 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.DevTools.Page;
|
||||
using OpenQA.Selenium.Interactions;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -117,7 +120,17 @@ namespace Microsoft.AspNetCore.E2ETesting
|
|||
|
||||
var fileId = $"{Guid.NewGuid():N}.png";
|
||||
var screenShotPath = Path.Combine(Path.GetFullPath(E2ETestOptions.Instance.ScreenShotsPath), fileId);
|
||||
var errors = driver.GetBrowserLogs(LogLevel.All);
|
||||
var errors = driver.GetBrowserLogs(LogLevel.All).Select(c => c.ToString()).ToList();
|
||||
if (errors.Count == 0)
|
||||
{
|
||||
// Workaround for selenium bug https://github.com/SeleniumHQ/selenium/issues/8229. Getting log does
|
||||
// not work. However some of our test apps provide a mechnanism to read the logs. Try that.
|
||||
|
||||
var logs = (IReadOnlyCollection<object>)((IJavaScriptExecutor)driver).ExecuteScript(
|
||||
"return window.getBrowserLogs && window.getBrowserLogs() || []");
|
||||
|
||||
errors = logs.Select(l => l.ToString()).ToList();
|
||||
}
|
||||
|
||||
TakeScreenShot(driver, screenShotPath);
|
||||
var exceptionInfo = lastException != null ? ExceptionDispatchInfo.Capture(lastException) :
|
||||
|
|
|
|||
Loading…
Reference in New Issue