Closed begueradj closed 4 years ago
Hey there, the link to your repo is busted :/ Also, does your v-tooltip have a Transition by any chance? We have noticed that those cause issues sometimes.
VTooltip [uses transitions(https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VTooltip/VTooltip.ts).
Can you try:
mount({
stubs: {
transition: true,
}
})
and see if that works?
@dobromir-hristov The link I provided is not broken.
I am not using transition
, but by default it is null.
@lmiller1990 Good point. I did that but still I do not get the tooltip text:
it('7. Displays help text on mouse hover', async () => {
const helpIcon = wrapper.find('.v-icon')
expect(helpIcon.exists()).toBe(true)
helpIcon.trigger('mousenter')
await wrapper.vm.$nextTick()
console.log(wrapper.text()) // tooltip text not shown here
})
@begueradj the link in the first post is 404ing. Can you check it? What is the link to your repo?
Ok, I figured the problem out. It's because VTooltip uses requestAnimationFrame
.
I got the test to pass:
import { mount } from '@vue/test-utils'
import Comp from '../../src/TooltipComp.vue'
it('2. User interface provides one help icon with tooltip text', async () => {
const wrapper = mount(Comp)
const icons = wrapper.findAll('.v-icon')
expect(icons.length).toBe(1) // Ok
const helpIcon = icons.at(0)
expect(helpIcon.text()).toEqual('help') // Ok
helpIcon.trigger('mouseenter')
await wrapper.vm.$nextTick()
requestAnimationFrame(() => {
expect(wrapper.text()).toEqual('science') // why this fails ?
})
})
Try that.
I don't think is something we can easily fix in VTU.
I am sorry, the repo I linked to was indeed invisible because I set it to be private. Now it is public. I will try your new approach. Thank you very much for the efforts and informatoin.
@lmiller1990
This gives a false positive:
requestAnimationFrame(() => {
expect(wrapper.text()).toEqual('science') // test passes whatever text I inject here
})
I will try this differently and I will update here. Thank you
Oh, you need done
so Jest waits for the update:
// added done callback to the function
it('2. User interface provides one help icon with tooltip text', async (done) => {
// stuff
helpIcon.trigger('mouseenter')
await wrapper.vm.$nextTick()
requestAnimationFrame(() => {
// assert
done() // <- here
})
})
Note both help
and science
will still be in the markup, from the looks of things (Vuetify does not seem to remove the template
from the markup, just hide it somehow. Add a selector to the span
:
<span id="custom-tooltip">
{{ tooltipText }}
</span>
For example.
Thank you again :+1:
I still can not access the tooltipText
value text on mouseenter
event.
I think I am missing something. This works for me (added id
and requestAnimationFrame
). Removing mousenter
makes it fail, which seems correct. Is there any other problem?
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon v-on="on" color="grey">
help
</v-icon>
</template>
<span id='tooltip-text'>
{{ tooltipText }}
</span>
</v-tooltip>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'ComponentWithTooltip',
props: {
tooltipText: {
type: String,
default: ''
}
}
}
</script>
import Vuetify from 'vuetify'
import { mount } from '@vue/test-utils'
import ComponentWithTooltip from '@/components/ComponentWithTooltip.vue'
const vuetify = new Vuetify()
let wrapper = null
beforeEach(() => {
wrapper = mount(ComponentWithTooltip, {
vuetify,
propsData: {
tooltipText: 'science'
}
})
})
afterEach(() => {
wrapper.destroy()
})
describe('ComponentWithTooltip.vue:', () => {
it('1. Mounts properly', () => {
expect(wrapper.isVueInstance()).toBe(true) // Ok
})
it('2. User interface provides one help icon with tooltip text', async (done) => {
const icons = wrapper.findAll('.v-icon')
expect(icons.length).toBe(1) // Ok
const helpIcon = icons.at(0)
expect(helpIcon.text()).toEqual('help') // Ok
helpIcon.trigger('mouseenter')
await wrapper.vm.$nextTick()
requestAnimationFrame(() => {
expect(wrapper.find('#tooltip-text').text()).toEqual('science') // why this fails ?
done()
})
})
})
Yes, that is exactly what I did (I read your comments carefully). As I said before, this line:
expect(wrapper.find('#tooltip-text').text()).toEqual('sddjkdkjdkje')
gives a false positive: any text other than science will be accepted.
Even not setting an id to the span
element gives a false positive.
I thank you for the efforts though.
That's not the case when I run it:
● ComponentWithTooltip.vue: › 2. User interface provides one help icon with tooltip text
expect(received).toEqual(expected) // deep equality
Expected: "sddjkdkjdkje"
Received: "science"
34 | await wrapper.vm.$nextTick()
35 | requestAnimationFrame(() => {
> 36 | expect(wrapper.find('#tooltip-text').text()).toEqual('sddjkdkjdkje') // why this fails ?
| ^
37 | done()
38 | })
39 | })
Anything other than science
fails (so it should).
Or I misunderstood something - I can push a repo with my changes if you like.
Indeed, I had a typo, your solution works perfectly well on the example I shared.
Thank you so much for your efforts and attention. Have a nice Sunday :+1: @lmiller1990
No problem, glad you got it working
Hello @lmiller1990, why does your example not work?
My component:
<template>
<div class="ml-4">
<v-tooltip v-if="!$vuetify.theme.dark" bottom>
<template v-slot:activator="{ on }">
<v-btn elevation=2 small fab rounded v-on="on" color="primary" @click="darkMode">
<v-icon color="primary">mdi-moon-waxing-crescent</v-icon>
</v-btn>
</template>
<span>Dark Mode On</span>
</v-tooltip>
<v-tooltip v-else bottom>
<template v-slot:activator="{ on }">
<v-btn elevation=2 small fab rounded v-on="on" color="secondary" class="darkmode-button" @click="darkMode">
<v-icon color="yellow">mdi-white-balance-sunny</v-icon>
</v-btn>
</template>
<span>Dark Mode Off</span>
</v-tooltip>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
name: "DarkModeButton",
methods: {
...mapActions(['updateTheme']),
darkMode() {
this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
this.updateTheme(this.$vuetify.theme.dark);
},
},
};
</script>
My test :
import Vue from "vue";
import Vuetify from "vuetify";
import Vuex from "vuex";
import DarkModeButton from "../../components/navigation/DarkModeButton.vue";
import { createLocalVue, mount } from "@vue/test-utils";
describe("DarkModeButton.vue", () => {
const localVue = createLocalVue()
let vuetify;
let wrapper;
Vue.use(Vuetify);
beforeEach(() => {
vuetify = new Vuetify();
});
afterEach(() => {
wrapper.destroy()
})
it("1.Find component", () => {
wrapper = mount(DarkModeButton, {
localVue,
vuetify
});
expect(wrapper.findComponent({ name: "DarkModeButton" }).exists()).toBe(true);
});
it("2.Theme light by default", () => {
wrapper = mount(DarkModeButton, {
localVue,
vuetify,
});
expect(wrapper.find('.mdi-moon-waxing-crescent').exists()).toBe(true)
});
it("3.Tootlip Dark Mode On", async (done) => {
const localVue = createLocalVue();
localVue.use(Vuex);
wrapper = mount(DarkModeButton, {
localVue,
vuetify
});
const vIcon = wrapper.find('.v-icon')
vIcon.trigger('mouseenter');
await wrapper.vm.$nextTick()
requestAnimationFrame(() => {
expect(wrapper.find('span').text()).toBe('Dark Mode On')
done()
})
});
});
Version
1.0.0-beta.31
Reproduction link
https://github.com/begueradj/test-vuetify-tooltip
Steps to reproduce
What is expected?
I expect when I trigger the
mouseenter
event in my test, the wrapper should be updated to show a new text which is the one I defined for the prop.What is actually happening?
WHen I trigger the mouse event, the wrapper keeps its former state, meaning its only available text is related to the help icon text.
Thank you, Billal BEGUERADJ