diff --git a/test/integration/i18n-support/test/index.test.js b/test/integration/i18n-support/test/index.test.js index c375fc27b3d4a2e..7ba2761afdf6106 100644 --- a/test/integration/i18n-support/test/index.test.js +++ b/test/integration/i18n-support/test/index.test.js @@ -672,7 +672,12 @@ function runTests(isDev) { }) it('should render 404 for fallback page that returned 404', async () => { - const browser = await webdriver(appPort, '/en/not-found/fallback/first') + const browser = await webdriver( + appPort, + '/en/not-found/fallback/first', + true, + true + ) await browser.waitForElementByCss('h1') await browser.eval('window.beforeNav = 1') diff --git a/test/lib/next-webdriver.d.ts b/test/lib/next-webdriver.d.ts index e366c58c9c65781..fe87e0363ab763b 100644 --- a/test/lib/next-webdriver.d.ts +++ b/test/lib/next-webdriver.d.ts @@ -24,5 +24,6 @@ interface Chain { export default function ( appPort: number, path: string, - waitHydration?: boolean + waitHydration?: boolean, + allowHydrationRetry?: boolean ): Promise diff --git a/test/lib/next-webdriver.js b/test/lib/next-webdriver.js index 9ad87b8b2237532..2d663205ccf896c 100644 --- a/test/lib/next-webdriver.js +++ b/test/lib/next-webdriver.js @@ -152,7 +152,12 @@ const freshWindow = async () => { await browser.switchTo().window(newWindow) } -export default async (appPort, path, waitHydration = true) => { +export default async ( + appPort, + path, + waitHydration = true, + allowHydrationRetry = false +) => { if (!initialWindow) { initialWindow = await browser.getWindowHandle() } @@ -176,24 +181,41 @@ export default async (appPort, path, waitHydration = true) => { // Wait for application to hydrate if (waitHydration) { console.log(`\n> Waiting hydration for ${url}\n`) - await browser.executeAsyncScript(function () { - var callback = arguments[arguments.length - 1] - // if it's not a Next.js app return - if (document.documentElement.innerHTML.indexOf('__NEXT_DATA__') === -1) { - callback() - } + const checkHydrated = async () => { + await browser.executeAsyncScript(function () { + var callback = arguments[arguments.length - 1] - if (window.__NEXT_HYDRATED) { - callback() - } else { - var timeout = setTimeout(callback, 10 * 1000) - window.__NEXT_HYDRATED_CB = function () { - clearTimeout(timeout) + // if it's not a Next.js app return + if ( + document.documentElement.innerHTML.indexOf('__NEXT_DATA__') === -1 + ) { + callback() + } + + if (window.__NEXT_HYDRATED) { callback() + } else { + var timeout = setTimeout(callback, 10 * 1000) + window.__NEXT_HYDRATED_CB = function () { + clearTimeout(timeout) + callback() + } } + }) + } + + try { + await checkHydrated() + } catch (err) { + if (allowHydrationRetry) { + // re-try in case the page reloaded during check + await checkHydrated() + } else { + throw err } - }) + } + console.log(`\n> Hydration complete for ${url}\n`) }