mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
### What? Relaxes the overly strict `default.tsx` validation for parallel routes to only require the file when it's actually needed (non-leaf segments with routable children). ### Why? The initial validation for parallel routes required `default.tsx` files for all parallel route slots to prevent a specific issue: when navigating to child routes, missing `default.tsx` files could cause silent 404s in slot content, creating a confusing user experience. However, this validation was **too strict** - it required `default.tsx` even in cases where it wasn't actually necessary: 1. **Leaf segments** (routes with no child routes) - There are no child routes to navigate to, so the 404 issue cannot occur 2. **Route groups** - These are organizational folders and aren't routable themselves 3. **Catch-all parameters** - The matched segments are dynamic parameter values, not actual child route segments This caused false positive build errors for valid parallel route configurations that don't have the underlying navigational issue. NAR-448
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import path from 'path'
|
|
import { nextTestSetup } from 'e2e-utils'
|
|
|
|
describe('parallel-routes-leaf-segments-no-build-error', () => {
|
|
const { next } = nextTestSetup({
|
|
files: path.join(__dirname, 'fixtures', 'no-build-error'),
|
|
})
|
|
|
|
it('should build successfully without default.tsx for leaf segments', async () => {
|
|
// This test verifies that the build does not throw
|
|
// MissingDefaultParallelRouteError for leaf segments
|
|
expect(next.cliOutput).not.toContain('MissingDefaultParallelRouteError')
|
|
})
|
|
|
|
afterAll(() => {
|
|
if (next.cliOutput.includes('MissingDefaultParallelRouteError')) {
|
|
throw new Error('MissingDefaultParallelRouteError was thrown')
|
|
}
|
|
})
|
|
|
|
describe('leaf segment without child routes', () => {
|
|
it('should render the leaf segment page with all parallel slots', async () => {
|
|
const $ = await next.render$('/leaf-segment')
|
|
|
|
// Verify main page content
|
|
expect($('h2').text()).toBe('Leaf Segment Page')
|
|
expect($('.main p').first().text()).toContain(
|
|
'This is a leaf segment with parallel routes but NO child routes'
|
|
)
|
|
|
|
// Verify all parallel slots render
|
|
expect($('.header h3').text()).toBe('Header Slot')
|
|
expect($('.sidebar h3').text()).toBe('Sidebar Slot')
|
|
expect($('.metrics h3').text()).toBe('Metrics Slot')
|
|
})
|
|
})
|
|
|
|
describe('leaf segment with route groups', () => {
|
|
it('should render leaf segment with route groups and parallel slots', async () => {
|
|
const $ = await next.render$('/leaf-with-groups')
|
|
|
|
// Verify main page content
|
|
expect($('h3').first().text()).toBe('Grouped Leaf Segment Page')
|
|
|
|
// Verify route groups are handled correctly
|
|
expect($('p').first().text()).toContain('route groups')
|
|
|
|
// Verify parallel slots render
|
|
expect($('.analytics h4').text()).toBe('Analytics Slot')
|
|
expect($('.reports h4').text()).toBe('Reports Slot')
|
|
})
|
|
})
|
|
|
|
describe('leaf segment with catch-all parameter', () => {
|
|
it('should render catch-all segment with multiple path segments', async () => {
|
|
const $ = await next.render$('/catch-all-with-parallel/a/b/c')
|
|
|
|
// Verify main page content
|
|
expect($('h2').text()).toBe('Catch-All Leaf Segment Page')
|
|
|
|
// Verify the slug captures all segments
|
|
expect($('.slug-info').text()).toBe('Current path: /a/b/c')
|
|
|
|
// Verify parallel slots still render correctly
|
|
expect($('.header h3').text()).toBe('Catch-All Header Slot')
|
|
expect($('.footer h3').text()).toBe('Catch-All Footer Slot')
|
|
})
|
|
})
|
|
|
|
describe('no children slot', () => {
|
|
it('should render the no children slot', async () => {
|
|
const $ = await next.render$('/no-children/other')
|
|
|
|
expect($('#slot').text()).toBe('No Children Other Page')
|
|
expect($('#children').text()).toBe('No Children Default')
|
|
})
|
|
})
|
|
})
|