test: slightly improve test reliability (#27811)

This commit is contained in:
Daniel Roe 2024-06-25 08:48:39 +02:00
parent e3448fa0da
commit 51c8c35667
No known key found for this signature in database
GPG Key ID: CBC814C393D93268
4 changed files with 39 additions and 16 deletions

View File

@ -492,7 +492,7 @@ describe('pages', () => {
})
it('client only page', async () => {
const response = await fetch('/client-only').then(r => r.text())
const response = await fetch('/client-only-page').then(r => r.text())
// Should not contain rendered page on initial request
expect(response).not.toContain('"hasAccessToWindow": true')
@ -520,10 +520,11 @@ describe('pages', () => {
// Then go to non client only page
await clientInitialPage.click('a')
await new Promise(resolve => setTimeout(resolve, 50)) // little delay to finish transition
await clientInitialPage.waitForFunction(() => window.useNuxtApp?.()._route.fullPath === '/client-only-page/normal')
// that page should be client rendered
expect(await clientInitialPage.locator('#server-rendered').textContent()).toMatchInlineSnapshot('"false"')
// TODO: investigate why multiple elements are appearing on page
expect(await clientInitialPage.locator('#server-rendered').first().textContent()).toMatchInlineSnapshot('"false"')
// and not contain any errors or warnings
expect(errors.length).toBe(0)
@ -545,6 +546,8 @@ describe('pages', () => {
// Go to client only page
await normalInitialPage.click('a')
await normalInitialPage.waitForFunction(() => window.useNuxtApp?.()._route.fullPath === '/client-only-page')
// and expect same object to be present
expect(await normalInitialPage.locator('#state').textContent()).toMatchInlineSnapshot(`
"{
@ -1421,6 +1424,7 @@ describe('deferred app suspense resolve', () => {
it.each(['/async-parent/child', '/internal-layout/async-parent/child'])('should wait for all suspense instance on initial hydration', async (path) => {
const { page, consoleLogs } = await renderPage(path)
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
// Wait for all pending micro ticks to be cleared in case hydration hasn't finished yet.
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
@ -1517,7 +1521,7 @@ describe('nested suspense', () => {
const first = start.match(/\/suspense\/(?<parentType>a?sync)-(?<parentNum>\d)\/(?<childType>a?sync)-(?<childNum>\d)\//)!.groups!
const last = nav.match(/\/suspense\/(?<parentType>a?sync)-(?<parentNum>\d)\//)!.groups!
await new Promise<void>(resolve => setTimeout(resolve, 50))
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, nav)
expect(consoleLogs.map(l => l.text).filter(i => !i.includes('[vite]') && !i.includes('<Suspense> is an experimental feature')).sort()).toEqual([
// [first load] from parent
@ -1579,6 +1583,7 @@ describe('page key', () => {
await page.click(`[href="${path}/1"]`)
await page.waitForSelector('#page-1')
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, `${path}/1`)
// Wait for all pending micro ticks to be cleared,
// so we are not resolved too early when there are repeated page loading
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
@ -1593,6 +1598,7 @@ describe('page key', () => {
await page.click(`[href="${path}/1"]`)
await page.waitForSelector('#page-1')
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, `${path}/1`)
// Wait for all pending micro ticks to be cleared,
// so we are not resolved too early when there are repeated page loading
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
@ -1625,6 +1631,7 @@ describe('layout change not load page twice', () => {
await page.click(`[href="${path2}"]`)
await page.waitForSelector('#with-layout2')
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, path2)
// Wait for all pending micro ticks to be cleared,
// so we are not resolved too early when there are repeated page loading
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
@ -1917,7 +1924,7 @@ describe.skipIf(isDev() || isWindows || !isRenderingJson)('prefetching', () => {
describe.runIf(isDev() && (!isWindows || !isCI))('detecting invalid root nodes', () => {
it.each(['1', '2', '3', '4'])('should detect invalid root nodes in pages (\'/invalid-root/%s\')', async (path) => {
const { consoleLogs, page } = await renderPage(joinURL('/invalid-root', path))
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, joinURL('/invalid-root', path))
await expectWithPolling(
() => consoleLogs
.map(w => w.text).join('\n')
@ -1930,7 +1937,7 @@ describe.runIf(isDev() && (!isWindows || !isCI))('detecting invalid root nodes',
it.each(['fine'])('should not complain if there is no transition (%s)', async (path) => {
const { consoleLogs, page } = await renderPage(joinURL('/invalid-root', path))
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
await page.waitForFunction(path => window.useNuxtApp?.()._route.fullPath === path, joinURL('/invalid-root', path))
const consoleLogsWarns = consoleLogs.filter(i => i.type === 'warning')
expect(consoleLogsWarns.length).toEqual(0)
@ -2597,12 +2604,12 @@ describe('teleports', () => {
describe('Node.js compatibility for client-side', () => {
it('should work', async () => {
const { page } = await renderPage('/node-compat')
const { page } = await renderPage('/experimental/node-compat')
await page.locator('body').getByText('Nuxt is Awesome!').waitFor()
expect(await page.innerHTML('body')).toContain('CWD: [available]')
await page.close()
})
}, 30_000)
}, 40_000)
})
function normaliseIslandResult (result: NuxtIslandResponse) {
return {

View File

@ -1,8 +1,8 @@
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
import { $fetch, setup } from '@nuxt/test-utils/e2e'
import { $fetch, createPage, setup } from '@nuxt/test-utils/e2e'
import { isWindows } from 'std-env'
import { expectNoClientErrors, renderPage } from './utils'
import { expectNoClientErrors } from './utils'
const isWebpack = process.env.TEST_BUILDER === 'webpack'
@ -24,31 +24,40 @@ describe('test basic config', () => {
it('test HelloWorld.vue', async () => {
const html = await $fetch('/')
const { page } = await renderPage('/')
const page = await createPage('/')
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
expect(html).toContain('<div id="hello-world">hello, Helloworld.vue here ! </div>')
expect(await page.locator('body').innerHTML()).toContain('<div id="hello-world">hello, Helloworld.vue here ! </div>')
await page.close()
})
it('test Name.ts', async () => {
const html = await $fetch('/')
const { page } = await renderPage('/')
const page = await createPage('/')
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
expect(html).toContain('<div id="name">I am the Name.ts component</div>')
expect(await page.locator('body').innerHTML()).toContain('<div id="name">I am the Name.ts component</div>')
await page.close()
})
it('test ShowTemplate.ts', async () => {
const html = await $fetch('/')
const { page } = await renderPage('/')
const page = await createPage('/')
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
expect(html).toContain('<div id="show-template">Hello my name is : John, i am defined by ShowTemplate.vue and my template is retrieved from the API</div>')
expect(await page.locator('body').innerHTML()).toContain('<div id="show-template">Hello my name is : John, i am defined by ShowTemplate.vue and my template is retrieved from the API</div>')
await page.close()
})
it('test Interactive component.ts', async () => {
const html = await $fetch('/')
const { page } = await renderPage('/')
const page = await createPage('/')
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
expect(html).toContain('I am defined by Interactive in the setup of App.vue. My full component definition is retrieved from the api')
expect(await page.locator('#interactive').innerHTML()).toContain('I am defined by Interactive in the setup of App.vue. My full component definition is retrieved from the api')
@ -56,5 +65,7 @@ describe('test basic config', () => {
await button.click()
const count = page.locator('#interactive-count')
expect(await count.innerHTML()).toBe('1')
await page.close()
})
})

View File

@ -22,15 +22,18 @@ await setup({
describe('suspense multiple nav', () => {
it('should not throw error', async () => {
const { page, consoleLogs, pageErrors } = await renderPage('/')
await page.waitForLoadState('networkidle')
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
expect(await page.locator('#btn-a').textContent()).toMatchInlineSnapshot('" Target A "')
// Make sure it navigates to the correct page
await page.locator('#btn-a').click()
await page.waitForFunction(() => window.useNuxtApp?.()._route.path === '/target')
console.log(page.url())
expect(await page.locator('#content').textContent()).toContain('Hello a')
await page.goBack()
await page.waitForFunction(() => window.useNuxtApp?.()._route.path === '/')
// When back
expect(await page.locator('body').textContent()).toContain('Index Page')
@ -40,6 +43,8 @@ describe('suspense multiple nav', () => {
page.locator('#btn-b').click(),
])
await page.waitForFunction(() => window.useNuxtApp?.()._route.path === '/target')
expect.soft(await page.locator('#content').textContent()).toContain('Hello b')
const consoleLogErrors = consoleLogs.filter(i => i.type === 'error')