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/ide/components/jobs')
-rw-r--r--spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap60
-rw-r--r--spec/frontend/ide/components/jobs/detail/description_spec.js35
-rw-r--r--spec/frontend/ide/components/jobs/detail_spec.js162
-rw-r--r--spec/frontend/ide/components/jobs/item_spec.js30
-rw-r--r--spec/frontend/ide/components/jobs/stage_spec.js9
5 files changed, 103 insertions, 193 deletions
diff --git a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
deleted file mode 100644
index 45444166a50..00000000000
--- a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
+++ /dev/null
@@ -1,60 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`IDE pipeline stage renders stage details & icon 1`] = `
-<div
- class="ide-stage card gl-mt-3"
->
- <div
- class="card-header"
- >
- <ci-icon-stub
- cssclasses=""
- size="24"
- status="[object Object]"
- />
-
- <strong
- class="gl-ml-3 text-truncate"
- data-container="body"
- >
-
- build
-
- </strong>
-
- <div
- class="gl-mr-3 gl-ml-2"
- >
- <gl-badge-stub
- size="md"
- variant="muted"
- >
- 4
- </gl-badge-stub>
- </div>
-
- <gl-icon-stub
- class="ide-stage-collapse-icon"
- name="chevron-lg-down"
- size="16"
- />
- </div>
-
- <div
- class="card-body p-0"
- >
- <item-stub
- job="[object Object]"
- />
- <item-stub
- job="[object Object]"
- />
- <item-stub
- job="[object Object]"
- />
- <item-stub
- job="[object Object]"
- />
- </div>
-</div>
-`;
diff --git a/spec/frontend/ide/components/jobs/detail/description_spec.js b/spec/frontend/ide/components/jobs/detail/description_spec.js
index 128ccff6568..629c4424314 100644
--- a/spec/frontend/ide/components/jobs/detail/description_spec.js
+++ b/spec/frontend/ide/components/jobs/detail/description_spec.js
@@ -1,44 +1,43 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
+import { mount } from '@vue/test-utils';
+import { GlIcon } from '@gitlab/ui';
import Description from '~/ide/components/jobs/detail/description.vue';
import { jobs } from '../../../mock_data';
describe('IDE job description', () => {
- const Component = Vue.extend(Description);
- let vm;
+ let wrapper;
beforeEach(() => {
- vm = mountComponent(Component, {
- job: jobs[0],
+ wrapper = mount(Description, {
+ propsData: {
+ job: jobs[0],
+ },
});
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
it('renders job details', () => {
- expect(vm.$el.textContent).toContain('#1');
- expect(vm.$el.textContent).toContain('test');
+ expect(wrapper.text()).toContain('#1');
+ expect(wrapper.text()).toContain('test');
});
it('renders CI icon', () => {
- expect(
- vm.$el.querySelector('.ci-status-icon [data-testid="status_success_borderless-icon"]'),
- ).not.toBe(null);
+ expect(wrapper.find('.ci-status-icon').findComponent(GlIcon).exists()).toBe(true);
});
it('renders a borderless CI icon', () => {
- expect(
- vm.$el.querySelector('.borderless [data-testid="status_success_borderless-icon"]'),
- ).not.toBe(null);
+ expect(wrapper.find('.borderless').findComponent(GlIcon).exists()).toBe(true);
});
it('renders bridge job details without the job link', () => {
- vm = mountComponent(Component, {
- job: { ...jobs[0], path: undefined },
+ wrapper = mount(Description, {
+ propsData: {
+ job: { ...jobs[0], path: undefined },
+ },
});
- expect(vm.$el.querySelector('[data-testid="description-detail-link"]')).toBe(null);
+ expect(wrapper.find('[data-testid="description-detail-link"]').exists()).toBe(false);
});
});
diff --git a/spec/frontend/ide/components/jobs/detail_spec.js b/spec/frontend/ide/components/jobs/detail_spec.js
index 9122471d421..bf2be3aa595 100644
--- a/spec/frontend/ide/components/jobs/detail_spec.js
+++ b/spec/frontend/ide/components/jobs/detail_spec.js
@@ -1,15 +1,17 @@
-import Vue, { nextTick } from 'vue';
+import { nextTick } from 'vue';
+import { mount } from '@vue/test-utils';
+
import { TEST_HOST } from 'helpers/test_constants';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import JobDetail from '~/ide/components/jobs/detail.vue';
import { createStore } from '~/ide/stores';
import { jobs } from '../../mock_data';
describe('IDE jobs detail view', () => {
- let vm;
+ let wrapper;
+ let store;
const createComponent = () => {
- const store = createStore();
+ store = createStore();
store.state.pipelines.detailJob = {
...jobs[0],
@@ -18,163 +20,129 @@ describe('IDE jobs detail view', () => {
rawPath: `${TEST_HOST}/raw`,
};
- return createComponentWithStore(Vue.extend(JobDetail), store);
+ jest.spyOn(store, 'dispatch');
+ store.dispatch.mockResolvedValue();
+
+ wrapper = mount(JobDetail, { store });
};
- beforeEach(() => {
- vm = createComponent();
+ const findBuildJobLog = () => wrapper.find('pre');
+ const findScrollToBottomButton = () => wrapper.find('button[aria-label="Scroll to bottom"]');
+ const findScrollToTopButton = () => wrapper.find('button[aria-label="Scroll to top"]');
- jest.spyOn(vm, 'fetchJobLogs').mockResolvedValue();
+ beforeEach(() => {
+ createComponent();
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('mounted', () => {
- beforeEach(() => {
- vm = vm.$mount();
- });
+ const findJobOutput = () => wrapper.find('.bash');
+ const findBuildLoaderAnimation = () => wrapper.find('.build-loader-animation');
it('calls fetchJobLogs', () => {
- expect(vm.fetchJobLogs).toHaveBeenCalled();
+ expect(store.dispatch).toHaveBeenCalledWith('pipelines/fetchJobLogs', undefined);
});
it('scrolls to bottom', () => {
- expect(vm.$refs.buildJobLog.scrollTo).toHaveBeenCalled();
+ expect(findBuildJobLog().element.scrollTo).toHaveBeenCalled();
});
it('renders job output', () => {
- expect(vm.$el.querySelector('.bash').textContent).toContain('testing');
+ expect(findJobOutput().text()).toContain('testing');
});
it('renders empty message output', async () => {
- vm.$store.state.pipelines.detailJob.output = '';
-
+ store.state.pipelines.detailJob.output = '';
await nextTick();
- expect(vm.$el.querySelector('.bash').textContent).toContain('No messages were logged');
+
+ expect(findJobOutput().text()).toContain('No messages were logged');
});
it('renders loading icon', () => {
- expect(vm.$el.querySelector('.build-loader-animation')).not.toBe(null);
- expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('');
+ expect(findBuildLoaderAnimation().exists()).toBe(true);
+ expect(findBuildLoaderAnimation().isVisible()).toBe(true);
});
it('hides output when loading', () => {
- expect(vm.$el.querySelector('.bash')).not.toBe(null);
- expect(vm.$el.querySelector('.bash').style.display).toBe('none');
+ expect(findJobOutput().exists()).toBe(true);
+ expect(findJobOutput().isVisible()).toBe(false);
});
it('hide loading icon when isLoading is false', async () => {
- vm.$store.state.pipelines.detailJob.isLoading = false;
-
+ store.state.pipelines.detailJob.isLoading = false;
await nextTick();
- expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('none');
- });
- it('resets detailJob when clicking header button', () => {
- jest.spyOn(vm, 'setDetailJob').mockImplementation();
+ expect(findBuildLoaderAnimation().isVisible()).toBe(false);
+ });
- vm.$el.querySelector('.btn').click();
+ it('resets detailJob when clicking header button', async () => {
+ await wrapper.find('.btn').trigger('click');
- expect(vm.setDetailJob).toHaveBeenCalledWith(null);
+ expect(store.dispatch).toHaveBeenCalledWith('pipelines/setDetailJob', null);
});
it('renders raw path link', () => {
- expect(vm.$el.querySelector('.controllers-buttons').getAttribute('href')).toBe(
- `${TEST_HOST}/raw`,
- );
+ expect(wrapper.find('.controllers-buttons').attributes('href')).toBe(`${TEST_HOST}/raw`);
});
});
describe('scroll buttons', () => {
beforeEach(() => {
- vm = createComponent();
- jest.spyOn(vm, 'fetchJobLogs').mockResolvedValue();
- });
-
- afterEach(() => {
- vm.$destroy();
+ createComponent();
});
it.each`
- fnName | btnName | scrollPos
- ${'scrollDown'} | ${'down'} | ${0}
- ${'scrollUp'} | ${'up'} | ${1}
- `('triggers $fnName when clicking $btnName button', async ({ fnName, scrollPos }) => {
- jest.spyOn(vm, fnName).mockImplementation();
-
- vm = vm.$mount();
+ fnName | btnName | scrollPos | targetScrollPos
+ ${'scroll down'} | ${'down'} | ${0} | ${200}
+ ${'scroll up'} | ${'up'} | ${200} | ${0}
+ `('triggers $fnName when clicking $btnName button', async ({ scrollPos, targetScrollPos }) => {
+ jest.spyOn(findBuildJobLog().element, 'offsetHeight', 'get').mockReturnValue(0);
+ jest.spyOn(findBuildJobLog().element, 'scrollHeight', 'get').mockReturnValue(200);
+ jest.spyOn(findBuildJobLog().element, 'scrollTop', 'get').mockReturnValue(scrollPos);
+ findBuildJobLog().element.scrollTo.mockReset();
- vm.scrollPos = scrollPos;
-
- await nextTick();
- vm.$el.querySelector('.btn-scroll:not([disabled])').click();
- expect(vm[fnName]).toHaveBeenCalled();
- });
- });
-
- describe('scrollDown', () => {
- beforeEach(() => {
- vm = vm.$mount();
-
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTo').mockImplementation();
- });
-
- it('scrolls build trace to bottom', () => {
- jest.spyOn(vm.$refs.buildJobLog, 'scrollHeight', 'get').mockReturnValue(1000);
-
- vm.scrollDown();
-
- expect(vm.$refs.buildJobLog.scrollTo).toHaveBeenCalledWith(0, 1000);
- });
- });
-
- describe('scrollUp', () => {
- beforeEach(() => {
- vm = vm.$mount();
-
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTo').mockImplementation();
- });
+ await findBuildJobLog().trigger('scroll'); // trigger button updates
- it('scrolls build trace to top', () => {
- vm.scrollUp();
+ await wrapper.find('.controllers button:not(:disabled)').trigger('click');
- expect(vm.$refs.buildJobLog.scrollTo).toHaveBeenCalledWith(0, 0);
+ expect(findBuildJobLog().element.scrollTo).toHaveBeenCalledWith(0, targetScrollPos);
});
});
- describe('scrollBuildLog', () => {
+ describe('scrolling build log', () => {
beforeEach(() => {
- vm = vm.$mount();
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTo').mockImplementation();
- jest.spyOn(vm.$refs.buildJobLog, 'offsetHeight', 'get').mockReturnValue(100);
- jest.spyOn(vm.$refs.buildJobLog, 'scrollHeight', 'get').mockReturnValue(200);
+ jest.spyOn(findBuildJobLog().element, 'offsetHeight', 'get').mockReturnValue(100);
+ jest.spyOn(findBuildJobLog().element, 'scrollHeight', 'get').mockReturnValue(200);
});
- it('sets scrollPos to bottom when at the bottom', () => {
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTop', 'get').mockReturnValue(100);
+ it('keeps scroll at bottom when already at the bottom', async () => {
+ jest.spyOn(findBuildJobLog().element, 'scrollTop', 'get').mockReturnValue(100);
- vm.scrollBuildLog();
+ await findBuildJobLog().trigger('scroll');
- expect(vm.scrollPos).toBe(1);
+ expect(findScrollToBottomButton().attributes('disabled')).toBe('disabled');
+ expect(findScrollToTopButton().attributes('disabled')).not.toBe('disabled');
});
- it('sets scrollPos to top when at the top', () => {
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTop', 'get').mockReturnValue(0);
- vm.scrollPos = 1;
+ it('keeps scroll at top when already at top', async () => {
+ jest.spyOn(findBuildJobLog().element, 'scrollTop', 'get').mockReturnValue(0);
- vm.scrollBuildLog();
+ await findBuildJobLog().trigger('scroll');
- expect(vm.scrollPos).toBe(0);
+ expect(findScrollToBottomButton().attributes('disabled')).not.toBe('disabled');
+ expect(findScrollToTopButton().attributes('disabled')).toBe('disabled');
});
- it('resets scrollPos when not at top or bottom', () => {
- jest.spyOn(vm.$refs.buildJobLog, 'scrollTop', 'get').mockReturnValue(10);
+ it('resets scroll when not at top or bottom', async () => {
+ jest.spyOn(findBuildJobLog().element, 'scrollTop', 'get').mockReturnValue(10);
- vm.scrollBuildLog();
+ await findBuildJobLog().trigger('scroll');
- expect(vm.scrollPos).toBe('');
+ expect(findScrollToBottomButton().attributes('disabled')).not.toBe('disabled');
+ expect(findScrollToTopButton().attributes('disabled')).not.toBe('disabled');
});
});
});
diff --git a/spec/frontend/ide/components/jobs/item_spec.js b/spec/frontend/ide/components/jobs/item_spec.js
index c76760a5522..32e27333e42 100644
--- a/spec/frontend/ide/components/jobs/item_spec.js
+++ b/spec/frontend/ide/components/jobs/item_spec.js
@@ -1,36 +1,38 @@
-import Vue, { nextTick } from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
+import { mount } from '@vue/test-utils';
+import { GlButton } from '@gitlab/ui';
+
import JobItem from '~/ide/components/jobs/item.vue';
import { jobs } from '../../mock_data';
describe('IDE jobs item', () => {
- const Component = Vue.extend(JobItem);
const job = jobs[0];
- let vm;
+ let wrapper;
beforeEach(() => {
- vm = mountComponent(Component, {
- job,
- });
+ wrapper = mount(JobItem, { propsData: { job } });
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
it('renders job details', () => {
- expect(vm.$el.textContent).toContain(job.name);
- expect(vm.$el.textContent).toContain(`#${job.id}`);
+ expect(wrapper.text()).toContain(job.name);
+ expect(wrapper.text()).toContain(`#${job.id}`);
});
it('renders CI icon', () => {
- expect(vm.$el.querySelector('[data-testid="status_success_borderless-icon"]')).not.toBe(null);
+ expect(wrapper.find('[data-testid="status_success_borderless-icon"]').exists()).toBe(true);
});
it('does not render view logs button if not started', async () => {
- vm.job.started = false;
+ await wrapper.setProps({
+ job: {
+ ...jobs[0],
+ started: false,
+ },
+ });
- await nextTick();
- expect(vm.$el.querySelector('.btn')).toBe(null);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(false);
});
});
diff --git a/spec/frontend/ide/components/jobs/stage_spec.js b/spec/frontend/ide/components/jobs/stage_spec.js
index 1d5e5743a4d..52fbff2f497 100644
--- a/spec/frontend/ide/components/jobs/stage_spec.js
+++ b/spec/frontend/ide/components/jobs/stage_spec.js
@@ -18,8 +18,9 @@ describe('IDE pipeline stage', () => {
},
};
- const findHeader = () => wrapper.findComponent({ ref: 'cardHeader' });
- const findJobList = () => wrapper.findComponent({ ref: 'jobList' });
+ const findHeader = () => wrapper.find('[data-testid="card-header"]');
+ const findJobList = () => wrapper.find('[data-testid="job-list"]');
+ const findStageTitle = () => wrapper.find('[data-testid="stage-title"]');
const createComponent = (props) => {
wrapper = shallowMount(Stage, {
@@ -65,9 +66,9 @@ describe('IDE pipeline stage', () => {
expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
});
- it('renders stage details & icon', () => {
+ it('renders stage title', () => {
createComponent();
- expect(wrapper.element).toMatchSnapshot();
+ expect(findStageTitle().isVisible()).toBe(true);
});
describe('when collapsed', () => {