Skip to content

Commit

Permalink
test(components): fix tests after Vue3 update BATCH 1
Browse files Browse the repository at this point in the history
* test(components): propsData is now props

* test(components): revert skip on test cases

* test(components): fix duplicated bus instance

* test(components): provide moved inside global property

* test(components): remove useless nextTick()

* test(components): update jsdoc for installNewXPlugin()
  • Loading branch information
victorcg88 authored Aug 9, 2024
1 parent 35968eb commit 5d4dec8
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 335 deletions.
21 changes: 9 additions & 12 deletions packages/x-components/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,29 +181,26 @@ function mergeStates<State extends Dictionary>(
}

/**
* Makes a clean installation of the {@link XPlugin} into the passed Vue object.
* This also resets the bus, and all the hardcoded dependencies of the XPlugin.
* Creates a new instance of the {@link XPlugin}. This also resets the bus.
*
* @param options - The options for installing the {@link XPlugin}. The
* {@link XComponentsAdapterDummy} is added by default.
* @param localVue - A clone of the Vue constructor to isolate tests.
* @param bus - The event bus to use.
* If not provided, one will be created.
* @returns An array containing the `xPlugin` singleton and the `localVue` and objects.
* @returns An array containing the `xPlugin` singleton and an object with
* the plugin install options.
*/
export function installNewXPlugin(
options: Partial<XPluginOptions> = {},
localVue = undefined,
bus = new XDummyBus()
): [XPlugin, undefined] {
): [XPlugin, XPluginOptions] {
XPlugin.resetInstance();
const xPlugin = new XPlugin(bus);
// const installOptions: XPluginOptions = {
// adapter: XComponentsAdapterDummy,
// ...options
// };
// localVue.use(xPlugin, installOptions);
return [xPlugin, localVue];
const installOptions: XPluginOptions = {
adapter: XComponentsAdapterDummy,
...options
};
return [xPlugin, installOptions];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function renderDropdown({
data: () => ({ value: initialValue })
},
{
propsData: { items }
props: { items }
}
);

Expand All @@ -42,7 +42,7 @@ function renderDropdown({
}

const clickToggleButton = () => getDropdownToggle().trigger('click');
const clickNthItem = (nth: number) => getListItems().at(nth).trigger('click');
const clickNthItem = (nth: number) => getListItems().at(nth)?.trigger('click');
const pressKeyFromToggle = (key: Key) => getDropdownToggle().trigger(`keydown`, { key });
const pressKeyFromFocusedItem = (key: Key) => getHighlightedItem().trigger(`keydown`, { key });

Expand Down Expand Up @@ -71,7 +71,7 @@ function renderDropdown({
}

function isListVisible() {
const element = dropdown.find(getDataTestSelector('dropdown-list')).element;
const element = dropdown.find(getDataTestSelector('dropdown-list')).element as HTMLElement;
return element.style.display !== 'none';
}

Expand Down Expand Up @@ -116,7 +116,7 @@ describe('testing Dropdown component', () => {
const listItemWrappers = getListItems();
expect(listItemWrappers).toHaveLength(4);
items.forEach((item, index) => {
expect(listItemWrappers.at(index).text()).toBe(typeof item === 'string' ? item : item.id);
expect(listItemWrappers.at(index)?.text()).toBe(typeof item === 'string' ? item : item.id);
});
});

Expand All @@ -143,8 +143,8 @@ describe('testing Dropdown component', () => {
const listItemWrappers = getListItems();
expect(getDropdownToggle().text()).toBe('select something');
expect(listItemWrappers.length).toBeGreaterThan(0);
expect(getHighlightedItem().text()).toBe(listItemWrappers.at(0).text());
expect(getSelectedItem().element).toBeUndefined();
expect(getHighlightedItem().text()).toBe(listItemWrappers.at(0)?.text());
expect(getSelectedItem().exists()).toBeFalsy();
});

it('allows to customize the toggle button', async () => {
Expand Down Expand Up @@ -177,7 +177,7 @@ describe('testing Dropdown component', () => {
await pressKeyFromToggle('ArrowDown');

const selectedElement = getListItems().at(selectedIndex);
expect(getHighlightedItem().text()).toBe(selectedElement.text());
expect(getHighlightedItem().text()).toBe(selectedElement?.text());
});

it('opens and focuses the selected element when the button has focus and arrow UP key is pressed', async () => {
Expand All @@ -189,7 +189,7 @@ describe('testing Dropdown component', () => {
await pressKeyFromToggle('ArrowUp');

const selectedElement = getListItems().at(selectedIndex);
expect(getHighlightedItem().text()).toBe(selectedElement.text());
expect(getHighlightedItem().text()).toBe(selectedElement?.text());
});
});

Expand Down Expand Up @@ -291,10 +291,10 @@ describe('testing Dropdown component', () => {
const listItems = getListItems();

await pressKeyFromFocusedItem('End');
expect(getHighlightedItem().text()).toBe(listItems.at(-1).text());
expect(getHighlightedItem().text()).toBe(listItems.at(-1)?.text());

await pressKeyFromFocusedItem('Home');
expect(getHighlightedItem().text()).toBe(listItems.at(0).text());
expect(getHighlightedItem().text()).toBe(listItems.at(0)?.text());
});

it('focuses the first element starting to search from the focused one which its text starts with the typed characters', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import { mount } from '@vue/test-utils';
import { ComponentMountingOptions, mount } from '@vue/test-utils';
import { installNewXPlugin } from '../../__tests__/utils';
import { XPlugin } from '../../plugins';
import { WireMetadata } from '../../wiring/wiring.types';
import BaseEventButton from '../base-event-button.vue';
import { XEventsTypes } from 'src/wiring';

function render() {
installNewXPlugin();
const stubSlot = `<span class="test-msg">button text</span>
<i class="test-icon"></i>`;

const wrapper = mount(
{
template: `<BaseEventButton :events="events">
<span class="test-msg">button text</span>
<i class="test-icon"></i>
</BaseEventButton>`,
components: { BaseEventButton },
props: ['events']
},
{
propsData: { events: {} }
}
);
function render(options: ComponentMountingOptions<typeof BaseEventButton> = {}) {
const wrapper = mount(BaseEventButton, {
props: { events: {} },
slots: { default: stubSlot },
global: { plugins: [installNewXPlugin()] },
...options
});

return {
wrapper,
Expand All @@ -44,7 +39,7 @@ describe('testing Base Event Button Component', () => {
it('emits an event with a payload', async () => {
const { wrapper, emitSpy, expectedMetadata } = render();

await wrapper.setProps({ events: { testEvent: 'test-payload' } });
await wrapper.setProps({ events: { testEvent: 'test-payload' } as Partial<XEventsTypes> });
await wrapper.trigger('click');

expect(emitSpy).toHaveBeenCalledTimes(1);
Expand All @@ -54,7 +49,7 @@ describe('testing Base Event Button Component', () => {
it('emits an event with no payload', async () => {
const { wrapper, emitSpy, expectedMetadata } = render();

await wrapper.setProps({ events: { testEvent: undefined } });
await wrapper.setProps({ events: { testEvent: undefined } as Partial<XEventsTypes> });
await wrapper.trigger('click');

expect(emitSpy).toHaveBeenCalledTimes(1);
Expand All @@ -68,7 +63,7 @@ describe('testing Base Event Button Component', () => {
testEvent1: 'test-payload-1',
testEvent2: 'test-payload-2',
testEvent3: undefined
};
} as Partial<XEventsTypes>;
await wrapper.setProps({ events });
await wrapper.trigger('click');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import { SearchInput } from '../../x-modules/search-box/components/index';
import { installNewXPlugin } from '../../__tests__/utils';
import BaseKeyboardNavigation from '../base-keyboard-navigation.vue';
import { DirectionalFocusNavigationService } from '../../services/directional-focus-navigation.service';
import { XPlugin } from '../../plugins/x-plugin';

describe('testing keyboard navigation component', () => {
let localVue: typeof Vue;

beforeEach(() => {
[, localVue] = installNewXPlugin();
});

it('takes control of the navigation when a defined condition is triggered', () => {
const navigateToSpy = jest.spyOn(
DirectionalFocusNavigationService.prototype as any,
'navigateTo'
);
const searchInput = mount(SearchInput, { localVue });
mount(BaseKeyboardNavigation, {
localVue,
propsData: {
global: { plugins: [installNewXPlugin()] },
props: {
navigationHijacker: [
{
xEvent: 'UserPressedArrowKey',
Expand All @@ -30,6 +23,8 @@ describe('testing keyboard navigation component', () => {
]
}
});

const searchInput = mount(SearchInput);
searchInput.trigger('keydown', { key: 'ArrowUp' });
expect(navigateToSpy).not.toHaveBeenCalled();

Expand All @@ -44,15 +39,14 @@ describe('testing keyboard navigation component', () => {
.spyOn(DirectionalFocusNavigationService.prototype as any, 'navigateTo')
.mockReturnValue(undefined);
const keyboardNavigation = mount(BaseKeyboardNavigation, {
localVue,
propsData: {
takeNavigationControl: [],
global: { plugins: [installNewXPlugin()] },
props: {
eventsForDirectionLimit: {
ArrowUp: 'UserReachedEmpathizeTop'
}
}
});
keyboardNavigation.vm.$x.on('UserReachedEmpathizeTop').subscribe(listener);
XPlugin.bus.on('UserReachedEmpathizeTop').subscribe(listener);
keyboardNavigation.trigger('keydown', { key: 'ArrowUp' });

expect(listener).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { mount, WrapperArray } from '@vue/test-utils';
import { mount, DOMWrapper } from '@vue/test-utils';
import { getDataTestSelector } from '../../__tests__/utils';
import BaseRating from '../base-rating.vue';

function renderBaseRating({ template }: RenderBaseRatingOptions): RenderBaseRatingApi {
const wrapper = mount({ template }, { components: { BaseRating } });

return {
getFilledIcons: (): WrapperArray<Vue> =>
getFilledIcons: (): DOMWrapper<Element>[] =>
wrapper.find(getDataTestSelector('rating-filled')).findAll(':scope > *'),
getEmptyIcons: (): WrapperArray<Vue> =>
getEmptyIcons: (): DOMWrapper<Element>[] =>
wrapper.find(getDataTestSelector('rating-empty')).findAll(':scope > *')
};
}
Expand Down Expand Up @@ -39,6 +39,6 @@ interface RenderBaseRatingOptions {
}

interface RenderBaseRatingApi {
getFilledIcons: () => WrapperArray<Vue>;
getEmptyIcons: () => WrapperArray<Vue>;
getFilledIcons: () => DOMWrapper<Element>[];
getEmptyIcons: () => DOMWrapper<Element>[];
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { mount, Wrapper } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { getSearchResponseStub } from '../../__stubs__/search-response-stubs.factory';
import { getDataTestSelector, installNewXPlugin } from '../../__tests__/utils';
import { ListItem } from '../../utils/types';
import BaseVariableColumnGrid from '../base-variable-column-grid.vue';
import { XPlugin } from '../../plugins/x-plugin';
import { XDummyBus } from '../../__tests__/bus.dummy';

const searchResponse = getSearchResponseStub();
const itemsStub = [
Expand All @@ -13,16 +13,16 @@ const itemsStub = [
...searchResponse.results
];

function renderComponent({ items = itemsStub }: RenderOptions = {}): RenderAPI {
const [, localVue] = installNewXPlugin();
function mountComponent(): Wrapper<Vue> {
const sharedBus = new XDummyBus();

function renderComponent({ items = itemsStub } = {}) {
function mountComponent() {
return mount(BaseVariableColumnGrid, {
props: ['items'],
propsData: {
global: { plugins: [installNewXPlugin({}, sharedBus)] },
props: {
items
},
localVue,
scopedSlots: {
slots: {
default: '<span data-test="default-slot" slot-scope="{ item }">{{ item.id }}</span>',
result: '<span data-test="result-slot" slot-scope="{ item }">{{ item.name }}</span>'
}
Expand All @@ -34,12 +34,9 @@ function renderComponent({ items = itemsStub }: RenderOptions = {}): RenderAPI {
return {
wrapper: wrapper,
mountComponent,
hasColumns(columns: number): boolean {
return wrapper.classes(`x-base-grid--cols-${columns}`);
},
isScopedSlotOverridden(selector): boolean {
return wrapper.find(getDataTestSelector(selector)).exists();
}
hasColumns: (columns: number) => wrapper.classes(`x-base-grid--cols-${columns}`),
isScopedSlotOverridden: (selector: string) =>
wrapper.find(getDataTestSelector(selector)).exists()
};
}

Expand Down Expand Up @@ -70,22 +67,9 @@ describe('testing BaseVariableColumnGrid component', () => {
expect(hasColumns(6)).toBe(true);

const wrapper2 = mountComponent();

await nextTick();

expect(wrapper2.classes('x-base-grid--cols-6')).toBe(true);
});
});

interface RenderOptions {
/** The array of items to render in the grid. */
items?: ListItem[];
}

interface RenderAPI {
/** The grid's wrapper. */
wrapper: Wrapper<Vue>;
/** Mounts the grid component. */
mountComponent: () => Wrapper<Vue>;
/** Checks if the grid has a certain number of columns. */
hasColumns: (columns: number) => boolean;
/** Check if a scoped slot is overridden. */
isScopedSlotOverridden: (selector: string) => boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function render({
});

return {
wrapper: wrapper.findComponent(DisplayEmitter),
wrapper,
displayEmiter: wrapper.findComponent(DisplayEmitter),
element: wrapper.find(getDataTestSelector('child')).element,
payload,
eventMetadata
Expand All @@ -38,9 +39,9 @@ describe('testing DisplayEmitter component', () => {
});

it('renders everything passed to its default slot', () => {
const { wrapper } = render();
const { displayEmiter } = render();

expect(wrapper.find(getDataTestSelector('child')).exists()).toBeTruthy();
expect(displayEmiter.find(getDataTestSelector('child')).exists()).toBeTruthy();
});

it('executes `useEmitDisplayEvent` composable underneath', () => {
Expand Down Expand Up @@ -70,7 +71,7 @@ describe('testing DisplayEmitter component', () => {
it('removes the watcher on unmount', async () => {
const { wrapper } = render();

wrapper.destroy();
wrapper.unmount();
await nextTick();

expect(unwatchDisplaySpy).toHaveBeenCalled();
Expand Down
Loading

0 comments on commit 5d4dec8

Please sign in to comment.