Skip to content

Commit 5d4c4d6

Browse files
committed
Make WaitAssert report browser errors
It turns out we frequently have errors in the browser console in cases where we're hitting a "timeout".
1 parent ab006e1 commit 5d4c4d6

File tree

4 files changed

+93
-4
lines changed

4 files changed

+93
-4
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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 System;
5+
using System.Collections.Generic;
6+
using Xunit.Sdk;
7+
8+
namespace OpenQA.Selenium
9+
{
10+
// Used to report errors when we find errors in the browser. This is useful
11+
// because the underlying assert probably doesn't provide good information in that
12+
// case.
13+
public class BrowserAssertFailedException : XunitException
14+
{
15+
public BrowserAssertFailedException(IReadOnlyList<LogEntry> logs, Exception innerException)
16+
: base(BuildMessage(logs), innerException)
17+
{
18+
}
19+
20+
private static string BuildMessage(IReadOnlyList<LogEntry> logs)
21+
{
22+
return
23+
"Encountered browser errors while running assertion." + Environment.NewLine +
24+
string.Join(Environment.NewLine, logs);
25+
}
26+
}
27+
}

src/Shared/E2ETesting/BrowserTestBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,14 @@ protected virtual void InitializeAsyncCore()
8080

8181
protected IWebElement WaitUntilExists(By findBy, int timeoutSeconds = 10, bool throwOnError = false)
8282
{
83-
List<LogEntry> errors = null;
83+
IReadOnlyList<LogEntry> errors = null;
8484
IWebElement result = null;
8585
new WebDriverWait(Browser, TimeSpan.FromSeconds(timeoutSeconds)).Until(driver =>
8686
{
8787
if (throwOnError && Browser.Manage().Logs.AvailableLogTypes.Contains(LogType.Browser))
8888
{
8989
// Fail-fast if any errors were logged to the console.
90-
var log = Browser.Manage().Logs.GetLog(LogType.Browser);
91-
errors = log.Where(IsError).ToList();
90+
errors = Browser.GetBrowserLogs(LogLevel.Severe);
9291
if (errors.Count > 0)
9392
{
9493
return true;

src/Shared/E2ETesting/WaitAssert.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ private static void WaitAssertCore(IWebDriver driver, Action assertion, TimeSpan
7373
}
7474
catch (WebDriverTimeoutException)
7575
{
76-
if (lastException != null)
76+
var errors = driver.GetBrowserLogs(LogLevel.Severe);
77+
if (errors.Count > 0)
78+
{
79+
throw new BrowserAssertFailedException(errors, lastException);
80+
}
81+
else if (lastException != null)
7782
{
7883
ExceptionDispatchInfo.Capture(lastException).Throw();
7984
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace OpenQA.Selenium
9+
{
10+
public static class WebDriverExtensions
11+
{
12+
public static IReadOnlyList<LogEntry> GetBrowserLogs(this IWebDriver driver, LogLevel level)
13+
{
14+
if (driver is null)
15+
{
16+
throw new ArgumentNullException(nameof(driver));
17+
}
18+
19+
// Fail-fast if any errors were logged to the console.
20+
var log = driver.Manage().Logs.GetLog(LogType.Browser);
21+
if (log == null)
22+
{
23+
return Array.Empty<LogEntry>();
24+
}
25+
26+
var logs = log.Where(entry => entry.Level >= level && !ShouldIgnore(entry)).ToList();
27+
if (logs.Count > 0)
28+
{
29+
return logs;
30+
}
31+
32+
return Array.Empty<LogEntry>();
33+
}
34+
35+
// Be careful adding anything new to this list. We only want to put things here that are ignorable
36+
// in all cases.
37+
private static bool ShouldIgnore(LogEntry entry)
38+
{
39+
// Don't fail if we're missing the favicon, that's not super important.
40+
if (entry.Message.Contains("favicon.ico"))
41+
{
42+
return true;
43+
}
44+
45+
// These two messages appear sometimes, but it doesn't actually block the tests.
46+
if (entry.Message.Contains("WASM: wasm streaming compile failed: TypeError: Could not download wasm module"))
47+
{
48+
return true;
49+
}
50+
if (entry.Message.Contains("WASM: falling back to ArrayBuffer instantiation"))
51+
{
52+
return true;
53+
}
54+
55+
return false;
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)