import { GlTable, GlSkeletonLoader } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import RunnerList from '~/runner/components/runner_list.vue'; import { runnersData } from '../mock_data'; const mockRunners = runnersData.data.runners.nodes; const mockActiveRunnersCount = mockRunners.length; describe('RunnerList', () => { let wrapper; const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); const findTable = () => wrapper.findComponent(GlTable); const findHeaders = () => wrapper.findAll('th'); const findRows = () => wrapper.findAll('[data-testid^="runner-row-"]'); const findCell = ({ row = 0, fieldKey }) => extendedWrapper(findRows().at(row).find(`[data-testid="td-${fieldKey}"]`)); const createComponent = ({ props = {} } = {}, mountFn = shallowMount) => { wrapper = extendedWrapper( mountFn(RunnerList, { propsData: { runners: mockRunners, activeRunnersCount: mockActiveRunnersCount, ...props, }, }), ); }; beforeEach(() => { createComponent({}, mount); }); afterEach(() => { wrapper.destroy(); }); it('Displays headers', () => { const headerLabels = findHeaders().wrappers.map((w) => w.text()); expect(headerLabels).toEqual([ 'Status', 'Runner ID', 'Version', 'IP Address', 'Tags', 'Last contact', '', // actions has no label ]); }); it('Displays a list of runners', () => { expect(findRows()).toHaveLength(4); expect(findSkeletonLoader().exists()).toBe(false); }); it('Displays details of a runner', () => { const { id, description, version, ipAddress, shortSha } = mockRunners[0]; // Badges expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText('not connected paused'); // Runner summary expect(findCell({ fieldKey: 'summary' }).text()).toContain( `#${getIdFromGraphQLId(id)} (${shortSha})`, ); expect(findCell({ fieldKey: 'summary' }).text()).toContain(description); // Other fields expect(findCell({ fieldKey: 'version' }).text()).toBe(version); expect(findCell({ fieldKey: 'ipAddress' }).text()).toBe(ipAddress); expect(findCell({ fieldKey: 'tagList' }).text()).toBe(''); expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String)); // Actions const actions = findCell({ fieldKey: 'actions' }); expect(actions.findByTestId('edit-runner').exists()).toBe(true); expect(actions.findByTestId('toggle-active-runner').exists()).toBe(true); }); it('Shows runner identifier', () => { const { id, shortSha } = mockRunners[0]; const numericId = getIdFromGraphQLId(id); expect(findCell({ fieldKey: 'summary' }).text()).toContain(`#${numericId} (${shortSha})`); }); describe('When data is loading', () => { it('shows a busy state', () => { createComponent({ props: { runners: [], loading: true } }); expect(findTable().attributes('busy')).toBeTruthy(); }); it('when there are no runners, shows an skeleton loader', () => { createComponent({ props: { runners: [], loading: true } }, mount); expect(findSkeletonLoader().exists()).toBe(true); }); it('when there are runners, shows a busy indicator skeleton loader', () => { createComponent({ props: { loading: true } }, mount); expect(findSkeletonLoader().exists()).toBe(false); }); }); });