Итак, я работаю над тестами e2e для проекта vue. Я хотел создать оболочку для browser.execute, которая будет искать именованный экземпляр vue, а затем выполнять внедренную функцию с найденным экземпляром vue в качестве его параметра.
пример полного кода
созданная мной оболочка показана ниже. но параметр operation
по какой-то причине является нулевым.
runNamedVueOperation: (browser, name, operation) => {
/**
* recursively traverse vue children until named route is found
* @param name (string) Vue component name defined in $options
* @param operation function(vueInstance) operation if found
* cannot return circular references!!! (do not return vue instance)
* @return Promise return value of operation
*/
return new Promise((resolve, reject) => {
browser.execute(function (...args) {
let name = args[0]
let operation = args[1]
let found = null
const traverseChildren = (vue) => {
if (vue.$options && vue.$options.name == name) {
found = vue
return vue
} else if (vue.$children && vue.$children.length) {
return vue.$children.map(c => traverseChildren(c))
} else {
return null
}
}
traverseChildren(window.vm)
if (!found) {
return 'No vue found'
} else if (!operation) {
return args // shows [name, null]
}
return operation(found)
}, [name, operation], result => {
console.log(name, operation) // shows [name, function]
if (result.status === -1 || result.error) {
return reject(result.error)
} else {
return resolve(result.value)
}
})
})
}
для дальнейшей ссылки на то, как эта функция используется; Я вызываю runNamedVueOperation
вот так
browser.globals.runNamedVueOperation(browser, 'WFU', function(vue) {
let dc = vue.$options.dc
let hourChart = dc.chartRegistry.list().filter(c => c.name === 'HourDateChart')[0]
let hours = []
let dates = vue.dates
let start = moment(dates[0]).startOf('day')
let end = moment(dates[1]).endOf('day')
let days = end.diff(start, 'days') + 1
let currentText = null
dc.filterAll() // ensure no current filters
for (let i = 0; i < days; i++) {
let day = start.clone().add(i, 'days')
hourChart.filter(dc.filters.RangedFilter(day.startOf('day'), day.endOf('day')))
dc.redrawAll() // update rendering
currentText = document.querySelector('#total-hours-display span.number-display').innerHTML
if (currentText && currentText.length && currentText.includes(' hour')) {
currentText = parseFloat(currentText.split(' hour'[0]).replace(/,/g, ''))
if (!Number.isNaN(currentText)) {
hours.push(currentText)
}
currentText = null // clear this out for next round
}
}
return hours
}).then(hours => {
console.log(hours) //shows returned [name, null] from wrapper
})
Я знаю, что могу точно скопировать введенную функцию прямо в оболочку и запустить ее таким образом, но я подумал, что было бы лучше использовать такую оболочку, как эта найдите именованный экземпляр vue и запустите любую функцию, которую я выбрал для внедрения.
Можно ли передать функцию в качестве параметра для browser.execute? если да, то как?
Минимальный пример
browser.execute(function (...args) {
let name = args[0]
let func = args[1]
if (func) {
return func(name)
} else {
return 'No function found'
}
}, ['SomeName', function (name) { return name + ' is ' + 42 }], function (result) {
console.log(result)
// expected: 42
// actual: 'No function found'
})