Skip to content

Commit 437134f

Browse files
authored
[Infrastructure] Standarize E2E test asserts and increase wait time (#9080)
* Standarize E2E test asserts and increase wait time
1 parent 23c88a1 commit 437134f

File tree

6 files changed

+55
-135
lines changed

6 files changed

+55
-135
lines changed

src/ProjectTemplates/test/Helpers/AspNetProcess.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public void VisitInBrowser(IWebDriver driver)
7575
if (driver.Title.Contains("Certificate error", StringComparison.OrdinalIgnoreCase))
7676
{
7777
_output.WriteLine("Page contains certificate error. Attempting to get around this...");
78-
driver.Click(By.Id("moreInformationDropdownSpan"));
78+
driver.FindElement(By.Id("moreInformationDropdownSpan")).Click();
7979
var continueLink = driver.FindElement(By.Id("invalidcert_continue"));
8080
if (continueLink != null)
8181
{

src/ProjectTemplates/test/Helpers/ProjectFactoryFixture.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Reflection;
1010
using System.Threading;
1111
using System.Threading.Tasks;
12+
using Microsoft.AspNetCore.E2ETesting;
1213
using Xunit.Abstractions;
1314

1415
namespace Templates.Test.Helpers
@@ -27,6 +28,13 @@ public ProjectFactoryFixture(IMessageSink diagnosticsMessageSink)
2728
DiagnosticsMessageSink = diagnosticsMessageSink;
2829
}
2930

31+
static ProjectFactoryFixture()
32+
{
33+
// There is no good place to put this, so this is the best one.
34+
// This sets the defualt timeout for all the Selenium test assertions.
35+
WaitAssert.DefaultTimeout = TimeSpan.FromSeconds(30);
36+
}
37+
3038
public async Task<Project> GetOrCreateProject(string projectKey, ITestOutputHelper output)
3139
{
3240
await TemplatePackageInstaller.EnsureTemplatingEngineInitializedAsync(output);

src/ProjectTemplates/test/Helpers/WebDriverExtensions.cs

Lines changed: 0 additions & 94 deletions
This file was deleted.

src/ProjectTemplates/test/RazorComponentsTemplateTest.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,35 +75,31 @@ private void TestBasicNavigation()
7575
// Give components.server enough time to load so that it can replace
7676
// the prerendered content before we start making assertions.
7777
Thread.Sleep(5000);
78-
Browser.WaitForElement("ul");
78+
Browser.Exists(By.TagName("ul"));
7979
// <title> element gets project ID injected into it during template execution
80-
Assert.Contains(Project.ProjectGuid, Browser.Title);
80+
Browser.Equal(Project.ProjectName.Trim(), () => Browser.Title.Trim());
8181

8282
// Initially displays the home page
83-
Assert.Equal("Hello, world!", Browser.GetText("h1"));
83+
Browser.Equal("Hello, world!", () => Browser.FindElement(By.TagName("h1")).Text);
8484

8585
// Can navigate to the counter page
86-
Browser.Click(By.PartialLinkText("Counter"));
87-
Browser.WaitForUrl("counter");
88-
Browser.WaitForText("h1", "Counter");
86+
Browser.FindElement(By.PartialLinkText("Counter")).Click();
87+
Browser.Contains("counter", () => Browser.Url);
88+
Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
8989

9090
// Clicking the counter button works
91-
var counterComponent = Browser.FindElement("h1").Parent();
92-
var counterDisplay = Browser.FindElement("h1 + p");
93-
Assert.Equal("Current count: 0", counterDisplay.Text);
94-
Browser.Click(counterComponent, "button");
95-
Browser.Equal("Current count: 1", () => Browser.FindElement("h1+p").Text);
91+
Browser.Equal("Current count: 0", () => Browser.FindElement(By.CssSelector("h1 + p")).Text);
92+
Browser.FindElement(By.CssSelector("p+button")).Click();
93+
Browser.Equal("Current count: 1", () => Browser.FindElement(By.CssSelector("h1 + p")).Text);
9694

9795
// Can navigate to the 'fetch data' page
98-
Browser.Click(By.PartialLinkText("Fetch data"));
99-
Browser.WaitForUrl("fetchdata");
100-
Browser.WaitForText("h1", "Weather forecast");
96+
Browser.FindElement(By.PartialLinkText("Fetch data")).Click();
97+
Browser.Contains("fetchdata", () => Browser.Url);
98+
Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
10199

102100
// Asynchronously loads and displays the table of weather forecasts
103-
var fetchDataComponent = Browser.FindElement("h1").Parent();
104-
Browser.WaitForElement("table>tbody>tr");
105-
var table = Browser.FindElement(fetchDataComponent, "table", timeoutSeconds: 5);
106-
Assert.Equal(5, table.FindElements(By.CssSelector("tbody tr")).Count);
101+
Browser.Exists(By.CssSelector("table>tbody>tr"));
102+
Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count);
107103
}
108104
}
109105
}

src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.IO;
6+
using System.Linq;
67
using System.Net;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.E2ETesting;
@@ -168,37 +169,34 @@ private void UpdatePublishedSettings()
168169

169170
private void TestBasicNavigation(bool visitFetchData)
170171
{
171-
Browser.WaitForElement("ul");
172+
Browser.Exists(By.TagName("ul"));
172173
// <title> element gets project ID injected into it during template execution
173-
Assert.Contains(Project.ProjectGuid, Browser.Title);
174+
Browser.Contains(Project.ProjectGuid, () => Browser.Title);
174175

175176
// Initially displays the home page
176-
Assert.Equal("Hello, world!", Browser.GetText("h1"));
177+
Browser.Equal("Hello, world!", () => Browser.FindElement(By.TagName("h1")).Text);
177178

178179
// Can navigate to the counter page
179-
Browser.Click(By.PartialLinkText("Counter"));
180-
Browser.WaitForUrl("counter");
180+
Browser.FindElement(By.PartialLinkText("Counter")).Click();
181+
Browser.Contains("counter", () => Browser.Url);
181182

182-
Assert.Equal("Counter", Browser.GetText("h1"));
183+
Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
183184

184185
// Clicking the counter button works
185-
var counterComponent = Browser.FindElement("h1").Parent();
186-
Assert.Equal("0", counterComponent.GetText("strong"));
187-
Browser.Click(counterComponent, "button");
188-
Assert.Equal("1", counterComponent.GetText("strong"));
186+
Browser.Equal("0", () => Browser.FindElement(By.CssSelector("p>strong")).Text);
187+
Browser.FindElement(By.CssSelector("p+button")).Click();
188+
Browser.Equal("1", () => Browser.FindElement(By.CssSelector("p>strong")).Text);
189189

190190
if (visitFetchData)
191191
{
192192
// Can navigate to the 'fetch data' page
193-
Browser.Click(By.PartialLinkText("Fetch data"));
194-
Browser.WaitForUrl("fetch-data");
195-
Assert.Equal("Weather forecast", Browser.GetText("h1"));
193+
Browser.FindElement(By.PartialLinkText("Fetch data")).Click();
194+
Browser.Contains("fetch-data", () => Browser.Url);
195+
Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
196196

197197
// Asynchronously loads and displays the table of weather forecasts
198-
var fetchDataComponent = Browser.FindElement("h1").Parent();
199-
Browser.WaitForElement("table>tbody>tr");
200-
var table = Browser.FindElement(fetchDataComponent, "table", timeoutSeconds: 5);
201-
Assert.Equal(5, table.FindElements(By.CssSelector("tbody tr")).Count);
198+
Browser.Exists(By.CssSelector("table>tbody>tr"));
199+
Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count);
202200
}
203201
}
204202

src/Shared/E2ETesting/WaitAssert.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System;
55
using System.Collections;
66
using System.Collections.Generic;
7-
using System.Collections.ObjectModel;
7+
using System.Runtime.ExceptionServices;
88
using OpenQA.Selenium;
99
using OpenQA.Selenium.Support.UI;
1010
using Xunit;
@@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.E2ETesting
1515

1616
public static class WaitAssert
1717
{
18-
private readonly static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(3);
18+
public static TimeSpan DefaultTimeout = TimeSpan.FromSeconds(3);
1919

2020
public static void Equal<T>(this IWebDriver driver, T expected, Func<T> actual)
2121
=> WaitAssertCore(driver, () => Assert.Equal(expected, actual()));
@@ -41,13 +41,17 @@ public static void Empty(this IWebDriver driver, Func<IEnumerable> actualValues)
4141
public static void Single(this IWebDriver driver, Func<IEnumerable> actualValues)
4242
=> WaitAssertCore(driver, () => Assert.Single(actualValues()));
4343

44+
public static void Exists(this IWebDriver driver, By finder)
45+
=> WaitAssertCore(driver, () => Assert.NotEmpty(driver.FindElements(finder)));
46+
4447
private static void WaitAssertCore(IWebDriver driver, Action assertion, TimeSpan timeout = default)
4548
{
4649
if (timeout == default)
4750
{
4851
timeout = DefaultTimeout;
4952
}
5053

54+
Exception lastException = null;
5155
try
5256
{
5357
new WebDriverWait(driver, timeout).Until(_ =>
@@ -57,16 +61,24 @@ private static void WaitAssertCore(IWebDriver driver, Action assertion, TimeSpan
5761
assertion();
5862
return true;
5963
}
60-
catch
64+
catch(Exception e)
6165
{
66+
lastException = e;
6267
return false;
6368
}
6469
});
6570
}
6671
catch (WebDriverTimeoutException)
6772
{
68-
// Instead of reporting it as a timeout, report the Xunit exception
69-
assertion();
73+
if (lastException != null)
74+
{
75+
ExceptionDispatchInfo.Capture(lastException).Throw();
76+
}
77+
else
78+
{
79+
// Instead of reporting it as a timeout, report the Xunit exception
80+
assertion();
81+
}
7082
}
7183
}
7284
}

0 commit comments

Comments
 (0)