2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-12 01:12:24 +03:00

test: use build/dist for e2e testing (#421)

* test: use build/dist for e2e testing

to prevent errors due to wrong build configs

* test: use wrong build conf to test the test

* test: exclude dist for babel-loader in test build

* chore: optimize more for ie9

prefer not to use language features which needs to be transpiled for ie9. Eg for..of to forEach and no spreads

* fix: continue
This commit is contained in:
Pim
2019-07-27 17:17:30 +02:00
committed by GitHub
parent 04b2692f0b
commit 0bf0ceb756
10 changed files with 121 additions and 103 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ jobs:
- attach-project
- run:
name: E2E SSR Tests
command: yarn test:e2e-ssr
command: yarn build && yarn test:e2e-ssr
- persist_to_workspace:
root: ~/project
paths:
+1 -1
View File
@@ -40,7 +40,7 @@ function rollupConfig({
delimiters: ['', ''],
values: {
// replaceConfig needs to have some values
'const polyfill = process.env.NODE_ENV === \'test\'': 'const polyfill = false',
'const polyfill = process.env.NODE_ENV === \'test\'': 'const polyfill = true',
}
}
+9 -9
View File
@@ -30,14 +30,14 @@ export function addCallback (query, callback) {
export function addCallbacks ({ tagIDKeyName }, type, tags, autoAddListeners) {
let hasAsyncCallback = false
for (const tag of tags) {
tags.forEach((tag) => {
if (!tag[tagIDKeyName] || !tag.callback) {
continue
return
}
hasAsyncCallback = true
addCallback(`${type}[data-${tagIDKeyName}="${tag[tagIDKeyName]}"]`, tag.callback)
}
})
if (!autoAddListeners || !hasAsyncCallback) {
return hasAsyncCallback
@@ -60,7 +60,7 @@ export function addListeners () {
}
export function applyCallbacks (matchElement) {
for (const [query, callback] of callbacks) {
callbacks.forEach(([query, callback]) => {
const selector = `${query}[onload="this.__vm_l=1"]`
let elements = []
@@ -72,13 +72,13 @@ export function applyCallbacks (matchElement) {
elements = [matchElement]
}
for (const element of elements) {
elements.forEach((element) => {
/* __vm_cb: whether the load callback has been called
* __vm_l: set by onload attribute, whether the element was loaded
* __vm_ev: whether the event listener was added or not
*/
if (element.__vm_cb) {
continue
return
}
const onload = () => {
@@ -105,7 +105,7 @@ export function applyCallbacks (matchElement) {
*/
if (element.__vm_l) {
onload()
continue
return
}
if (!element.__vm_ev) {
@@ -113,6 +113,6 @@ export function applyCallbacks (matchElement) {
element.addEventListener('load', onload)
}
}
}
})
})
}
+2 -2
View File
@@ -25,11 +25,11 @@ export default function updateClientMetaInfo (appId, options = {}, newInfo) {
// add load callbacks if the
let addLoadListeners = false
for (const type of tagsSupportingOnload) {
tagsSupportingOnload.forEach((type) => {
if (newInfo[type] && addCallbacks(options, type, newInfo[type])) {
addLoadListeners = true
}
}
})
if (addLoadListeners) {
addListeners()
+72 -75
View File
@@ -13,7 +13,9 @@ import { queryElements, getElementsKey } from '../../utils/elements.js'
export default function updateTag (appId, options = {}, type, tags, head, body) {
const { attribute, tagIDKeyName } = options
const dataAttributes = [tagIDKeyName, ...commonDataAttributes]
const dataAttributes = commonDataAttributes.slice()
dataAttributes.push(tagIDKeyName)
const newElements = []
const queryOptions = { appId, attribute, type, tagIDKeyName }
@@ -36,103 +38,98 @@ export default function updateTag (appId, options = {}, type, tags, head, body)
})
}
if (tags.length) {
for (const tag of tags) {
if (tag.skip) {
tags.forEach((tag) => {
if (tag.skip) {
return
}
const newElement = document.createElement(type)
newElement.setAttribute(attribute, appId)
for (const attr in tag) {
/* istanbul ignore next */
if (!tag.hasOwnProperty(attr)) {
continue
}
const newElement = document.createElement(type)
newElement.setAttribute(attribute, appId)
for (const attr in tag) {
/* istanbul ignore next */
if (!tag.hasOwnProperty(attr)) {
continue
}
if (attr === 'innerHTML') {
newElement.innerHTML = tag.innerHTML
continue
}
if (attr === 'json') {
newElement.innerHTML = JSON.stringify(tag.json)
continue
}
if (attr === 'cssText') {
if (newElement.styleSheet) {
/* istanbul ignore next */
newElement.styleSheet.cssText = tag.cssText
} else {
newElement.appendChild(document.createTextNode(tag.cssText))
}
continue
}
if (attr === 'callback') {
newElement.onload = () => tag[attr](newElement)
continue
}
const _attr = includes(dataAttributes, attr)
? `data-${attr}`
: attr
const isBooleanAttribute = includes(booleanHtmlAttributes, attr)
if (isBooleanAttribute && !tag[attr]) {
continue
}
const value = isBooleanAttribute ? '' : tag[attr]
newElement.setAttribute(_attr, value)
if (attr === 'innerHTML') {
newElement.innerHTML = tag.innerHTML
continue
}
const oldElements = currentElements[getElementsKey(tag)]
// Remove a duplicate tag from domTagstoRemove, so it isn't cleared.
let indexToDelete
const hasEqualElement = oldElements.some((existingTag, index) => {
indexToDelete = index
return newElement.isEqualNode(existingTag)
})
if (hasEqualElement && (indexToDelete || indexToDelete === 0)) {
oldElements.splice(indexToDelete, 1)
} else {
newElements.push(newElement)
if (attr === 'json') {
newElement.innerHTML = JSON.stringify(tag.json)
continue
}
if (attr === 'cssText') {
if (newElement.styleSheet) {
/* istanbul ignore next */
newElement.styleSheet.cssText = tag.cssText
} else {
newElement.appendChild(document.createTextNode(tag.cssText))
}
continue
}
if (attr === 'callback') {
newElement.onload = () => tag[attr](newElement)
continue
}
const _attr = includes(dataAttributes, attr)
? `data-${attr}`
: attr
const isBooleanAttribute = includes(booleanHtmlAttributes, attr)
if (isBooleanAttribute && !tag[attr]) {
continue
}
const value = isBooleanAttribute ? '' : tag[attr]
newElement.setAttribute(_attr, value)
}
}
let oldElements = []
for (const current of Object.values(currentElements)) {
oldElements = [
...oldElements,
...current
]
const oldElements = currentElements[getElementsKey(tag)]
// Remove a duplicate tag from domTagstoRemove, so it isn't cleared.
let indexToDelete
const hasEqualElement = oldElements.some((existingTag, index) => {
indexToDelete = index
return newElement.isEqualNode(existingTag)
})
if (hasEqualElement && (indexToDelete || indexToDelete === 0)) {
oldElements.splice(indexToDelete, 1)
} else {
newElements.push(newElement)
}
})
const oldElements = []
for (const type in currentElements) {
Array.prototype.push.apply(oldElements, currentElements[type])
}
// remove old elements
for (const element of oldElements) {
oldElements.forEach((element) => {
element.parentNode.removeChild(element)
}
})
// insert new elements
for (const element of newElements) {
newElements.forEach((element) => {
if (element.hasAttribute('data-body')) {
body.appendChild(element)
continue
return
}
if (element.hasAttribute('data-pbody')) {
body.insertBefore(element, body.firstChild)
continue
return
}
head.appendChild(element)
}
})
return {
oldTags: oldElements,
+4 -4
View File
@@ -19,9 +19,9 @@ export const clientSequences = [
]
// sanitizes potentially dangerous characters
export function escape (info, options, escapeOptions) {
export function escape (info, options, escapeOptions, escapeKeys) {
const { tagIDKeyName } = options
const { doEscape = v => v, escapeKeys } = escapeOptions
const { doEscape = v => v } = escapeOptions
const escaped = {}
for (const key in info) {
@@ -56,13 +56,13 @@ export function escape (info, options, escapeOptions) {
} else if (isArray(value)) {
escaped[key] = value.map((v) => {
if (isPureObject(v)) {
return escape(v, options, { ...escapeOptions, escapeKeys: true })
return escape(v, options, escapeOptions, true)
}
return doEscape(v)
})
} else if (isPureObject(value)) {
escaped[key] = escape(value, options, { ...escapeOptions, escapeKeys: true })
escaped[key] = escape(value, options, escapeOptions, true)
} else {
escaped[key] = value
}
+2 -2
View File
@@ -4,13 +4,13 @@ const _global = hasGlobalWindow ? window : global
const console = (_global.console = _global.console || {})
export function warn (...args) {
export function warn (str) {
/* istanbul ignore next */
if (!console || !console.warn) {
return
}
console.warn(...args)
console.warn(str)
}
export const showWarningNotSupported = () => warn('This vue app/component has no vue-meta configuration')
+1 -1
View File
@@ -1,5 +1,5 @@
import Vue from 'vue'
import VueMeta from '../../../src/browser'
import VueMeta from 'vue-meta'
import App from './App.vue'
import createRouter from './router'
+8 -4
View File
@@ -1,10 +1,14 @@
import Vue from 'vue'
import VueMeta from '../../../src'
import { _import, getVueMetaPath } from '../../utils/build'
import App from './App.vue'
import createRouter from './router'
Vue.use(VueMeta)
export default async function createServerApp () {
const VueMeta = await _import(getVueMetaPath())
App.router = createRouter()
Vue.use(VueMeta)
export default new Vue(App)
App.router = createRouter()
return new Vue(App)
}
+21 -4
View File
@@ -5,11 +5,26 @@ import webpack from 'webpack'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import VueLoaderPlugin from 'vue-loader/lib/plugin'
import { createRenderer } from 'vue-server-renderer'
import stdEnv from 'std-env'
const renderer = createRenderer()
export { default as getPort } from 'get-port'
export function _import (moduleName) {
return import(moduleName).then(m => m.default || m)
}
export const useDist = stdEnv.test && stdEnv.ci
export function getVueMetaPath (browser) {
if (useDist) {
return path.resolve(__dirname, `../..${browser ? '/dist/vue-meta.js' : ''}`)
}
return path.resolve(__dirname, `../../src${browser ? '/browser' : ''}`)
}
export function webpackRun (config) {
const compiler = webpack(config)
@@ -48,7 +63,8 @@ export async function buildFixture (fixture, config = {}) {
webpackStats.errors.forEach(e => console.error(e)) // eslint-disable-line no-console
webpackStats.warnings.forEach(e => console.warn(e)) // eslint-disable-line no-console
const vueApp = await import(path.resolve(fixturePath, 'server')).then(m => m.default || m)
const createApp = await _import(path.resolve(fixturePath, 'server'))
const vueApp = await createApp()
const templateFile = await fs.readFile(path.resolve(fixturePath, '..', 'app.template.html'), { encoding: 'utf8' })
const compiled = template(templateFile, { interpolate: /{{([\s\S]+?)}}/g })
@@ -64,7 +80,7 @@ export async function buildFixture (fixture, config = {}) {
.reduce((s, asset) => `${s}<script src="./${asset.name}"></script>\n`, '')
const app = await renderer.renderToString(vueApp)
// !!! run inject after renderToString !!!
const metaInfo = vueApp.$meta().inject()
const appFile = path.resolve(webpackStats.outputPath, 'index.html')
@@ -97,7 +113,7 @@ export function createWebpackConfig (config = {}) {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
exclude: /(node_modules|dist)/,
use: {
loader: 'babel-loader',
options: {
@@ -144,7 +160,8 @@ export function createWebpackConfig (config = {}) {
],
resolve: {
alias: {
'vue': 'vue/dist/vue.esm.js'
'vue': 'vue/dist/vue.esm.js',
'vue-meta': getVueMetaPath(true)
}
},
...config