export { testRun }
import {
page,
run,
partRegex,
autoRetry,
fetchHtml,
getServerUrl,
expectLog,
editFile,
editFileRevert,
sleep,
test,
expect
} from '@brillout/test-e2e'
import assert from 'assert'
function testRun(
cmd: 'npm run dev' | 'npm run prod' | 'npm run preview',
{
skipCssTest,
uiFramewok,
lang
}: {
skipCssTest?: boolean
uiFramewok: 'react' | 'vue' | 'preact' | 'solid'
lang?: 'ts'
isSPA?: true
}
) {
run(cmd)
const isProd = cmd === 'npm run prod' || cmd === 'npm run preview'
const isDev = !isProd
test('page content is rendered to HTML', async () => {
const html = await fetchHtml('/')
// Solid injects attribute:
Welcome
expect(html).toMatch(partRegex`]*/}>Welcome
`)
// Vue injects: `Home`
expect(html).toMatch(partRegex`]+/}>${/.*/}Home${/.*/}`)
expect(html).toMatch(partRegex`]+/}>${/.*/}About${/.*/}`)
})
test('page is rendered to the DOM and interactive', async () => {
await page.goto(getServerUrl() + '/')
expect(await page.textContent('h1')).toBe('Welcome')
expect(await page.textContent('button')).toBe('Counter 0')
// autoRetry() because browser-side code may not be loaded yet
await autoRetry(async () => {
await page.click('button')
if (uiFramewok === 'solid') {
expect(await page.textContent('button')).not.toBe('Counter 0')
} else {
expect(await page.textContent('button')).toBe('Counter 1')
}
})
})
if (isDev && (uiFramewok === 'react' || uiFramewok === 'vue')) {
test('HMR', async () => {
const file = (() => {
if (uiFramewok === 'vue') {
return './pages/index/index.page.vue'
}
if (uiFramewok === 'react') {
if (lang === 'ts') {
return './pages/index/index.page.tsx'
} else {
return './pages/index/index.page.jsx'
}
}
assert(false)
})()
expect(await page.textContent('button')).toBe('Counter 1')
expect(await page.textContent('h1')).toBe('Welcome')
await sleep(2 * 1000) // timeout can probably be decreased
editFile(file, (s) => s.replace('Welcome', 'Welcome !'))
await autoRetry(async () => {
expect(await page.textContent('h1')).toBe('Welcome !')
})
expect(await page.textContent('button')).toBe('Counter 1')
await sleep(300)
editFileRevert()
await autoRetry(async () => {
expect(await page.textContent('h1')).toBe('Welcome')
})
expect(await page.textContent('button')).toBe('Counter 1')
})
}
test('about page', async () => {
await page.click('a[href="/about"]')
await autoRetry(async () => {
const title = await page.textContent('h1')
expect(title).toBe('About')
})
// CSS is loaded only after being dynamically `import()`'d from JS
await autoRetry(async () => {
if (skipCssTest) {
return
}
expect(await page.$eval('code', (e) => getComputedStyle(e).backgroundColor)).toBe('rgb(234, 234, 234)')
})
})
test('active links', async () => {
// Not sure why `autoRetry()` is needed here; isn't the CSS loading already awaited for in the previous `test()` call?
await autoRetry(async () => {
expect(await page.$eval('a[href="/about"]', (e) => getComputedStyle(e).backgroundColor)).toBe(
'rgb(238, 238, 238)'
)
expect(await page.$eval('a[href="/"]', (e) => getComputedStyle(e).backgroundColor)).toBe('rgba(0, 0, 0, 0)')
})
})
test('error page', async () => {
await page.goto(getServerUrl() + '/does-not-exist')
expect(await page.textContent('h1')).toBe('404 Page Not Found')
expect(await page.textContent('p')).toBe('This page could not be found.')
expectLog(
'Failed to load resource: the server responded with a status of 404 (Not Found)',
(log) => log.logSource === 'Browser Error' && partRegex`http://${/[^\/]+/}:3000/does-not-exist`.test(log.logText)
)
})
}