Skip to content

Commit a8087dc

Browse files
[release/8.0] [Blazor] Fix default reconnect display not showing after enhanced navigation (#51173)
# Fix default reconnect display not showing after enhanced navigation Fixes an issue where the Blazor Server default reconnect display stops showing up during reconnection if an enhanced navigation occurs after the first time it was displayed. ## Description This issue happened because the reconnect display had its own state tracking whether it added itself to the DOM. However, an enhanced navigation may forcefully remove the reconnect display from the DOM without its knowing. This PR fixes the issue by changing the existing logic to instead check whether the reconnect display's root element is part of the `document`, and if it isn't, it gets added to the `body`. Fixes #51083 ## Customer Impact If a customer's app has a user with a flaky connection, it's likely that the reconnect display will stop appearing if the user reconnects multiple times in the same session. This means that the user will not receive any feedback that the app is reconnecting and may attempt to keep interacting with the app without understanding why it's not responding. It should be noted that this bug only applies to "Blazor Web"-style apps, which are new in .NET 8. Existing Blazor Server scenarios are not affected. ## Regression? - [ ] Yes - [X] No This only affects "Blazor Web"-style apps which are new in .NET 8. The reconnect display always exhibited this bug for Blazor Web apps, so this is not a regression. ## Risk - [ ] High - [ ] Medium - [X] Low The change is extremely small, isolated, and easy to reason about. ## Verification - [X] Manual (required) - [X] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [X] N/A --------- Co-authored-by: Christoph <[email protected]>
1 parent 6f2357f commit a8087dc

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

src/Components/Web.JS/dist/Release/blazor.server.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/dist/Release/blazor.web.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
1212

1313
button: HTMLButtonElement;
1414

15-
addedToDom = false;
16-
1715
reloadParagraph: HTMLParagraphElement;
1816

1917
loader: HTMLDivElement;
@@ -85,8 +83,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
8583
}
8684

8785
show(): void {
88-
if (!this.addedToDom) {
89-
this.addedToDom = true;
86+
if (!this.document.contains(this.modal)) {
9087
this.document.body.appendChild(this.modal);
9188
}
9289
this.modal.style.display = 'block';
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Components.TestServer.RazorComponents;
5+
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
6+
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
7+
using Microsoft.AspNetCore.E2ETesting;
8+
using OpenQA.Selenium;
9+
using TestServer;
10+
using Xunit.Abstractions;
11+
12+
namespace Microsoft.AspNetCore.Components.E2ETests.ServerRenderingTests;
13+
14+
[CollectionDefinition(nameof(InteractivityTest), DisableParallelization = true)]
15+
public class EndpointsServerReconnectionTest : ServerTestBase<BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<App>>>
16+
{
17+
public EndpointsServerReconnectionTest(
18+
BrowserFixture browserFixture,
19+
BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<App>> serverFixture,
20+
ITestOutputHelper output)
21+
: base(browserFixture, serverFixture, output)
22+
{
23+
}
24+
25+
public override Task InitializeAsync()
26+
=> InitializeAsync(BrowserFixture.StreamingContext);
27+
28+
[Fact]
29+
public void ReconnectUI_Displays_OnFirstReconnect()
30+
{
31+
Navigate($"{ServerPathBase}/streaming-interactivity");
32+
33+
Browser.Equal("Not streaming", () => Browser.FindElement(By.Id("status")).Text);
34+
35+
Browser.Click(By.Id("add-server-counter-prerendered-link"));
36+
Browser.Equal("True", () => Browser.FindElement(By.Id("is-interactive-0")).Text);
37+
38+
var javascript = (IJavaScriptExecutor)Browser;
39+
40+
javascript.ExecuteScript("Blazor._internal.forceCloseConnection()");
41+
Browser.Equal("block", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
42+
Browser.Equal("none", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
43+
Browser.Exists(By.Id("increment-0")).Click();
44+
Browser.Equal("1", () => Browser.Exists(By.Id("count-0")).Text);
45+
}
46+
47+
[Fact]
48+
public void ReconnectUI_Displays_OnSuccessiveReconnects_AfterEnhancedNavigation()
49+
{
50+
Navigate($"{ServerPathBase}/streaming-interactivity");
51+
52+
Browser.Equal("Not streaming", () => Browser.FindElement(By.Id("status")).Text);
53+
54+
Browser.Click(By.Id("add-server-counter-prerendered-link"));
55+
Browser.Equal("True", () => Browser.FindElement(By.Id("is-interactive-0")).Text);
56+
57+
var javascript = (IJavaScriptExecutor)Browser;
58+
59+
// Perform the first reconnect
60+
javascript.ExecuteScript("Blazor._internal.forceCloseConnection()");
61+
Browser.Equal("block", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
62+
Browser.Equal("none", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
63+
Browser.Exists(By.Id("increment-0")).Click();
64+
Browser.Equal("1", () => Browser.Exists(By.Id("count-0")).Text);
65+
66+
// Perform an enhanced navigation by updating the component's parameters
67+
Browser.Exists(By.Id("update-counter-link-0")).Click();
68+
Browser.Equal("2", () => Browser.FindElement(By.Id("increment-amount-0")).Text);
69+
70+
// Perform the second reconnect
71+
javascript.ExecuteScript("Blazor._internal.forceCloseConnection()");
72+
Browser.Equal("block", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
73+
Browser.Equal("none", () => Browser.Exists(By.Id("components-reconnect-modal")).GetCssValue("display"));
74+
Browser.Exists(By.Id("increment-0")).Click();
75+
Browser.Equal("3", () => Browser.Exists(By.Id("count-0")).Text);
76+
}
77+
}

0 commit comments

Comments
 (0)