Skip to content

Improve SSR navigation tests #62536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,28 @@ public void NavigatesWithoutInteractivityByRequestRedirection(bool controlFlowBy
[Theory]
[InlineData(true)]
[InlineData(false)]
public void ProgrammaticNavigationToNotExistingPathReExecutesTo404(bool streaming)
public void ProgrammaticNavigationToNotExistingPath_ReExecutesTo404(bool streaming)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", isEnabled: true);
string streamingPath = streaming ? "-streaming" : "";
Navigate($"{ServerPathBase}/reexecution/redirection-not-found-ssr{streamingPath}?navigate-programmatically=true");
AssertReExecutionPageRendered();
}

[Fact]
public void ProgrammaticNavigationToNotExistingPath_AfterAsyncOperation_ReExecutesTo404()
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", isEnabled: true);
Navigate($"{ServerPathBase}/reexecution/redirection-not-found-ssr?doAsync=true&navigate-programmatically=true");
AssertReExecutionPageRendered();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void LinkNavigationToNotExistingPathReExecutesTo404(bool streaming)
public void LinkNavigationToNotExistingPath_ReExecutesTo404(bool streaming)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", isEnabled: true);
string streamingPath = streaming ? "-streaming" : "";
Navigate($"{ServerPathBase}/reexecution/redirection-not-found-ssr{streamingPath}");
Browser.Click(By.Id("link-to-not-existing-page"));
Expand All @@ -104,8 +114,9 @@ public void LinkNavigationToNotExistingPathReExecutesTo404(bool streaming)
[Theory]
[InlineData(true)]
[InlineData(false)]
public void BrowserNavigationToNotExistingPathReExecutesTo404(bool streaming)
public void BrowserNavigationToNotExistingPath_ReExecutesTo404(bool streaming)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", isEnabled: true);
// non-existing path has to have re-execution middleware set up
// so it has to have "reexecution" prefix. Otherwise middleware mapping
// will not be activated, see configuration in Startup
Expand Down
125 changes: 93 additions & 32 deletions src/Components/test/E2ETest/ServerRenderingTests/RedirectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ public override async Task InitializeAsync()
Browser.Equal("Redirections", () => _originalH1Element.Text);
}

[Fact]
public void RedirectStreamingGetToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingGetToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

Browser.Exists(By.LinkText("Streaming GET with internal redirection")).Click();
AssertElementRemoved(_originalH1Element);
Browser.Equal("Scroll to hash", () => Browser.Exists(By.TagName("h1")).Text);
Expand All @@ -47,16 +51,23 @@ public void RedirectStreamingGetToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectStreamingGetToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingGetToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);
Browser.Exists(By.LinkText("Streaming GET with external redirection")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectStreamingPostToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingPostToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

Browser.Exists(By.CssSelector("#form-streaming-internal button")).Click();
AssertElementRemoved(_originalH1Element);
Browser.Equal("Scroll to hash", () => Browser.Exists(By.TagName("h1")).Text);
Expand All @@ -69,16 +80,23 @@ public void RedirectStreamingPostToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectStreamingPostToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingPostToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);
Browser.Exists(By.CssSelector("#form-streaming-external button")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectEnhancedGetToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedGetToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// Note that for enhanced nav we can't preserve the hash part of the URL, as it
// gets discarded when the browser follows a 'fetch' redirection. This is not solvable
// unless we are willing to make the server return extra information so that the
Expand All @@ -95,16 +113,23 @@ public void RedirectEnhancedGetToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectEnhancedGetToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedGetToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);
Browser.Exists(By.LinkText("Enhanced GET with external redirection")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectEnhancedPostToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedPostToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// See above for why enhanced nav doesn't support preserving the hash
Browser.Exists(By.CssSelector("#form-enhanced-internal button")).Click();
Browser.Equal("Scroll to hash", () => _originalH1Element.Text);
Expand All @@ -116,16 +141,23 @@ public void RedirectEnhancedPostToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectEnhancedPostToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedPostToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);
Browser.Exists(By.CssSelector("#form-enhanced-external button")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectStreamingEnhancedGetToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingEnhancedGetToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// See above for why enhanced nav doesn't support preserving the hash
Browser.Exists(By.LinkText("Streaming enhanced GET with internal redirection")).Click();
Browser.Equal("Scroll to hash", () => _originalH1Element.Text);
Expand All @@ -137,16 +169,25 @@ public void RedirectStreamingEnhancedGetToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectStreamingEnhancedGetToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingEnhancedGetToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

Browser.Exists(By.LinkText("Streaming enhanced GET with external redirection")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}


[Fact]
public void RedirectStreamingEnhancedPostToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingEnhancedPostToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// See above for why enhanced nav doesn't support preserving the hash
Browser.Exists(By.CssSelector("#form-streaming-enhanced-internal button")).Click();
Browser.Equal("Scroll to hash", () => _originalH1Element.Text);
Expand All @@ -158,16 +199,24 @@ public void RedirectStreamingEnhancedPostToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectStreamingEnhancedPostToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectStreamingEnhancedPostToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

Browser.Exists(By.CssSelector("#form-streaming-enhanced-external button")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectEnhancedNonBlazorGetToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedNonBlazorGetToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// See above for why enhanced nav doesn't support preserving the hash
Browser.Exists(By.LinkText("Enhanced GET to non-Blazor endpoint with internal redirection")).Click();
Browser.Equal("Scroll to hash", () => _originalH1Element.Text);
Expand All @@ -179,16 +228,24 @@ public void RedirectEnhancedNonBlazorGetToInternal()
Assert.EndsWith("/subdir/redirect", Browser.Url);
}

[Fact]
public void RedirectEnhancedNonBlazorGetToExternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedNonBlazorGetToExternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

Browser.Exists(By.LinkText("Enhanced GET to non-Blazor endpoint with external redirection")).Click();
Browser.Contains("microsoft.com", () => Browser.Url);
}

[Fact]
public void RedirectEnhancedNonBlazorPostToInternal()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedNonBlazorPostToInternal(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// See above for why enhanced nav doesn't support preserving the hash
Browser.Exists(By.CssSelector("#form-nonblazor-enhanced-internal button")).Click();
Browser.Equal("Scroll to hash", () => _originalH1Element.Text);
Expand All @@ -205,9 +262,13 @@ public void RedirectEnhancedNonBlazorPostToInternal()
// response to something like a 200 that the 'fetch' is allowed to read (embedding the
// destination URL).

[Fact]
public void RedirectEnhancedGetToInternalWithErrorBoundary()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RedirectEnhancedGetToInternalWithErrorBoundary(bool disableThrowNavigationException)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.DisableThrowNavigationException", disableThrowNavigationException);

// This test verifies that redirection works even if an ErrorBoundary wraps
// a component throwing a NavigationException.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
@page "/reexecution/redirection-not-found-ssr-streaming"
@attribute [StreamRendering(true)]

<Components.WasmMinimal.Pages.NotFound.RedirectionNotFoundComponent StartStreaming="true" />
<Components.WasmMinimal.Pages.NotFound.RedirectionNotFoundComponent DoAsyncOperationBeforeRedirection="true" />
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
@page "/reexecution/redirection-not-found-ssr"
@attribute [StreamRendering(false)]

<Components.WasmMinimal.Pages.NotFound.RedirectionNotFoundComponent />
<Components.WasmMinimal.Pages.NotFound.RedirectionNotFoundComponent DoAsyncOperationBeforeRedirection="@DoAsync" />

@code{
[SupplyParameterFromQuery(Name = "doAsync")]
public bool DoAsync { get; set; } = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public bool? NavigateProgrammatically { get; set; }

[Parameter]
public bool StartStreaming { get; set; } = false;
public bool DoAsyncOperationBeforeRedirection { get; set; } = false;

[Parameter]
public bool WaitForInteractivity { get; set; } = false;
Expand All @@ -25,7 +25,7 @@

protected override async Task OnInitializedAsync()
{
if (StartStreaming)
if (DoAsyncOperationBeforeRedirection)
{
await Task.Yield();
}
Expand Down
Loading