tests: Add more tests with dom testing

This commit is contained in:
Sébastien Chopin 2017-11-01 16:44:27 +01:00
parent dc7d4bfab7
commit 2c8023bde9
7 changed files with 179 additions and 28 deletions

View File

@ -1,20 +1,12 @@
import test from 'ava' import test from 'ava'
import { resolve } from 'path' import { resolve } from 'path'
import puppeteer from 'puppeteer' import { Nuxt, Builder } from '../index'
import { Nuxt, Builder } from '../index.js' import * as browser from './helpers/browser'
const port = 4003 const port = 4003
const url = (route) => 'http://localhost:' + port + route const url = (route) => 'http://localhost:' + port + route
let nuxt = null let nuxt = null
let browser
const open = async (path) => {
const page = await browser.newPage()
await page.goto(url(path))
await page.waitForFunction('!!window.$nuxt')
page.html = () => page.evaluate(() => window.document.documentElement.outerHTML)
return page
}
// Init nuxt.js and create server listening on localhost:4003 // Init nuxt.js and create server listening on localhost:4003
test.before('Init Nuxt.js', async t => { test.before('Init Nuxt.js', async t => {
@ -33,34 +25,30 @@ test.before('Init Nuxt.js', async t => {
await nuxt.listen(port, 'localhost') await nuxt.listen(port, 'localhost')
}) })
test.before('Start Puppeteer', async t => { test.before('Start browser', async t => {
// https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions await browser.start()
browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
})
}) })
test('/stateless', async t => { test('/stateless', async t => {
const page = await open('/stateless') const page = await browser.page(url('/stateless'))
const h1 = await page.$eval('h1', (h1) => h1.textContent) const loading = await page.nuxt.loadingData()
const loading = await page.evaluate(() => window.$nuxt.$loading.$data)
t.is(await page.title(), 'Nuxt.js') t.is(await page.title(), 'Nuxt.js')
t.is(h1, 'My component!') t.is(await page.$text('h1'), 'My component!')
t.is(loading.show, false) t.is(loading.show, false)
t.is(loading.percent, 0) t.is(loading.percent, 0)
await page.close() await page.close()
}) })
test('/css', async t => { test('/css', async t => {
const page = await open('/css') const page = await browser.page(url('/css'))
t.is(await page.$eval('.red', (red) => red.textContent), 'This is red') t.is(await page.$eval('.red', (red) => red.textContent), 'This is red')
t.is(await page.$eval('.red', (red) => window.getComputedStyle(red).color), 'rgb(255, 0, 0)') t.is(await page.$eval('.red', (red) => window.getComputedStyle(red).color), 'rgb(255, 0, 0)')
await page.close() await page.close()
}) })
test('/stateful', async t => { test('/stateful', async t => {
const page = await open('/stateful') const page = await browser.page(url('/stateful'))
const html = await page.html() const html = await page.html()
t.true(html.includes('<div><p>The answer is 42</p></div>')) t.true(html.includes('<div><p>The answer is 42</p></div>'))
await page.close() await page.close()
@ -207,7 +195,6 @@ test.after('Closing server and nuxt.js', t => {
nuxt.close() nuxt.close()
}) })
test.after('Close Puppeteer', async t => { test.after('Stop browser', async t => {
await browser.close() await browser.stop()
browser = null
}) })

View File

@ -0,0 +1,80 @@
import test from 'ava'
import { resolve } from 'path'
import { Nuxt, Builder } from '../index.js'
import * as browser from './helpers/browser'
const port = 4005
const url = (route) => 'http://localhost:' + port + route
let nuxt = null
// Init nuxt.js and create server listening on localhost:4000
test.before('Init Nuxt.js', async t => {
const options = {
rootDir: resolve(__dirname, 'fixtures/children'),
dev: false
}
nuxt = new Nuxt(options)
await new Builder(nuxt).build()
await nuxt.listen(port, 'localhost')
})
test.before('Start browser', async t => {
await browser.start()
})
let page
const dates = {}
test('Loading /patch and keep ', async t => {
page = await browser.page(url('/patch'))
const h1 = await page.$text('h1')
t.true(h1.includes('patch:'))
const h2 = await page.$text('h2')
t.is(h2, 'Index')
dates.patch = await page.$text('[data-date-patch]')
})
test('Navigate to /patch/1', async t => {
await page.nuxt.navigate('/patch/1')
const loading = await page.nuxt.loadingData()
t.is(loading.show, true)
await page.nuxt.waitForNavigation()
const h2 = await page.$text('h2')
t.true(h2.includes('_id:'))
dates.id = await page.$text('[data-date-id]')
t.is(dates.patch, await page.$text('[data-date-patch]'))
})
test('Navigate to /patch/2', async t => {
await page.nuxt.navigate('/patch/2', true)
const date = await page.$text('[data-date-id]')
t.is(dates.patch, await page.$text('[data-date-patch]'))
t.true(+dates.id < +date)
dates.id = date
})
test('Navigate to /patch/2?test=true', async t => {
await page.nuxt.navigate('/patch/2?test=true', true)
t.is(dates.patch, await page.$text('[data-date-patch]'))
t.is(dates.id, await page.$text('[data-date-id]'))
})
test('Navigate to /patch/2#test', async t => {
await page.nuxt.navigate('/patch/2#test', true)
t.is(dates.patch, await page.$text('[data-date-patch]'))
t.is(dates.id, await page.$text('[data-date-id]'))
})
// Close server and ask nuxt to stop listening to file changes
test.after('Closing server and nuxt.js', t => {
nuxt.close()
})
test.after('Stop browser', async t => {
await page.close()
await browser.stop()
})

View File

@ -5,9 +5,11 @@
<li><nuxt-link data-test-id="patch" to="/patch">/patch</nuxt-link></li> <li><nuxt-link data-test-id="patch" to="/patch">/patch</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-1" to="/patch/1">/patch/1</nuxt-link></li> <li><nuxt-link data-test-id="patch-id-1" to="/patch/1">/patch/1</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-2" to="/patch/2">/patch/2</nuxt-link></li> <li><nuxt-link data-test-id="patch-id-2" to="/patch/2">/patch/2</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-2" to="/patch/2#test">/patch/2#test</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-child" to="/patch/2/child">/patch/2/child</nuxt-link></li> <li><nuxt-link data-test-id="patch-id-child" to="/patch/2/child">/patch/2/child</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-2-child-1" to="/patch/2/child/1">/patch/2/child/1</nuxt-link></li> <li><nuxt-link data-test-id="patch-id-2-child-1" to="/patch/2/child/1">/patch/2/child/1</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-2-child-1" to="/patch/2/child/1?query=true">/patch/2/child/1?query=true</nuxt-link></li> <li><nuxt-link data-test-id="patch-id-2-child-1" to="/patch/2/child/1?query=true">/patch/2/child/1?query=true</nuxt-link></li>
<li><nuxt-link data-test-id="patch-id-2-child-1" to="/patch/2/child/1?query=true#test">/patch/2/child/1?query=true#test</nuxt-link></li>
</ul> </ul>
</div> </div>
</template> </template>

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<h1>patch: {{ date }}</h1> <h1>patch: <i data-date-patch>{{ date }}</i></h1>
<nuxt-child/> <nuxt-child/>
</div> </div>
</template> </template>

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<h2>_id: {{ date }}</h2> <h2>_id: <i data-date-id>{{ date }}</i></h2>
<nuxt-child/> <nuxt-child/>
</div> </div>
</template> </template>

View File

@ -1,13 +1,54 @@
<template> <template>
<div>
<h4>_id: {{ date }}</h4> <h4>_id: {{ date }}</h4>
<input ref="search" type="text" v-model="q" @input="update"/>
<ul><li v-for="s in searchResults">{{ s }}</li></ul>
</div>
</template> </template>
<script> <script>
const countries = [
'Bhutan',
'United Kingdom',
'Guinea',
'Czech Republic',
'Netherlands'
]
async function search(q) {
q = String(q || '').toLowerCase()
return new Promise((resolve) => {
const searchResults = countries.filter((s) => s.toLowerCase().includes(q))
setTimeout(() => resolve(searchResults), 100)
})
}
export default { export default {
asyncData() { watch: {
'$route.query.q': async function (q) {
this.searchResults = await search(q)
}
},
async asyncData({ query }) {
const searchResults = await search(query.q)
return { return {
searchResults,
date: Date.now() date: Date.now()
} }
},
data() {
return {
q: this.$route.query.q || ''
}
},
mounted() {
this.$refs.search.selectionStart = this.$refs.search.selectionEnd = this.$refs.search.value.length
this.$refs.search.focus()
},
methods: {
update() {
this.$router.replace({ query: Object.assign({}, this.$route.query, { q: this.q }) })
}
} }
} }
</script> </script>

41
test/helpers/browser.js Normal file
View File

@ -0,0 +1,41 @@
import puppeteer from 'puppeteer'
let browser = null
export async function start() {
// https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions
browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
})
}
export async function stop() {
if (!browser) return
await browser.close()
}
export async function page(url) {
if (!browser) throw new Error('Please call start() before page(url)')
const page = await browser.newPage()
await page.goto(url)
await page.waitForFunction('!!window.$nuxt')
page.html = () => page.evaluate(() => window.document.documentElement.outerHTML)
page.$text = (selector) => page.$eval(selector, (el) => el.textContent)
page.$nuxt = await page.evaluateHandle('window.$nuxt')
page.nuxt = {
async navigate(path, wait = false) {
await page.evaluate(($nuxt, path) => $nuxt.$router.push(path), page.$nuxt, path)
if (wait) {
await this.waitForNavigation()
}
},
loadingData() {
return page.evaluate(($nuxt) => $nuxt.$loading.$data, page.$nuxt)
},
waitForNavigation() {
return page.waitForFunction('window.$nuxt.$loading.$data.show === false')
}
}
return page
}