2018-10-30 20:42:53 +00:00
|
|
|
import consola from 'consola'
|
2018-12-22 21:05:13 +00:00
|
|
|
import { timeout } from '@nuxt/utils'
|
2018-10-30 20:42:53 +00:00
|
|
|
|
2019-07-10 10:45:49 +00:00
|
|
|
export default async function renderAndGetWindow (
|
2018-10-30 20:42:53 +00:00
|
|
|
url = 'http://localhost:3000',
|
|
|
|
jsdomOpts = {},
|
|
|
|
{
|
|
|
|
loadedCallback,
|
|
|
|
loadingTimeout = 2000,
|
|
|
|
ssr,
|
|
|
|
globals
|
|
|
|
} = {}
|
|
|
|
) {
|
|
|
|
const jsdom = await import('jsdom')
|
|
|
|
.then(m => m.default || m)
|
|
|
|
.catch((e) => {
|
|
|
|
consola.error(`
|
|
|
|
jsdom is not installed. Please install jsdom with:
|
|
|
|
$ yarn add --dev jsdom
|
|
|
|
OR
|
|
|
|
$ npm install --dev jsdom
|
|
|
|
`)
|
|
|
|
throw e
|
|
|
|
})
|
|
|
|
|
|
|
|
const options = Object.assign({
|
|
|
|
// Load subresources (https://github.com/tmpvar/jsdom#loading-subresources)
|
|
|
|
resources: 'usable',
|
|
|
|
runScripts: 'dangerously',
|
|
|
|
virtualConsole: true,
|
2019-07-10 10:45:49 +00:00
|
|
|
beforeParse (window) {
|
2018-10-30 20:42:53 +00:00
|
|
|
// Mock window.scrollTo
|
|
|
|
window.scrollTo = () => {}
|
|
|
|
}
|
|
|
|
}, jsdomOpts)
|
|
|
|
|
|
|
|
const jsdomErrHandler = (err) => {
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.virtualConsole) {
|
|
|
|
if (options.virtualConsole === true) {
|
|
|
|
options.virtualConsole = new jsdom.VirtualConsole().sendTo(consola)
|
|
|
|
}
|
|
|
|
// Throw error when window creation failed
|
|
|
|
options.virtualConsole.on('jsdomError', jsdomErrHandler)
|
|
|
|
}
|
|
|
|
|
|
|
|
const { window } = await jsdom.JSDOM.fromURL(url, options)
|
|
|
|
|
|
|
|
// If Nuxt could not be loaded (error from the server-side)
|
|
|
|
const nuxtExists = window.document.body.innerHTML.includes(
|
|
|
|
ssr ? `window.${globals.context}` : `<div id="${globals.id}">`
|
|
|
|
)
|
|
|
|
|
|
|
|
if (!nuxtExists) {
|
|
|
|
const error = new Error('Could not load the nuxt app')
|
|
|
|
error.body = window.document.body.innerHTML
|
2019-03-11 13:22:09 +00:00
|
|
|
window.close()
|
2018-10-30 20:42:53 +00:00
|
|
|
throw error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Used by Nuxt.js to say when the components are loaded and the app ready
|
|
|
|
await timeout(new Promise((resolve) => {
|
|
|
|
window[loadedCallback] = () => resolve(window)
|
2018-11-25 14:51:32 +00:00
|
|
|
}), loadingTimeout, `Components loading in renderAndGetWindow was not completed in ${loadingTimeout / 1000}s`)
|
2018-10-30 20:42:53 +00:00
|
|
|
|
|
|
|
if (options.virtualConsole) {
|
|
|
|
// After window initialized successfully
|
|
|
|
options.virtualConsole.removeListener('jsdomError', jsdomErrHandler)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send back window object
|
|
|
|
return window
|
|
|
|
}
|