debian-mirror-gitlab/spec/javascripts/vue_shared/components/tooltip_on_truncate_browser_spec.js

241 lines
6.5 KiB
JavaScript
Raw Normal View History

2020-07-28 23:09:34 +05:30
// this file can't be migrated to jest because it relies on the browser to perform integration tests:
// (specifically testing around css properties `overflow` and `white-space`)
// see: https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
2020-03-13 15:44:24 +05:30
import { mount, shallowMount } from '@vue/test-utils';
2018-11-20 20:47:30 +05:30
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
2020-03-13 15:44:24 +05:30
const TEXT_SHORT = 'lorem';
const TEXT_LONG = 'lorem-ipsum-dolar-sit-amit-consectur-adipiscing-elit-sed-do';
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
const TEXT_TRUNCATE = 'white-space: nowrap; overflow:hidden;';
const STYLE_NORMAL = `${TEXT_TRUNCATE} display: inline-block; max-width: 1000px;`; // does not overflows
const STYLE_OVERFLOWED = `${TEXT_TRUNCATE} display: inline-block; max-width: 50px;`; // overflowed when text is long
2018-11-20 20:47:30 +05:30
2019-09-30 21:07:59 +05:30
const createElementWithStyle = (style, content) => `<a href="#" style="${style}">${content}</a>`;
describe('TooltipOnTruncate component', () => {
let wrapper;
2020-03-13 15:44:24 +05:30
let parent;
2019-09-30 21:07:59 +05:30
const createComponent = ({ propsData, ...options } = {}) => {
2020-03-13 15:44:24 +05:30
wrapper = shallowMount(TooltipOnTruncate, {
2019-09-30 21:07:59 +05:30
attachToDocument: true,
propsData: {
...propsData,
},
2020-03-13 15:44:24 +05:30
attrs: {
style: STYLE_OVERFLOWED,
},
2019-09-30 21:07:59 +05:30
...options,
});
};
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
const createWrappedComponent = ({ propsData, ...options }) => {
// set a parent around the tested component
parent = mount(
{
props: {
title: { default: '' },
},
template: `
<TooltipOnTruncate :title="title" truncate-target="child" style="${STYLE_OVERFLOWED}">
<div>{{title}}</div>
</TooltipOnTruncate>
`,
components: {
TooltipOnTruncate,
},
},
{
propsData: { ...propsData },
attachToDocument: true,
...options,
},
);
wrapper = parent.find(TooltipOnTruncate);
};
const hasTooltip = () => wrapper.classes('js-show-tooltip');
2018-11-20 20:47:30 +05:30
afterEach(() => {
2019-09-30 21:07:59 +05:30
wrapper.destroy();
2018-11-20 20:47:30 +05:30
});
describe('with default target', () => {
2020-03-13 15:44:24 +05:30
it('renders tooltip if truncated', () => {
2019-09-30 21:07:59 +05:30
createComponent({
2020-03-13 15:44:24 +05:30
propsData: {
title: TEXT_LONG,
2018-11-20 20:47:30 +05:30
},
2019-09-30 21:07:59 +05:30
slots: {
2020-03-13 15:44:24 +05:30
default: [TEXT_LONG],
2019-09-30 21:07:59 +05:30
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(true);
expect(wrapper.attributes('data-original-title')).toEqual(TEXT_LONG);
expect(wrapper.attributes('data-placement')).toEqual('top');
});
2018-11-20 20:47:30 +05:30
});
2020-03-13 15:44:24 +05:30
it('does not render tooltip if normal', () => {
2019-09-30 21:07:59 +05:30
createComponent({
2020-03-13 15:44:24 +05:30
propsData: {
title: TEXT_SHORT,
2018-11-20 20:47:30 +05:30
},
2019-09-30 21:07:59 +05:30
slots: {
2020-03-13 15:44:24 +05:30
default: [TEXT_SHORT],
2019-09-30 21:07:59 +05:30
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(false);
});
2018-11-20 20:47:30 +05:30
});
});
describe('with child target', () => {
2020-03-13 15:44:24 +05:30
it('renders tooltip if truncated', () => {
2019-09-30 21:07:59 +05:30
createComponent({
attrs: {
style: STYLE_NORMAL,
},
propsData: {
2020-03-13 15:44:24 +05:30
title: TEXT_LONG,
2018-11-20 20:47:30 +05:30
truncateTarget: 'child',
},
2019-09-30 21:07:59 +05:30
slots: {
2020-03-13 15:44:24 +05:30
default: createElementWithStyle(STYLE_OVERFLOWED, TEXT_LONG),
2019-09-30 21:07:59 +05:30
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(true);
});
2018-11-20 20:47:30 +05:30
});
2020-03-13 15:44:24 +05:30
it('does not render tooltip if normal', () => {
2019-09-30 21:07:59 +05:30
createComponent({
propsData: {
2018-11-20 20:47:30 +05:30
truncateTarget: 'child',
},
2019-09-30 21:07:59 +05:30
slots: {
2020-03-13 15:44:24 +05:30
default: createElementWithStyle(STYLE_NORMAL, TEXT_LONG),
2019-09-30 21:07:59 +05:30
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(false);
});
2018-11-20 20:47:30 +05:30
});
});
describe('with fn target', () => {
2020-03-13 15:44:24 +05:30
it('renders tooltip if truncated', () => {
2019-09-30 21:07:59 +05:30
createComponent({
attrs: {
style: STYLE_NORMAL,
},
propsData: {
2020-03-13 15:44:24 +05:30
title: TEXT_LONG,
2018-12-13 13:39:08 +05:30
truncateTarget: el => el.childNodes[1],
2018-11-20 20:47:30 +05:30
},
2019-09-30 21:07:59 +05:30
slots: {
default: [
2020-03-13 15:44:24 +05:30
createElementWithStyle('', TEXT_LONG),
createElementWithStyle(STYLE_OVERFLOWED, TEXT_LONG),
2019-09-30 21:07:59 +05:30
],
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(true);
});
2018-11-20 20:47:30 +05:30
});
});
describe('placement', () => {
2020-03-13 15:44:24 +05:30
it('sets data-placement when tooltip is rendered', () => {
2019-09-30 21:07:59 +05:30
const placement = 'bottom';
2018-11-20 20:47:30 +05:30
2019-09-30 21:07:59 +05:30
createComponent({
propsData: {
placement,
},
attrs: {
2020-03-13 15:44:24 +05:30
style: STYLE_OVERFLOWED,
2019-09-30 21:07:59 +05:30
},
slots: {
2020-03-13 15:44:24 +05:30
default: TEXT_LONG,
2019-09-30 21:07:59 +05:30
},
});
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
return wrapper.vm.$nextTick().then(() => {
expect(hasTooltip()).toBe(true);
expect(wrapper.attributes('data-placement')).toEqual(placement);
});
});
});
describe('updates when title and slot content changes', () => {
describe('is initialized with a long text', () => {
beforeEach(() => {
createWrappedComponent({
propsData: { title: TEXT_LONG },
});
return parent.vm.$nextTick();
});
it('renders tooltip', () => {
expect(hasTooltip()).toBe(true);
expect(wrapper.attributes('data-original-title')).toEqual(TEXT_LONG);
expect(wrapper.attributes('data-placement')).toEqual('top');
});
it('does not render tooltip after updated to a short text', () => {
parent.setProps({
title: TEXT_SHORT,
});
return wrapper.vm
.$nextTick()
.then(() => wrapper.vm.$nextTick()) // wait 2 times to get an updated slot
.then(() => {
expect(hasTooltip()).toBe(false);
});
});
});
describe('is initialized with a short text', () => {
beforeEach(() => {
createWrappedComponent({
propsData: { title: TEXT_SHORT },
});
return wrapper.vm.$nextTick();
});
it('does not render tooltip', () => {
expect(hasTooltip()).toBe(false);
});
it('renders tooltip after updated to a long text', () => {
parent.setProps({
title: TEXT_LONG,
});
return wrapper.vm
.$nextTick()
.then(() => wrapper.vm.$nextTick()) // wait 2 times to get an updated slot
.then(() => {
expect(hasTooltip()).toBe(true);
expect(wrapper.attributes('data-original-title')).toEqual(TEXT_LONG);
expect(wrapper.attributes('data-placement')).toEqual('top');
});
});
2018-11-20 20:47:30 +05:30
});
});
});