diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-16 06:09:20 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-16 06:09:20 +0000 |
commit | 0ab17699c88587c5872f9517b29be5f43224a8ea (patch) | |
tree | 802baa1569e3cb9dc74a3d745922b257233645b3 /spec/frontend | |
parent | af7743776201b4c9cfea8a66dd522854fc9fb838 (diff) | |
download | gitlab-ce-0ab17699c88587c5872f9517b29be5f43224a8ea.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
7 files changed, 339 insertions, 62 deletions
diff --git a/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_new_spec.js.snap b/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_new_spec.js.snap index ff61afefebd..e4ef232a320 100644 --- a/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_new_spec.js.snap +++ b/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_new_spec.js.snap @@ -1,14 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`AlertsSettingsFormNew with default values renders the initial template 1`] = ` -"<form class=\\"gl-mt-6\\"> +"<form class=\\"gl-mt-6\\" canmanageopsgenie=\\"true\\"> <h5 class=\\"gl-font-lg gl-my-5\\">Add new integrations</h5> <div id=\\"integration-type\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"integration-type__BV_label_\\" for=\\"integration-type\\" class=\\"d-block col-form-label\\">1. Select integration type</label> <div class=\\"bv-no-focus-ring\\"><select class=\\"gl-form-select custom-select\\" id=\\"__BVID__8\\"> <option value=\\"\\">Select integration type</option> <option value=\\"HTTP\\">HTTP Endpoint</option> <option value=\\"PROMETHEUS\\">External Prometheus</option> - <option value=\\"OPSGENIE\\">Opsgenie</option> + <option disabled=\\"disabled\\" value=\\"OPSGENIE\\">Opsgenie</option> </select> <div class=\\"gl-my-4\\"><span class=\\"gl-text-gray-500\\">Learn more about our upcoming <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"https://gitlab.com/groups/gitlab-org/-/epics/4390\\" class=\\"gl-link gl-display-inline-block\\">integrations</a></span></div> <!----> @@ -18,71 +18,73 @@ exports[`AlertsSettingsFormNew with default values renders the initial template </div> </div> <div class=\\"gl-mt-3 collapse\\" style=\\"display: none;\\" id=\\"__BVID__13\\"> - <div id=\\"name-integration\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"name-integration__BV_label_\\" for=\\"name-integration\\" class=\\"d-block col-form-label\\">2. Name integration</label> - <div class=\\"bv-no-focus-ring\\"><input type=\\"text\\" placeholder=\\"Enter integration name\\" class=\\"gl-form-input form-control\\" id=\\"__BVID__18\\"> - <!----> - <!----> - <!----> + <div> + <div id=\\"name-integration\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"name-integration__BV_label_\\" for=\\"name-integration\\" class=\\"d-block col-form-label\\">2. Name integration</label> + <div class=\\"bv-no-focus-ring\\"><input type=\\"text\\" placeholder=\\"Enter integration name\\" class=\\"gl-form-input form-control\\" id=\\"__BVID__18\\"> + <!----> + <!----> + <!----> + </div> </div> - </div> - <div id=\\"integration-webhook\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"integration-webhook__BV_label_\\" for=\\"integration-webhook\\" class=\\"d-block col-form-label\\">3. Set up webhook</label> - <div class=\\"bv-no-focus-ring\\"><span class=\\"gl-text-gray-500\\">Utilize the URL and authorization key below to authorize an external service to send Alerts to GitLab. Review your chosen services documentation to learn where to add these details, and the <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"https://docs.gitlab.com/ee/operations/incident_management/alert_integrations.html\\" class=\\"gl-link gl-display-inline-block\\">GitLab documentation</a> to learn more about configuring your endpoint.</span> <label class=\\"gl-display-flex gl-flex-direction-column gl-mb-0 gl-w-max-content gl-my-4 gl-font-weight-normal\\"> - <div class=\\"gl-toggle-wrapper\\"><span class=\\"gl-toggle-label\\">Active</span> - <!----> <button aria-label=\\"Active\\" type=\\"button\\" class=\\"gl-toggle\\"><span class=\\"toggle-icon\\"><svg data-testid=\\"close-icon\\" class=\\"gl-icon s16\\"><use href=\\"#close\\"></use></svg></span></button></div> + <div id=\\"integration-webhook\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"integration-webhook__BV_label_\\" for=\\"integration-webhook\\" class=\\"d-block col-form-label\\">3. Set up webhook</label> + <div class=\\"bv-no-focus-ring\\"><span class=\\"gl-text-gray-500\\">Utilize the URL and authorization key below to authorize an external service to send Alerts to GitLab. Review your chosen services documentation to learn where to add these details, and the <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"https://docs.gitlab.com/ee/operations/incident_management/alert_integrations.html\\" class=\\"gl-link gl-display-inline-block\\">GitLab documentation</a> to learn more about configuring your endpoint.</span> <label class=\\"gl-display-flex gl-flex-direction-column gl-mb-0 gl-w-max-content gl-my-4 gl-font-weight-normal\\"> + <div class=\\"gl-toggle-wrapper\\"><span class=\\"gl-toggle-label\\">Active</span> + <!----> <button aria-label=\\"Active\\" type=\\"button\\" class=\\"gl-toggle\\"><span class=\\"toggle-icon\\"><svg data-testid=\\"close-icon\\" class=\\"gl-icon s16\\"><use href=\\"#close\\"></use></svg></span></button></div> + <!----> + </label> <!----> - </label> - <!----> - <div class=\\"gl-my-4\\"><span> - Webhook URL - </span> - <div id=\\"url\\" readonly=\\"readonly\\"> - <div role=\\"group\\" class=\\"input-group\\"> - <!----> - <!----> <input id=\\"url\\" type=\\"text\\" readonly=\\"readonly\\" class=\\"gl-form-input form-control\\"> - <div class=\\"input-group-append\\"><button title=\\"Copy\\" data-clipboard-text=\\"\\" aria-label=\\"Copy this value\\" type=\\"button\\" class=\\"btn gl-m-0! btn-default btn-md gl-button btn-default-secondary btn-icon\\"> - <!----> <svg data-testid=\\"copy-to-clipboard-icon\\" class=\\"gl-button-icon gl-icon s16\\"> - <use href=\\"#copy-to-clipboard\\"></use> - </svg> - <!----></button></div> - <!----> + <div class=\\"gl-my-4\\"><span> + Webhook URL + </span> + <div id=\\"url\\" readonly=\\"readonly\\"> + <div role=\\"group\\" class=\\"input-group\\"> + <!----> + <!----> <input id=\\"url\\" type=\\"text\\" readonly=\\"readonly\\" class=\\"gl-form-input form-control\\"> + <div class=\\"input-group-append\\"><button title=\\"Copy\\" data-clipboard-text=\\"\\" aria-label=\\"Copy this value\\" type=\\"button\\" class=\\"btn gl-m-0! btn-default btn-md gl-button btn-default-secondary btn-icon\\"> + <!----> <svg data-testid=\\"copy-to-clipboard-icon\\" class=\\"gl-button-icon gl-icon s16\\"> + <use href=\\"#copy-to-clipboard\\"></use> + </svg> + <!----></button></div> + <!----> + </div> </div> </div> - </div> - <div class=\\"gl-my-4\\"><span> - Authorization key - </span> - <div id=\\"authorization-key\\" readonly=\\"readonly\\" class=\\"gl-mb-2\\"> - <div role=\\"group\\" class=\\"input-group\\"> - <!----> - <!----> <input id=\\"authorization-key\\" type=\\"text\\" readonly=\\"readonly\\" class=\\"gl-form-input form-control\\"> - <div class=\\"input-group-append\\"><button title=\\"Copy\\" data-clipboard-text=\\"\\" aria-label=\\"Copy this value\\" type=\\"button\\" class=\\"btn gl-m-0! btn-default btn-md gl-button btn-default-secondary btn-icon\\"> - <!----> <svg data-testid=\\"copy-to-clipboard-icon\\" class=\\"gl-button-icon gl-icon s16\\"> - <use href=\\"#copy-to-clipboard\\"></use> - </svg> - <!----></button></div> + <div class=\\"gl-my-4\\"><span> + Authorization key + </span> + <div id=\\"authorization-key\\" readonly=\\"readonly\\" class=\\"gl-mb-2\\"> + <div role=\\"group\\" class=\\"input-group\\"> + <!----> + <!----> <input id=\\"authorization-key\\" type=\\"text\\" readonly=\\"readonly\\" class=\\"gl-form-input form-control\\"> + <div class=\\"input-group-append\\"><button title=\\"Copy\\" data-clipboard-text=\\"\\" aria-label=\\"Copy this value\\" type=\\"button\\" class=\\"btn gl-m-0! btn-default btn-md gl-button btn-default-secondary btn-icon\\"> + <!----> <svg data-testid=\\"copy-to-clipboard-icon\\" class=\\"gl-button-icon gl-icon s16\\"> + <use href=\\"#copy-to-clipboard\\"></use> + </svg> + <!----></button></div> + <!----> + </div> + </div> <button type=\\"button\\" disabled=\\"disabled\\" class=\\"btn gl-mt-3 btn-default btn-md disabled gl-button\\"> <!----> - </div> - </div> <button type=\\"button\\" disabled=\\"disabled\\" class=\\"btn gl-mt-3 btn-default btn-md disabled gl-button\\"> + <!----> <span class=\\"gl-button-text\\"> + Reset Key + </span></button> <!----> - <!----> <span class=\\"gl-button-text\\"> - Reset Key - </span></button> + </div> + <!----> + <!----> <!----> </div> - <!----> - <!----> - <!----> </div> - </div> - <div id=\\"test-integration\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"test-integration__BV_label_\\" for=\\"test-integration\\" class=\\"d-block col-form-label\\">4. Test integration(optional)</label> - <div class=\\"bv-no-focus-ring\\"><span class=\\"gl-text-gray-500\\">Provide an example payload from the monitoring tool you intend to integrate with to send a test alert to the <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"http://invalid\\" class=\\"gl-link gl-display-inline-block\\">alerts page</a>. This payload can be used to test the integration using the \\"save and test payload\\" button.</span> <textarea id=\\"test-payload\\" disabled=\\"disabled\\" placeholder=\\"Enter test alert JSON....\\" wrap=\\"soft\\" class=\\"gl-form-input gl-form-textarea gl-my-4 form-control is-valid\\" style=\\"resize: none; overflow-y: scroll;\\"></textarea> - <!----> - <!----> - <!----> - <!----> + <div id=\\"test-integration\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"test-integration__BV_label_\\" for=\\"test-integration\\" class=\\"d-block col-form-label\\">4. Test integration(optional)</label> + <div class=\\"bv-no-focus-ring\\"><span class=\\"gl-text-gray-500\\">Provide an example payload from the monitoring tool you intend to integrate with to send a test alert to the <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"http://invalid\\" class=\\"gl-link gl-display-inline-block\\">alerts page</a>. This payload can be used to test the integration using the \\"save and test payload\\" button.</span> <textarea id=\\"test-payload\\" disabled=\\"disabled\\" placeholder=\\"Enter test alert JSON....\\" wrap=\\"soft\\" class=\\"gl-form-input gl-form-textarea gl-my-4 form-control is-valid\\" style=\\"resize: none; overflow-y: scroll;\\"></textarea> + <!----> + <!----> + <!----> + <!----> + </div> </div> + <!----> </div> - <!----> <div class=\\"gl-display-flex gl-justify-content-end\\"><button type=\\"reset\\" class=\\"btn gl-mr-3 js-no-auto-disable btn-default btn-md gl-button\\"> <!----> <!----> <span class=\\"gl-button-text\\">Cancel</span></button> <button data-testid=\\"integration-test-and-submit\\" type=\\"button\\" class=\\"btn gl-mr-1 js-no-auto-disable btn-success btn-md gl-button btn-success-secondary\\"> diff --git a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js index 04ecefa7140..051caf0e49d 100644 --- a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js +++ b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js @@ -33,6 +33,9 @@ describe('AlertIntegrationsList', () => { integrations: mockIntegrations, ...props, }, + provide: { + glFeatures: { httpIntegrationsList: true }, + }, stubs: { GlIcon: true, GlButton: true, diff --git a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js index 97a53c20b6b..539ea5676ef 100644 --- a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js +++ b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js @@ -27,6 +27,7 @@ describe('AlertsSettingsFormNew', () => { propsData: { loading: false, canAddIntegration: true, + canManageOpsgenie: true, ...props, }, provide: { diff --git a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js index 4bd881d0460..c24a76f1df0 100644 --- a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js +++ b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js @@ -2,7 +2,7 @@ import VueApollo from 'vue-apollo'; import { mount, createLocalVue } from '@vue/test-utils'; import createMockApollo from 'jest/helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlLoadingIcon, GlAlert } from '@gitlab/ui'; import AlertsSettingsWrapper from '~/alerts_settings/components/alerts_settings_wrapper.vue'; import AlertsSettingsFormOld from '~/alerts_settings/components/alerts_settings_form_old.vue'; import AlertsSettingsFormNew from '~/alerts_settings/components/alerts_settings_form_new.vue'; @@ -21,6 +21,7 @@ import { RESET_INTEGRATION_TOKEN_ERROR, UPDATE_INTEGRATION_ERROR, INTEGRATION_PAYLOAD_TEST_ERROR, + DELETE_INTEGRATION_ERROR, } from '~/alerts_settings/utils/error_messages'; import createFlash from '~/flash'; import { defaultAlertSettingsConfig } from './util'; @@ -59,6 +60,12 @@ describe('AlertsSettingsWrapper', () => { .vm.$emit('delete-integration', { id: integrationToDestroy.id }); } + async function awaitApolloDomMock() { + await wrapper.vm.$nextTick(); // kick off the DOM update + await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises) + await wrapper.vm.$nextTick(); // kick off the DOM update for flash + } + const createComponent = ({ data = {}, provide = {}, loading = false } = {}) => { wrapper = mount(AlertsSettingsWrapper, { data() { @@ -372,12 +379,35 @@ describe('AlertsSettingsWrapper', () => { }); await destroyHttpIntegration(wrapper); - - await wrapper.vm.$nextTick(); // kick off the DOM update - await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises) - await wrapper.vm.$nextTick(); // kick off the DOM update for flash + await awaitApolloDomMock(); expect(createFlash).toHaveBeenCalledWith({ message: 'Houston, we have a problem' }); }); + + it('displays flash if mutation had a non-recoverable error', async () => { + createComponentWithApollo({ + destroyHandler: jest.fn().mockRejectedValue('Error'), + }); + + await destroyHttpIntegration(wrapper); + await awaitApolloDomMock(); + + expect(createFlash).toHaveBeenCalledWith({ + message: DELETE_INTEGRATION_ERROR, + }); + }); + }); + + // TODO: Will be removed in 13.7 as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/273657 + describe('Opsgenie integration', () => { + it.each([true, false])('it shows/hides the alert when opsgenie is %s', active => { + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true }, opsgenie: { active } }, + loading: false, + }); + + expect(wrapper.find(GlAlert).exists()).toBe(active); + }); }); }); diff --git a/spec/frontend/boards/components/board_column_new_spec.js b/spec/frontend/boards/components/board_column_new_spec.js new file mode 100644 index 00000000000..4aafc3a867a --- /dev/null +++ b/spec/frontend/boards/components/board_column_new_spec.js @@ -0,0 +1,72 @@ +import { shallowMount } from '@vue/test-utils'; + +import { listObj } from 'jest/boards/mock_data'; +import BoardColumn from '~/boards/components/board_column_new.vue'; +import List from '~/boards/models/list'; +import { ListType } from '~/boards/constants'; +import { createStore } from '~/boards/stores'; + +describe('Board Column Component', () => { + let wrapper; + let store; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const createComponent = ({ listType = ListType.backlog, collapsed = false } = {}) => { + const boardId = '1'; + + const listMock = { + ...listObj, + list_type: listType, + collapsed, + }; + + if (listType === ListType.assignee) { + delete listMock.label; + listMock.user = {}; + } + + const list = new List({ ...listMock, doNotFetchIssues: true }); + + store = createStore(); + + wrapper = shallowMount(BoardColumn, { + store, + propsData: { + disabled: false, + list, + }, + provide: { + boardId, + }, + }); + }; + + const isExpandable = () => wrapper.classes('is-expandable'); + const isCollapsed = () => wrapper.classes('is-collapsed'); + + describe('Given different list types', () => { + it('is expandable when List Type is `backlog`', () => { + createComponent({ listType: ListType.backlog }); + + expect(isExpandable()).toBe(true); + }); + }); + + describe('expanded / collapsed column', () => { + it('has class is-collapsed when list is collapsed', () => { + createComponent({ collapsed: false }); + + expect(wrapper.vm.list.isExpanded).toBe(true); + }); + + it('does not have class is-collapsed when list is expanded', () => { + createComponent({ collapsed: true }); + + expect(isCollapsed()).toBe(true); + }); + }); +}); diff --git a/spec/frontend/boards/components/board_column_spec.js b/spec/frontend/boards/components/board_column_spec.js index 2a4dbbb989e..ba11225676b 100644 --- a/spec/frontend/boards/components/board_column_spec.js +++ b/spec/frontend/boards/components/board_column_spec.js @@ -78,7 +78,7 @@ describe('Board Column Component', () => { }); }); - describe('expanded / collaped column', () => { + describe('expanded / collapsed column', () => { it('has class is-collapsed when list is collapsed', () => { createComponent({ collapsed: false }); diff --git a/spec/frontend/boards/components/board_list_header_new_spec.js b/spec/frontend/boards/components/board_list_header_new_spec.js new file mode 100644 index 00000000000..80786d82620 --- /dev/null +++ b/spec/frontend/boards/components/board_list_header_new_spec.js @@ -0,0 +1,169 @@ +import Vuex from 'vuex'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; + +import { listObj } from 'jest/boards/mock_data'; +import BoardListHeader from '~/boards/components/board_list_header_new.vue'; +import List from '~/boards/models/list'; +import { ListType } from '~/boards/constants'; + +const localVue = createLocalVue(); + +localVue.use(Vuex); + +describe('Board List Header Component', () => { + let wrapper; + let store; + + const updateListSpy = jest.fn(); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + + localStorage.clear(); + }); + + const createComponent = ({ + listType = ListType.backlog, + collapsed = false, + withLocalStorage = true, + currentUserId = null, + } = {}) => { + const boardId = '1'; + + const listMock = { + ...listObj, + list_type: listType, + collapsed, + }; + + if (listType === ListType.assignee) { + delete listMock.label; + listMock.user = {}; + } + + const list = new List({ ...listMock, doNotFetchIssues: true }); + + if (withLocalStorage) { + localStorage.setItem( + `boards.${boardId}.${list.type}.${list.id}.expanded`, + (!collapsed).toString(), + ); + } + + store = new Vuex.Store({ + state: {}, + actions: { updateList: updateListSpy }, + getters: {}, + }); + + wrapper = shallowMount(BoardListHeader, { + store, + localVue, + propsData: { + disabled: false, + list, + }, + provide: { + boardId, + weightFeatureAvailable: false, + currentUserId, + }, + }); + }; + + const isExpanded = () => wrapper.vm.list.isExpanded; + const isCollapsed = () => !isExpanded(); + + const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' }); + const findCaret = () => wrapper.find('.board-title-caret'); + + describe('Add issue button', () => { + const hasNoAddButton = [ListType.promotion, ListType.blank, ListType.closed]; + const hasAddButton = [ListType.backlog, ListType.label, ListType.milestone, ListType.assignee]; + + it.each(hasNoAddButton)('does not render when List Type is `%s`', listType => { + createComponent({ listType }); + + expect(findAddIssueButton().exists()).toBe(false); + }); + + it.each(hasAddButton)('does render when List Type is `%s`', listType => { + createComponent({ listType }); + + expect(findAddIssueButton().exists()).toBe(true); + }); + + it('has a test for each list type', () => { + createComponent(); + + Object.values(ListType).forEach(value => { + expect([...hasAddButton, ...hasNoAddButton]).toContain(value); + }); + }); + + it('does render when logged out', () => { + createComponent(); + + expect(findAddIssueButton().exists()).toBe(true); + }); + }); + + describe('expanding / collapsing the column', () => { + it('does not collapse when clicking the header', async () => { + createComponent(); + + expect(isCollapsed()).toBe(false); + + wrapper.find('[data-testid="board-list-header"]').trigger('click'); + + await wrapper.vm.$nextTick(); + + expect(isCollapsed()).toBe(false); + }); + + it('collapses expanded Column when clicking the collapse icon', async () => { + createComponent(); + + expect(isExpanded()).toBe(true); + + findCaret().vm.$emit('click'); + + await wrapper.vm.$nextTick(); + + expect(isCollapsed()).toBe(true); + }); + + it('expands collapsed Column when clicking the expand icon', async () => { + createComponent({ collapsed: true }); + + expect(isCollapsed()).toBe(true); + + findCaret().vm.$emit('click'); + + await wrapper.vm.$nextTick(); + + expect(isCollapsed()).toBe(false); + }); + + it("when logged in it calls list update and doesn't set localStorage", async () => { + createComponent({ withLocalStorage: false, currentUserId: 1 }); + + findCaret().vm.$emit('click'); + await wrapper.vm.$nextTick(); + + expect(updateListSpy).toHaveBeenCalledTimes(1); + expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(null); + }); + + it("when logged out it doesn't call list update and sets localStorage", async () => { + createComponent(); + + findCaret().vm.$emit('click'); + await wrapper.vm.$nextTick(); + + expect(updateListSpy).not.toHaveBeenCalled(); + expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(String(isExpanded())); + }); + }); +}); |