Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/pipeline_wizard/components/wrapper_spec.js')
-rw-r--r--spec/frontend/pipeline_wizard/components/wrapper_spec.js250
1 files changed, 250 insertions, 0 deletions
diff --git a/spec/frontend/pipeline_wizard/components/wrapper_spec.js b/spec/frontend/pipeline_wizard/components/wrapper_spec.js
new file mode 100644
index 00000000000..bd1679baf48
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/wrapper_spec.js
@@ -0,0 +1,250 @@
+import { Document, parseDocument } from 'yaml';
+import { GlProgressBar } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import PipelineWizardWrapper, { i18n } from '~/pipeline_wizard/components/wrapper.vue';
+import WizardStep from '~/pipeline_wizard/components/step.vue';
+import CommitStep from '~/pipeline_wizard/components/commit.vue';
+import YamlEditor from '~/pipeline_wizard/components/editor.vue';
+import { sprintf } from '~/locale';
+import { steps as stepsYaml } from '../mock/yaml';
+
+describe('Pipeline Wizard - wrapper.vue', () => {
+ let wrapper;
+ const steps = parseDocument(stepsYaml).toJS();
+
+ const getAsYamlNode = (value) => new Document(value).contents;
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(PipelineWizardWrapper, {
+ propsData: {
+ projectPath: '/user/repo',
+ defaultBranch: 'main',
+ filename: '.gitlab-ci.yml',
+ steps: getAsYamlNode(steps),
+ ...props,
+ },
+ });
+ };
+ const getEditorContent = () => {
+ return wrapper.getComponent(YamlEditor).attributes().doc.toString();
+ };
+ const getStepWrapper = () => wrapper.getComponent(WizardStep);
+ const getGlProgressBarWrapper = () => wrapper.getComponent(GlProgressBar);
+
+ describe('display', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('shows the steps', () => {
+ createComponent();
+
+ expect(getStepWrapper().exists()).toBe(true);
+ });
+
+ it('shows the progress bar', () => {
+ createComponent();
+
+ const expectedMessage = sprintf(i18n.stepNofN, {
+ currentStep: 1,
+ stepCount: 3,
+ });
+
+ expect(wrapper.findByTestId('step-count').text()).toBe(expectedMessage);
+ expect(getGlProgressBarWrapper().exists()).toBe(true);
+ });
+
+ it('shows the editor', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(YamlEditor).exists()).toBe(true);
+ });
+
+ it('shows the editor header with the default filename', () => {
+ createComponent();
+
+ const expectedMessage = sprintf(i18n.draft, {
+ filename: '.gitlab-ci.yml',
+ });
+
+ expect(wrapper.findByTestId('editor-header').text()).toBe(expectedMessage);
+ });
+
+ it('shows the editor header with a custom filename', async () => {
+ const filename = 'my-file.yml';
+ createComponent({
+ filename,
+ });
+
+ const expectedMessage = sprintf(i18n.draft, {
+ filename,
+ });
+
+ expect(wrapper.findByTestId('editor-header').text()).toBe(expectedMessage);
+ });
+ });
+
+ describe('steps', () => {
+ const totalSteps = steps.length + 1;
+
+ // **Note** on `expectProgressBarValue`
+ // Why are we expecting 50% here and not 66% or even 100%?
+ // The reason is mostly a UX thing.
+ // First, we count the commit step as an extra step, so that would
+ // be 66% by now (2 of 3).
+ // But then we add yet another one to the calc, because when we
+ // arrived on the second step's page, it's not *completed* (which is
+ // what the progress bar indicates). So in that case we're at 33%.
+ // Lastly, we want to start out with the progress bar not at zero,
+ // because UX research indicates that makes a process like this less
+ // intimidating, so we're always adding one step to the value bar
+ // (but not to the step counter. Now we're back at 50%.
+ describe.each`
+ step | navigationEventChain | expectStepNumber | expectCommitStepShown | expectStepDef | expectProgressBarValue
+ ${'initial step'} | ${[]} | ${1} | ${false} | ${steps[0]} | ${25}
+ ${'second step'} | ${['next']} | ${2} | ${false} | ${steps[1]} | ${50}
+ ${'commit step'} | ${['next', 'next']} | ${3} | ${true} | ${null} | ${75}
+ ${'stepping back'} | ${['next', 'back']} | ${1} | ${false} | ${steps[0]} | ${25}
+ ${'clicking next>next>back'} | ${['next', 'next', 'back']} | ${2} | ${false} | ${steps[1]} | ${50}
+ ${'clicking all the way through and back'} | ${['next', 'next', 'back', 'back']} | ${1} | ${false} | ${steps[0]} | ${25}
+ `(
+ '$step',
+ ({
+ navigationEventChain,
+ expectStepNumber,
+ expectCommitStepShown,
+ expectStepDef,
+ expectProgressBarValue,
+ }) => {
+ beforeAll(async () => {
+ createComponent();
+ for (const emittedValue of navigationEventChain) {
+ wrapper.findComponent({ ref: 'step' }).vm.$emit(emittedValue);
+ // We have to wait for the next step to be mounted
+ // before we can emit the next event, so we have to await
+ // inside the loop.
+ // eslint-disable-next-line no-await-in-loop
+ await nextTick();
+ }
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ if (expectCommitStepShown) {
+ it('does not show the step wrapper', async () => {
+ expect(wrapper.findComponent(WizardStep).exists()).toBe(false);
+ });
+
+ it('shows the commit step page', () => {
+ expect(wrapper.findComponent(CommitStep).exists()).toBe(true);
+ });
+ } else {
+ it('passes the correct step config to the step component', async () => {
+ expect(getStepWrapper().props('inputs')).toMatchObject(expectStepDef.inputs);
+ });
+
+ it('does not show the commit step page', () => {
+ expect(wrapper.findComponent(CommitStep).exists()).toBe(false);
+ });
+ }
+
+ it('updates the progress bar', () => {
+ expect(getGlProgressBarWrapper().attributes('value')).toBe(`${expectProgressBarValue}`);
+ });
+
+ it('updates the step number', () => {
+ const expectedMessage = sprintf(i18n.stepNofN, {
+ currentStep: expectStepNumber,
+ stepCount: totalSteps,
+ });
+
+ expect(wrapper.findByTestId('step-count').text()).toBe(expectedMessage);
+ });
+ },
+ );
+ });
+
+ describe('editor overlay', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('initially shows a placeholder', async () => {
+ const editorContent = getEditorContent();
+
+ await nextTick();
+
+ expect(editorContent).toBe('foo: $FOO\nbar: $BAR\n');
+ });
+
+ it('shows an overlay with help text after setup', () => {
+ expect(wrapper.findByTestId('placeholder-overlay').exists()).toBe(true);
+ expect(wrapper.findByTestId('filename').text()).toBe('.gitlab-ci.yml');
+ expect(wrapper.findByTestId('description').text()).toBe(i18n.overlayMessage);
+ });
+
+ it('does not show overlay when content has changed', async () => {
+ const newCompiledDoc = new Document({ faa: 'bur' });
+
+ await getStepWrapper().vm.$emit('update:compiled', newCompiledDoc);
+ await nextTick();
+
+ const overlay = wrapper.findByTestId('placeholder-overlay');
+
+ expect(overlay.exists()).toBe(false);
+ });
+ });
+
+ describe('editor updates', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('editor reflects changes', async () => {
+ const newCompiledDoc = new Document({ faa: 'bur' });
+ await getStepWrapper().vm.$emit('update:compiled', newCompiledDoc);
+
+ expect(getEditorContent()).toBe(newCompiledDoc.toString());
+ });
+ });
+
+ describe('line highlights', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('highlight requests by the step get passed on to the editor', async () => {
+ const highlight = 'foo';
+
+ await getStepWrapper().vm.$emit('update:highlight', highlight);
+
+ expect(wrapper.getComponent(YamlEditor).props('highlight')).toBe(highlight);
+ });
+
+ it('removes the highlight when clicking through to the commit step', async () => {
+ // Simulate clicking through all steps until the last one
+ await Promise.all(
+ steps.map(async () => {
+ await getStepWrapper().vm.$emit('next');
+ await nextTick();
+ }),
+ );
+
+ expect(wrapper.getComponent(YamlEditor).props('highlight')).toBe(null);
+ });
+ });
+});