Skip to content
42 changes: 42 additions & 0 deletions e2e/react-router/basic-file-based/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as RemountDepsRouteImport } from './routes/remountDeps'
import { Route as PostsRouteImport } from './routes/posts'
import { Route as NotRemountDepsRouteImport } from './routes/notRemountDeps'
import { Route as LazyPageRouteImport } from './routes/lazy-page'
import { Route as EditingBRouteImport } from './routes/editing-b'
import { Route as EditingARouteImport } from './routes/editing-a'
import { Route as ComponentTypesTestRouteImport } from './routes/component-types-test'
Expand All @@ -31,6 +32,7 @@ import { Route as SearchParamsDefaultRouteImport } from './routes/search-params/
import { Route as RedirectTargetRouteImport } from './routes/redirect/$target'
import { Route as PostsPostIdRouteImport } from './routes/posts.$postId'
import { Route as LayoutLayout2RouteImport } from './routes/_layout/_layout-2'
import { Route as testsNormalPageRouteImport } from './routes/(tests)/normal-page'
import { Route as groupLazyinsideRouteImport } from './routes/(group)/lazyinside'
import { Route as groupInsideRouteImport } from './routes/(group)/inside'
import { Route as groupLayoutRouteImport } from './routes/(group)/_layout'
Expand Down Expand Up @@ -125,6 +127,11 @@ const NotRemountDepsRoute = NotRemountDepsRouteImport.update({
path: '/notRemountDeps',
getParentRoute: () => rootRouteImport,
} as any)
const LazyPageRoute = LazyPageRouteImport.update({
id: '/lazy-page',
path: '/lazy-page',
getParentRoute: () => rootRouteImport,
} as any)
const EditingBRoute = EditingBRouteImport.update({
id: '/editing-b',
path: '/editing-b',
Expand Down Expand Up @@ -220,6 +227,11 @@ const LayoutLayout2Route = LayoutLayout2RouteImport.update({
id: '/_layout-2',
getParentRoute: () => LayoutRoute,
} as any)
const testsNormalPageRoute = testsNormalPageRouteImport.update({
id: '/(tests)/normal-page',
path: '/normal-page',
getParentRoute: () => rootRouteImport,
} as any)
const groupLazyinsideRoute = groupLazyinsideRouteImport
.update({
id: '/(group)/lazyinside',
Expand Down Expand Up @@ -659,6 +671,7 @@ export interface FileRoutesByFullPath {
'/component-types-test': typeof ComponentTypesTestRoute
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/lazy-page': typeof LazyPageRoute
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
Expand All @@ -673,6 +686,7 @@ export interface FileRoutesByFullPath {
'/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute
'/inside': typeof groupInsideRoute
'/lazyinside': typeof groupLazyinsideRoute
'/normal-page': typeof testsNormalPageRoute
'/posts/$postId': typeof PostsPostIdRoute
'/redirect/$target': typeof RedirectTargetRouteWithChildren
'/search-params/default': typeof SearchParamsDefaultRoute
Expand Down Expand Up @@ -757,6 +771,7 @@ export interface FileRoutesByTo {
'/component-types-test': typeof ComponentTypesTestRoute
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/lazy-page': typeof LazyPageRoute
'/notRemountDeps': typeof NotRemountDepsRoute
'/remountDeps': typeof RemountDepsRoute
'/non-nested/deep': typeof NonNestedDeepRouteRouteWithChildren
Expand All @@ -770,6 +785,7 @@ export interface FileRoutesByTo {
'/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute
'/inside': typeof groupInsideRoute
'/lazyinside': typeof groupLazyinsideRoute
'/normal-page': typeof testsNormalPageRoute
'/posts/$postId': typeof PostsPostIdRoute
'/search-params/default': typeof SearchParamsDefaultRoute
'/structural-sharing/$enabled': typeof StructuralSharingEnabledRoute
Expand Down Expand Up @@ -849,6 +865,7 @@ export interface FileRoutesById {
'/component-types-test': typeof ComponentTypesTestRoute
'/editing-a': typeof EditingARoute
'/editing-b': typeof EditingBRoute
'/lazy-page': typeof LazyPageRoute
'/notRemountDeps': typeof NotRemountDepsRoute
'/posts': typeof PostsRouteWithChildren
'/remountDeps': typeof RemountDepsRoute
Expand All @@ -864,6 +881,7 @@ export interface FileRoutesById {
'/(group)/_layout': typeof groupLayoutRouteWithChildren
'/(group)/inside': typeof groupInsideRoute
'/(group)/lazyinside': typeof groupLazyinsideRoute
'/(tests)/normal-page': typeof testsNormalPageRoute
'/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren
'/posts/$postId': typeof PostsPostIdRoute
'/redirect/$target': typeof RedirectTargetRouteWithChildren
Expand Down Expand Up @@ -952,6 +970,7 @@ export interface FileRouteTypes {
| '/component-types-test'
| '/editing-a'
| '/editing-b'
| '/lazy-page'
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
Expand All @@ -966,6 +985,7 @@ export interface FileRouteTypes {
| '/onlyrouteinside'
| '/inside'
| '/lazyinside'
| '/normal-page'
| '/posts/$postId'
| '/redirect/$target'
| '/search-params/default'
Expand Down Expand Up @@ -1050,6 +1070,7 @@ export interface FileRouteTypes {
| '/component-types-test'
| '/editing-a'
| '/editing-b'
| '/lazy-page'
| '/notRemountDeps'
| '/remountDeps'
| '/non-nested/deep'
Expand All @@ -1063,6 +1084,7 @@ export interface FileRouteTypes {
| '/onlyrouteinside'
| '/inside'
| '/lazyinside'
| '/normal-page'
| '/posts/$postId'
| '/search-params/default'
| '/structural-sharing/$enabled'
Expand Down Expand Up @@ -1141,6 +1163,7 @@ export interface FileRouteTypes {
| '/component-types-test'
| '/editing-a'
| '/editing-b'
| '/lazy-page'
| '/notRemountDeps'
| '/posts'
| '/remountDeps'
Expand All @@ -1156,6 +1179,7 @@ export interface FileRouteTypes {
| '/(group)/_layout'
| '/(group)/inside'
| '/(group)/lazyinside'
| '/(tests)/normal-page'
| '/_layout/_layout-2'
| '/posts/$postId'
| '/redirect/$target'
Expand Down Expand Up @@ -1244,6 +1268,7 @@ export interface RootRouteChildren {
ComponentTypesTestRoute: typeof ComponentTypesTestRoute
EditingARoute: typeof EditingARoute
EditingBRoute: typeof EditingBRoute
LazyPageRoute: typeof LazyPageRoute
NotRemountDepsRoute: typeof NotRemountDepsRoute
PostsRoute: typeof PostsRouteWithChildren
RemountDepsRoute: typeof RemountDepsRoute
Expand All @@ -1254,6 +1279,7 @@ export interface RootRouteChildren {
groupLayoutRoute: typeof groupLayoutRouteWithChildren
groupInsideRoute: typeof groupInsideRoute
groupLazyinsideRoute: typeof groupLazyinsideRoute
testsNormalPageRoute: typeof testsNormalPageRoute
RedirectTargetRoute: typeof RedirectTargetRouteWithChildren
StructuralSharingEnabledRoute: typeof StructuralSharingEnabledRoute
ParamsPsIndexRoute: typeof ParamsPsIndexRoute
Expand Down Expand Up @@ -1300,6 +1326,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof NotRemountDepsRouteImport
parentRoute: typeof rootRouteImport
}
'/lazy-page': {
id: '/lazy-page'
path: '/lazy-page'
fullPath: '/lazy-page'
preLoaderRoute: typeof LazyPageRouteImport
parentRoute: typeof rootRouteImport
}
'/editing-b': {
id: '/editing-b'
path: '/editing-b'
Expand Down Expand Up @@ -1433,6 +1466,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof LayoutLayout2RouteImport
parentRoute: typeof LayoutRoute
}
'/(tests)/normal-page': {
id: '/(tests)/normal-page'
path: '/normal-page'
fullPath: '/normal-page'
preLoaderRoute: typeof testsNormalPageRouteImport
parentRoute: typeof rootRouteImport
}
'/(group)/lazyinside': {
id: '/(group)/lazyinside'
path: '/lazyinside'
Expand Down Expand Up @@ -2402,6 +2442,7 @@ const rootRouteChildren: RootRouteChildren = {
ComponentTypesTestRoute: ComponentTypesTestRoute,
EditingARoute: EditingARoute,
EditingBRoute: EditingBRoute,
LazyPageRoute: LazyPageRoute,
NotRemountDepsRoute: NotRemountDepsRoute,
PostsRoute: PostsRouteWithChildren,
RemountDepsRoute: RemountDepsRoute,
Expand All @@ -2412,6 +2453,7 @@ const rootRouteChildren: RootRouteChildren = {
groupLayoutRoute: groupLayoutRouteWithChildren,
groupInsideRoute: groupInsideRoute,
groupLazyinsideRoute: groupLazyinsideRoute,
testsNormalPageRoute: testsNormalPageRoute,
RedirectTargetRoute: RedirectTargetRouteWithChildren,
StructuralSharingEnabledRoute: StructuralSharingEnabledRoute,
ParamsPsIndexRoute: ParamsPsIndexRoute,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Link, createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/(tests)/normal-page')({
component: NormalPage,
})

function NormalPage() {
return (
<div className="p-2">
<h3>Normal Page</h3>

{/* Add the link that the test is looking for */}
<div style={{ marginBottom: '1rem' }}>
<Link to="/lazy-page" className="header-link">
Head-/lazy-page
</Link>
</div>

<div style={{ height: '200vh' }}>
Scroll down to see the target element
</div>

<div
id="at-the-bottom"
data-testid="at-the-bottom"
style={{
height: '100px',
background: '#f0f0f0',
border: '1px solid #ccc',
padding: '1rem',
marginTop: '2rem',
}}
>
This is the target element at the bottom of the page
</div>
</div>
)
}
14 changes: 14 additions & 0 deletions e2e/react-router/basic-file-based/src/routes/lazy-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/lazy-page')({
component: LazyPage,
})

function LazyPage() {
return (
<div className="p-2">
<h3>Lazy Loaded Page</h3>
<p>This page was loaded lazily.</p>
</div>
)
}
22 changes: 22 additions & 0 deletions e2e/react-router/basic-file-based/tests/hover-preload-hash.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test } from '@playwright/test'
import { toRuntimePath } from '@tanstack/router-e2e-utils'

// This test guards against a regression where hovering (intent preload)
test('hovering links does not trigger hash scroll (no navigation)', async ({
page,
}) => {
// Go to a page with a hash target at the bottom
await page.goto(toRuntimePath('/normal-page#at-the-bottom'))
await expect(page.getByTestId('at-the-bottom')).toBeInViewport()

// Scroll up so the hash target is no longer in view
await page.evaluate(() => window.scrollBy(0, -300))
await expect(page.getByTestId('at-the-bottom')).not.toBeInViewport()

// Hover a header link to trigger intent preload (should NOT change scroll)
await page.getByRole('link', { name: 'Head-/lazy-page' }).hover()
await page.waitForTimeout(400)

// Ensure we did not jump back to the hash target
await expect(page.getByTestId('at-the-bottom')).not.toBeInViewport()
})
Loading
Loading