Skip to content

Commit

Permalink
Current behavior for fallbacks with async metadata and prefetching
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Nov 22, 2024
1 parent 5b7833e commit 13f97cb
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import React from 'react'
// ensure this page is dynamically rendered so we always trigger a loading state
export const dynamic = 'force-dynamic'

export default function page() {
export default function Page() {
return <div id="page-content">Content</div>
}

async function getTitle() {
return await new Promise((resolve) =>
setTimeout(() => resolve('Async Title'), 1000)
setTimeout(() => resolve('Async Title'), 5000)
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from 'next/link'

export default function page() {
export default function Page() {
return (
<div>
<Link href="/metadata-await-promise/nested">Link to nested</Link>
Expand Down
66 changes: 50 additions & 16 deletions test/e2e/app-dir/navigation/navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -881,29 +881,63 @@ describe('app dir - navigation', () => {
})

describe('navigating to a page with async metadata', () => {
it('should render the final state of the page with correct metadata', async () => {
it('shows a fallback when prefetch was pending', async () => {
const resolveMetadataDuration = 5000
const browser = await next.browser('/metadata-await-promise')

// dev doesn't trigger the loading boundary as it's not prefetched
if (isNextDev) {
await browser
.elementByCss("[href='/metadata-await-promise/nested']")
.click()
} else {
const loadingText = await browser
.elementByCss("[href='/metadata-await-promise/nested']")
.click()
.waitForElementByCss('#loading')
.text()
// Hopefully this click happened before the prefetch was completed.
// TODO: Programmatically trigger prefetch e.g. by mounting the link later.
await browser
.elementByCss("[href='/metadata-await-promise/nested']")
.click()

expect(loadingText).toBe('Loading')
if (!isNextDev) {
// next-dev has no prefetch
expect(
await browser
.waitForElementByCss(
'#loading',
// Wait a bit longer than the prefetch duration since the click takes a while to register and the fallback render also takes time.
resolveMetadataDuration + 500
)
.text()
).toEqual('Loading')
expect(await browser.elementByCss('title').text()).toBe('Async Title')
}

await retry(async () => {
expect(await browser.elementById('page-content').text()).toBe('Content')
await waitFor(resolveMetadataDuration)

expect(await browser.elementById('page-content').text()).toBe('Content')
})

it('shows a fallback when prefetch completed', async () => {
const resolveMetadataDuration = 5000
const browser = await next.browser('/metadata-await-promise')

if (!isNextDev) {
await waitFor(resolveMetadataDuration + 500)
}

await browser
.elementByCss("[href='/metadata-await-promise/nested']")
.click()

if (!isNextDev) {
expect(
await browser
.waitForElementByCss(
'#loading',
// Give it some time to commit
100
)
.text()
).toEqual('Loading')
expect(await browser.elementByCss('title').text()).toBe('Async Title')
})

await waitFor(resolveMetadataDuration + 500)
}

expect(await browser.elementById('page-content').text()).toBe('Content')
})
})

Expand Down

0 comments on commit 13f97cb

Please sign in to comment.