Commit 7b72248b authored by Tim Zallmann's avatar Tim Zallmann

Merge branch 'leipert-jsdom-sixteen' into 'master'

Utilize jest-environment-jsdom-sixteen for tests

See merge request gitlab-org/gitlab!34362
parents ad899ebd 4d1389e6
......@@ -4,6 +4,7 @@ exports[`PathNavigation matches snapshot 1`] = `
<div
class="gl-path-nav"
data-testid="gl-path-nav"
style="--path-bg-color: #fafafa;"
>
<span
class="gl-path-fade gl-path-fade-left"
......
......@@ -3,13 +3,13 @@
exports[`AuditFilterToken when initialized with a value matches the snapshot 1`] = `
<div
config="[object Object]"
fetchitem="function mockConstructor() {
fetchitem="function () {
return fn.apply(this, arguments);
}"
fetchsuggestions="function mockConstructor() {
fetchsuggestions="function () {
return fn.apply(this, arguments);
}"
getitemname="function mockConstructor() {
getitemname="function () {
return fn.apply(this, arguments);
}"
id="filtered-search-token"
......@@ -47,13 +47,13 @@ exports[`AuditFilterToken when initialized with a value matches the snapshot 1`]
exports[`AuditFilterToken when initialized without a value matches the snapshot 1`] = `
<div
config="[object Object]"
fetchitem="function mockConstructor() {
fetchitem="function () {
return fn.apply(this, arguments);
}"
fetchsuggestions="function mockConstructor() {
fetchsuggestions="function () {
return fn.apply(this, arguments);
}"
getitemname="function mockConstructor() {
getitemname="function () {
return fn.apply(this, arguments);
}"
id="filtered-search-token"
......
......@@ -63,7 +63,6 @@ describe('PackagesApp', () => {
stubs: {
...stubChildren(PackagesApp),
GlDeprecatedButton: false,
GlLink: false,
GlModal: false,
GlTab: false,
GlTabs: false,
......@@ -278,7 +277,8 @@ describe('PackagesApp', () => {
it(`file download link call event with ${TrackingActions.PULL_PACKAGE}`, () => {
createComponent({ packageEntity: conanPackage });
firstFileDownloadLink().trigger('click');
firstFileDownloadLink().vm.$emit('click');
expect(eventSpy).toHaveBeenCalledWith(
category,
TrackingActions.PULL_PACKAGE,
......
......@@ -56,6 +56,7 @@ describe('packages_coming_soon', () => {
},
stubs: {
ApolloQuery,
GlLink: true,
},
mocks: {
$apolloData,
......@@ -115,7 +116,7 @@ describe('packages_coming_soon', () => {
it('tracks when an issue title link is clicked', () => {
eventSpy.mockClear();
findIssueTitleLink().trigger('click');
findIssueTitleLink().vm.$emit('click');
expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, {
label: firstIssue.title,
......@@ -126,7 +127,7 @@ describe('packages_coming_soon', () => {
it('tracks when an issue id link is clicked', () => {
eventSpy.mockClear();
findIssueIdLink().trigger('click');
findIssueIdLink().vm.$emit('click');
expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, {
label: firstIssue.title,
......
......@@ -70,19 +70,21 @@ describe('RelatedIssuableInput', () => {
});
describe('focus', () => {
it('when clicking anywhere on the input wrapper it should focus the input', () => {
it('when clicking anywhere on the input wrapper it should focus the input', async () => {
const wrapper = shallowMount(RelatedIssuableInput, {
propsData: {
...propsData,
references: ['foo', 'bar'],
},
// We need to attach to document, so that `document.activeElement` is properly set in jsdom
attachToDocument: true,
});
wrapper.find('li').trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(document.activeElement).toBe(wrapper.find({ ref: 'input' }).element);
});
await wrapper.vm.$nextTick();
expect(document.activeElement).toBe(wrapper.find({ ref: 'input' }).element);
});
});
......
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
......@@ -628,13 +629,13 @@ describe('Subscriptions Actions', () => {
});
describe('confirmOrderSuccess', () => {
useMockLocationHelper();
const params = { location: 'http://example.com', plan_id: 'x', quantity: 10 };
it('changes the window location', done => {
const spy = jest.spyOn(window.location, 'assign').mockImplementation();
testAction(actions.confirmOrderSuccess, params, {}, [], [], () => {
expect(spy).toHaveBeenCalledWith('http://example.com');
expect(window.location.assign).toHaveBeenCalledWith('http://example.com');
done();
});
});
......
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import MockAdapter from 'axios-mock-adapter';
import createState from '~/create_cluster/eks_cluster/store/state';
import * as actions from '~/create_cluster/eks_cluster/store/actions';
......@@ -251,12 +252,7 @@ describe('EKS Cluster Store Actions', () => {
});
describe('createClusterSuccess', () => {
beforeEach(() => {
jest.spyOn(window.location, 'assign').mockImplementation(() => {});
});
afterEach(() => {
window.location.assign.mockRestore();
});
useMockLocationHelper();
it('redirects to the new cluster URL', () => {
actions.createClusterSuccess(null, newClusterUrl);
......
......@@ -18,7 +18,7 @@ describe('Design reply form component', () => {
const findCancelButton = () => wrapper.find({ ref: 'cancelButton' });
const findModal = () => wrapper.find({ ref: 'cancelCommentModal' });
function createComponent(props = {}) {
function createComponent(props = {}, mountOptions = {}) {
wrapper = mount(DesignReplyForm, {
propsData: {
value: '',
......@@ -26,6 +26,7 @@ describe('Design reply form component', () => {
...props,
},
stubs: { GlModal },
...mountOptions,
});
}
......@@ -34,7 +35,8 @@ describe('Design reply form component', () => {
});
it('textarea has focus after component mount', () => {
createComponent();
// We need to attach to document, so that `document.activeElement` is properly set in jsdom
createComponent({}, { attachToDocument: true });
expect(findTextarea().element).toEqual(document.activeElement);
});
......
......@@ -2,7 +2,7 @@
const path = require('path');
const { ErrorWithStack } = require('jest-util');
const JSDOMEnvironment = require('jest-environment-jsdom');
const JSDOMEnvironment = require('jest-environment-jsdom-sixteen');
const ROOT_PATH = path.resolve(__dirname, '../..');
......
/**
* Manage the instance of a custom `window.location`
*
* This only encapsulates the setup / teardown logic so that it can easily be
* reused with different implementations (i.e. a spy or a [fake][1])
*
* [1]: https://stackoverflow.com/a/41434763/1708147
*
* @param {() => any} fn Function that returns the object to use for window.location
*/
const useMockLocation = fn => {
const origWindowLocation = window.location;
let currentWindowLocation;
Object.defineProperty(window, 'location', {
get: () => currentWindowLocation,
});
beforeEach(() => {
currentWindowLocation = fn();
});
afterEach(() => {
currentWindowLocation = origWindowLocation;
});
};
/**
* Create an object with the location interface but `jest.fn()` implementations.
*/
export const createWindowLocationSpy = () => {
return {
assign: jest.fn(),
reload: jest.fn(),
replace: jest.fn(),
toString: jest.fn(),
};
};
/**
* Before each test, overwrite `window.location` with a spy implementation.
*/
export const useMockLocationHelper = () => useMockLocation(createWindowLocationSpy);
......@@ -33,7 +33,7 @@ describe('setWindowLocation', () => {
it.each([null, 1, undefined, false, '', 'gitlab.com'])(
'throws an error when called with an invalid url: "%s"',
invalidUrl => {
expect(() => setWindowLocation(invalidUrl)).toThrow(new TypeError('Invalid URL'));
expect(() => setWindowLocation(invalidUrl)).toThrow(/Invalid URL/);
expect(window.location).toBe(originalLocation);
},
);
......
......@@ -12,7 +12,8 @@ import {
} from '~/ide/stores/actions';
import service from '~/ide/services';
import api from '~/api';
import testAction from '../../../helpers/vuex_action_helper';
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
const TEST_PROJECT_ID = 'abc/def';
......@@ -116,6 +117,8 @@ describe('IDE store project actions', () => {
});
describe('createNewBranchFromDefault', () => {
useMockLocationHelper();
beforeEach(() => {
jest.spyOn(api, 'createBranch').mockResolvedValue();
});
......@@ -170,8 +173,6 @@ describe('IDE store project actions', () => {
});
it('reloads window', done => {
jest.spyOn(window.location, 'reload').mockImplementation();
createNewBranchFromDefault(
{
state: {
......
......@@ -10,6 +10,8 @@ const createMountedWrapper = (props = {}) => {
wrapper = mount(DuplicateDashboardForm, {
propsData: { ...props },
sync: false,
// We need to attach to document, so that `document.activeElement` is properly set in jsdom
attachToDocument: true,
});
};
......
......@@ -6,11 +6,14 @@ import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
import createStore from '~/notes/stores';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
describe('Confidential Issue Sidebar Block', () => {
useMockLocationHelper();
let wrapper;
const findRecaptchaModal = () => wrapper.find(RecaptchaModal);
......@@ -43,10 +46,6 @@ describe('Confidential Issue Sidebar Block', () => {
});
};
beforeEach(() => {
jest.spyOn(window.location, 'reload').mockImplementation();
});
afterEach(() => {
wrapper.destroy();
});
......
......@@ -121,11 +121,6 @@ describe('Tracking', () => {
describe('tracking interface events', () => {
let eventSpy;
const trigger = (selector, eventName = 'click') => {
const event = new Event(eventName, { bubbles: true });
document.querySelector(selector).dispatchEvent(event);
};
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
Tracking.bindDocument('_category_'); // only happens once
......@@ -140,7 +135,7 @@ describe('Tracking', () => {
});
it('binds to clicks on elements matching [data-track-event]', () => {
trigger('[data-track-event="click_input1"]');
document.querySelector('[data-track-event="click_input1"]').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input1', {
label: '_label_',
......@@ -149,13 +144,13 @@ describe('Tracking', () => {
});
it('does not bind to clicks on elements without [data-track-event]', () => {
trigger('[data-track-eventbogus="click_bogusinput"]');
document.querySelector('[data-track-eventbogus="click_bogusinput"]').click();
expect(eventSpy).not.toHaveBeenCalled();
});
it('allows value override with the data-track-value attribute', () => {
trigger('[data-track-event="click_input2"]');
document.querySelector('[data-track-event="click_input2"]').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input2', {
value: '_value_override_',
......@@ -163,13 +158,15 @@ describe('Tracking', () => {
});
it('handles checkbox values correctly', () => {
trigger('[data-track-event="toggle_checkbox"]'); // checking
const checkbox = document.querySelector('[data-track-event="toggle_checkbox"]');
checkbox.click(); // unchecking
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_checkbox', {
value: false,
});
trigger('[data-track-event="toggle_checkbox"]'); // unchecking
checkbox.click(); // checking
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_checkbox', {
value: '_value_',
......@@ -177,17 +174,19 @@ describe('Tracking', () => {
});
it('handles bootstrap dropdowns', () => {
trigger('[data-track-event="toggle_dropdown"]', 'show.bs.dropdown'); // showing
const dropdown = document.querySelector('[data-track-event="toggle_dropdown"]');
dropdown.dispatchEvent(new Event('show.bs.dropdown', { bubbles: true }));
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_dropdown_show', {});
trigger('[data-track-event="toggle_dropdown"]', 'hide.bs.dropdown'); // hiding
dropdown.dispatchEvent(new Event('hide.bs.dropdown', { bubbles: true }));
expect(eventSpy).toHaveBeenCalledWith('_category_', 'toggle_dropdown_hide', {});
});
it('handles nested elements inside an element with tracking', () => {
trigger('span.nested', 'click');
document.querySelector('span.nested').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'nested_event', {});
});
......
......@@ -274,7 +274,7 @@ describe('Renamed Diff Viewer', () => {
expect(link.text()).toEqual(linkText);
expect(link.attributes('href')).toEqual(DIFF_FILE_VIEW_PATH);
link.trigger('click');
link.vm.$emit('click');
expect(clickMock).toHaveBeenCalled();
},
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment