Closed matthieuHanne closed 6 years ago
We face the same issue and tried to locate the culprit. And I found that the problematic line in ElSelectDropdown is the line it accessing $ref in mounted() as below.
mounted() {
...
this.referenceElm = this.$parent.$refs.reference.$el;
...
}
The Vue official documents for $ref usage specifies.
An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render - they don’t exist yet! $refs is also non-reactive, therefore you should not attempt to use it in templates for data-binding.
As per document, the this.$parent.$refs does not contain child references on mounted. This seems quite clear.
@JaekwanLee Have you find a solution ?
@matthieuHanne Not really. Just testing it with shallowMount for now. It is weird that it seems working when it runs on browser though.
Hi, is there any development @JaekwanLee ? or @matthieuHanne have found some kind of solution ? I'm currently adding some unit tests with Mocha to my Vue project and I have the same issue.
Thank you :)
We've also encountered exactly same issue in tests
@ziyoung @wacky6 Any ideas what is to be done here?
As far as I know, Element requires the page to be render in a real browser.
referenceElm
is used by Popper mixin to show popup according to this reference element's position.
What to be done?
Maybe, set referenceElm
to null
, hope vue-popper does not throw and mounts the dropdown (or you won't be able to select the option).
I think there is modifications going on in vue-popper for next
branch. You have to ask @ziyoung for details. That part of Element is out of my expertise.
My recommendation for testing applications with Vue/Element (in fact any MVVM framework applications, such as those built with React) is to use a state management library.
Then, assume UI library's implementation is correct, test the states / data (of state management libraries) are correct (through mutations / setState
), instead of performing MVVM component-level tests.
I write a simple demo https://github.com/ziyoung/vue-test-with-jest All test cases pass.
PASS src/components/__tests__/hello-world.test.js
PASS src/components/Select/__tests__/select.test.js
● Console
console.log src/components/Select/select.vue:18
HTMLParagraphElement {}
Maybe it's not a bug of Element.
@ziyoung Here's a patch to your vue-test-with-jest
that will allow you to reproduce the issue:
ref.txt
https://vue-test-utils.vuejs.org/api/components/
import { config } from '@vue/test-utils'
config.stubs.transition = false
This may solve this problem.
The built-in transition component has property named abstract, but transitionStub does not.
vue/src/core/instance/lifecycle.js
export function initLifecycle (vm: Component) {
const options = vm.$opti
// locate first non-abstract parent
let parent = options.parent
if (parent && !options.abstract) {
while (parent.$options.abstract && parent.$parent) {
parent = parent.$parent
}
parent.$children.push(vm)
}
...
}
This causes the child component to have the wrong parent component.
Thank you @huihao. @matthieuHanne @syn-zeta it should work for you. https://github.com/ziyoung/vue-test-with-jest/blob/master/src/components/__tests__/hello-world.test.js
Thank you @huihao. @matthieuHanne @syn-zeta it should work for you. https://github.com/ziyoung/vue-test-with-jest/blob/master/src/components/__tests__/hello-world.test.js
This is the same mistake.
@huihao Thank you for your solution!
@huihao Thank you
We face the same issue and tried to locate the culprit. And I found that the problematic line in ElSelectDropdown is the line it accessing $ref in mounted() as below.
mounted() { ... this.referenceElm = this.$parent.$refs.reference.$el; ... }
I couldn't find where this this.referenceElm
is used. What is this variable for?
I commented it out and both the tests and browser view worked fine.
@ziyoung I would like to ask if this issue could be reopened. I am still having that same exact error, and huihao's answer
import { config } from '@vue/test-utils';
config.stubs.transition = false;
doesn't solve it. Did anyone find a workaround or a working solution?
Heads up for anyone Googling this in the future, the work around is no longer needed in Vue Test Utils 1.3.1
Heads up for anyone Googling this in the future, the work around is no longer needed in Vue Test Utils 1.3.1
Thanks a thousand times
Element UI version
2.4.6
OS/Browsers version
mac os
Vue version
2.5.17
Reproduction Link
https://github.com/valterbarros/trackthings
Steps to reproduce
try to mount a component with el-select inside throw :
TypeError: Cannot read property '$el' of undefined at VueComponent.mounted (/Users/mhanne/src/report-builder/viewer/node_modules/element-ui/lib/element-ui.common.js:9131:54) at callHook (/Users/mhanne/src/report-builder/viewer/node_modules/vue/dist/vue.runtime.common.js:2919:21) at Object.insert (/Users/mhanne/src/report-builder/viewer/node_modules/vue/dist/vue.runtime.common.js:4156:7) at invokeInsertHook (/Users/mhanne/src/report-builder/viewer/node_modules/vue/dist/vue.runtime.common.js:5958:28)
What is Expected?
Mount le select input
What is actually happening?
test crash. with jest or ava same issues