Files
JosephandGitHub b59fae0429 [fragment-scroll] Stop blurring on navigations (#96113)
Dynamic pages (all pages in dev), blur and select the body as
`activeElement`.

- [x] e2e for https://github.com/vercel/next.js/issues/96050
- [ ] attempt a fix that prevents blur
2026-07-29 19:13:35 -04:00

96 lines
3.1 KiB
TypeScript

import { nextTestSetup } from 'e2e-utils'
import { retry } from 'next-test-utils'
const enableNewScrollHandler =
process.env.__NEXT_EXPERIMENTAL_APP_NEW_SCROLL_HANDLER !== 'false'
// The new handler leaves focus on the clicked link; the old handler focuses the
// navigated segment.
describe('navigation-focus', () => {
const { next } = nextTestSetup({
files: __dirname,
})
it('navigation to an interactive segment', async () => {
const browser = await next.browser('/')
await browser.elementByCss('a[href="/interactive-segment"]').click()
await retry(async () => {
// Good debug info is a moving target. Use Playwright traces to find out
// what was focused if this fails
if (enableNewScrollHandler) {
expect(
await browser.eval(() => document.activeElement.getAttribute('href'))
).toBe('/interactive-segment')
} else {
expect(
await browser.eval(() =>
document.activeElement.getAttribute('data-testid')
)
).toBe('segment-container')
}
})
})
it('navigation to a scrollable segment', async () => {
const browser = await next.browser('/')
await browser.elementByCss('a[href="/scrollable-segment"]').click()
await retry(async () => {
if (enableNewScrollHandler) {
expect(
await browser.eval(() => document.activeElement.getAttribute('href'))
).toBe('/scrollable-segment')
} else {
expect(
await browser.eval(() =>
document.activeElement.getAttribute('data-testid')
)
).toBe('segment-container')
}
})
})
it('navigation to a segment with a focusable descendant', async () => {
const browser = await next.browser('/')
await browser
.elementByCss('a[href="/segment-with-focusable-descendant"]')
.click()
await retry(async () => {
// Focus stays on the original link in both handlers.
expect(
await browser.eval(() => document.activeElement.getAttribute('href'))
).toBe('/segment-with-focusable-descendant')
})
})
it('navigation to a fragment within a page', async () => {
const browser = await next.browser('/')
await browser.elementByCss('a[href="/uri-fragments#section-2"]').click()
await retry(async () => {
// Focus stays on the anchor unlike native behavior.
expect(
await browser.eval(() => document.activeElement.getAttribute('href'))
).toEqual('/uri-fragments#section-2')
})
// Fragment URI not targetted unlike native behavior
expect(await browser.locator(':target').isVisible()).toEqual(false)
})
it('navigation within a page to fragments', async () => {
const browser = await next.browser('/uri-fragments')
await browser.elementByCss('a[href="#section-1"]').click()
await retry(async () => {
// Focus stays on the anchor unlike native behavior.
expect(
await browser.eval(() => document.activeElement.getAttribute('href'))
).toEqual('#section-1')
})
// Fragment URI not targetted unlike native behavior
expect(await browser.locator(':target').isVisible()).toEqual(false)
})
})