Skip to content

Commit bad98de

Browse files
committed
Merge remote-tracking branch 'origin/main' into mbuck/close-unused-circuits
2 parents 6daf13d + 445e2cf commit bad98de

File tree

26 files changed

+452
-269
lines changed

26 files changed

+452
-269
lines changed

eng/SourceBuildPrebuiltBaseline.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@
4040

4141
<!-- Transivite dependency of Microsoft.CodeAnalysis.ExternalAccess.AspNetCore -> Microsoft.CodeAnalysis.Features.
4242
In product build the dependency is bumped to latest, which also bumps the version of DiaSymReader -->
43-
<UsagePattern IdentityGlob="Microsoft.DiaSymReader/*1.4.0*" />
43+
<UsagePattern IdentityGlob="Microsoft.DiaSymReader/*2.0.0*" />
4444
</IgnorePatterns>
4545
</UsageData>

eng/Version.Details.xml

Lines changed: 163 additions & 163 deletions
Large diffs are not rendered by default.

eng/Versions.props

Lines changed: 80 additions & 80 deletions
Large diffs are not rendered by default.

eng/targets/Helix.Common.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<HelixQueueAlmaLinux8>(AlmaLinux.8.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:almalinux-8-helix-amd64</HelixQueueAlmaLinux8>
55
<HelixQueueAlpine316>(Alpine.316.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:alpine-3.16-helix-amd64</HelixQueueAlpine316>
66
<HelixQueueDebian11>(Debian.11.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:debian-11-helix-amd64</HelixQueueDebian11>
7-
<HelixQueueFedora34>(Fedora.34.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:fedora-34-helix</HelixQueueFedora34>
7+
<HelixQueueFedora38>(Fedora.38.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:fedora-38-helix</HelixQueueFedora38>
88
<HelixQueueMariner>(Mariner)[email protected]/dotnet-buildtools/prereqs:cbl-mariner-1.0-helix</HelixQueueMariner>
99
<HelixQueueArmDebian12>(Debian.12.Arm64.Open)[email protected]/dotnet-buildtools/prereqs:debian-12-helix-arm64v8</HelixQueueArmDebian12>
1010

@@ -44,7 +44,7 @@
4444
<!-- Containers -->
4545
<HelixAvailableTargetQueue Include="$(HelixQueueAlpine316)" Platform="Linux" />
4646
<HelixAvailableTargetQueue Include="$(HelixQueueDebian11)" Platform="Linux" />
47-
<HelixAvailableTargetQueue Include="$(HelixQueueFedora34)" Platform="Linux" />
47+
<HelixAvailableTargetQueue Include="$(HelixQueueFedora38)" Platform="Linux" />
4848
<HelixAvailableTargetQueue Include="$(HelixQueueMariner)" Platform="Linux" />
4949
<HelixAvailableTargetQueue Include="$(HelixQueueArmDebian12)" Platform="Linux" />
5050

eng/targets/Helix.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
$(HelixQueueAlmaLinux8);
2020
$(HelixQueueAlpine316);
2121
$(HelixQueueDebian11);
22-
$(HelixQueueFedora34);
22+
$(HelixQueueFedora38);
2323
$(HelixQueueMariner);
2424
Ubuntu.2004.Amd64.Open;
2525
</SkipHelixQueues>

src/Components/Components/src/NavigationManager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,17 @@ protected virtual void NavigateToCore([StringSyntax(StringSyntaxAttribute.Uri)]
166166
protected virtual void NavigateToCore([StringSyntax(StringSyntaxAttribute.Uri)] string uri, NavigationOptions options) =>
167167
throw new NotImplementedException($"The type {GetType().FullName} does not support supplying {nameof(NavigationOptions)}. To add support, that type should override {nameof(NavigateToCore)}(string uri, {nameof(NavigationOptions)} options).");
168168

169+
/// <summary>
170+
/// Refreshes the current page via request to the server.
171+
/// </summary>
172+
/// <remarks>
173+
/// If <paramref name="forceReload"/> is <c>true</c>, a full page reload will always be performed.
174+
/// Otherwise, the response HTML may be merged with the document's existing HTML to preserve client-side state,
175+
/// falling back on a full page reload if necessary.
176+
/// </remarks>
177+
public virtual void Refresh(bool forceReload = false)
178+
=> NavigateTo(Uri, forceLoad: true, replace: true);
179+
169180
/// <summary>
170181
/// Called to initialize BaseURI and current URI before these values are used for the first time.
171182
/// Override <see cref="EnsureInitialized" /> and call this method to dynamically calculate these values.

src/Components/Components/src/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static Microsoft.AspNetCore.Components.SupplyParameterFromQueryProviderServiceCo
101101
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, string! name, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
102102
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, Microsoft.AspNetCore.Components.CascadingValueSource<TValue>!>! sourceFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
103103
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
104+
virtual Microsoft.AspNetCore.Components.NavigationManager.Refresh(bool forceReload = false) -> void
104105
virtual Microsoft.AspNetCore.Components.Rendering.ComponentState.DisposeAsync() -> System.Threading.Tasks.ValueTask
105106
virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.AddPendingTask(Microsoft.AspNetCore.Components.Rendering.ComponentState? componentState, System.Threading.Tasks.Task! task) -> void
106107
virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.CreateComponentState(int componentId, Microsoft.AspNetCore.Components.IComponent! component, Microsoft.AspNetCore.Components.Rendering.ComponentState? parentComponentState) -> Microsoft.AspNetCore.Components.Rendering.ComponentState!

src/Components/Server/src/Circuits/RemoteNavigationManager.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ async Task PerformNavigationAsync()
117117
}
118118
}
119119

120+
/// <inheritdoc />
121+
public override void Refresh(bool forceReload = false)
122+
{
123+
_ = RefreshAsync();
124+
125+
async Task RefreshAsync()
126+
{
127+
try
128+
{
129+
await _jsRuntime.InvokeVoidAsync(Interop.Refresh, forceReload);
130+
}
131+
catch (Exception ex)
132+
{
133+
Log.RefreshFailed(_logger, ex);
134+
UnhandledException?.Invoke(this, ex);
135+
}
136+
}
137+
}
138+
120139
protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context)
121140
{
122141
Log.NavigationFailed(_logger, context.TargetLocation, ex);
@@ -162,5 +181,8 @@ public static void RequestingNavigation(ILogger logger, string uri, NavigationOp
162181

163182
[LoggerMessage(4, LogLevel.Error, "Navigation failed when changing the location to {Uri}", EventName = "NavigationFailed")]
164183
public static partial void NavigationFailed(ILogger logger, string uri, Exception exception);
184+
185+
[LoggerMessage(5, LogLevel.Error, "Failed to refresh", EventName = "RefreshFailed")]
186+
public static partial void RefreshFailed(ILogger logger, Exception exception);
165187
}
166188
}

src/Components/Shared/src/BrowserNavigationManagerInterop.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ internal static class BrowserNavigationManagerInterop
1616

1717
public const string NavigateTo = Prefix + "navigateTo";
1818

19+
public const string Refresh = Prefix + "refresh";
20+
1921
public const string SetHasLocationChangingListeners = Prefix + "setHasLocationChangingListeners";
2022

2123
public const string ScrollToElement = Prefix + "scrollToElement";

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/dist/Release/blazor.webview.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/WebView/WebViewIpcReceiver.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export function startIpcReceiver(): void {
4141

4242
'Navigate': navigationManagerFunctions.navigateTo,
4343

44+
'Refresh': navigationManagerFunctions.refresh,
45+
4446
'SetHasLocationChangingListeners': navigationManagerFunctions.setHasLocationChangingListeners,
4547

4648
'EndLocationChanging': navigationManagerFunctions.endLocationChanging,

src/Components/Web.JS/src/Services/NavigationEnhancement.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export function attachProgressivelyEnhancedNavigationListener(callbacks: Navigat
4848
document.addEventListener('click', onDocumentClick);
4949
document.addEventListener('submit', onDocumentSubmit);
5050
window.addEventListener('popstate', onPopState);
51+
52+
attachProgrammaticEnhancedNavigationHandler(performProgrammaticEnhancedNavigation);
5153
}
5254

5355
export function detachProgressivelyEnhancedNavigationListener() {
@@ -57,10 +59,6 @@ export function detachProgressivelyEnhancedNavigationListener() {
5759
}
5860

5961
function performProgrammaticEnhancedNavigation(absoluteInternalHref: string, replace: boolean) {
60-
if (hasInteractiveRouter()) {
61-
return;
62-
}
63-
6462
if (replace) {
6563
history.replaceState(null, /* ignored title */ '', absoluteInternalHref);
6664
} else {
@@ -70,8 +68,6 @@ function performProgrammaticEnhancedNavigation(absoluteInternalHref: string, rep
7068
performEnhancedPageLoad(absoluteInternalHref);
7169
}
7270

73-
attachProgrammaticEnhancedNavigationHandler(performProgrammaticEnhancedNavigation);
74-
7571
function onDocumentClick(event: MouseEvent) {
7672
if (hasInteractiveRouter()) {
7773
return;

src/Components/Web.JS/src/Services/NavigationManager.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const internalFunctions = {
2525
setHasLocationChangingListeners,
2626
endLocationChanging,
2727
navigateTo: navigateToFromDotNet,
28+
refresh,
2829
getBaseURI: (): string => document.baseURI,
2930
getLocationHref: (): string => location.href,
3031
scrollToElement,
@@ -93,6 +94,14 @@ function performScrollToElementOnTheSamePage(absoluteHref : string, replace: boo
9394
scrollToElement(identifier);
9495
}
9596

97+
function refresh(forceReload: boolean): void {
98+
if (!forceReload && hasProgrammaticEnhancedNavigationHandler()) {
99+
performProgrammaticEnhancedNavigation(location.href, /* replace */ true);
100+
} else {
101+
location.reload();
102+
}
103+
}
104+
96105
// For back-compat, we need to accept multiple overloads
97106
export function navigateTo(uri: string, options: NavigationOptions): void;
98107
export function navigateTo(uri: string, forceLoad: boolean): void;

src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ async Task PerformNavigationAsync()
7979
}
8080
}
8181

82+
/// <inheritdoc />
83+
public override void Refresh(bool forceReload = false)
84+
{
85+
DefaultWebAssemblyJSRuntime.Instance.InvokeVoid(Interop.Refresh, forceReload);
86+
}
87+
8288
protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context)
8389
{
8490
Log.NavigationFailed(_logger, context.TargetLocation, ex);

src/Components/WebAssembly/testassets/HostedInAspNet.Client/wwwroot/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
return type === 'dotnetjs'
2020
? `${defaultUri}?customizedbootresource=true`
2121
: fetch(defaultUri, { integrity: integrity, cache: 'no-cache', headers: { 'customizedbootresource': 'true' } });
22+
},
23+
configureRuntime: function (builder) {
24+
builder.withConfig({
25+
cachedResourcesPurgeDelay: 0
26+
});
2227
}
2328
});
2429
</script>

src/Components/WebView/WebView/src/IpcCommon.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,6 @@ public enum OutgoingMessageType
7676
SendByteArrayToJS,
7777
SetHasLocationChangingListeners,
7878
EndLocationChanging,
79+
Refresh,
7980
}
8081
}

src/Components/WebView/WebView/src/IpcSender.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Microsoft.AspNetCore.Components.WebView;
1010

11-
// Handles comunication between the component abstractions (Renderer, NavigationManager, JSInterop, etc.)
11+
// Handles communication between the component abstractions (Renderer, NavigationManager, JSInterop, etc.)
1212
// and the underlying transport channel
1313
internal sealed class IpcSender
1414
{
@@ -39,6 +39,11 @@ public void Navigate(string uri, NavigationOptions options)
3939
DispatchMessageWithErrorHandling(IpcCommon.Serialize(IpcCommon.OutgoingMessageType.Navigate, uri, options));
4040
}
4141

42+
public void Refresh(bool forceReload)
43+
{
44+
DispatchMessageWithErrorHandling(IpcCommon.Serialize(IpcCommon.OutgoingMessageType.Refresh, forceReload));
45+
}
46+
4247
public void AttachToDocument(int componentId, string selector)
4348
{
4449
DispatchMessageWithErrorHandling(IpcCommon.Serialize(IpcCommon.OutgoingMessageType.AttachToDocument, componentId, selector));

src/Components/WebView/WebView/src/Services/WebViewNavigationManager.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ async Task PerformNavigationAsync()
8484
}
8585
}
8686

87+
/// <inheritdoc />
88+
public override void Refresh(bool forceReload = false)
89+
{
90+
_ipcSender.Refresh(forceReload);
91+
}
92+
8793
protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context)
8894
{
8995
Log.NavigationFailed(_logger, context.TargetLocation, ex);

src/Components/test/E2ETest/ServerRenderingTests/EnhancedNavigationTest.cs

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,11 @@ public void CanPerformProgrammaticEnhancedNavigation(string renderMode)
181181
}
182182

183183
[Theory]
184-
[InlineData("server")]
185-
[InlineData("webassembly")]
186-
public void CanPerformProgrammaticEnhancedRefresh(string renderMode)
184+
[InlineData("server", "refresh-with-navigate-to")]
185+
[InlineData("webassembly", "refresh-with-navigate-to")]
186+
[InlineData("server", "refresh-with-refresh")]
187+
[InlineData("webassembly", "refresh-with-refresh")]
188+
public void CanPerformProgrammaticEnhancedRefresh(string renderMode, string refreshButtonId)
187189
{
188190
Navigate($"{ServerPathBase}/nav");
189191
Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text);
@@ -199,7 +201,7 @@ public void CanPerformProgrammaticEnhancedRefresh(string renderMode)
199201
Browser.True(() => int.TryParse(renderIdElement.Text, out initialRenderId));
200202
Assert.NotEqual(-1, initialRenderId);
201203

202-
Browser.Exists(By.Id("perform-enhanced-refresh")).Click();
204+
Browser.Exists(By.Id(refreshButtonId)).Click();
203205
Browser.True(() =>
204206
{
205207
if (IsElementStale(renderIdElement) || !int.TryParse(renderIdElement.Text, out var newRenderId))
@@ -235,7 +237,79 @@ public void NavigateToCanFallBackOnFullPageReload(string renderMode)
235237
Browser.True(() => int.TryParse(initialRenderIdElement.Text, out initialRenderId));
236238
Assert.NotEqual(-1, initialRenderId);
237239

238-
Browser.Exists(By.Id("perform-page-reload")).Click();
240+
Browser.Exists(By.Id("reload-with-navigate-to")).Click();
241+
Browser.True(() => IsElementStale(initialRenderIdElement));
242+
243+
var finalRenderIdElement = Browser.Exists(By.Id("render-id"));
244+
var finalRenderId = -1;
245+
Browser.True(() => int.TryParse(finalRenderIdElement.Text, out finalRenderId));
246+
Assert.NotEqual(-1, initialRenderId);
247+
Assert.True(finalRenderId > initialRenderId);
248+
249+
// Ensure that the history stack was correctly updated
250+
Browser.Navigate().Back();
251+
Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text);
252+
Assert.EndsWith("/nav", Browser.Url);
253+
}
254+
255+
[Theory]
256+
[InlineData("server")]
257+
[InlineData("webassembly")]
258+
public void RefreshCanFallBackOnFullPageReload(string renderMode)
259+
{
260+
Navigate($"{ServerPathBase}/nav");
261+
Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text);
262+
263+
Browser.Exists(By.TagName("nav")).FindElement(By.LinkText($"Interactive component navigation ({renderMode})")).Click();
264+
Browser.Equal("Page with interactive components that navigate", () => Browser.Exists(By.TagName("h1")).Text);
265+
266+
((IJavaScriptExecutor)Browser).ExecuteScript("sessionStorage.setItem('suppress-enhanced-navigation', 'true')");
267+
Browser.Navigate().Refresh();
268+
Browser.Equal("Page with interactive components that navigate", () => Browser.Exists(By.TagName("h1")).Text);
269+
270+
// Normally, you shouldn't store references to elements because they could become stale references
271+
// after the page re-renders. However, we want to explicitly test that the element becomes stale
272+
// across renders to ensure that a full page reload occurs.
273+
var initialRenderIdElement = Browser.Exists(By.Id("render-id"));
274+
var initialRenderId = -1;
275+
Browser.True(() => int.TryParse(initialRenderIdElement.Text, out initialRenderId));
276+
Assert.NotEqual(-1, initialRenderId);
277+
278+
Browser.Exists(By.Id("refresh-with-refresh")).Click();
279+
Browser.True(() => IsElementStale(initialRenderIdElement));
280+
281+
var finalRenderIdElement = Browser.Exists(By.Id("render-id"));
282+
var finalRenderId = -1;
283+
Browser.True(() => int.TryParse(finalRenderIdElement.Text, out finalRenderId));
284+
Assert.NotEqual(-1, initialRenderId);
285+
Assert.True(finalRenderId > initialRenderId);
286+
287+
// Ensure that the history stack was correctly updated
288+
Browser.Navigate().Back();
289+
Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text);
290+
Assert.EndsWith("/nav", Browser.Url);
291+
}
292+
293+
[Theory]
294+
[InlineData("server")]
295+
[InlineData("webassembly")]
296+
public void RefreshWithForceReloadDoesFullPageReload(string renderMode)
297+
{
298+
Navigate($"{ServerPathBase}/nav");
299+
Browser.Equal("Hello", () => Browser.Exists(By.TagName("h1")).Text);
300+
301+
Browser.Exists(By.TagName("nav")).FindElement(By.LinkText($"Interactive component navigation ({renderMode})")).Click();
302+
Browser.Equal("Page with interactive components that navigate", () => Browser.Exists(By.TagName("h1")).Text);
303+
304+
// Normally, you shouldn't store references to elements because they could become stale references
305+
// after the page re-renders. However, we want to explicitly test that the element becomes stale
306+
// across renders to ensure that a full page reload occurs.
307+
var initialRenderIdElement = Browser.Exists(By.Id("render-id"));
308+
var initialRenderId = -1;
309+
Browser.True(() => int.TryParse(initialRenderIdElement.Text, out initialRenderId));
310+
Assert.NotEqual(-1, initialRenderId);
311+
312+
Browser.Exists(By.Id("reload-with-refresh")).Click();
239313
Browser.True(() => IsElementStale(initialRenderIdElement));
240314

241315
var finalRenderIdElement = Browser.Exists(By.Id("render-id"));

src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,17 @@ public async Task IncrementallyUpdatesCache()
9191
requestedDll => Assert.Contains("/Microsoft.AspNetCore.Components.wasm", requestedDll),
9292
requestedDll => Assert.Contains("/dotnet.native.wasm", requestedDll));
9393

94-
// We also update the cache (add new items, remove unnecessary items)
95-
await Task.Delay(10500); // wait for cache purge, which is 10 seconds delayed after app start
9694
var cacheEntryUrls3 = GetCacheEntryUrls();
95+
// wait until the cache was cleaned, max 500ms
96+
for (var i = 0; i < 5; i++)
97+
{
98+
if (!cacheEntryUrls3.Contains(cacheEntryForDotNetWasmWithChangedHash))
99+
{
100+
break;
101+
}
102+
await Task.Delay(100); // wait for cache purge
103+
cacheEntryUrls3 = GetCacheEntryUrls();
104+
}
97105
Assert.Contains(cacheEntryForComponentsDll, cacheEntryUrls3);
98106
Assert.Contains(cacheEntryForDotNetWasm, cacheEntryUrls3);
99107
Assert.DoesNotContain(cacheEntryForDotNetWasmWithChangedHash, cacheEntryUrls3);

src/Components/test/E2ETest/Tests/RoutingTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,18 @@ public void ResetsScrollPositionWhenPerformingInternalNavigation_ProgrammaticNav
12881288
Browser.Equal(0, () => BrowserScrollY);
12891289
}
12901290

1291+
[Fact]
1292+
public void Refresh_FullyReloadsTheCurrentPage()
1293+
{
1294+
SetUrlViaPushState("/");
1295+
1296+
Browser.MountTestComponent<NavigationManagerComponent>();
1297+
Browser.FindElement(By.Id("programmatic-refresh")).Click();
1298+
1299+
// If the page fully reloads, the NavigationManagerComponent will no longer be mounted
1300+
Browser.DoesNotExist(By.Id("programmatic-refresh"));
1301+
}
1302+
12911303
[Fact]
12921304
public void PreventDefault_CanBlockNavigation_ForInternalNavigation_PreventDefaultTarget()
12931305
=> PreventDefault_CanBlockNavigation("internal", "target");

src/Components/test/testassets/BasicTestApp/RouterTest/NavigationManagerComponent.razor

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<button id="programmatic-navigation" @onclick="ProgrammaticNavigation">Programmatic navigation</button><br />
1515
</p>
1616

17+
<p>
18+
<button id="programmatic-refresh" @onclick="ProgrammaticRefresh">Programmatic refresh</button><br />
19+
</p>
20+
1721
<p>
1822
<a id="internal-link-navigation" href="some-path-@nextLinkNavigationIndex">/some-path-@nextLinkNavigationIndex</a>
1923
<button id="increment-link-navigation-index" @onclick="IncrementLinkNavigationIndex">Increment path index</button><br />
@@ -100,4 +104,9 @@
100104

101105
nextProgrammaticNavigationIndex++;
102106
}
107+
108+
void ProgrammaticRefresh()
109+
{
110+
NavigationManager.Refresh();
111+
}
103112
}

0 commit comments

Comments
 (0)