Skip to content

Conversation

ilonatommy
Copy link
Member

@ilonatommy ilonatommy commented Aug 5, 2025

Suppress enhanced navigation once per test

Enhanced navigation suppression was per page, after navigating away we were falling back to enhanced navigation, regardless of the test settings. It's because we were treating the storage as temporary measure where we were setting the suppression flag and instantly removing it after reading it in blazor start function. For tests that never navigated away (did not re-trigger blazor boot function) it was enough but for other ones, not.

Description

  • The enhanced navigation suppression flag is saved in the storage for the entire test runtime.
  • To avoid usage of the flag by multiple tests, we always try to clean the session storage from it on disposal.
  • Consecutive navigations in the test will run with same settings as the first page load.
  • This PR fixed order of actions: we should navigate to a page only after the suppression method got called.
  • It also enabled tests that got disabled because of issues with enhanced navigation suppression.
  • Session storage has to be available if we want to suppress enhanced navigation. If a developer wrote a test that is not navigating to any page and chose to skip the automatic navigation in EnhancedNavigationTestUtil.SuppressEnhancedNavigation, they will get an exception like:
Failed to read the 'sessionStorage' property from 'Window': Access 

SuppressEnhancedNavigation appends to the exception message an instruction how to fix this situation.

  • To be able to clean the sessionStorage, we have to have access to it. It's accessible only on loaded pages, so we chose the index page as the secure place for conducting the cleanup. To assure we're at the correct location we're checking for "session-storage-anchor" tag, adding it to test projects.
  • This PR is changing expectations of test apps that got broken during development because they were not looking for a specific html element ID but for an element type (h1/p) etc. The selectors got more precise.
  • Executing JS script to find the location of an element was infrequently failing and was blocked by the same quarantine issue. This PR changes the location finding method to rely less on JS, more on selenium tooling.

Fixes #60875

@ilonatommy ilonatommy force-pushed the improve-enhanced-nav-supression branch from 604e029 to 8c5c3b1 Compare August 21, 2025 07:57
@ilonatommy ilonatommy added this to the 10.0-rc2 milestone Aug 21, 2025
@ilonatommy ilonatommy marked this pull request as ready for review August 25, 2025 10:43
… inheritance to ServerTestBase, so that it calls ID granting method as well.
…ems locally because it runs in a small window).
@ilonatommy
Copy link
Member Author

I missed one test to be fixed:

 Failed Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests.PrerenderingTest.CanUseJSInteropFromOnAfterRenderAsync [1 ms]
  Error Message:
   OpenQA.Selenium.BrowserAssertFailedException : Xunit.Sdk.NotEmptyException: Assert.NotEmpty() Failure: Collection was empty
   at Xunit.Assert.NotEmpty(IEnumerable collection) in /_/src/xunit.assert/Asserts/CollectionAsserts.cs:line 539
   at Microsoft.AspNetCore.E2ETesting.WaitAssert.<>c__DisplayClass21_0`1.<WaitAssertCore>b__0(IWebDriver _) in /home/vsts/work/1/s/src/Shared/E2ETesting/WaitAssert.cs:line 109
Screen shot captured at '/home/vsts/work/1/s/src/Components/test/E2ETest/bin/screenshots/fbab61cc46724c0487172d8f671234b0.png'
Encountered browser errors
[2025-08-28T11:28:28Z] [Severe] chrome-error://chromewebdata/ - Failed to load resource: the server responded with a status of 404 ()Page content:
<head>
  <meta charset="utf-8">
  <meta name="color-scheme" content="light dark">
  <meta name="theme-color" content="#fff">
  <meta name="viewport" content="width=device-width, initial-scale=1.0,
                                 maximum-scale=1.0, user-scalable=no">
  <title>127.0.0.1</title>
  <style>/* Copyright 2017 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

a {
  color: var(--link-color);
}

but there's a bigger problem: if we grant ID to each test (with navigation to origin at the test start etc, the tests run time prolongs significantly. It's Duration: 1 h 40 m with the corrected approach, while granting ID only to tests with supression was Duration: 48 m 46 s and on other PRs with not related changes, e.g. log it's Duration: 46 m 30 s.

From this reason, I will revert to the previous approach, instead of fixing the last failing test.

This reverts commit 6dcfd16.
…as problems locally because it runs in a small window)."

This reverts commit 18ee068.
…ientTest inheritance to ServerTestBase, so that it calls ID granting method as well."

This reverts commit 7ac455c.
Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general approach looks good. I have some thoughts on things we can potentially tweak.

@ilonatommy ilonatommy changed the title Improve enhanced navigation suppression in tests Run entire E2E test with consistent enhanced navigation suppression setting Sep 3, 2025
@ilonatommy ilonatommy requested a review from javiercn September 3, 2025 07:31
Comment on lines +74 to +85
catch (WebDriverException ex) when (ex.Message.Contains("invalid session id"))
{
// Browser session is no longer valid (e.g., browser was closed)
// Session storage is automatically cleared when browser closes, so cleanup is already done
// This is expected in some tests, so we silently return
return;
}
finally
{
_isSuppressed = false;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than doing this. Can we check Browser.SessionId == null and just return? Another option might be Browser.WindowHandles

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can try. This was added because we have failures in tests that close the browser intentionally, it should be easy to check if Browser.SessionId == null works for them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Browser.SessionId does not exist. We can cast browser to driver instance but then..the session id exists even when there are no windows handlers and the browser is closed.
Referencing WindowsHandles or CurrentWindowHandle when the session is out creates the exact exception that we were catching.
I don't see a good replacement for the exception flow.

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of comments but looks great besides that!

@ilonatommy ilonatommy merged commit d16321c into dotnet:main Sep 3, 2025
29 checks passed
@ilonatommy
Copy link
Member Author

/backport to release/10.0

Copy link
Contributor

github-actions bot commented Sep 3, 2025

Started backporting to release/10.0: https://github.com/dotnet/aspnetcore/actions/runs/17438587545

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components tell-mode Indicates a PR which is being merged during tell-mode test-fixed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Quarantine EnhancedNavigationScrollBehavesSameAsBrowserOnNavigation
3 participants