summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-05 03:11:53 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-05 03:11:53 +0000
commitb892ac7767d111a4762161fecf826f7030d30689 (patch)
tree6fcbbadc3e4af092640c171888e1d7231ca67ca7
parent33a1d1835f5fc146acf0cdda402b5a327ae0d52f (diff)
downloadgitlab-ce-b892ac7767d111a4762161fecf826f7030d30689.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.eslintrc.yml1
-rw-r--r--app/assets/javascripts/related_issues/components/add_issuable_form.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue8
-rw-r--r--app/assets/javascripts/sidebar/components/participants/participants.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue12
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/issuable.scss44
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml4
-rw-r--r--doc/development/testing_guide/frontend_testing.md15
-rw-r--r--jest.config.base.js1
-rw-r--r--jest_resolver.js17
-rw-r--r--spec/frontend/.eslintrc.yml7
-rw-r--r--spec/frontend/deploy_freeze/helpers.js5
-rw-r--r--spec/frontend/sidebar/assignees_spec.js8
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/graphql.js4
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 = {