Commit b5835ba5 authored by Mireya Andres's avatar Mireya Andres Committed by Peter Hegman

Use gl-drawer for pipeline editor help drawer

This aligns the behavior and styling of the drawer with
GitLab's standards. The drawer can be opened using the
help button in the pipeline editor.

Changelog: changed
parent 6f55625a
<script> <script>
import { GlCard, GlLink, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
...@@ -22,7 +22,6 @@ export default { ...@@ -22,7 +22,6 @@ export default {
), ),
}, },
components: { components: {
GlCard,
GlLink, GlLink,
GlSprintf, GlSprintf,
}, },
...@@ -30,22 +29,20 @@ export default { ...@@ -30,22 +29,20 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-card> <div>
<template #default> <h3 class="gl-font-lg gl-mt-0 gl-mb-5">{{ $options.i18n.title }}</h3>
<h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4> <p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p>
<p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p> <ol class="gl-mb-3">
<ol class="gl-mb-3"> <li v-for="(item, i) in $options.i18n.listItems" :key="`li-${i}`">{{ item }}</li>
<li v-for="(item, i) in $options.i18n.listItems" :key="`li-${i}`">{{ item }}</li> </ol>
</ol> <p class="gl-mb-0">
<p class="gl-mb-0"> <gl-sprintf :message="$options.i18n.note">
<gl-sprintf :message="$options.i18n.note"> <template #link="{ content }">
<template #link="{ content }"> <gl-link :href="runnerHelpPagePath" target="_blank">
<gl-link :href="runnerHelpPagePath" target="_blank"> {{ content }}
{{ content }} </gl-link>
</gl-link> </template>
</template> </gl-sprintf>
</gl-sprintf> </p>
</p> </div>
</template>
</gl-card>
</template> </template>
<script> <script>
import { GlCard, GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
...@@ -13,23 +13,20 @@ export default { ...@@ -13,23 +13,20 @@ export default {
), ),
}, },
components: { components: {
GlCard,
GlSprintf, GlSprintf,
}, },
}; };
</script> </script>
<template> <template>
<gl-card> <div>
<template #default> <h3 class="gl-font-lg gl-mt-0 gl-mb-5">{{ $options.i18n.title }}</h3>
<h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4> <p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p>
<p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p> <p class="gl-mb-0">
<p class="gl-mb-0"> <gl-sprintf :message="$options.i18n.secondParagraph">
<gl-sprintf :message="$options.i18n.secondParagraph"> <template #code="{ content }">
<template #code="{ content }"> <code>{{ content }}</code>
<code>{{ content }}</code> </template>
</template> </gl-sprintf>
</gl-sprintf> </p>
</p> </div>
</template>
</gl-card>
</template> </template>
<script> <script>
import { GlCard, GlLink, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
...@@ -20,7 +20,6 @@ export default { ...@@ -20,7 +20,6 @@ export default {
), ),
}, },
components: { components: {
GlCard,
GlLink, GlLink,
GlSprintf, GlSprintf,
}, },
...@@ -28,48 +27,46 @@ export default { ...@@ -28,48 +27,46 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-card> <div>
<template #default> <h3 class="gl-font-lg gl-mt-0 gl-mb-5">{{ $options.i18n.title }}</h3>
<h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4> <p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p>
<p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p> <ul>
<ul> <li>
<li> <gl-sprintf :message="$options.i18n.browseExamples">
<gl-sprintf :message="$options.i18n.browseExamples"> <template #link="{ content }">
<template #link="{ content }"> <gl-link :href="ciExamplesHelpPagePath" target="_blank">
<gl-link :href="ciExamplesHelpPagePath" target="_blank"> {{ content }}
{{ content }} </gl-link>
</gl-link> </template>
</template> </gl-sprintf>
</gl-sprintf> </li>
</li> <li>
<li> <gl-sprintf :message="$options.i18n.viewSyntaxRef">
<gl-sprintf :message="$options.i18n.viewSyntaxRef"> <template #link="{ content }">
<template #link="{ content }"> <gl-link :href="ymlHelpPagePath" target="_blank">
<gl-link :href="ymlHelpPagePath" target="_blank"> {{ content }}
{{ content }} </gl-link>
</gl-link> </template>
</template> </gl-sprintf>
</gl-sprintf> </li>
</li> <li>
<li> <gl-sprintf :message="$options.i18n.learnMore">
<gl-sprintf :message="$options.i18n.learnMore"> <template #link="{ content }">
<template #link="{ content }"> <gl-link :href="ciHelpPagePath" target="_blank">
<gl-link :href="ciHelpPagePath" target="_blank"> {{ content }}
{{ content }} </gl-link>
</gl-link> </template>
</template> </gl-sprintf>
</gl-sprintf> </li>
</li> <li>
<li> <gl-sprintf :message="$options.i18n.needs">
<gl-sprintf :message="$options.i18n.needs"> <template #link="{ content }">
<template #link="{ content }"> <gl-link :href="needsHelpPagePath" target="_blank">
<gl-link :href="needsHelpPagePath" target="_blank"> {{ content }}
{{ content }} </gl-link>
</gl-link> </template>
</template> </gl-sprintf>
</gl-sprintf> </li>
</li> </ul>
</ul> </div>
</template>
</gl-card>
</template> </template>
<script> <script>
import { GlCard } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
...@@ -9,16 +8,11 @@ export default { ...@@ -9,16 +8,11 @@ export default {
'PipelineEditorTutorial|Use the Visualize and Lint tabs in the Pipeline Editor to visualize your pipeline and check for any errors or warnings before committing your changes.', 'PipelineEditorTutorial|Use the Visualize and Lint tabs in the Pipeline Editor to visualize your pipeline and check for any errors or warnings before committing your changes.',
), ),
}, },
components: {
GlCard,
},
}; };
</script> </script>
<template> <template>
<gl-card> <div>
<template #default> <h3 class="gl-font-lg gl-mt-0 gl-mb-5">{{ $options.i18n.title }}</h3>
<h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4> <p class="gl-mb-0">{{ $options.i18n.firstParagraph }}</p>
<p class="gl-mb-0">{{ $options.i18n.firstParagraph }}</p> </div>
</template>
</gl-card>
</template> </template>
<script> <script>
import { GlButton, GlIcon } from '@gitlab/ui'; import { GlDrawer } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { DRAWER_EXPANDED_KEY } from '../../constants';
import FirstPipelineCard from './cards/first_pipeline_card.vue'; import FirstPipelineCard from './cards/first_pipeline_card.vue';
import GettingStartedCard from './cards/getting_started_card.vue'; import GettingStartedCard from './cards/getting_started_card.vue';
import PipelineConfigReferenceCard from './cards/pipeline_config_reference_card.vue'; import PipelineConfigReferenceCard from './cards/pipeline_config_reference_card.vue';
import VisualizeAndLintCard from './cards/visualize_and_lint_card.vue'; import VisualizeAndLintCard from './cards/visualize_and_lint_card.vue';
const DRAWER_CARD_STYLES = ['gl-border-bottom-0', 'gl-pt-6!', 'gl-pb-0!', 'gl-line-height-20'];
export default { export default {
width: { DRAWER_CARD_STYLES,
expanded: '482px',
collapsed: '58px',
},
i18n: { i18n: {
toggleTxt: __('Collapse'), title: __('Help'),
}, },
localDrawerKey: DRAWER_EXPANDED_KEY,
components: { components: {
FirstPipelineCard, FirstPipelineCard,
GettingStartedCard, GettingStartedCard,
GlButton, GlDrawer,
GlIcon,
LocalStorageSync,
PipelineConfigReferenceCard, PipelineConfigReferenceCard,
VisualizeAndLintCard, VisualizeAndLintCard,
}, },
data() { props: {
return { isVisible: {
isExpanded: false, type: Boolean,
topPosition: 0, required: false,
}; default: false,
},
}, },
computed: { computed: {
buttonIconName() { drawerCardStyles() {
return this.isExpanded ? 'chevron-double-lg-right' : 'chevron-double-lg-left'; return '';
},
buttonClass() {
return this.isExpanded ? 'gl-justify-content-end!' : '';
}, },
rootStyle() { drawerHeightOffset() {
const { expanded, collapsed } = this.$options.width; const wrapperEl = document.querySelector('.content-wrapper');
const top = this.topPosition; return wrapperEl ? `${wrapperEl.offsetTop}px` : '';
const style = { top: `${top}px` };
return this.isExpanded ? { ...style, width: expanded } : { ...style, width: collapsed };
}, },
}, },
mounted() {
this.setTopPosition();
},
methods: { methods: {
setTopPosition() { closeDrawer() {
const navbarEl = document.querySelector('.js-navbar'); this.$emit('close-drawer');
if (navbarEl) {
this.topPosition = navbarEl.getBoundingClientRect().bottom;
}
},
toggleDrawer() {
this.isExpanded = !this.isExpanded;
}, },
}, },
}; };
</script> </script>
<template> <template>
<local-storage-sync v-model="isExpanded" :storage-key="$options.localDrawerKey" as-json> <gl-drawer
<aside :header-height="drawerHeightOffset"
aria-live="polite" :open="isVisible"
class="gl-fixed gl-right-0 gl-bg-gray-10 gl-shadow-drawer gl-transition-property-width gl-transition-duration-medium gl-border-l-solid gl-border-1 gl-border-gray-100 gl-h-full gl-z-index-200 gl-overflow-y-auto" :z-index="200"
:style="rootStyle" @close="closeDrawer"
> >
<gl-button <template #title>
category="tertiary" <h2 class="gl-m-0 gl-font-lg">{{ $options.i18n.title }}</h2>
class="gl-w-full gl-h-9 gl-rounded-0! gl-border-none! gl-border-b-solid! gl-border-1! gl-border-gray-100 gl-text-decoration-none! gl-outline-0! gl-display-flex" </template>
:class="buttonClass" <getting-started-card :class="$options.DRAWER_CARD_STYLES" />
:title="__('Toggle sidebar')" <first-pipeline-card :class="$options.DRAWER_CARD_STYLES" />
data-qa-selector="toggle_sidebar_collapse_button" <visualize-and-lint-card :class="$options.DRAWER_CARD_STYLES" />
@click="toggleDrawer" <pipeline-config-reference-card :class="$options.DRAWER_CARD_STYLES" />
> </gl-drawer>
<span v-if="isExpanded" class="gl-text-gray-500 gl-mr-3" data-testid="collapse-text">
{{ __('Collapse') }}
</span>
<gl-icon data-testid="toggle-icon" :name="buttonIconName" />
</gl-button>
<div
v-if="isExpanded"
class="gl-h-full gl-p-5"
data-testid="drawer-content"
data-qa-selector="drawer_content"
>
<getting-started-card class="gl-mb-4" />
<first-pipeline-card class="gl-mb-4" />
<visualize-and-lint-card class="gl-mb-4" />
<pipeline-config-reference-card />
<div class="gl-h-13"></div>
</div>
</aside>
</local-storage-sync>
</template> </template>
...@@ -7,13 +7,23 @@ import { pipelineEditorTrackingOptions, TEMPLATE_REPOSITORY_URL } from '../../co ...@@ -7,13 +7,23 @@ import { pipelineEditorTrackingOptions, TEMPLATE_REPOSITORY_URL } from '../../co
export default { export default {
i18n: { i18n: {
browseTemplates: __('Browse templates'), browseTemplates: __('Browse templates'),
help: __('Help'),
}, },
TEMPLATE_REPOSITORY_URL, TEMPLATE_REPOSITORY_URL,
components: { components: {
GlButton, GlButton,
}, },
mixins: [Tracking.mixin()], mixins: [Tracking.mixin()],
props: {
showDrawer: {
type: Boolean,
required: true,
},
},
methods: { methods: {
toggleDrawer() {
this.$emit(this.showDrawer ? 'close-drawer' : 'open-drawer');
},
trackTemplateBrowsing() { trackTemplateBrowsing() {
const { label, actions } = pipelineEditorTrackingOptions; const { label, actions } = pipelineEditorTrackingOptions;
...@@ -30,9 +40,20 @@ export default { ...@@ -30,9 +40,20 @@ export default {
size="small" size="small"
icon="external-link" icon="external-link"
target="_blank" target="_blank"
data-testid="template-repo-link"
data-qa-selector="template_repo_link"
@click="trackTemplateBrowsing" @click="trackTemplateBrowsing"
> >
{{ $options.i18n.browseTemplates }} {{ $options.i18n.browseTemplates }}
</gl-button> </gl-button>
<gl-button
icon="information-o"
size="small"
data-testid="drawer-toggle"
data-qa-selector="drawer_toggle"
@click="toggleDrawer"
>
{{ $options.i18n.help }}
</gl-button>
</div> </div>
</template> </template>
...@@ -86,6 +86,10 @@ export default { ...@@ -86,6 +86,10 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
showDrawer: {
type: Boolean,
required: true,
},
}, },
apollo: { apollo: {
appStatus: { appStatus: {
...@@ -157,7 +161,7 @@ export default { ...@@ -157,7 +161,7 @@ export default {
@click="setCurrentTab($options.tabConstants.CREATE_TAB)" @click="setCurrentTab($options.tabConstants.CREATE_TAB)"
> >
<walkthrough-popover v-if="isNewCiConfigFile" v-on="$listeners" /> <walkthrough-popover v-if="isNewCiConfigFile" v-on="$listeners" />
<ci-editor-header /> <ci-editor-header :show-drawer="showDrawer" v-on="$listeners" />
<text-editor :commit-sha="commitSha" :value="ciFileContent" v-on="$listeners" /> <text-editor :commit-sha="commitSha" :value="ciFileContent" v-on="$listeners" />
</editor-tab> </editor-tab>
<editor-tab <editor-tab
......
...@@ -45,8 +45,6 @@ export const TAB_QUERY_PARAM = 'tab'; ...@@ -45,8 +45,6 @@ export const TAB_QUERY_PARAM = 'tab';
export const COMMIT_ACTION_CREATE = 'CREATE'; export const COMMIT_ACTION_CREATE = 'CREATE';
export const COMMIT_ACTION_UPDATE = 'UPDATE'; export const COMMIT_ACTION_UPDATE = 'UPDATE';
export const DRAWER_EXPANDED_KEY = 'pipeline_editor_drawer_expanded';
export const BRANCH_PAGINATION_LIMIT = 20; export const BRANCH_PAGINATION_LIMIT = 20;
export const BRANCH_SEARCH_DEBOUNCE = '500'; export const BRANCH_SEARCH_DEBOUNCE = '500';
export const SOURCE_EDITOR_DEBOUNCE = 500; export const SOURCE_EDITOR_DEBOUNCE = 500;
......
...@@ -388,7 +388,7 @@ export default { ...@@ -388,7 +388,7 @@ export default {
@createEmptyConfigFile="setNewEmptyCiConfigFile" @createEmptyConfigFile="setNewEmptyCiConfigFile"
@refetchContent="refetchContent" @refetchContent="refetchContent"
/> />
<div v-else class="gl-pr-10"> <div v-else>
<pipeline-editor-messages <pipeline-editor-messages
:failure-type="failureType" :failure-type="failureType"
:failure-reasons="failureReasons" :failure-reasons="failureReasons"
......
...@@ -60,6 +60,7 @@ export default { ...@@ -60,6 +60,7 @@ export default {
currentTab: CREATE_TAB, currentTab: CREATE_TAB,
scrollToCommitForm: false, scrollToCommitForm: false,
shouldLoadNewBranch: false, shouldLoadNewBranch: false,
showDrawer: false,
showSwitchBranchModal: false, showSwitchBranchModal: false,
}; };
}, },
...@@ -72,9 +73,15 @@ export default { ...@@ -72,9 +73,15 @@ export default {
closeBranchModal() { closeBranchModal() {
this.showSwitchBranchModal = false; this.showSwitchBranchModal = false;
}, },
closeDrawer() {
this.showDrawer = false;
},
handleConfirmSwitchBranch() { handleConfirmSwitchBranch() {
this.showSwitchBranchModal = true; this.showSwitchBranchModal = true;
}, },
openDrawer() {
this.showDrawer = true;
},
switchBranch() { switchBranch() {
this.showSwitchBranchModal = false; this.showSwitchBranchModal = false;
this.shouldLoadNewBranch = true; this.shouldLoadNewBranch = true;
...@@ -122,7 +129,10 @@ export default { ...@@ -122,7 +129,10 @@ export default {
:ci-file-content="ciFileContent" :ci-file-content="ciFileContent"
:commit-sha="commitSha" :commit-sha="commitSha"
:is-new-ci-config-file="isNewCiConfigFile" :is-new-ci-config-file="isNewCiConfigFile"
:show-drawer="showDrawer"
v-on="$listeners" v-on="$listeners"
@open-drawer="openDrawer"
@close-drawer="closeDrawer"
@set-current-tab="setCurrentTab" @set-current-tab="setCurrentTab"
@walkthrough-popover-cta-clicked="setScrollToCommitForm" @walkthrough-popover-cta-clicked="setScrollToCommitForm"
/> />
...@@ -137,6 +147,10 @@ export default { ...@@ -137,6 +147,10 @@ export default {
@scrolled-to-commit-form="setScrollToCommitForm(false)" @scrolled-to-commit-form="setScrollToCommitForm(false)"
v-on="$listeners" v-on="$listeners"
/> />
<pipeline-editor-drawer /> <pipeline-editor-drawer
:is-visible="showDrawer"
v-on="$listeners"
@close-drawer="closeDrawer"
/>
</div> </div>
</template> </template>
...@@ -15,9 +15,9 @@ module QA ...@@ -15,9 +15,9 @@ module QA
element :target_branch_field, required: true element :target_branch_field, required: true
end end
view 'app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue' do view 'app/assets/javascripts/pipeline_editor/components/editor/ci_editor_header.vue' do
element :toggle_sidebar_collapse_button element :drawer_toggle, required: true
element :drawer_content element :template_repo_link, required: true
end end
view 'app/assets/javascripts/vue_shared/components/source_editor.vue' do view 'app/assets/javascripts/vue_shared/components/source_editor.vue' do
...@@ -46,13 +46,6 @@ module QA ...@@ -46,13 +46,6 @@ module QA
element :file_editor_container element :file_editor_container
end end
def initialize
super
wait_for_requests
close_toggle_sidebar
end
def open_branch_selector_dropdown def open_branch_selector_dropdown
click_element(:branch_selector_button) click_element(:branch_selector_button)
end end
...@@ -148,15 +141,6 @@ module QA ...@@ -148,15 +141,6 @@ module QA
find('.nav-item', text: name).click find('.nav-item', text: name).click
end end
end end
# If the page thinks user has never opened pipeline editor before
# It will expand pipeline editor sidebar by default
# Collapse the sidebar if it is expanded
def close_toggle_sidebar
return unless has_element?(:drawer_content)
click_element(:toggle_sidebar_collapse_button)
end
end end
end end
end end
......
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { GlDrawer } from '@gitlab/ui';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue';
import GettingStartedCard from '~/pipeline_editor/components/drawer/cards/getting_started_card.vue';
import PipelineConfigReferenceCard from '~/pipeline_editor/components/drawer/cards/pipeline_config_reference_card.vue';
import VisualizeAndLintCard from '~/pipeline_editor/components/drawer/cards/visualize_and_lint_card.vue';
import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue'; import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue';
import { DRAWER_EXPANDED_KEY } from '~/pipeline_editor/constants';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
describe('Pipeline editor drawer', () => { describe('Pipeline editor drawer', () => {
useLocalStorageSpy();
let wrapper; let wrapper;
const findDrawer = () => wrapper.findComponent(GlDrawer);
const createComponent = () => { const createComponent = () => {
wrapper = shallowMount(PipelineEditorDrawer, { wrapper = shallowMount(PipelineEditorDrawer);
stubs: { LocalStorageSync },
});
}; };
const findFirstPipelineCard = () => wrapper.findComponent(FirstPipelineCard);
const findGettingStartedCard = () => wrapper.findComponent(GettingStartedCard);
const findPipelineConfigReferenceCard = () => wrapper.findComponent(PipelineConfigReferenceCard);
const findToggleBtn = () => wrapper.findComponent(GlButton);
const findVisualizeAndLintCard = () => wrapper.findComponent(VisualizeAndLintCard);
const findArrowIcon = () => wrapper.find('[data-testid="toggle-icon"]');
const findCollapseText = () => wrapper.find('[data-testid="collapse-text"]');
const findDrawerContent = () => wrapper.find('[data-testid="drawer-content"]');
const clickToggleBtn = async () => findToggleBtn().vm.$emit('click');
const originalObjects = [];
beforeEach(() => {
originalObjects.push(window.gon, window.gl);
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
localStorage.clear();
[window.gon, window.gl] = originalObjects;
});
describe('default expanded state', () => {
it('sets the drawer to be closed by default', async () => {
createComponent();
expect(findDrawerContent().exists()).toBe(false);
});
});
describe('when the drawer is collapsed', () => {
beforeEach(async () => {
createComponent();
});
it('shows the left facing arrow icon', () => {
expect(findArrowIcon().props('name')).toBe('chevron-double-lg-left');
});
it('does not show the collapse text', () => {
expect(findCollapseText().exists()).toBe(false);
});
it('does not show the drawer content', () => {
expect(findDrawerContent().exists()).toBe(false);
});
it('can open the drawer by clicking on the toggle button', async () => {
expect(findDrawerContent().exists()).toBe(false);
await clickToggleBtn();
expect(findDrawerContent().exists()).toBe(true);
});
});
describe('when the drawer is expanded', () => {
beforeEach(async () => {
createComponent();
await clickToggleBtn();
});
it('shows the right facing arrow icon', () => {
expect(findArrowIcon().props('name')).toBe('chevron-double-lg-right');
});
it('shows the collapse text', () => {
expect(findCollapseText().exists()).toBe(true);
});
it('shows the drawer content', () => {
expect(findDrawerContent().exists()).toBe(true);
});
it('shows all the introduction cards', () => {
expect(findFirstPipelineCard().exists()).toBe(true);
expect(findGettingStartedCard().exists()).toBe(true);
expect(findPipelineConfigReferenceCard().exists()).toBe(true);
expect(findVisualizeAndLintCard().exists()).toBe(true);
});
it('can close the drawer by clicking on the toggle button', async () => {
expect(findDrawerContent().exists()).toBe(true);
await clickToggleBtn();
expect(findDrawerContent().exists()).toBe(false);
});
}); });
describe('local storage', () => { it('emits close event when closing the drawer', () => {
it('saves the drawer expanded value to local storage', async () => { createComponent();
localStorage.setItem(DRAWER_EXPANDED_KEY, 'false');
createComponent();
await clickToggleBtn();
expect(localStorage.setItem.mock.calls).toEqual([
[DRAWER_EXPANDED_KEY, 'false'],
[DRAWER_EXPANDED_KEY, 'true'],
]);
});
it('loads the drawer collapsed when local storage is set to `false`, ', async () => {
localStorage.setItem(DRAWER_EXPANDED_KEY, false);
createComponent();
await nextTick();
expect(findDrawerContent().exists()).toBe(false);
});
it('loads the drawer expanded when local storage is set to `true`, ', async () => { expect(wrapper.emitted('close-drawer')).toBeUndefined();
localStorage.setItem(DRAWER_EXPANDED_KEY, true);
createComponent();
await nextTick(); findDrawer().vm.$emit('close');
expect(findDrawerContent().exists()).toBe(true); expect(wrapper.emitted('close-drawer')).toHaveLength(1);
});
}); });
}); });
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import CiEditorHeader from '~/pipeline_editor/components/editor/ci_editor_header.vue'; import CiEditorHeader from '~/pipeline_editor/components/editor/ci_editor_header.vue';
import { import {
...@@ -11,11 +11,18 @@ describe('CI Editor Header', () => { ...@@ -11,11 +11,18 @@ describe('CI Editor Header', () => {
let wrapper; let wrapper;
let trackingSpy = null; let trackingSpy = null;
const createComponent = () => { const createComponent = ({ showDrawer = false } = {}) => {
wrapper = shallowMount(CiEditorHeader, {}); wrapper = extendedWrapper(
shallowMount(CiEditorHeader, {
propsData: {
showDrawer,
},
}),
);
}; };
const findLinkBtn = () => wrapper.findComponent(GlButton); const findLinkBtn = () => wrapper.findByTestId('template-repo-link');
const findHelpBtn = () => wrapper.findByTestId('drawer-toggle');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -50,4 +57,42 @@ describe('CI Editor Header', () => { ...@@ -50,4 +57,42 @@ describe('CI Editor Header', () => {
}); });
}); });
}); });
describe('help button', () => {
beforeEach(() => {
createComponent();
});
it('finds the help button', () => {
expect(findHelpBtn().exists()).toBe(true);
});
it('has the information-o icon', () => {
expect(findHelpBtn().props('icon')).toBe('information-o');
});
describe('when pipeline editor drawer is closed', () => {
it('emits open drawer event when clicked', () => {
createComponent({ showDrawer: false });
expect(wrapper.emitted('open-drawer')).toBeUndefined();
findHelpBtn().vm.$emit('click');
expect(wrapper.emitted('open-drawer')).toHaveLength(1);
});
});
describe('when pipeline editor drawer is open', () => {
it('emits close drawer event when clicked', () => {
createComponent({ showDrawer: true });
expect(wrapper.emitted('close-drawer')).toBeUndefined();
findHelpBtn().vm.$emit('click');
expect(wrapper.emitted('close-drawer')).toHaveLength(1);
});
});
});
}); });
...@@ -40,6 +40,7 @@ describe('Pipeline editor tabs component', () => { ...@@ -40,6 +40,7 @@ describe('Pipeline editor tabs component', () => {
ciConfigData: mockLintResponse, ciConfigData: mockLintResponse,
ciFileContent: mockCiYml, ciFileContent: mockCiYml,
isNewCiConfigFile: true, isNewCiConfigFile: true,
showDrawer: false,
...props, ...props,
}, },
data() { data() {
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { GlModal } from '@gitlab/ui'; import { GlButton, GlDrawer, GlModal } from '@gitlab/ui';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import CiEditorHeader from '~/pipeline_editor/components/editor/ci_editor_header.vue';
import CommitSection from '~/pipeline_editor/components/commit/commit_section.vue'; import CommitSection from '~/pipeline_editor/components/commit/commit_section.vue';
import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue'; import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue';
import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue'; import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue';
...@@ -18,24 +20,26 @@ describe('Pipeline editor home wrapper', () => { ...@@ -18,24 +20,26 @@ describe('Pipeline editor home wrapper', () => {
let wrapper; let wrapper;
const createComponent = ({ props = {}, glFeatures = {}, data = {}, stubs = {} } = {}) => { const createComponent = ({ props = {}, glFeatures = {}, data = {}, stubs = {} } = {}) => {
wrapper = shallowMount(PipelineEditorHome, { wrapper = extendedWrapper(
data: () => data, shallowMount(PipelineEditorHome, {
propsData: { data: () => data,
ciConfigData: mockLintResponse, propsData: {
ciFileContent: mockCiYml, ciConfigData: mockLintResponse,
isCiConfigDataLoading: false, ciFileContent: mockCiYml,
isNewCiConfigFile: false, isCiConfigDataLoading: false,
...props, isNewCiConfigFile: false,
}, ...props,
provide: {
projectFullPath: '',
totalBranches: 19,
glFeatures: {
...glFeatures,
}, },
}, provide: {
stubs, projectFullPath: '',
}); totalBranches: 19,
glFeatures: {
...glFeatures,
},
},
stubs,
}),
);
}; };
const findBranchSwitcher = () => wrapper.findComponent(BranchSwitcher); const findBranchSwitcher = () => wrapper.findComponent(BranchSwitcher);
...@@ -45,6 +49,7 @@ describe('Pipeline editor home wrapper', () => { ...@@ -45,6 +49,7 @@ describe('Pipeline editor home wrapper', () => {
const findPipelineEditorDrawer = () => wrapper.findComponent(PipelineEditorDrawer); const findPipelineEditorDrawer = () => wrapper.findComponent(PipelineEditorDrawer);
const findPipelineEditorHeader = () => wrapper.findComponent(PipelineEditorHeader); const findPipelineEditorHeader = () => wrapper.findComponent(PipelineEditorHeader);
const findPipelineEditorTabs = () => wrapper.findComponent(PipelineEditorTabs); const findPipelineEditorTabs = () => wrapper.findComponent(PipelineEditorTabs);
const findHelpBtn = () => wrapper.findByTestId('drawer-toggle');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -70,10 +75,6 @@ describe('Pipeline editor home wrapper', () => { ...@@ -70,10 +75,6 @@ describe('Pipeline editor home wrapper', () => {
it('shows the commit section by default', () => { it('shows the commit section by default', () => {
expect(findCommitSection().exists()).toBe(true); expect(findCommitSection().exists()).toBe(true);
}); });
it('show the pipeline drawer', () => {
expect(findPipelineEditorDrawer().exists()).toBe(true);
});
}); });
describe('modal when switching branch', () => { describe('modal when switching branch', () => {
...@@ -175,4 +176,58 @@ describe('Pipeline editor home wrapper', () => { ...@@ -175,4 +176,58 @@ describe('Pipeline editor home wrapper', () => {
}); });
}); });
}); });
describe('help drawer', () => {
const clickHelpBtn = async () => {
findHelpBtn().vm.$emit('click');
await nextTick();
};
it('hides the drawer by default', () => {
createComponent();
expect(findPipelineEditorDrawer().props('isVisible')).toBe(false);
});
it('toggles the drawer on button click', async () => {
createComponent({
stubs: {
CiEditorHeader,
GlButton,
GlDrawer,
PipelineEditorTabs,
PipelineEditorDrawer,
},
});
await clickHelpBtn();
expect(findPipelineEditorDrawer().props('isVisible')).toBe(true);
await clickHelpBtn();
expect(findPipelineEditorDrawer().props('isVisible')).toBe(false);
});
it("closes the drawer through the drawer's close button", async () => {
createComponent({
stubs: {
CiEditorHeader,
GlButton,
GlDrawer,
PipelineEditorTabs,
PipelineEditorDrawer,
},
});
await clickHelpBtn();
expect(findPipelineEditorDrawer().props('isVisible')).toBe(true);
findPipelineEditorDrawer().find(GlDrawer).vm.$emit('close');
await nextTick();
expect(findPipelineEditorDrawer().props('isVisible')).toBe(false);
});
});
}); });
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