From 5e74fe4e0b661745647e5f25449ca7c27a2a476d Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 11 May 2023 18:57:18 +0100 Subject: [PATCH] fix(nuxt): enable suspensible behaviour for nested pages (#20777) --- packages/nuxt/src/pages/runtime/page.ts | 1 + test/basic.test.ts | 30 +++++++++++++++++++ test/fixtures/basic/pages/suspense.vue | 22 ++++++++++++++ .../basic/pages/suspense/async-[parent].vue | 14 +++++++++ .../suspense/async-[parent]/async-[child].vue | 15 ++++++++++ .../suspense/async-[parent]/sync-[child].vue | 10 +++++++ .../basic/pages/suspense/sync-[parent].vue | 12 ++++++++ .../suspense/sync-[parent]/async-[child].vue | 15 ++++++++++ .../suspense/sync-[parent]/sync-[child].vue | 10 +++++++ 9 files changed, 129 insertions(+) create mode 100644 test/fixtures/basic/pages/suspense.vue create mode 100644 test/fixtures/basic/pages/suspense/async-[parent].vue create mode 100644 test/fixtures/basic/pages/suspense/async-[parent]/async-[child].vue create mode 100644 test/fixtures/basic/pages/suspense/async-[parent]/sync-[child].vue create mode 100644 test/fixtures/basic/pages/suspense/sync-[parent].vue create mode 100644 test/fixtures/basic/pages/suspense/sync-[parent]/async-[child].vue create mode 100644 test/fixtures/basic/pages/suspense/sync-[parent]/sync-[child].vue diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index 7e971a3652..d906c008f8 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -54,6 +54,7 @@ export default defineComponent({ return _wrapIf(Transition, hasTransition && transitionProps, wrapInKeepAlive(props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps), h(Suspense, { + suspensible: true, onPending: () => nuxtApp.callHook('page:start', routeProps.Component), onResolve: () => { nextTick(() => nuxtApp.callHook('page:finish', routeProps.Component).finally(done)) } }, { default: () => h(RouteProvider, { key, routeProps, pageKey: key, hasTransition } as {}) }) diff --git a/test/basic.test.ts b/test/basic.test.ts index af4a2f0fc6..c7d2a94d00 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -891,6 +891,36 @@ describe('deferred app suspense resolve', () => { }) }) +describe('nested suspense', () => { + const navigations = [ + ['/suspense/sync-1/async-1/', '/suspense/sync-2/async-1/'], + ['/suspense/sync-1/sync-1/', '/suspense/sync-2/async-1/'], + ['/suspense/async-1/async-1/', '/suspense/async-2/async-1/'], + ['/suspense/async-1/sync-1/', '/suspense/async-2/async-1/'] + ] + + it.each(navigations)('should navigate from %s to %s with no white flash', async (start, nav) => { + const page = await createPage(start, {}) + await page.waitForLoadState('networkidle') + + const slug = nav.replace(/[/-]+/g, '-') + await page.click(`[href^="${nav}"]`) + + const text = await page.waitForFunction(slug => document.querySelector(`#${slug}`)?.innerHTML, slug) + // @ts-expect-error TODO: fix upstream in playwright - types for evaluate are broken + .then(r => r.evaluate(r => r)) + + // expect(text).toMatchInlineSnapshot() + + // const parent = await page.waitForSelector(`#${slug}`, { state: 'attached' }) + + // const text = await parent.innerText() + expect(text).toContain('Async child: 2 - 1') + + await page.close() + }) +}) + // Bug #6592 describe('page key', () => { it('should not cause run of setup if navigation not change page key and layout', async () => { diff --git a/test/fixtures/basic/pages/suspense.vue b/test/fixtures/basic/pages/suspense.vue new file mode 100644 index 0000000000..0e082baa04 --- /dev/null +++ b/test/fixtures/basic/pages/suspense.vue @@ -0,0 +1,22 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/async-[parent].vue b/test/fixtures/basic/pages/suspense/async-[parent].vue new file mode 100644 index 0000000000..9f778ef62c --- /dev/null +++ b/test/fixtures/basic/pages/suspense/async-[parent].vue @@ -0,0 +1,14 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/async-[parent]/async-[child].vue b/test/fixtures/basic/pages/suspense/async-[parent]/async-[child].vue new file mode 100644 index 0000000000..a7689a79de --- /dev/null +++ b/test/fixtures/basic/pages/suspense/async-[parent]/async-[child].vue @@ -0,0 +1,15 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/async-[parent]/sync-[child].vue b/test/fixtures/basic/pages/suspense/async-[parent]/sync-[child].vue new file mode 100644 index 0000000000..a84b1b5625 --- /dev/null +++ b/test/fixtures/basic/pages/suspense/async-[parent]/sync-[child].vue @@ -0,0 +1,10 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/sync-[parent].vue b/test/fixtures/basic/pages/suspense/sync-[parent].vue new file mode 100644 index 0000000000..bb18dd3bf2 --- /dev/null +++ b/test/fixtures/basic/pages/suspense/sync-[parent].vue @@ -0,0 +1,12 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/sync-[parent]/async-[child].vue b/test/fixtures/basic/pages/suspense/sync-[parent]/async-[child].vue new file mode 100644 index 0000000000..82d7ee7057 --- /dev/null +++ b/test/fixtures/basic/pages/suspense/sync-[parent]/async-[child].vue @@ -0,0 +1,15 @@ + + + diff --git a/test/fixtures/basic/pages/suspense/sync-[parent]/sync-[child].vue b/test/fixtures/basic/pages/suspense/sync-[parent]/sync-[child].vue new file mode 100644 index 0000000000..5918ad9d1d --- /dev/null +++ b/test/fixtures/basic/pages/suspense/sync-[parent]/sync-[child].vue @@ -0,0 +1,10 @@ + + +