diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-05 03:11:53 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-05 03:11:53 +0000 |
commit | b892ac7767d111a4762161fecf826f7030d30689 (patch) | |
tree | 6fcbbadc3e4af092640c171888e1d7231ca67ca7 | |
parent | 33a1d1835f5fc146acf0cdda402b5a327ae0d52f (diff) | |
download | gitlab-ce-b892ac7767d111a4762161fecf826f7030d30689.tar.gz |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | .eslintrc.yml | 1 | ||||
-rw-r--r-- | app/assets/javascripts/related_issues/components/add_issuable_form.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue | 8 | ||||
-rw-r--r-- | app/assets/javascripts/sidebar/components/participants/participants.vue | 4 | ||||
-rw-r--r-- | app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue | 12 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/variables.scss | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/issuable.scss | 44 | ||||
-rw-r--r-- | app/views/shared/milestones/_sidebar.html.haml | 4 | ||||
-rw-r--r-- | doc/development/testing_guide/frontend_testing.md | 15 | ||||
-rw-r--r-- | jest.config.base.js | 1 | ||||
-rw-r--r-- | jest_resolver.js | 17 | ||||
-rw-r--r-- | spec/frontend/.eslintrc.yml | 7 | ||||
-rw-r--r-- | spec/frontend/deploy_freeze/helpers.js | 5 | ||||
-rw-r--r-- | spec/frontend/sidebar/assignees_spec.js | 8 | ||||
-rw-r--r-- | spec/frontend_integration/test_helpers/mock_server/graphql.js | 4 |
15 files changed, 63 insertions, 70 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml index 2eb52b59dea..cd3cd82d4e7 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -100,6 +100,7 @@ overrides: - 'scripts/**/*' - '*.config.js' - '*.config.*.js' + - 'jest_resolver.js' - storybook/config/*.js rules: '@gitlab/require-i18n-strings': off diff --git a/app/assets/javascripts/related_issues/components/add_issuable_form.vue b/app/assets/javascripts/related_issues/components/add_issuable_form.vue index a9b5942efa9..4deb93e4b30 100644 --- a/app/assets/javascripts/related_issues/components/add_issuable_form.vue +++ b/app/assets/javascripts/related_issues/components/add_issuable_form.vue @@ -197,7 +197,7 @@ export default { <p v-if="hasError" class="gl-field-error"> {{ addRelatedErrorMessage }} </p> - <div class="add-issuable-form-actions clearfix"> + <div class="gl-mt-5 gl-clearfix"> <gl-button ref="addButton" category="primary" diff --git a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue index b7080bb05b8..c2ca87af9ce 100644 --- a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue +++ b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue @@ -82,8 +82,12 @@ export default { </div> </assignee-avatar-link> <div v-else> - <div class="user-list"> - <div v-for="user in uncollapsedUsers" :key="user.id" class="user-item"> + <div class="gl-display-flex gl-flex-wrap"> + <div + v-for="user in uncollapsedUsers" + :key="user.id" + class="user-item gl-display-inline-block" + > <assignee-avatar-link :user="user" :issuable-type="issuableType" /> </div> </div> diff --git a/app/assets/javascripts/sidebar/components/participants/participants.vue b/app/assets/javascripts/sidebar/components/participants/participants.vue index ad4bfe5b665..4a255a3b916 100644 --- a/app/assets/javascripts/sidebar/components/participants/participants.vue +++ b/app/assets/javascripts/sidebar/components/participants/participants.vue @@ -104,11 +104,11 @@ export default { <gl-loading-icon v-if="loading" size="sm" :inline="true" /> {{ participantLabel }} </div> - <div class="participants-list hide-collapsed"> + <div class="hide-collapsed gl-display-flex gl-flex-wrap"> <div v-for="participant in visibleParticipants" :key="participant.id" - class="participants-author" + class="participants-author gl-display-inline-block gl-pr-3 gl-pb-3" > <a :href="participant.web_url || participant.webUrl" class="author-link"> <user-avatar-image diff --git a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue index 3705d725a15..7b4be659330 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue @@ -83,13 +83,15 @@ export default { :value="timeRemainingPercent" :variant="progressBarVariant" /> - <div class="compare-display-container"> - <div class="compare-display float-left"> - <span class="compare-label">{{ s__('TimeTracking|Spent') }}</span> + <div + class="compare-display-container gl-display-flex gl-justify-content-space-between gl-mt-2" + > + <div class="gl-float-left"> + <span class="gl-text-gray-400">{{ s__('TimeTracking|Spent') }}</span> <span class="compare-value spent">{{ timeSpentHumanReadable }}</span> </div> - <div class="compare-display estimated float-right"> - <span class="compare-label">{{ s__('TimeTrackingEstimated|Est') }}</span> + <div class="estimated gl-float-right"> + <span class="gl-text-gray-400">{{ s__('TimeTrackingEstimated|Est') }}</span> <span class="compare-value">{{ timeEstimateHumanReadable }}</span> </div> </div> diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 099dfa28b9f..c0e297d8554 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -759,7 +759,6 @@ $help-shortcut-header-color: #333; */ $issues-today-bg: #f3fff2 !default; $issues-today-border: #e1e8d5 !default; -$compare-display-color: #888; /* * Label diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index d8fc94cce0c..c4df2e102bd 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -220,21 +220,12 @@ } .cross-project-reference { - color: inherit; - span { - white-space: nowrap; width: 85%; - overflow: hidden; - position: relative; - display: inline-block; - text-overflow: ellipsis; } button { - float: right; padding: 1px 5px; - background-color: $gray-light; } } @@ -563,35 +554,17 @@ } } -.participants-list { - display: flex; - flex-wrap: wrap; -} - -.user-list { - display: flex; - flex-wrap: wrap; -} - .participants-author { - display: inline-block; - padding: 0 $gl-padding-8 $gl-padding-8 0; - &:nth-of-type(7n) { padding-right: 0; } - .author-link { - display: block; - } - .avatar.avatar-inline { margin: 0; } } .user-item { - display: inline-block; padding: 5px; flex-basis: 20%; @@ -803,10 +776,6 @@ } } -.add-issuable-form-actions { - margin-top: $gl-padding; -} - .time-tracker { .sidebar-collapsed-icon { > .stopwatch-svg { @@ -839,18 +808,7 @@ } .compare-display-container { - display: flex; - justify-content: space-between; - margin-top: 5px; - - .compare-display { - font-size: 13px; - color: $compare-display-color; - - .compare-value { - color: $gl-text-color; - } - } + font-size: 13px; } .time-tracking-help-state { diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 56b2b0d5801..8ed40f74c88 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -164,8 +164,8 @@ .sidebar-collapsed-icon.dont-change-state = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport') .cross-project-reference.hide-collapsed - %span + %span.gl-display-inline-block.gl-text-truncate = s_('MilestoneSidebar|Reference:') %span{ title: milestone_ref } = milestone_ref - = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport') + = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport', class: 'btn-clipboard btn-transparent gl-float-right gl-bg-gray-10') diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md index 0417dbeeede..2708159979e 100644 --- a/doc/development/testing_guide/frontend_testing.md +++ b/doc/development/testing_guide/frontend_testing.md @@ -783,20 +783,25 @@ often using fixtures to validate correct integration with the backend code. ### Use fixtures -Jest uses `spec/frontend/__helpers__/fixtures.js` to import fixtures in tests. - -The following are examples of tests that work for Jest: +To import a JSON fixture, `import` it using the `test_fixtures` alias. ```javascript +import responseBody from 'test_fixtures/some/fixture.json' // loads spec/frontend/fixtures/some/fixture.json + it('makes a request', () => { - const responseBody = getJSONFixture('some/fixture.json'); // loads spec/frontend/fixtures/some/fixture.json axiosMock.onGet(endpoint).reply(200, responseBody); myButton.click(); // ... }); +``` +For other fixtures, Jest uses `spec/frontend/__helpers__/fixtures.js` to import them in tests. + +The following are examples of tests that work for Jest: + +```javascript it('uses some HTML element', () => { loadFixtures('some/page.html'); // loads spec/frontend/fixtures/some/page.html and adds it to the DOM @@ -860,7 +865,7 @@ end This will create a new fixture located at `tmp/tests/frontend/fixtures-ee/graphql/releases/graphql/queries/all_releases.query.graphql.json`. -You can import the JSON fixture in a Jest test using the `getJSONFixture` method +You can import the JSON fixture in a Jest test using the `test_fixtures` alias [as described below](#use-fixtures). ## Data-driven tests diff --git a/jest.config.base.js b/jest.config.base.js index e0d5afbdbc9..7cf1136a073 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -112,6 +112,7 @@ module.exports = (path, options = {}) => { cacheDirectory: '<rootDir>/tmp/cache/jest', modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'], reporters, + resolver: './jest_resolver.js', setupFilesAfterEnv: [`<rootDir>/${path}/test_setup.js`, 'jest-canvas-mock'], restoreMocks: true, transform: { diff --git a/jest_resolver.js b/jest_resolver.js new file mode 100644 index 00000000000..6cbc1b9f18f --- /dev/null +++ b/jest_resolver.js @@ -0,0 +1,17 @@ +const fs = require('fs'); + +// Wrap jest default resolver to detect missing frontend fixtures. +module.exports = (request, options) => { + try { + return options.defaultResolver(request, options); + } catch (e) { + if (request.match(/tmp\/tests\/frontend\/fixtures/) && !fs.existsSync(request)) { + console.error( + '\x1b[1m\x1b[41m\x1b[30m %s \x1b[0m %s', + '!', + `Fixture file ${request} does not exist. Did you run bin/rake frontend:fixtures?`, + ); + } + throw e; + } +}; diff --git a/spec/frontend/.eslintrc.yml b/spec/frontend/.eslintrc.yml index 145e6c8961a..2686a14f9eb 100644 --- a/spec/frontend/.eslintrc.yml +++ b/spec/frontend/.eslintrc.yml @@ -26,4 +26,9 @@ rules: - off "@gitlab/no-global-event-off": - off - + import/no-unresolved: + - error + # The test fixtures and graphql schema are dynamically generated in CI + # during the `frontend-fixtures` and `graphql-schema-dump` jobs. + # They may not be present during linting. + - ignore: ['^test_fixtures\/', 'tmp/tests/graphql/gitlab_schema.graphql'] diff --git a/spec/frontend/deploy_freeze/helpers.js b/spec/frontend/deploy_freeze/helpers.js index 598f14d45f6..43e66183ab5 100644 --- a/spec/frontend/deploy_freeze/helpers.js +++ b/spec/frontend/deploy_freeze/helpers.js @@ -1,7 +1,8 @@ +import freezePeriodsFixture from 'test_fixtures/api/freeze-periods/freeze_periods.json'; +import timezoneDataFixture from 'test_fixtures/timezones/short.json'; import { secondsToHours } from '~/lib/utils/datetime_utility'; -export const freezePeriodsFixture = getJSONFixture('/api/freeze-periods/freeze_periods.json'); -export const timezoneDataFixture = getJSONFixture('/timezones/short.json'); +export { freezePeriodsFixture, timezoneDataFixture }; export const findTzByName = (identifier = '') => timezoneDataFixture.find(({ name }) => name.toLowerCase() === identifier.toLowerCase()); diff --git a/spec/frontend/sidebar/assignees_spec.js b/spec/frontend/sidebar/assignees_spec.js index be27a800418..b3a67f18f82 100644 --- a/spec/frontend/sidebar/assignees_spec.js +++ b/spec/frontend/sidebar/assignees_spec.js @@ -3,6 +3,7 @@ import { mount } from '@vue/test-utils'; import { trimText } from 'helpers/text_helper'; import UsersMockHelper from 'helpers/user_mock_data_helper'; import Assignee from '~/sidebar/components/assignees/assignees.vue'; +import AssigneeAvatarLink from '~/sidebar/components/assignees/assignee_avatar_link.vue'; import UsersMock from './mock_data'; describe('Assignee component', () => { @@ -19,6 +20,7 @@ describe('Assignee component', () => { }); }; + const findAllAvatarLinks = () => wrapper.findAllComponents(AssigneeAvatarLink); const findComponentTextNoUsers = () => wrapper.find('[data-testid="no-value"]'); const findCollapsedChildren = () => wrapper.findAll('.sidebar-collapsed-icon > *'); @@ -148,7 +150,7 @@ describe('Assignee component', () => { editable: true, }); - expect(wrapper.findAll('.user-item').length).toBe(users.length); + expect(findAllAvatarLinks()).toHaveLength(users.length); expect(wrapper.find('.user-list-more').exists()).toBe(false); }); @@ -178,9 +180,9 @@ describe('Assignee component', () => { users, }); - const userItems = wrapper.findAll('.user-list .user-item a'); + const userItems = findAllAvatarLinks(); - expect(userItems.length).toBe(3); + expect(userItems).toHaveLength(3); expect(userItems.at(0).attributes('title')).toBe(users[2].name); }); diff --git a/spec/frontend_integration/test_helpers/mock_server/graphql.js b/spec/frontend_integration/test_helpers/mock_server/graphql.js index 27396842523..d4ee7c02839 100644 --- a/spec/frontend_integration/test_helpers/mock_server/graphql.js +++ b/spec/frontend_integration/test_helpers/mock_server/graphql.js @@ -1,9 +1,7 @@ import { buildSchema, graphql } from 'graphql'; import { memoize } from 'lodash'; -// The graphql schema is dynamically generated in CI -// during the `graphql-schema-dump` job. -// eslint-disable-next-line global-require, import/no-unresolved +// eslint-disable-next-line global-require const getGraphqlSchema = () => require('../../../../tmp/tests/graphql/gitlab_schema.graphql'); const graphqlResolvers = { |