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:
-rw-r--r--.rubocop.yml1
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_list.vue12
-rw-r--r--app/assets/javascripts/environments/components/stop_environment_modal.vue2
-rw-r--r--app/views/shared/issuable/_close_reopen_report_toggle.html.haml2
-rw-r--r--changelogs/unreleased/217992.yml5
-rw-r--r--changelogs/unreleased/leaky-constant-fix-2.yml5
-rw-r--r--changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-environments-co.yml5
-rw-r--r--db/migrate/20200513224143_add_section_to_approval_merge_request_rule.rb21
-rw-r--r--db/structure.sql5
-rw-r--r--doc/ci/pipelines/job_artifacts.md23
-rw-r--r--doc/development/documentation/index.md18
-rw-r--r--doc/development/documentation/styleguide.md8
-rw-r--r--doc/development/testing_guide/end_to_end/page_objects.md47
-rw-r--r--doc/user/application_security/sast/index.md7
-rw-r--r--doc/user/incident_management/index.md164
-rw-r--r--locale/gitlab.pot11
-rw-r--r--qa/qa.rb3
-rw-r--r--qa/qa/page/component/breadcrumbs.rb4
-rw-r--r--qa/qa/page/component/ci_badge_link.rb4
-rw-r--r--qa/qa/page/component/clone_panel.rb4
-rw-r--r--qa/qa/page/component/confirm_modal.rb4
-rw-r--r--qa/qa/page/component/custom_metric.rb4
-rw-r--r--qa/qa/page/component/design_management.rb8
-rw-r--r--qa/qa/page/component/groups_filter.rb4
-rw-r--r--qa/qa/page/component/issuable/common.rb4
-rw-r--r--qa/qa/page/component/lazy_loader.rb4
-rw-r--r--qa/qa/page/component/legacy_clone_panel.rb4
-rw-r--r--qa/qa/page/component/note.rb4
-rw-r--r--qa/qa/page/component/web_ide/alert.rb8
-rw-r--r--qa/qa/page/file/shared/commit_button.rb4
-rw-r--r--qa/qa/page/file/shared/commit_message.rb4
-rw-r--r--qa/qa/page/file/shared/editor.rb4
-rw-r--r--qa/qa/page/group/sub_menus/common.rb3
-rw-r--r--qa/qa/page/main/terms.rb24
-rw-r--r--qa/qa/page/page_concern.rb16
-rw-r--r--qa/qa/page/project/job/show.rb72
-rw-r--r--qa/qa/page/project/pipeline/index.rb76
-rw-r--r--qa/qa/page/project/pipeline/show.rb112
-rw-r--r--qa/qa/page/project/settings/ci_cd.rb2
-rw-r--r--qa/qa/page/project/settings/ci_variables.rb2
-rw-r--r--qa/qa/page/project/settings/common.rb13
-rw-r--r--qa/qa/page/project/settings/general_pipelines.rb2
-rw-r--r--qa/qa/page/project/settings/main.rb2
-rw-r--r--qa/qa/page/project/settings/merge_request.rb2
-rw-r--r--qa/qa/page/project/settings/operations.rb2
-rw-r--r--qa/qa/page/project/settings/repository.rb2
-rw-r--r--qa/qa/page/project/sub_menus/ci_cd.rb6
-rw-r--r--qa/qa/page/project/sub_menus/common.rb1
-rw-r--r--qa/qa/page/project/sub_menus/issues.rb6
-rw-r--r--qa/qa/page/project/sub_menus/operations.rb6
-rw-r--r--qa/qa/page/project/sub_menus/project.rb6
-rw-r--r--qa/qa/page/project/sub_menus/repository.rb8
-rw-r--r--qa/qa/page/project/sub_menus/settings.rb6
-rw-r--r--qa/qa/page/search/results.rb76
-rw-r--r--qa/qa/specs/helpers/quarantine.rb130
-rw-r--r--spec/frontend/alert_management/components/alert_management_list_spec.js10
-rw-r--r--spec/uploaders/content_type_whitelist_spec.rb18
57 files changed, 607 insertions, 403 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 4ee8d4962b3..d744fe4d7db 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -404,7 +404,6 @@ RSpec/LeakyConstantDeclaration:
- 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
- 'spec/support_specs/helpers/active_record/query_recorder_spec.rb'
- 'spec/support_specs/matchers/exceed_query_limit_helpers_spec.rb'
- - 'spec/uploaders/content_type_whitelist_spec.rb'
- 'spec/uploaders/records_uploads_spec.rb'
RSpec/EmptyLineAfterHook:
diff --git a/app/assets/javascripts/alert_management/components/alert_management_list.vue b/app/assets/javascripts/alert_management/components/alert_management_list.vue
index ce1738f1961..74fc19ff3d4 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_list.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_list.vue
@@ -13,7 +13,7 @@ import {
} from '@gitlab/ui';
import createFlash from '~/flash';
import { s__ } from '~/locale';
-import { joinPaths } from '~/lib/utils/url_utility';
+import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import getAlerts from '../graphql/queries/getAlerts.query.graphql';
import { ALERTS_STATUS, ALERTS_STATUS_TABS, ALERTS_SEVERITY_LABELS } from '../constants';
@@ -165,6 +165,9 @@ export default {
projectPath: this.projectPath,
},
})
+ .then(() => {
+ this.$apollo.queries.alerts.refetch();
+ })
.catch(() => {
createFlash(
s__(
@@ -173,13 +176,12 @@ export default {
);
});
},
- handleRowClick({ iid }) {
- window.location.assign(joinPaths(window.location.pathname, iid, 'details'));
+ navigateToAlertDetails({ iid }) {
+ return visitUrl(joinPaths(window.location.pathname, iid, 'details'));
},
},
};
</script>
-
<template>
<div>
<div v-if="alertManagementEnabled" class="alert-management-list">
@@ -209,7 +211,7 @@ export default {
:busy="loading"
stacked="md"
:tbody-tr-class="$options.bodyTrClass"
- @row-clicked="handleRowClick"
+ @row-clicked="navigateToAlertDetails"
>
<template #cell(severity)="{ item }">
<div
diff --git a/app/assets/javascripts/environments/components/stop_environment_modal.vue b/app/assets/javascripts/environments/components/stop_environment_modal.vue
index d3e8fb7ff08..7448fd584c6 100644
--- a/app/assets/javascripts/environments/components/stop_environment_modal.vue
+++ b/app/assets/javascripts/environments/components/stop_environment_modal.vue
@@ -60,7 +60,7 @@ export default {
footer-primary-button-variant="danger"
@submit="onSubmit"
>
- <template slot="header">
+ <template #header>
<h4 class="modal-title d-flex mw-100">
Stopping
<span v-gl-tooltip :title="environment.name" class="text-truncate ml-1 mr-1 flex-fill">
diff --git a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
index fcdd3f6a625..9d718083d2d 100644
--- a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
+++ b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
@@ -45,6 +45,6 @@
%button.btn.btn-transparent
= icon('check', class: 'icon')
.description
- %strong.title = _('Report abuse')
+ %strong.title= _('Report abuse')
%p.text
= _('Report %{display_issuable_type} that are abusive, inappropriate or spam.') % { display_issuable_type: display_issuable_type.pluralize }
diff --git a/changelogs/unreleased/217992.yml b/changelogs/unreleased/217992.yml
new file mode 100644
index 00000000000..fd0c5a4af9d
--- /dev/null
+++ b/changelogs/unreleased/217992.yml
@@ -0,0 +1,5 @@
+---
+title: Use visitUrl in Alert management
+merge_request: 32414
+author:
+type: other
diff --git a/changelogs/unreleased/leaky-constant-fix-2.yml b/changelogs/unreleased/leaky-constant-fix-2.yml
new file mode 100644
index 00000000000..194450da556
--- /dev/null
+++ b/changelogs/unreleased/leaky-constant-fix-2.yml
@@ -0,0 +1,5 @@
+---
+title: Add class stubs and fix leaky constant alert in content whitelist spec
+merge_request: 31946
+author: Rajendra Kadam
+type: fixed
diff --git a/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-environments-co.yml b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-environments-co.yml
new file mode 100644
index 00000000000..317da0d88f5
--- /dev/null
+++ b/changelogs/unreleased/update-deprecated-slot-syntax-in---app-assets-javascripts-environments-co.yml
@@ -0,0 +1,5 @@
+---
+title: Update deprecated slot syntax in ./app/assets/javascripts/environments/components/stop_environment_modal.vue
+merge_request: 32012
+author: Gilang Gumilar
+type: other
diff --git a/db/migrate/20200513224143_add_section_to_approval_merge_request_rule.rb b/db/migrate/20200513224143_add_section_to_approval_merge_request_rule.rb
new file mode 100644
index 00000000000..98424e9b735
--- /dev/null
+++ b/db/migrate/20200513224143_add_section_to_approval_merge_request_rule.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class AddSectionToApprovalMergeRequestRule < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless column_exists?(:approval_merge_request_rules, :section)
+ add_column :approval_merge_request_rules, :section, :text
+ end
+
+ add_text_limit :approval_merge_request_rules, :section, 255
+ end
+
+ def down
+ remove_column :approval_merge_request_rules, :section
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index fe4a36b365c..e7040c3f852 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -479,7 +479,9 @@ CREATE TABLE public.approval_merge_request_rules (
code_owner boolean DEFAULT false NOT NULL,
name character varying NOT NULL,
rule_type smallint DEFAULT 1 NOT NULL,
- report_type smallint
+ report_type smallint,
+ section text,
+ CONSTRAINT check_6fca5928b2 CHECK ((char_length(section) <= 255))
);
CREATE TABLE public.approval_merge_request_rules_approved_approvers (
@@ -13832,6 +13834,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200512164334
20200513160930
20200513171959
+20200513224143
20200513234502
20200513235347
20200513235532
diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md
index 0e18b6e8423..d4774016d9c 100644
--- a/doc/ci/pipelines/job_artifacts.md
+++ b/doc/ci/pipelines/job_artifacts.md
@@ -110,7 +110,6 @@ The `dotenv` report collects a set of environment variables as artifacts.
The collected variables are registered as runtime-created variables of the job,
which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes).
-It's not available for download through the web interface.
There are a couple of limitations on top of the [original dotenv rules](https://github.com/motdotla/dotenv#rules).
@@ -151,7 +150,7 @@ The `codequality` report collects [CodeQuality issues](../../user/project/merge_
as artifacts.
The collected Code Quality report will be uploaded to GitLab as an artifact and will
-be summarized in merge requests. It's not available for download through the web interface.
+be summarized in merge requests.
#### `artifacts:reports:sast` **(ULTIMATE)**
@@ -163,7 +162,7 @@ as artifacts.
The collected SAST report will be uploaded to GitLab as an artifact and will be summarized
in the merge requests and pipeline view. It's also used to provide data for security
-dashboards. It's not available for download through the web interface.
+dashboards.
#### `artifacts:reports:dependency_scanning` **(ULTIMATE)**
@@ -175,7 +174,7 @@ as artifacts.
The collected Dependency Scanning report will be uploaded to GitLab as an artifact and will
be summarized in the merge requests and pipeline view. It's also used to provide data for security
-dashboards. It's not available for download through the web interface.
+dashboards.
#### `artifacts:reports:container_scanning` **(ULTIMATE)**
@@ -187,7 +186,7 @@ as artifacts.
The collected Container Scanning report will be uploaded to GitLab as an artifact and will
be summarized in the merge requests and pipeline view. It's also used to provide data for security
-dashboards. It's not available for download through the web interface.
+dashboards.
#### `artifacts:reports:dast` **(ULTIMATE)**
@@ -199,7 +198,7 @@ as artifacts.
The collected DAST report will be uploaded to GitLab as an artifact and will
be summarized in the merge requests and pipeline view. It's also used to provide data for security
-dashboards. It's not available for download through the web interface.
+dashboards.
#### `artifacts:reports:license_management` **(ULTIMATE)**
@@ -216,7 +215,7 @@ as artifacts.
The collected License Compliance report will be uploaded to GitLab as an artifact and will
be summarized in the merge requests and pipeline view. It's also used to provide data for security
-dashboards. It's not available for download through the web interface.
+dashboards.
#### `artifacts:reports:license_scanning` **(ULTIMATE)**
@@ -239,7 +238,7 @@ The `performance` report collects [Performance metrics](../../user/project/merge
as artifacts.
The collected Performance report will be uploaded to GitLab as an artifact and will
-be automatically shown in merge requests. It's not available for download through the web interface.
+be automatically shown in merge requests.
#### `artifacts:reports:metrics` **(PREMIUM)**
@@ -249,7 +248,7 @@ The `metrics` report collects [Metrics](../metrics_reports.md)
as artifacts.
The collected Metrics report will be uploaded to GitLab as an artifact and will
-be automatically shown in merge requests. It's not available for download through the web interface.
+be automatically shown in merge requests.
## Browsing artifacts
@@ -277,16 +276,16 @@ one HTML file that you can view directly online when
## Downloading artifacts
-If you need to download the whole archive, there are buttons in various places
+If you need to download an artifact or the whole archive, there are buttons in various places
in the GitLab UI to do this:
1. While on the pipelines page, you can see the download icon for each job's
- artifacts archive in the right corner:
+ artifacts and archive in the right corner:
![Job artifacts in Pipelines page](img/job_artifacts_pipelines_page.png)
1. While on the **Jobs** page, you can see the download icon for each job's
- artifacts archive in the right corner:
+ artifacts and archive in the right corner:
![Job artifacts in Builds page](img/job_artifacts_builds_page.png)
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index cdfa4b2fe43..ca393fbb63c 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -550,6 +550,24 @@ You can also
[configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer)
to display the results.
+Vale's test results are not currently displayed in CI, but may be displayed in the future.
+
+##### Disable a Vale test
+
+You can disable a specific Vale linting rule or all Vale linting rules for any portion of a document:
+
+- To disable a specific rule, add a `<!-- vale gitlab.rulename = NO -->` tag
+ before the text, and a `<!-- vale gitlab.rulename = YES -->` tag after the text,
+ replacing `rulename` with the filename of a test in the [GitLab styles](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc/.linting/vale/styles/gitlab) directory.
+- To disable all Vale linting rules, add a `<!-- vale off -->` tag before the text,
+ and a `<!-- vale on -->` tag after the text.
+
+Whenever possible, exclude only the problematic rule and line(s).
+In some cases, such as list items, you may need to disable linting for the entire
+list until ["Ignore comments are not honored in a Markdown file"](https://github.com/errata-ai/vale/issues/175) is resolved.
+
+For more information, see [Vale's documentation](https://errata-ai.gitbook.io/vale/getting-started/markup#markup-based-configuration).
+
## Danger Bot
GitLab uses [Danger](https://github.com/danger/danger) for some elements in
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 44f3a83bbcb..c75eccd71c1 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -308,12 +308,14 @@ tenses, words, and phrases:
appropriate way.
- Exceptions to this rule include commonly accepted technical terms, such as
CI/CD and TCP/IP.
-- We discourage use of Latin abbreviations, such as "e.g.," "i.e.," or "etc.,"
+- <!-- vale gitlab.LatinTerms = NO -->
+ We discourage use of Latin abbreviations, such as "e.g.," "i.e.," or "etc.,"
as even native users of English might misunderstand them.
- Instead of "i.e.," use "that is."
- Instead of "e.g.," use "for example," "such as," "for instance," or "like."
- Instead of "etc.," either use "and so on" or consider editing it out, since
it can be vague.
+ <!-- vale gitlab.rulename = NO -->
- Avoid using the word *currently* when talking about the product or its
features. The documentation describes the product as it is, and not as it
will be at some indeterminate point in the future.
@@ -379,6 +381,8 @@ tenses, words, and phrases:
| Requests to localhost are not allowed | Requests to localhost aren't allowed |
| Specified URL cannot be used | Specified URL can't be used |
+<!-- vale on -->
+
## Text
- [Write in Markdown](#markdown).
@@ -1308,7 +1312,7 @@ a helpful link back to how the feature was developed.
```
NOTE: **Note:**
-Version text must be on its own line and surounded by blank lines to render correctly.
+Version text must be on its own line and surrounded by blank lines to render correctly.
### Versions in the past or future
diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md
index 22e7375be1f..9d4fa5316c4 100644
--- a/doc/development/testing_guide/end_to_end/page_objects.md
+++ b/doc/development/testing_guide/end_to_end/page_objects.md
@@ -238,6 +238,53 @@ the view for code in a library.
In such rare cases it's reasonable to use CSS selectors in page object methods,
with a comment explaining why an `element` can't be added.
+### Define Page concerns
+
+Some pages share common behaviors, and/or are prepended with EE-specific modules that adds EE-specific methods.
+
+These modules must:
+
+1. Extend from the `QA::Page::PageConcern` module, with `extend QA::Page::PageConcern`.
+1. Override the `self.prepended` method if they need to `include`/`prepend` other modules themselves, and/or define
+ `view` or `elements`.
+1. Call `super` as the first thing in `self.prepended`.
+1. Include/prepend other modules and define their `view`/`elements` in a `base.class_eval` block to ensure they're
+ defined in the class that prepends the module.
+
+These steps ensure the sanity selectors check will detect problems properly.
+
+For example, `qa/qa/ee/page/merge_request/show.rb` adds EE-specific methods to `qa/qa/page/merge_request/show.rb` (with
+`QA::Page::MergeRequest::Show.prepend_if_ee('QA::EE::Page::MergeRequest::Show')`) and following is how it's implemented
+(only showing the relevant part and refering to the 4 steps described above with inline comments):
+
+```ruby
+module QA
+ module EE
+ module Page
+ module MergeRequest
+ module Show
+ extend QA::Page::PageConcern # 1.
+
+ def self.prepended(base) # 2.
+ super # 3.
+
+ base.class_eval do # 4.
+ prepend Page::Component::LicenseManagement
+
+ view 'app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue' do
+ element :head_mismatch, "The source branch HEAD has recently changed."
+ end
+
+ [...]
+ end
+ end
+ end
+ end
+ end
+ end
+end
+```
+
## Running the test locally
During development, you can run the `qa:selectors` test by running
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index c932f434684..2c980752dc4 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -469,7 +469,12 @@ vulnerabilities in your groups, projects and pipelines. Read more about the
Once a vulnerability is found, you can interact with it. Read more on how to
[interact with the vulnerabilities](../index.md#interacting-with-the-vulnerabilities).
-## Vulnerabilities database update
+## Vulnerabilities database
+
+Vulnerabilities contained within the vulnerability database can be searched
+and viewed at the [GitLab vulnerability advisory database](https://advisories.gitlab.com).
+
+### Vulnerabilities database update
For more information about the vulnerabilities database update, check the
[maintenance table](../index.md#maintenance-and-update-of-the-vulnerabilities-database).
diff --git a/doc/user/incident_management/index.md b/doc/user/incident_management/index.md
index d8294d35d2a..73d6e0e055d 100644
--- a/doc/user/incident_management/index.md
+++ b/doc/user/incident_management/index.md
@@ -1,5 +1,4 @@
---
-description: "GitLab - Incident Management. GitLab offers solutions for handling incidents in your applications and services"
stage: Monitor
group: Health
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
@@ -8,141 +7,106 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Incident Management
GitLab offers solutions for handling incidents in your applications and services,
-from setting up an alert with Prometheus, to receiving a notification via a
-monitoring tool like Slack, and automatically setting up Zoom calls with your
-support team.
+from setting up an alert with Prometheus, to receiving a notification through a
+monitoring tool like Slack, and [setting up Zoom calls](#zoom-integration-in-issues) with your
+support team. Incidents can display [metrics](#embed-metrics-in-incidents-and-issues)
+and [logs](#view-logs-from-metrics-panel).
-## Configuring incidents **(ULTIMATE)**
+## Configure incidents **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4925) in GitLab Ultimate 11.11.
-The Incident Management features can be enabled and disabled via your project's
-**Settings > Operations > Incidents**.
+You can enable or disable Incident Management features in your project's
+**{settings}** **Settings > Operations > Incidents**. Issues can be created for
+each alert triggered, and separate email notifications can be sent to users with
+[Developer permissions](../permissions.md). Appropriately configured alerts include an
+[embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues)
+for the query corresponding to the alert. You can also configure GitLab to
+[close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
+when you receive notification that the alert is resolved.
![Incident Management Settings](img/incident_management_settings.png)
-### Automatically create issues from alerts
+### Create issues from alerts
-GitLab issues can automatically be created as a result of an alert notification.
-An issue created this way will contain the error information to help you further
-debug it.
+You can create GitLab issues from an alert notification. These issues contain
+information about the alerts to help you diagnose the source of the alerts.
-### Issue templates
-
-You can create your own [issue templates](../project/description_templates.md#creating-issue-templates)
-that can be [used within Incident Management](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate).
-
-To select your issue template for use within Incident Management:
-
-1. Visit your project's **Settings > Operations > Incidents**.
+1. Visit your project's **{settings}** **Settings > Operations > Incidents**.
+1. Select the **Create an issue** checkbox for GitLab to create an issue from
+ the incident.
1. Select the template from the **Issue Template** dropdown.
+ You can create your own [issue templates](../project/description_templates.md#creating-issue-templates)
+ to [use within Incident Management](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate).
+1. Click **Save changes**.
-## Alerting
+## Notify developers of alerts
-GitLab can react to the alerts that your applications and services may be
-triggering by automatically creating issues, and alerting developers via email.
+GitLab can react to the alerts triggered from your applications and services
+by creating issues and alerting developers through email. GitLab sends these emails
+to [owners and maintainers](../permissions.md) of the project. They contain details
+of the alert, and a link for more information.
-The emails will be sent to [owners and maintainers](../permissions.md) of the project and will contain details on the alert as well as a link to see more information.
+### Configure Prometheus alerts
-### Prometheus alerts
+You can set up Prometheus alerts in:
-Prometheus alerts can be set up in both:
-
-- [GitLab-managed Prometheus](../project/integrations/prometheus.md#setting-up-alerts-for-prometheus-metrics) and
+- [GitLab-managed Prometheus](../project/integrations/prometheus.md#setting-up-alerts-for-prometheus-metrics) installations.
- [Self-managed Prometheus](../project/integrations/prometheus.md#external-prometheus-instances) installations.
-#### Alert Bot user
-
-Behind the scenes, Prometheus alerts are created by the special Alert Bot user creating issues. This user cannot be removed but does not count toward the license limit count.
-
-### Alert endpoint
+Prometheus alerts are created by the special Alert Bot user. You can't remove this
+user, but it does not count toward your license limit.
-GitLab can accept alerts from any source via a generic webhook receiver. When
-you set up the generic alerts integration, a unique endpoint will
-be created which can receive a payload in JSON format.
+### Configure external generic alerts
-[Read more on setting this up, including how to customize the payload](../project/integrations/generic_alerts.md).
+GitLab can accept alerts from any source through a generic webhook receiver. When
+[configuring the generic alerts integration](../project/integrations/generic_alerts.md),
+GitLab creates a unique endpoint which receives a JSON-formatted, customizable payload.
-### Recovery alerts
+## Embed metrics in incidents and issues
-GitLab can [automatically close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
-that have been automatically created when you receive notification that the
-alert is resolved.
-
-## Embedded metrics
-
-Metrics can be embedded anywhere where GitLab Markdown is used, for example,
-descriptions and comments on issues and merge requests.
-
-This can be useful for when you're sharing metrics, such as for discussing
-an incident or performance issues, so you can output the dashboard directly
+You can embed metrics anywhere GitLab Markdown is used, such as descriptions,
+comments on issues, and merge requests. Embedding metrics helps you share them
+when discussing incidents or performance issues. You can output the dashboard directly
into any issue, merge request, epic, or any other Markdown text field in GitLab
-by simply [copying and pasting the link to the metrics dashboard](../project/integrations/prometheus.md#embedding-gitlab-managed-kubernetes-metrics).
+by [copying and pasting the link to the metrics dashboard](../project/integrations/prometheus.md#embedding-gitlab-managed-kubernetes-metrics).
-TIP: **Tip:**
-Both GitLab-hosted and Grafana metrics can also be
-[embedded in issue templates](../project/integrations/prometheus.md#embedding-metrics-in-issue-templates).
+You can embed both
+[GitLab-hosted metrics](../project/integrations/prometheus.md#embedding-metric-charts-within-gitlab-flavored-markdown) and
+[Grafana metrics](../project/integrations/prometheus.md#embedding-grafana-charts)
+in incidents and issue templates.
-### GitLab-hosted metrics
-
-Learn how to embed [GitLab hosted metric charts](../project/integrations/prometheus.md#embedding-metric-charts-within-gitlab-flavored-markdown).
-
-#### Context menu
+### Context menu
From each of the embedded metrics panels, you can access more details
-about the data you are viewing from a context menu.
-
-You can access the context menu by clicking the **{ellipsis_v}** **More actions**
-dropdown box above the upper right corner of the panel:
+about the data you're viewing from a context menu. You can access the context menu
+by clicking the **{ellipsis_v}** **More actions** dropdown box above the
+upper right corner of the panel. The options are:
-The options are:
+- [View logs](#view-logs-from-metrics-panel).
+- **Download CSV** - Data from embedded charts can be
+ [downloaded as CSV](../project/integrations/prometheus.md#downloading-data-as-csv).
-- [View logs](#view-logs)
-- [Download CSV](#download-csv)
-
-##### View logs
+#### View logs from metrics panel
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201846) in GitLab Ultimate 12.8.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25455) to [GitLab Core](https://about.gitlab.com/pricing/) 12.9.
-This can be useful if you are triaging an application incident and need to
-[explore logs](../project/integrations/prometheus.md#view-logs-ultimate)
-from across your application. It also helps you to understand
-what is affecting your application's performance and quickly resolve any problems.
-
-##### Download CSV
-
-Data from embedded charts can be [downloaded as CSV](../project/integrations/prometheus.md#downloading-data-as-csv).
-
-### Grafana metrics
-
-Learn how to embed [Grafana hosted metric charts](../project/integrations/prometheus.md#embedding-grafana-charts).
+Viewing logs from a metrics panel can be useful if you're triaging an application
+incident and need to [explore logs](../project/integrations/prometheus.md#view-logs-ultimate)
+from across your application. These logs help you understand what is affecting
+your application's performance and resolve any problems.
## Slack integration
-Slack slash commands allow you to control GitLab and view content right inside
-Slack, without having to leave it.
+Slack slash commands allow you to control GitLab and view GitLab content without leaving Slack.
Learn how to [set up Slack slash commands](../project/integrations/slack_slash_commands.md)
-and how to [use them](../../integration/slash_commands.md).
-
-### Slash commands
-
-Please refer to a list of [available slash commands](../../integration/slash_commands.md) and associated descriptions.
-
-## Zoom in issues
-
-In order to communicate synchronously for incidents management, GitLab allows you to
-associate a Zoom meeting with an issue. Once you start a Zoom call for a fire-fight,
-you need a way to associate the conference call with an issue, so that your team
-members can join swiftly without requesting a link.
-
-Read more how to [add or remove a zoom meeting](../project/issues/associate_zoom_meeting.md).
-
-### Configuring Incidents
-
-Incident Management features can be easily enabled & disabled via the Project settings page. Head to Project -> Settings -> Operations -> Incidents.
+and how to [use the available slash commands](../../integration/slash_commands.md).
-#### Auto-creation
+## Zoom integration in issues
-You can automatically create GitLab issues from an Alert notification. Issues created this way contain error information to help you debug the error. Appropriately configured alerts include an [embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues) for the query corresponding to the alert.
+GitLab enables you to [associate a Zoom meeting with an issue](../project/issues/associate_zoom_meeting.md)
+for synchronous communication during incident management. After starting a Zoom
+call for an incident, you can associate the conference call with an issue, so your
+team members can join without requesting a link.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 6a4e0246090..86261d56ec3 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1725,6 +1725,15 @@ msgstr ""
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
msgstr ""
+msgid "After that, you will not to be able to use merge approvals or code quality as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many other features."
+msgstr ""
+
+msgid "After that, you will not to be able to use merge approvals or epics as well as many security features."
+msgstr ""
+
msgid "Alert"
msgid_plural "Alerts"
msgstr[0] ""
@@ -25014,7 +25023,7 @@ msgstr ""
msgid "YouTube"
msgstr ""
-msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
+msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
diff --git a/qa/qa.rb b/qa/qa.rb
index 73fccf3edd5..309a662a845 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -162,6 +162,7 @@ module QA
autoload :Base, 'qa/page/base'
autoload :View, 'qa/page/view'
autoload :Element, 'qa/page/element'
+ autoload :PageConcern, 'qa/page/page_concern'
autoload :Validator, 'qa/page/validator'
autoload :Validatable, 'qa/page/validatable'
@@ -248,7 +249,6 @@ module QA
end
module Settings
- autoload :Common, 'qa/page/project/settings/common'
autoload :Advanced, 'qa/page/project/settings/advanced'
autoload :Main, 'qa/page/project/settings/main'
autoload :Repository, 'qa/page/project/settings/repository'
@@ -409,6 +409,7 @@ module QA
autoload :Breadcrumbs, 'qa/page/component/breadcrumbs'
autoload :CiBadgeLink, 'qa/page/component/ci_badge_link'
autoload :ClonePanel, 'qa/page/component/clone_panel'
+ autoload :DesignManagement, 'qa/page/component/design_management'
autoload :LazyLoader, 'qa/page/component/lazy_loader'
autoload :LegacyClonePanel, 'qa/page/component/legacy_clone_panel'
autoload :Dropzone, 'qa/page/component/dropzone'
diff --git a/qa/qa/page/component/breadcrumbs.rb b/qa/qa/page/component/breadcrumbs.rb
index 656aa380bbd..2576e376e4e 100644
--- a/qa/qa/page/component/breadcrumbs.rb
+++ b/qa/qa/page/component/breadcrumbs.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module Breadcrumbs
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/layouts/nav/_breadcrumbs.html.haml' do
element :breadcrumb_links_content
end
diff --git a/qa/qa/page/component/ci_badge_link.rb b/qa/qa/page/component/ci_badge_link.rb
index 3db675c3a60..8629399e911 100644
--- a/qa/qa/page/component/ci_badge_link.rb
+++ b/qa/qa/page/component/ci_badge_link.rb
@@ -4,6 +4,8 @@ module QA
module Page
module Component
module CiBadgeLink
+ extend QA::Page::PageConcern
+
COMPLETED_STATUSES = %w[passed failed canceled blocked skipped manual].freeze # excludes created, pending, running
INCOMPLETE_STATUSES = %w[pending created running].freeze
@@ -27,6 +29,8 @@ module QA
end
def self.included(base)
+ super
+
base.view 'app/assets/javascripts/vue_shared/components/ci_badge_link.vue' do
element :status_badge
end
diff --git a/qa/qa/page/component/clone_panel.rb b/qa/qa/page/component/clone_panel.rb
index fbe19e5802b..a0aea6fe44d 100644
--- a/qa/qa/page/component/clone_panel.rb
+++ b/qa/qa/page/component/clone_panel.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module ClonePanel
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/projects/buttons/_clone.html.haml' do
element :clone_dropdown
element :clone_options
diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb
index 355e2783fb7..039640d207a 100644
--- a/qa/qa/page/component/confirm_modal.rb
+++ b/qa/qa/page/component/confirm_modal.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module ConfirmModal
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/shared/_confirm_modal.html.haml' do
element :confirm_modal
element :confirm_input
diff --git a/qa/qa/page/component/custom_metric.rb b/qa/qa/page/component/custom_metric.rb
index 9c402855709..094979f5e18 100644
--- a/qa/qa/page/component/custom_metric.rb
+++ b/qa/qa/page/component/custom_metric.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module CustomMetric
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/assets/javascripts/custom_metrics/components/custom_metrics_form_fields.vue' do
element :custom_metric_prometheus_title_field
element :custom_metric_prometheus_query_field
diff --git a/qa/qa/page/component/design_management.rb b/qa/qa/page/component/design_management.rb
index e61003cf350..a8a24bd3949 100644
--- a/qa/qa/page/component/design_management.rb
+++ b/qa/qa/page/component/design_management.rb
@@ -4,8 +4,12 @@ module QA
module Page
module Component
module DesignManagement
- def self.prepended(page)
- page.module_eval do
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
view 'app/assets/javascripts/design_management/components/design_notes/design_discussion.vue' do
element :design_discussion_content
end
diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb
index 7eb1257db71..f82bb81a3fc 100644
--- a/qa/qa/page/component/groups_filter.rb
+++ b/qa/qa/page/component/groups_filter.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module GroupsFilter
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/shared/groups/_search_form.html.haml' do
element :groups_filter
end
diff --git a/qa/qa/page/component/issuable/common.rb b/qa/qa/page/component/issuable/common.rb
index 1155d4da036..bbab1746d7a 100644
--- a/qa/qa/page/component/issuable/common.rb
+++ b/qa/qa/page/component/issuable/common.rb
@@ -5,7 +5,11 @@ module QA
module Component
module Issuable
module Common
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/assets/javascripts/issue_show/components/title.vue' do
element :edit_button
element :title, required: true
diff --git a/qa/qa/page/component/lazy_loader.rb b/qa/qa/page/component/lazy_loader.rb
index 6f74a4691ba..2123431fc55 100644
--- a/qa/qa/page/component/lazy_loader.rb
+++ b/qa/qa/page/component/lazy_loader.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module LazyLoader
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/assets/javascripts/lazy_loader.js' do
element :js_lazy_loaded
end
diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb
index 7b4b30623a6..ebab9fd708c 100644
--- a/qa/qa/page/component/legacy_clone_panel.rb
+++ b/qa/qa/page/component/legacy_clone_panel.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module LegacyClonePanel
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/shared/_clone_panel.html.haml' do
element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern
diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb
index 3e8ed9069ce..0e9cdd49519 100644
--- a/qa/qa/page/component/note.rb
+++ b/qa/qa/page/component/note.rb
@@ -4,7 +4,11 @@ module QA
module Page
module Component
module Note
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/assets/javascripts/notes/components/comment_form.vue' do
element :note_dropdown
element :discussion_option
diff --git a/qa/qa/page/component/web_ide/alert.rb b/qa/qa/page/component/web_ide/alert.rb
index 0f0623d5ebf..c2903662b52 100644
--- a/qa/qa/page/component/web_ide/alert.rb
+++ b/qa/qa/page/component/web_ide/alert.rb
@@ -5,8 +5,12 @@ module QA
module Component
module WebIDE
module Alert
- def self.prepended(page)
- page.module_eval do
+ extend QA::Page::PageConcern
+
+ def self.prepended(base)
+ super
+
+ base.class_eval do
view 'app/assets/javascripts/ide/components/error_message.vue' do
element :flash_alert
end
diff --git a/qa/qa/page/file/shared/commit_button.rb b/qa/qa/page/file/shared/commit_button.rb
index 9ea4f4e7818..c1c5907f27d 100644
--- a/qa/qa/page/file/shared/commit_button.rb
+++ b/qa/qa/page/file/shared/commit_button.rb
@@ -5,7 +5,11 @@ module QA
module File
module Shared
module CommitButton
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/projects/_commit_button.html.haml' do
element :commit_button
end
diff --git a/qa/qa/page/file/shared/commit_message.rb b/qa/qa/page/file/shared/commit_message.rb
index ce3b1e9939c..823ce7bf7f9 100644
--- a/qa/qa/page/file/shared/commit_message.rb
+++ b/qa/qa/page/file/shared/commit_message.rb
@@ -5,7 +5,11 @@ module QA
module File
module Shared
module CommitMessage
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/shared/_commit_message_container.html.haml' do
element :commit_message, "text_area_tag 'commit_message'" # rubocop:disable QA/ElementWithPattern
end
diff --git a/qa/qa/page/file/shared/editor.rb b/qa/qa/page/file/shared/editor.rb
index 448c09cfbca..ce4465d2a5c 100644
--- a/qa/qa/page/file/shared/editor.rb
+++ b/qa/qa/page/file/shared/editor.rb
@@ -5,7 +5,11 @@ module QA
module File
module Shared
module Editor
+ extend QA::Page::PageConcern
+
def self.included(base)
+ super
+
base.view 'app/views/projects/blob/_editor.html.haml' do
element :editor
end
diff --git a/qa/qa/page/group/sub_menus/common.rb b/qa/qa/page/group/sub_menus/common.rb
index 96efc8da98d..86102f70d29 100644
--- a/qa/qa/page/group/sub_menus/common.rb
+++ b/qa/qa/page/group/sub_menus/common.rb
@@ -5,9 +5,12 @@ module QA
module Group
module SubMenus
module Common
+ extend QA::Page::PageConcern
include QA::Page::SubMenus::Common
def self.included(base)
+ super
+
base.class_eval do
view 'app/views/layouts/nav/sidebar/_group.html.haml' do
element :group_sidebar
diff --git a/qa/qa/page/main/terms.rb b/qa/qa/page/main/terms.rb
index a4928f24397..a0de267fb31 100644
--- a/qa/qa/page/main/terms.rb
+++ b/qa/qa/page/main/terms.rb
@@ -1,20 +1,22 @@
# frozen_string_literal: true
module QA
- module Page::Main
- class Terms < Page::Base
- view 'app/views/layouts/terms.html.haml' do
- element :user_avatar, required: true
- end
+ module Page
+ module Main
+ class Terms < Page::Base
+ view 'app/views/layouts/terms.html.haml' do
+ element :user_avatar, required: true
+ end
- view 'app/views/users/terms/index.html.haml' do
- element :terms_content, required: true
+ view 'app/views/users/terms/index.html.haml' do
+ element :terms_content, required: true
- element :accept_terms_button
- end
+ element :accept_terms_button
+ end
- def accept_terms
- click_element :accept_terms_button, Page::Main::Menu
+ def accept_terms
+ click_element :accept_terms_button, Page::Main::Menu
+ end
end
end
end
diff --git a/qa/qa/page/page_concern.rb b/qa/qa/page/page_concern.rb
new file mode 100644
index 00000000000..6ba2d27f574
--- /dev/null
+++ b/qa/qa/page/page_concern.rb
@@ -0,0 +1,16 @@
+module QA
+ module Page
+ module PageConcern
+ def included(base)
+ unless base.is_a?(Class)
+ raise "Expected #{self} to be prepended to a class, but #{base} is a module!"
+ end
+
+ unless base.ancestors.include?(::QA::Page::Base)
+ raise "Expected #{self} to be prepended to a class that inherits from ::QA::Page::Base, but #{base} doesn't!"
+ end
+ end
+ alias_method :prepended, :included
+ end
+ end
+end
diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb
index 26db2f20c1b..971b8c5e5f8 100644
--- a/qa/qa/page/project/job/show.rb
+++ b/qa/qa/page/project/job/show.rb
@@ -1,51 +1,55 @@
# frozen_string_literal: true
-module QA::Page
- module Project::Job
- class Show < QA::Page::Base
- include Component::CiBadgeLink
+module QA
+ module Page
+ module Project
+ module Job
+ class Show < QA::Page::Base
+ include Component::CiBadgeLink
- view 'app/assets/javascripts/jobs/components/log/log.vue' do
- element :job_log_content
- end
+ view 'app/assets/javascripts/jobs/components/log/log.vue' do
+ element :job_log_content
+ end
- view 'app/assets/javascripts/jobs/components/stages_dropdown.vue' do
- element :pipeline_path
- end
+ view 'app/assets/javascripts/jobs/components/stages_dropdown.vue' do
+ element :pipeline_path
+ end
- view 'app/assets/javascripts/jobs/components/sidebar.vue' do
- element :retry_button
- end
+ view 'app/assets/javascripts/jobs/components/sidebar.vue' do
+ element :retry_button
+ end
- def successful?(timeout: 60)
- raise "Timed out waiting for the build trace to load" unless loaded?
- raise "Timed out waiting for the status to be a valid completed state" unless completed?(timeout: timeout)
+ def successful?(timeout: 60)
+ raise "Timed out waiting for the build trace to load" unless loaded?
+ raise "Timed out waiting for the status to be a valid completed state" unless completed?(timeout: timeout)
- passed?
- end
+ passed?
+ end
- # Reminder: You may wish to wait for a particular job status before checking output
- def output(wait: 5)
- result = ''
+ # Reminder: You may wish to wait for a particular job status before checking output
+ def output(wait: 5)
+ result = ''
- wait_until(reload: false, max_duration: wait, sleep_interval: 1) do
- result = find_element(:job_log_content).text
+ wait_until(reload: false, max_duration: wait, sleep_interval: 1) do
+ result = find_element(:job_log_content).text
- result.include?('Job')
- end
+ result.include?('Job')
+ end
- result
- end
+ result
+ end
- def retry!
- click_element :retry_button
- end
+ def retry!
+ click_element :retry_button
+ end
- private
+ private
- def loaded?(wait: 60)
- wait_until(reload: true, max_duration: wait, sleep_interval: 1) do
- has_element?(:job_log_content, wait: 1)
+ def loaded?(wait: 60)
+ wait_until(reload: true, max_duration: wait, sleep_interval: 1) do
+ has_element?(:job_log_content, wait: 1)
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb
index 327eedeaf91..54e4d0fb2fc 100644
--- a/qa/qa/page/project/pipeline/index.rb
+++ b/qa/qa/page/project/pipeline/index.rb
@@ -1,41 +1,45 @@
# frozen_string_literal: true
-module QA::Page
- module Project::Pipeline
- class Index < QA::Page::Base
- view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do
- element :pipeline_url_link
- end
-
- view 'app/assets/javascripts/pipelines/components/pipelines_table_row.vue' do
- element :pipeline_commit_status
- element :pipeline_retry_button
- end
-
- def click_on_latest_pipeline
- all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click
- end
-
- def wait_for_latest_pipeline_success
- wait_for_latest_pipeline_status { has_text?('passed') }
- end
-
- def wait_for_latest_pipeline_completion
- wait_for_latest_pipeline_status { has_text?('passed') || has_text?('failed') }
- end
-
- def wait_for_latest_pipeline_status
- wait_until(reload: false, max_duration: 360) do
- within_element_by_index(:pipeline_commit_status, 0) { yield }
- end
- end
-
- def wait_for_latest_pipeline_success_or_retry
- wait_for_latest_pipeline_completion
-
- if has_text?('failed')
- click_element :pipeline_retry_button
- wait_for_latest_pipeline_success
+module QA
+ module Page
+ module Project
+ module Pipeline
+ class Index < QA::Page::Base
+ view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do
+ element :pipeline_url_link
+ end
+
+ view 'app/assets/javascripts/pipelines/components/pipelines_table_row.vue' do
+ element :pipeline_commit_status
+ element :pipeline_retry_button
+ end
+
+ def click_on_latest_pipeline
+ all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click
+ end
+
+ def wait_for_latest_pipeline_success
+ wait_for_latest_pipeline_status { has_text?('passed') }
+ end
+
+ def wait_for_latest_pipeline_completion
+ wait_for_latest_pipeline_status { has_text?('passed') || has_text?('failed') }
+ end
+
+ def wait_for_latest_pipeline_status
+ wait_until(reload: false, max_duration: 360) do
+ within_element_by_index(:pipeline_commit_status, 0) { yield }
+ end
+ end
+
+ def wait_for_latest_pipeline_success_or_retry
+ wait_for_latest_pipeline_completion
+
+ if has_text?('failed')
+ click_element :pipeline_retry_button
+ wait_for_latest_pipeline_success
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb
index 1003b828a32..d22dfefc096 100644
--- a/qa/qa/page/project/pipeline/show.rb
+++ b/qa/qa/page/project/pipeline/show.rb
@@ -1,73 +1,77 @@
# frozen_string_literal: true
-module QA::Page
- module Project::Pipeline
- class Show < QA::Page::Base
- include Component::CiBadgeLink
-
- view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do
- element :pipeline_header, /header class.*ci-header-container.*/ # rubocop:disable QA/ElementWithPattern
- end
+module QA
+ module Page
+ module Project
+ module Pipeline
+ class Show < QA::Page::Base
+ include Component::CiBadgeLink
+
+ view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do
+ element :pipeline_header, /header class.*ci-header-container.*/ # rubocop:disable QA/ElementWithPattern
+ end
- view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do
- element :pipeline_graph, /class.*pipeline-graph.*/ # rubocop:disable QA/ElementWithPattern
- end
+ view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do
+ element :pipeline_graph, /class.*pipeline-graph.*/ # rubocop:disable QA/ElementWithPattern
+ end
- view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do
- element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern
- element :job_link
- end
+ view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do
+ element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern
+ element :job_link
+ end
- view 'app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue' do
- element :linked_pipeline_button
- end
+ view 'app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue' do
+ element :linked_pipeline_button
+ end
- view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do
- element :status_icon, 'ci-status-icon-${status}' # rubocop:disable QA/ElementWithPattern
- end
+ view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do
+ element :status_icon, 'ci-status-icon-${status}' # rubocop:disable QA/ElementWithPattern
+ end
- view 'app/views/projects/pipelines/_info.html.haml' do
- element :pipeline_badges
- end
+ view 'app/views/projects/pipelines/_info.html.haml' do
+ element :pipeline_badges
+ end
- def running?(wait: 0)
- within('.ci-header-container') do
- page.has_content?('running', wait: wait)
- end
- end
+ def running?(wait: 0)
+ within('.ci-header-container') do
+ page.has_content?('running', wait: wait)
+ end
+ end
- def has_build?(name, status: :success, wait: nil)
- within('.pipeline-graph') do
- within('.ci-job-component', text: name) do
- has_selector?(".ci-status-icon-#{status}", { wait: wait }.compact)
+ def has_build?(name, status: :success, wait: nil)
+ within('.pipeline-graph') do
+ within('.ci-job-component', text: name) do
+ has_selector?(".ci-status-icon-#{status}", { wait: wait }.compact)
+ end
+ end
end
- end
- end
- def has_job?(job_name)
- has_element?(:job_link, text: job_name)
- end
+ def has_job?(job_name)
+ has_element?(:job_link, text: job_name)
+ end
- def has_no_job?(job_name)
- has_no_element?(:job_link, text: job_name)
- end
+ def has_no_job?(job_name)
+ has_no_element?(:job_link, text: job_name)
+ end
- def has_tag?(tag_name)
- within_element(:pipeline_badges) do
- has_selector?('.badge', text: tag_name)
- end
- end
+ def has_tag?(tag_name)
+ within_element(:pipeline_badges) do
+ has_selector?('.badge', text: tag_name)
+ end
+ end
- def click_job(job_name)
- click_element(:job_link, text: job_name)
- end
+ def click_job(job_name)
+ click_element(:job_link, text: job_name)
+ end
- def click_linked_job(project_name)
- click_element(:linked_pipeline_button, text: /#{project_name}/)
- end
+ def click_linked_job(project_name)
+ click_element(:linked_pipeline_button, text: /#{project_name}/)
+ end
- def click_on_first_job
- first('.js-pipeline-graph-job-link', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).click
+ def click_on_first_job
+ first('.js-pipeline-graph-job-link', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).click
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb
index 6d4f05f877a..aa27c030b78 100644
--- a/qa/qa/page/project/settings/ci_cd.rb
+++ b/qa/qa/page/project/settings/ci_cd.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class CICD < Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/views/projects/settings/ci_cd/show.html.haml' do
element :autodevops_settings_content
diff --git a/qa/qa/page/project/settings/ci_variables.rb b/qa/qa/page/project/settings/ci_variables.rb
index 6cdf40cd1da..de268b14aa2 100644
--- a/qa/qa/page/project/settings/ci_variables.rb
+++ b/qa/qa/page/project/settings/ci_variables.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class CiVariables < Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue' do
element :ci_variable_key_field
diff --git a/qa/qa/page/project/settings/common.rb b/qa/qa/page/project/settings/common.rb
deleted file mode 100644
index f5f22623060..00000000000
--- a/qa/qa/page/project/settings/common.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Settings
- module Common
- include QA::Page::Settings::Common
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/settings/general_pipelines.rb b/qa/qa/page/project/settings/general_pipelines.rb
index 2265281a3f4..5a98849a41d 100644
--- a/qa/qa/page/project/settings/general_pipelines.rb
+++ b/qa/qa/page/project/settings/general_pipelines.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class GeneralPipelines < Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/views/projects/settings/ci_cd/_form.html.haml' do
element :build_coverage_regex_field
diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb
index 18d55598d90..efae497b6ba 100644
--- a/qa/qa/page/project/settings/main.rb
+++ b/qa/qa/page/project/settings/main.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class Main < Page::Base
- include Common
+ include QA::Page::Settings::Common
include Component::Select2
include SubMenus::Project
diff --git a/qa/qa/page/project/settings/merge_request.rb b/qa/qa/page/project/settings/merge_request.rb
index 7da2c9d168c..0092426b31f 100644
--- a/qa/qa/page/project/settings/merge_request.rb
+++ b/qa/qa/page/project/settings/merge_request.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class MergeRequest < QA::Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/views/projects/edit.html.haml' do
element :save_merge_request_changes
diff --git a/qa/qa/page/project/settings/operations.rb b/qa/qa/page/project/settings/operations.rb
index 637eba39f56..f6e005d3189 100644
--- a/qa/qa/page/project/settings/operations.rb
+++ b/qa/qa/page/project/settings/operations.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class Operations < Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/views/projects/settings/operations/_incidents.html.haml' do
element :incidents_settings_content
diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb
index e208fb308ee..8e9a24a4741 100644
--- a/qa/qa/page/project/settings/repository.rb
+++ b/qa/qa/page/project/settings/repository.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class Repository < Page::Base
- include Common
+ include QA::Page::Settings::Common
view 'app/views/projects/protected_branches/shared/_index.html.haml' do
element :protected_branches_settings
diff --git a/qa/qa/page/project/sub_menus/ci_cd.rb b/qa/qa/page/project/sub_menus/ci_cd.rb
index 2f0bc8b9ba6..9405ea97fff 100644
--- a/qa/qa/page/project/sub_menus/ci_cd.rb
+++ b/qa/qa/page/project/sub_menus/ci_cd.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module CiCd
- include Page::Project::SubMenus::Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :link_pipelines
end
diff --git a/qa/qa/page/project/sub_menus/common.rb b/qa/qa/page/project/sub_menus/common.rb
index da759398cff..85bf932be4a 100644
--- a/qa/qa/page/project/sub_menus/common.rb
+++ b/qa/qa/page/project/sub_menus/common.rb
@@ -5,6 +5,7 @@ module QA
module Project
module SubMenus
module Common
+ extend QA::Page::PageConcern
include QA::Page::SubMenus::Common
private
diff --git a/qa/qa/page/project/sub_menus/issues.rb b/qa/qa/page/project/sub_menus/issues.rb
index d27a250a300..c15a8ec4cc7 100644
--- a/qa/qa/page/project/sub_menus/issues.rb
+++ b/qa/qa/page/project/sub_menus/issues.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module Issues
- include Page::Project::SubMenus::Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :issue_boards_link
element :issues_item
diff --git a/qa/qa/page/project/sub_menus/operations.rb b/qa/qa/page/project/sub_menus/operations.rb
index 5d7c9869cde..ff9c8a21174 100644
--- a/qa/qa/page/project/sub_menus/operations.rb
+++ b/qa/qa/page/project/sub_menus/operations.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module Operations
- include Page::Project::SubMenus::Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :operations_link
element :operations_environments_link
diff --git a/qa/qa/page/project/sub_menus/project.rb b/qa/qa/page/project/sub_menus/project.rb
index 6f1bc131f84..4af640301b9 100644
--- a/qa/qa/page/project/sub_menus/project.rb
+++ b/qa/qa/page/project/sub_menus/project.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module Project
- include Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :project_link
end
diff --git a/qa/qa/page/project/sub_menus/repository.rb b/qa/qa/page/project/sub_menus/repository.rb
index 65149e631f3..38d6b8e50f4 100644
--- a/qa/qa/page/project/sub_menus/repository.rb
+++ b/qa/qa/page/project/sub_menus/repository.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module Repository
- include Page::Project::SubMenus::Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :project_menu_repo
element :branches_link
@@ -44,5 +48,3 @@ module QA
end
end
end
-
-QA::Page::Project::SubMenus::Repository.prepend_if_ee('QA::EE::Page::Project::SubMenus::Repository')
diff --git a/qa/qa/page/project/sub_menus/settings.rb b/qa/qa/page/project/sub_menus/settings.rb
index 1bbb6aaa5cf..0dd4bd1817a 100644
--- a/qa/qa/page/project/sub_menus/settings.rb
+++ b/qa/qa/page/project/sub_menus/settings.rb
@@ -5,10 +5,14 @@ module QA
module Project
module SubMenus
module Settings
- include Page::Project::SubMenus::Common
+ extend QA::Page::PageConcern
def self.included(base)
+ super
+
base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :settings_item
element :link_members_settings
diff --git a/qa/qa/page/search/results.rb b/qa/qa/page/search/results.rb
index 85f1d224935..55477db8804 100644
--- a/qa/qa/page/search/results.rb
+++ b/qa/qa/page/search/results.rb
@@ -1,53 +1,55 @@
# frozen_string_literal: true
-module QA::Page
- module Search
- class Results < QA::Page::Base
- view 'app/views/search/_category.html.haml' do
- element :code_tab
- element :projects_tab
- end
+module QA
+ module Page
+ module Search
+ class Results < QA::Page::Base
+ view 'app/views/search/_category.html.haml' do
+ element :code_tab
+ element :projects_tab
+ end
- view 'app/views/search/results/_blob_data.html.haml' do
- element :result_item_content
- element :file_title_content
- element :file_text_content
- end
+ view 'app/views/search/results/_blob_data.html.haml' do
+ element :result_item_content
+ element :file_title_content
+ element :file_text_content
+ end
- view 'app/views/shared/projects/_project.html.haml' do
- element :project
- end
+ view 'app/views/shared/projects/_project.html.haml' do
+ element :project
+ end
- def switch_to_code
- switch_to_tab(:code_tab)
- end
+ def switch_to_code
+ switch_to_tab(:code_tab)
+ end
- def switch_to_projects
- switch_to_tab(:projects_tab)
- end
+ def switch_to_projects
+ switch_to_tab(:projects_tab)
+ end
- def has_file_in_project?(file_name, project_name)
- has_element?(:result_item_content, text: "#{project_name}: #{file_name}")
- end
+ def has_file_in_project?(file_name, project_name)
+ has_element?(:result_item_content, text: "#{project_name}: #{file_name}")
+ end
- def has_file_with_content?(file_name, file_text)
- within_element_by_index(:result_item_content, 0) do
- break false unless has_element?(:file_title_content, text: file_name)
+ def has_file_with_content?(file_name, file_text)
+ within_element_by_index(:result_item_content, 0) do
+ break false unless has_element?(:file_title_content, text: file_name)
- has_element?(:file_text_content, text: file_text)
+ has_element?(:file_text_content, text: file_text)
+ end
end
- end
- def has_project?(project_name)
- has_element?(:project, project_name: project_name)
- end
+ def has_project?(project_name)
+ has_element?(:project, project_name: project_name)
+ end
- private
+ private
- def switch_to_tab(tab)
- retry_until do
- click_element(tab)
- has_active_element?(tab)
+ def switch_to_tab(tab)
+ retry_until do
+ click_element(tab)
+ has_active_element?(tab)
+ end
end
end
end
diff --git a/qa/qa/specs/helpers/quarantine.rb b/qa/qa/specs/helpers/quarantine.rb
index 8b14184f3b7..dd3a50ac128 100644
--- a/qa/qa/specs/helpers/quarantine.rb
+++ b/qa/qa/specs/helpers/quarantine.rb
@@ -2,83 +2,87 @@
require 'rspec/core'
-module QA::Specs::Helpers
- module Quarantine
- include RSpec::Core::Pending
+module QA
+ module Specs
+ module Helpers
+ module Quarantine
+ include RSpec::Core::Pending
- extend self
+ extend self
- def configure_rspec
- RSpec.configure do |config|
- config.before(:context, :quarantine) do
- Quarantine.skip_or_run_quarantined_contexts(config.inclusion_filter.rules, self.class)
- end
+ def configure_rspec
+ RSpec.configure do |config|
+ config.before(:context, :quarantine) do
+ Quarantine.skip_or_run_quarantined_contexts(config.inclusion_filter.rules, self.class)
+ end
- config.before do |example|
- Quarantine.skip_or_run_quarantined_tests_or_contexts(config.inclusion_filter.rules, example)
+ config.before do |example|
+ Quarantine.skip_or_run_quarantined_tests_or_contexts(config.inclusion_filter.rules, example)
+ end
+ end
end
- end
- end
- # Skip the entire context if a context is quarantined. This avoids running
- # before blocks unnecessarily.
- def skip_or_run_quarantined_contexts(filters, example)
- return unless example.metadata.key?(:quarantine)
+ # Skip the entire context if a context is quarantined. This avoids running
+ # before blocks unnecessarily.
+ def skip_or_run_quarantined_contexts(filters, example)
+ return unless example.metadata.key?(:quarantine)
- skip_or_run_quarantined_tests_or_contexts(filters, example)
- end
+ skip_or_run_quarantined_tests_or_contexts(filters, example)
+ end
- # Skip tests in quarantine unless we explicitly focus on them.
- def skip_or_run_quarantined_tests_or_contexts(filters, example)
- if filters.key?(:quarantine)
- included_filters = filters_other_than_quarantine(filters)
+ # Skip tests in quarantine unless we explicitly focus on them.
+ def skip_or_run_quarantined_tests_or_contexts(filters, example)
+ if filters.key?(:quarantine)
+ included_filters = filters_other_than_quarantine(filters)
- # If :quarantine is focused, skip the test/context unless its metadata
- # includes quarantine and any other filters
- # E.g., Suppose a test is tagged :smoke and :quarantine, and another is tagged
- # :ldap and :quarantine. If we wanted to run just quarantined smoke tests
- # using `--tag quarantine --tag smoke`, without this check we'd end up
- # running that ldap test as well because of the :quarantine metadata.
- # We could use an exclusion filter, but this way the test report will list
- # the quarantined tests when they're not run so that we're aware of them
- skip("Only running tests tagged with :quarantine and any of #{included_filters.keys}") if should_skip_when_focused?(example.metadata, included_filters)
- else
- if example.metadata.key?(:quarantine)
- quarantine_message = %w(In quarantine)
- quarantine_tag = example.metadata[:quarantine]
+ # If :quarantine is focused, skip the test/context unless its metadata
+ # includes quarantine and any other filters
+ # E.g., Suppose a test is tagged :smoke and :quarantine, and another is tagged
+ # :ldap and :quarantine. If we wanted to run just quarantined smoke tests
+ # using `--tag quarantine --tag smoke`, without this check we'd end up
+ # running that ldap test as well because of the :quarantine metadata.
+ # We could use an exclusion filter, but this way the test report will list
+ # the quarantined tests when they're not run so that we're aware of them
+ skip("Only running tests tagged with :quarantine and any of #{included_filters.keys}") if should_skip_when_focused?(example.metadata, included_filters)
+ else
+ if example.metadata.key?(:quarantine)
+ quarantine_message = %w(In quarantine)
+ quarantine_tag = example.metadata[:quarantine]
- if !!quarantine_tag
- quarantine_message << case quarantine_tag
- when String
- ": #{quarantine_tag}"
- when Hash
- ": #{quarantine_tag[:issue]}"
- else
- ''
- end
- end
+ if !!quarantine_tag
+ quarantine_message << case quarantine_tag
+ when String
+ ": #{quarantine_tag}"
+ when Hash
+ ": #{quarantine_tag[:issue]}"
+ else
+ ''
+ end
+ end
- skip(quarantine_message.join(' ').strip)
+ skip(quarantine_message.join(' ').strip)
+ end
+ end
end
- end
- end
- def filters_other_than_quarantine(filter)
- filter.reject { |key, _| key == :quarantine }
- end
+ def filters_other_than_quarantine(filter)
+ filter.reject { |key, _| key == :quarantine }
+ end
- # Checks if a test or context should be skipped.
- #
- # Returns true if
- # - the metadata does not includes the :quarantine tag
- # or if
- # - the metadata includes the :quarantine tag
- # - and the filter includes other tags that aren't in the metadata
- def should_skip_when_focused?(metadata, included_filters)
- return true unless metadata.key?(:quarantine)
- return false if included_filters.empty?
+ # Checks if a test or context should be skipped.
+ #
+ # Returns true if
+ # - the metadata does not includes the :quarantine tag
+ # or if
+ # - the metadata includes the :quarantine tag
+ # - and the filter includes other tags that aren't in the metadata
+ def should_skip_when_focused?(metadata, included_filters)
+ return true unless metadata.key?(:quarantine)
+ return false if included_filters.empty?
- (metadata.keys & included_filters.keys).empty?
+ (metadata.keys & included_filters.keys).empty?
+ end
+ end
end
end
end
diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js
index c80b132eab9..c4630ac57fe 100644
--- a/spec/frontend/alert_management/components/alert_management_list_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_list_spec.js
@@ -9,6 +9,7 @@ import {
GlIcon,
GlTab,
} from '@gitlab/ui';
+import { visitUrl } from '~/lib/utils/url_utility';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import createFlash from '~/flash';
import AlertManagementList from '~/alert_management/components/alert_management_list.vue';
@@ -18,6 +19,11 @@ import mockAlerts from '../mocks/alerts.json';
jest.mock('~/flash');
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn().mockName('visitUrlMock'),
+ joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
+}));
+
describe('AlertManagementList', () => {
let wrapper;
@@ -220,12 +226,10 @@ describe('AlertManagementList', () => {
loading: false,
});
- window.location.assign = jest.fn();
-
findAlerts()
.at(0)
.trigger('click');
- expect(window.location.assign).toHaveBeenCalledWith('/1527542/details');
+ expect(visitUrl).toHaveBeenCalledWith('/1527542/details');
});
describe('handle date fields', () => {
diff --git a/spec/uploaders/content_type_whitelist_spec.rb b/spec/uploaders/content_type_whitelist_spec.rb
index 4689f83759d..32d030cdfee 100644
--- a/spec/uploaders/content_type_whitelist_spec.rb
+++ b/spec/uploaders/content_type_whitelist_spec.rb
@@ -3,16 +3,20 @@
require 'spec_helper'
describe ContentTypeWhitelist do
- class DummyUploader < CarrierWave::Uploader::Base
- include ContentTypeWhitelist::Concern
+ let_it_be(:model) { build_stubbed(:user) }
+ let!(:uploader) do
+ stub_const('DummyUploader', Class.new(CarrierWave::Uploader::Base))
+
+ DummyUploader.class_eval do
+ include ContentTypeWhitelist::Concern
- def content_type_whitelist
- %w[image/png image/jpeg]
+ def content_type_whitelist
+ %w[image/png image/jpeg]
+ end
end
- end
- let_it_be(:model) { build_stubbed(:user) }
- let_it_be(:uploader) { DummyUploader.new(model, :dummy) }
+ DummyUploader.new(model, :dummy)
+ end
context 'upload whitelisted file content type' do
let(:path) { File.join('spec', 'fixtures', 'rails_sample.jpg') }