Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f397d486bc
commit
4905885126
55 changed files with 317 additions and 176 deletions
|
@ -701,3 +701,11 @@ RSpec/TopLevelDescribePath:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/fixtures/**/*.rb'
|
- 'spec/fixtures/**/*.rb'
|
||||||
- 'ee/spec/fixtures/**/*.rb'
|
- 'ee/spec/fixtures/**/*.rb'
|
||||||
|
|
||||||
|
QA/SelectorUsage:
|
||||||
|
Enabled: true
|
||||||
|
Include:
|
||||||
|
- 'spec/**/*.rb'
|
||||||
|
- 'ee/spec/**/*.rb'
|
||||||
|
Exclude:
|
||||||
|
- 'spec/rubocop/**/*_spec.rb'
|
||||||
|
|
|
@ -140,16 +140,13 @@ export default {
|
||||||
},
|
},
|
||||||
(line) => line.type,
|
(line) => line.type,
|
||||||
),
|
),
|
||||||
lineContent: memoize(
|
lineContent: (line) => {
|
||||||
(line) => {
|
if (line.isConflictMarker) {
|
||||||
if (line.isConflictMarker) {
|
return line.type === CONFLICT_MARKER_THEIR ? 'HEAD//our changes' : 'origin//their changes';
|
||||||
return line.type === CONFLICT_MARKER_THEIR ? 'HEAD//our changes' : 'origin//their changes';
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return line.rich_text;
|
return line.rich_text;
|
||||||
},
|
},
|
||||||
(line) => line.line_code,
|
|
||||||
),
|
|
||||||
CONFLICT_MARKER,
|
CONFLICT_MARKER,
|
||||||
CONFLICT_MARKER_THEIR,
|
CONFLICT_MARKER_THEIR,
|
||||||
CONFLICT_OUR,
|
CONFLICT_OUR,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
featureAccessLevel,
|
featureAccessLevel,
|
||||||
featureAccessLevelNone,
|
featureAccessLevelNone,
|
||||||
CVE_ID_REQUEST_BUTTON_I18N,
|
CVE_ID_REQUEST_BUTTON_I18N,
|
||||||
|
featureAccessLevelDescriptions,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { toggleHiddenClassBySelector } from '../external';
|
import { toggleHiddenClassBySelector } from '../external';
|
||||||
import projectFeatureSetting from './project_feature_setting.vue';
|
import projectFeatureSetting from './project_feature_setting.vue';
|
||||||
|
@ -176,7 +177,7 @@ export default {
|
||||||
requirementsAccessLevel: featureAccessLevel.EVERYONE,
|
requirementsAccessLevel: featureAccessLevel.EVERYONE,
|
||||||
securityAndComplianceAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
|
securityAndComplianceAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
|
||||||
operationsAccessLevel: featureAccessLevel.EVERYONE,
|
operationsAccessLevel: featureAccessLevel.EVERYONE,
|
||||||
containerRegistryEnabled: true,
|
containerRegistryAccessLevel: featureAccessLevel.EVERYONE,
|
||||||
lfsEnabled: true,
|
lfsEnabled: true,
|
||||||
requestAccessEnabled: true,
|
requestAccessEnabled: true,
|
||||||
highlightChangesClass: false,
|
highlightChangesClass: false,
|
||||||
|
@ -184,6 +185,8 @@ export default {
|
||||||
cveIdRequestEnabled: true,
|
cveIdRequestEnabled: true,
|
||||||
featureAccessLevelEveryone,
|
featureAccessLevelEveryone,
|
||||||
featureAccessLevelMembers,
|
featureAccessLevelMembers,
|
||||||
|
featureAccessLevel,
|
||||||
|
featureAccessLevelDescriptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
return { ...defaults, ...this.currentSettings };
|
return { ...defaults, ...this.currentSettings };
|
||||||
|
@ -248,7 +251,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
showContainerRegistryPublicNote() {
|
showContainerRegistryPublicNote() {
|
||||||
return this.visibilityLevel === visibilityOptions.PUBLIC;
|
return (
|
||||||
|
this.visibilityLevel === visibilityOptions.PUBLIC &&
|
||||||
|
this.containerRegistryAccessLevel === featureAccessLevel.EVERYONE
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
repositoryHelpText() {
|
repositoryHelpText() {
|
||||||
|
@ -310,6 +316,10 @@ export default {
|
||||||
featureAccessLevel.PROJECT_MEMBERS,
|
featureAccessLevel.PROJECT_MEMBERS,
|
||||||
this.operationsAccessLevel,
|
this.operationsAccessLevel,
|
||||||
);
|
);
|
||||||
|
this.containerRegistryAccessLevel = Math.min(
|
||||||
|
featureAccessLevel.PROJECT_MEMBERS,
|
||||||
|
this.containerRegistryAccessLevel,
|
||||||
|
);
|
||||||
if (this.pagesAccessLevel === featureAccessLevel.EVERYONE) {
|
if (this.pagesAccessLevel === featureAccessLevel.EVERYONE) {
|
||||||
// When from Internal->Private narrow access for only members
|
// When from Internal->Private narrow access for only members
|
||||||
this.pagesAccessLevel = featureAccessLevel.PROJECT_MEMBERS;
|
this.pagesAccessLevel = featureAccessLevel.PROJECT_MEMBERS;
|
||||||
|
@ -339,6 +349,8 @@ export default {
|
||||||
this.requirementsAccessLevel = featureAccessLevel.EVERYONE;
|
this.requirementsAccessLevel = featureAccessLevel.EVERYONE;
|
||||||
if (this.operationsAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
|
if (this.operationsAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
|
||||||
this.operationsAccessLevel = featureAccessLevel.EVERYONE;
|
this.operationsAccessLevel = featureAccessLevel.EVERYONE;
|
||||||
|
if (this.containerRegistryAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
|
||||||
|
this.containerRegistryAccessLevel = featureAccessLevel.EVERYONE;
|
||||||
|
|
||||||
this.highlightChanges();
|
this.highlightChanges();
|
||||||
}
|
}
|
||||||
|
@ -521,19 +533,24 @@ export default {
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div v-if="showContainerRegistryPublicNote" class="text-muted">
|
<div v-if="showContainerRegistryPublicNote" class="text-muted">
|
||||||
{{
|
<gl-sprintf
|
||||||
s__(
|
:message="
|
||||||
'ProjectSettings|Note: the container registry is always visible when a project is public',
|
s__(
|
||||||
)
|
`ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'`,
|
||||||
}}
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #access_level_description>{{
|
||||||
|
featureAccessLevelDescriptions[featureAccessLevel.EVERYONE]
|
||||||
|
}}</template>
|
||||||
|
</gl-sprintf>
|
||||||
</div>
|
</div>
|
||||||
<gl-toggle
|
<project-feature-setting
|
||||||
v-model="containerRegistryEnabled"
|
v-model="containerRegistryAccessLevel"
|
||||||
class="gl-my-2"
|
:options="repoFeatureAccessLevelOptions"
|
||||||
:disabled="!repositoryEnabled"
|
:disabled-input="!repositoryEnabled"
|
||||||
:label="$options.i18n.containerRegistryLabel"
|
:label="$options.i18n.containerRegistryLabel"
|
||||||
label-position="hidden"
|
name="project[project_feature_attributes][container_registry_access_level]"
|
||||||
name="project[container_registry_enabled]"
|
|
||||||
/>
|
/>
|
||||||
</project-setting-row>
|
</project-setting-row>
|
||||||
<project-setting-row
|
<project-setting-row
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const featureAccessLevel = {
|
||||||
EVERYONE: 20,
|
EVERYONE: 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
const featureAccessLevelDescriptions = {
|
export const featureAccessLevelDescriptions = {
|
||||||
[featureAccessLevel.NOT_ENABLED]: __('Enable feature to choose access level'),
|
[featureAccessLevel.NOT_ENABLED]: __('Enable feature to choose access level'),
|
||||||
[featureAccessLevel.PROJECT_MEMBERS]: __('Only Project Members'),
|
[featureAccessLevel.PROJECT_MEMBERS]: __('Only Project Members'),
|
||||||
[featureAccessLevel.EVERYONE]: __('Everyone With Access'),
|
[featureAccessLevel.EVERYONE]: __('Everyone With Access'),
|
||||||
|
|
|
@ -6,28 +6,19 @@ import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants';
|
||||||
|
|
||||||
const ALERT_DATA = {
|
const ALERT_DATA = {
|
||||||
[INSTANCE_TYPE]: {
|
[INSTANCE_TYPE]: {
|
||||||
title: s__(
|
|
||||||
'Runners|This runner is available to all groups and projects in your GitLab instance.',
|
|
||||||
),
|
|
||||||
message: s__(
|
message: s__(
|
||||||
'Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner.',
|
'Runners|This runner is available to all groups and projects in your GitLab instance.',
|
||||||
),
|
),
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
anchor: 'shared-runners',
|
anchor: 'shared-runners',
|
||||||
},
|
},
|
||||||
[GROUP_TYPE]: {
|
[GROUP_TYPE]: {
|
||||||
title: s__('Runners|This runner is available to all projects and subgroups in a group.'),
|
message: s__('Runners|This runner is available to all projects and subgroups in a group.'),
|
||||||
message: s__(
|
|
||||||
'Runners|Use Group runners when you want all projects in a group to have access to a set of runners.',
|
|
||||||
),
|
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
anchor: 'group-runners',
|
anchor: 'group-runners',
|
||||||
},
|
},
|
||||||
[PROJECT_TYPE]: {
|
[PROJECT_TYPE]: {
|
||||||
title: s__('Runners|This runner is associated with specific projects.'),
|
message: s__('Runners|This runner is associated with one or more projects.'),
|
||||||
message: s__(
|
|
||||||
'Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner.',
|
|
||||||
),
|
|
||||||
variant: 'info',
|
variant: 'info',
|
||||||
anchor: 'specific-runners',
|
anchor: 'specific-runners',
|
||||||
},
|
},
|
||||||
|
@ -59,7 +50,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<gl-alert v-if="alert" :variant="alert.variant" :title="alert.title" :dismissible="false">
|
<gl-alert v-if="alert" :variant="alert.variant" :dismissible="false">
|
||||||
{{ alert.message }}
|
{{ alert.message }}
|
||||||
<gl-link :href="helpHref">{{ __('Learn more.') }}</gl-link>
|
<gl-link :href="helpHref">{{ __('Learn more.') }}</gl-link>
|
||||||
</gl-alert>
|
</gl-alert>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
|
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
|
||||||
import { __, sprintf } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import { isUserBusy } from '~/set_status_modal/utils';
|
import { isUserBusy } from '~/set_status_modal/utils';
|
||||||
import AssigneeAvatar from './assignee_avatar.vue';
|
import AssigneeAvatar from './assignee_avatar.vue';
|
||||||
|
|
||||||
|
@ -32,10 +32,9 @@ const generateAssigneeTooltip = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltipHasName && statusInformation.length) {
|
if (tooltipHasName && statusInformation.length) {
|
||||||
return sprintf(__('%{name} %{status}'), {
|
const status = statusInformation.map(paranthesize).join(' ');
|
||||||
name,
|
|
||||||
status: statusInformation.map(paranthesize).join(' '),
|
return `${name} ${status}`;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
|
|
@ -480,7 +480,7 @@ body {
|
||||||
.btn:active,
|
.btn:active,
|
||||||
.btn.active {
|
.btn.active {
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
border-color: #fafafa;
|
border-color: #4f4f4f;
|
||||||
color: #fafafa;
|
color: #fafafa;
|
||||||
}
|
}
|
||||||
.btn svg {
|
.btn svg {
|
||||||
|
|
|
@ -186,8 +186,7 @@ body.gl-dark {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$border-white-light: $gray-900;
|
$border-white-normal: $border-color;
|
||||||
$border-white-normal: $gray-900;
|
|
||||||
|
|
||||||
$body-bg: $gray-10;
|
$body-bg: $gray-10;
|
||||||
$input-bg: $white;
|
$input-bg: $white;
|
||||||
|
|
|
@ -51,7 +51,7 @@ module Git
|
||||||
change: change,
|
change: change,
|
||||||
push_options: params[:push_options],
|
push_options: params[:push_options],
|
||||||
merge_request_branches: merge_request_branches,
|
merge_request_branches: merge_request_branches,
|
||||||
create_pipelines: change[:index] < PIPELINE_PROCESS_LIMIT || Feature.enabled?(:git_push_create_all_pipelines, project),
|
create_pipelines: under_process_limit?(change),
|
||||||
execute_project_hooks: execute_project_hooks,
|
execute_project_hooks: execute_project_hooks,
|
||||||
create_push_event: !create_bulk_push_event
|
create_push_event: !create_bulk_push_event
|
||||||
).execute
|
).execute
|
||||||
|
@ -60,6 +60,10 @@ module Git
|
||||||
create_bulk_push_event(ref_type, action, changes) if create_bulk_push_event
|
create_bulk_push_event(ref_type, action, changes) if create_bulk_push_event
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def under_process_limit?(change)
|
||||||
|
change[:index] < PIPELINE_PROCESS_LIMIT || Feature.enabled?(:git_push_create_all_pipelines, project)
|
||||||
|
end
|
||||||
|
|
||||||
def create_bulk_push_event(ref_type, action, changes)
|
def create_bulk_push_event(ref_type, action, changes)
|
||||||
EventCreateService.new.bulk_push(
|
EventCreateService.new.bulk_push(
|
||||||
project,
|
project,
|
||||||
|
|
|
@ -20,7 +20,7 @@ if gitlab.mr_body.size < 5
|
||||||
end
|
end
|
||||||
|
|
||||||
if (THROUGHPUT_LABELS & gitlab.mr_labels).empty?
|
if (THROUGHPUT_LABELS & gitlab.mr_labels).empty?
|
||||||
warn 'Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#data-classification) to this merge request.'
|
warn 'Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) to this merge request.'
|
||||||
end
|
end
|
||||||
|
|
||||||
unless gitlab.mr_json["assignee"]
|
unless gitlab.mr_json["assignee"]
|
||||||
|
|
|
@ -40,9 +40,9 @@ There are no reviewer and maintainer suggestions for the changes in this MR.
|
||||||
MARKDOWN
|
MARKDOWN
|
||||||
|
|
||||||
UNKNOWN_FILES_MESSAGE = <<MARKDOWN
|
UNKNOWN_FILES_MESSAGE = <<MARKDOWN
|
||||||
### Uncategorised files
|
### Uncategorized files
|
||||||
|
|
||||||
These files couldn't be categorised, so Danger was unable to suggest a reviewer.
|
These files couldn't be categorized, so Danger was unable to suggest a reviewer.
|
||||||
Please consider creating a merge request to
|
Please consider creating a merge request to
|
||||||
[add support](https://gitlab.com/gitlab-org/gitlab/blob/master/tooling/danger/project_helper.rb)
|
[add support](https://gitlab.com/gitlab-org/gitlab/blob/master/tooling/danger/project_helper.rb)
|
||||||
for them.
|
for them.
|
||||||
|
|
|
@ -320,7 +320,7 @@ create an issue or an MR to propose a change to the user interface text.
|
||||||
- *Feature names are typically lowercase*.
|
- *Feature names are typically lowercase*.
|
||||||
- *Some features are capitalized*, typically nouns naming GitLab-specific
|
- *Some features are capitalized*, typically nouns naming GitLab-specific
|
||||||
capabilities or tools.
|
capabilities or tools.
|
||||||
|
|
||||||
See the [word list](word_list.md) for details.
|
See the [word list](word_list.md) for details.
|
||||||
|
|
||||||
If the term is not in the word list, ask a GitLab Technical Writer for advice.
|
If the term is not in the word list, ask a GitLab Technical Writer for advice.
|
||||||
|
@ -839,7 +839,7 @@ We include guidance for links in these categories:
|
||||||
### Basic link criteria
|
### Basic link criteria
|
||||||
|
|
||||||
- Use inline link Markdown markup `[Text](https://example.com)`.
|
- Use inline link Markdown markup `[Text](https://example.com)`.
|
||||||
It's easier to read, review, and maintain. _Do not_ use `[Text][identifier]`.
|
It's easier to read, review, and maintain. _Do not_ use `[Text][identifier]` reference-style links.
|
||||||
|
|
||||||
- Use [meaningful anchor texts](https://www.futurehosting.com/blog/links-should-have-meaningful-anchor-text-heres-why/).
|
- Use [meaningful anchor texts](https://www.futurehosting.com/blog/links-should-have-meaningful-anchor-text-heres-why/).
|
||||||
For example, instead of writing something like `Read more about GitLab Issue Boards [here](LINK)`,
|
For example, instead of writing something like `Read more about GitLab Issue Boards [here](LINK)`,
|
||||||
|
|
|
@ -745,6 +745,25 @@ You can, however, remove the Container Registry for a project:
|
||||||
|
|
||||||
The **Packages & Registries > Container Registry** entry is removed from the project's sidebar.
|
The **Packages & Registries > Container Registry** entry is removed from the project's sidebar.
|
||||||
|
|
||||||
|
## Set visibility of the Container Registry
|
||||||
|
|
||||||
|
By default, the Container Registry is visible to everyone with access to the project.
|
||||||
|
You can, however, change the visibility of the Container Registry for a project:
|
||||||
|
|
||||||
|
1. Go to your project's **Settings > General** page.
|
||||||
|
1. Expand the section **Visibility, project features, permissions**.
|
||||||
|
1. Under **Container Registry**, select an option from the dropdown:
|
||||||
|
|
||||||
|
- **Everyone With Access** (Default): The Container Registry is visible to everyone with access
|
||||||
|
to the project. If the project is public, the Container Registry is also public. If the project
|
||||||
|
is internal or private, the Container Registry is also internal or private.
|
||||||
|
|
||||||
|
- **Only Project Members**: The Container Registry is visible only to project members with
|
||||||
|
Reporter role or higher. This is similar to the behavior of a private project with Container
|
||||||
|
Registry visibility set to **Everyone With Access**.
|
||||||
|
|
||||||
|
1. Select **Save changes**.
|
||||||
|
|
||||||
## Manifest lists and garbage collection
|
## Manifest lists and garbage collection
|
||||||
|
|
||||||
Manifest lists are commonly used for creating multi-architecture images. If you rely on manifest
|
Manifest lists are commonly used for creating multi-architecture images. If you rely on manifest
|
||||||
|
|
|
@ -733,9 +733,6 @@ msgstr ""
|
||||||
msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes. No new jobs or pipelines in its projects will run."
|
msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes. No new jobs or pipelines in its projects will run."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "%{name} %{status}"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "%{name} (Busy)"
|
msgid "%{name} (Busy)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -26025,7 +26022,7 @@ msgstr ""
|
||||||
msgid "ProjectSettings|No merge commits are created."
|
msgid "ProjectSettings|No merge commits are created."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "ProjectSettings|Note: the container registry is always visible when a project is public"
|
msgid "ProjectSettings|Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
|
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
|
||||||
|
@ -28607,6 +28604,9 @@ msgstr ""
|
||||||
msgid "Runners|Tags"
|
msgid "Runners|Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Runners|This runner is associated with one or more projects."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Runners|This runner is associated with specific projects."
|
msgid "Runners|This runner is associated with specific projects."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ module QA
|
||||||
install:
|
install:
|
||||||
stage: install
|
stage: install
|
||||||
script:
|
script:
|
||||||
- "pip install mypypipackage --no-deps --index-url http://#{personal_access_token}:#{personal_access_token}@#{gitlab_host_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host #{gitlab_host_with_port}"
|
- "pip install mypypipackage --no-deps --index-url #{uri.scheme}://#{personal_access_token}:#{personal_access_token}@#{gitlab_host_with_port}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host #{gitlab_host_with_port}"
|
||||||
tags:
|
tags:
|
||||||
- "runner-for-#{project.name}"
|
- "runner-for-#{project.name}"
|
||||||
|
|
||||||
|
|
39
rubocop/cop/qa/selector_usage.rb
Normal file
39
rubocop/cop/qa/selector_usage.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative '../../qa_helpers'
|
||||||
|
require_relative '../../code_reuse_helpers'
|
||||||
|
|
||||||
|
module RuboCop
|
||||||
|
module Cop
|
||||||
|
module QA
|
||||||
|
# This cop checks for the usage of data-qa-selectors or .qa-* classes in non-QA files
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# # bad
|
||||||
|
# find('[data-qa-selector="the_selector"]')
|
||||||
|
# find('.qa-selector')
|
||||||
|
#
|
||||||
|
# # good
|
||||||
|
# find('[data-testid="the_selector"]')
|
||||||
|
# find('#selector')
|
||||||
|
class SelectorUsage < RuboCop::Cop::Cop
|
||||||
|
include QAHelpers
|
||||||
|
include CodeReuseHelpers
|
||||||
|
|
||||||
|
SELECTORS = /\.qa-\w+|data-qa-\w+/.freeze
|
||||||
|
MESSAGE = %(Do not use `%s` as this is reserved for the end-to-end specs. Use a different selector or a data-testid instead.)
|
||||||
|
|
||||||
|
def on_str(node)
|
||||||
|
return if in_qa_file?(node)
|
||||||
|
return unless in_spec?(node)
|
||||||
|
|
||||||
|
add_offense(node, message: MESSAGE % node.value) if SELECTORS =~ node.value
|
||||||
|
rescue StandardError
|
||||||
|
# catch all errors and ignore them.
|
||||||
|
# without this catch-all rescue, rubocop will fail
|
||||||
|
# because of non-UTF-8 characters in some Strings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -90,7 +90,7 @@ RSpec.describe 'Admin Appearance' do
|
||||||
sign_in(admin)
|
sign_in(admin)
|
||||||
gitlab_enable_admin_mode_sign_in(admin)
|
gitlab_enable_admin_mode_sign_in(admin)
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect_custom_new_project_appearance(appearance)
|
expect_custom_new_project_appearance(appearance)
|
||||||
end
|
end
|
||||||
|
|
|
@ -256,7 +256,7 @@ RSpec.describe 'Admin Groups' do
|
||||||
|
|
||||||
visit group_group_members_path(group)
|
visit group_group_members_path(group)
|
||||||
|
|
||||||
page.within '[data-qa-selector="members_list"]' do
|
page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
|
||||||
expect(page).to have_content(current_user.name)
|
expect(page).to have_content(current_user.name)
|
||||||
expect(page).to have_content('Developer')
|
expect(page).to have_content('Developer')
|
||||||
end
|
end
|
||||||
|
@ -265,7 +265,7 @@ RSpec.describe 'Admin Groups' do
|
||||||
|
|
||||||
visit group_group_members_path(group)
|
visit group_group_members_path(group)
|
||||||
|
|
||||||
page.within '[data-qa-selector="members_list"]' do
|
page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
|
||||||
expect(page).not_to have_content(current_user.name)
|
expect(page).not_to have_content(current_user.name)
|
||||||
expect(page).not_to have_content('Developer')
|
expect(page).not_to have_content('Developer')
|
||||||
end
|
end
|
||||||
|
|
|
@ -184,7 +184,7 @@ RSpec.describe 'Admin::Users::User' do
|
||||||
it 'logs in as the user when impersonate is clicked' do
|
it 'logs in as the user when impersonate is clicked' do
|
||||||
subject
|
subject
|
||||||
|
|
||||||
find('[data-qa-selector="user_menu"]').click
|
find('[data-qa-selector="user_menu"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eql(another_user.username)
|
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eql(another_user.username)
|
||||||
end
|
end
|
||||||
|
@ -220,7 +220,7 @@ RSpec.describe 'Admin::Users::User' do
|
||||||
it 'logs out of impersonated user back to original user' do
|
it 'logs out of impersonated user back to original user' do
|
||||||
subject
|
subject
|
||||||
|
|
||||||
find('[data-qa-selector="user_menu"]').click
|
find('[data-qa-selector="user_menu"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eq(current_user.username)
|
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eq(current_user.username)
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
|
||||||
|
|
||||||
context 'resolving the thread' do
|
context 'resolving the thread' do
|
||||||
before do
|
before do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the link for creating a new issue' do
|
it 'hides the link for creating a new issue' do
|
||||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
|
||||||
|
|
||||||
context 'resolving the thread' do
|
context 'resolving the thread' do
|
||||||
before do
|
before do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the link for creating a new issue' do
|
it 'hides the link for creating a new issue' do
|
||||||
|
|
|
@ -408,7 +408,7 @@ RSpec.describe 'Issue Sidebar' do
|
||||||
|
|
||||||
context 'sidebar', :js do
|
context 'sidebar', :js do
|
||||||
it 'finds issue copy forwarding email' do
|
it 'finds issue copy forwarding email' do
|
||||||
expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}"
|
expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}" # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ RSpec.describe 'Issue Sidebar' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not find issue email' do
|
it 'does not find issue email' do
|
||||||
expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]')
|
expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -182,7 +182,7 @@ RSpec.describe "User creates issue" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not hide the milestone select' do
|
it 'does not hide the milestone select' do
|
||||||
expect(page).to have_selector('.qa-issuable-milestone-dropdown')
|
expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,11 +202,11 @@ RSpec.describe "User creates issue" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows the milestone select' do
|
it 'shows the milestone select' do
|
||||||
expect(page).to have_selector('.qa-issuable-milestone-dropdown')
|
expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the weight input' do
|
it 'hides the weight input' do
|
||||||
expect(page).not_to have_selector('.qa-issuable-weight-input')
|
expect(page).not_to have_selector('.qa-issuable-weight-input') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows the incident help text' do
|
it 'shows the incident help text' do
|
||||||
|
|
|
@ -63,7 +63,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to mark thread as resolved' do
|
it 'allows user to mark thread as resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_selector('.discussion-body', visible: false)
|
expect(page).to have_selector('.discussion-body', visible: false)
|
||||||
|
@ -80,7 +80,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to unresolve thread' do
|
it 'allows user to unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
click_button 'Unresolve thread'
|
click_button 'Unresolve thread'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
describe 'resolved thread' do
|
describe 'resolved thread' do
|
||||||
before do
|
before do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
visit_merge_request
|
visit_merge_request
|
||||||
|
@ -193,7 +193,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to resolve from reply form without a comment' do
|
it 'allows user to resolve from reply form without a comment' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.line-resolve-all-container' do
|
page.within '.line-resolve-all-container' do
|
||||||
|
@ -230,7 +230,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'hides jump to next button when all resolved' do
|
it 'hides jump to next button when all resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_selector('.discussion-next-btn', visible: false)
|
expect(page).to have_selector('.discussion-next-btn', visible: false)
|
||||||
|
@ -326,7 +326,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
it 'allows user to mark all threads as resolved' do
|
it 'allows user to mark all threads as resolved' do
|
||||||
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
|
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
|
||||||
page.within reply_holder do
|
page.within reply_holder do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to quickly scroll to next unresolved thread' do
|
it 'allows user to quickly scroll to next unresolved thread' do
|
||||||
page.within('.discussion-reply-holder', match: :first) do
|
page.within('.discussion-reply-holder', match: :first) do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.line-resolve-all-container' do
|
page.within '.line-resolve-all-container' do
|
||||||
|
@ -410,7 +410,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to mark thread as resolved' do
|
it 'allows user to mark thread as resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.diff-content .note' do
|
page.within '.diff-content .note' do
|
||||||
|
@ -425,7 +425,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to unresolve thread' do
|
it 'allows user to unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
click_button 'Unresolve thread'
|
click_button 'Unresolve thread'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to comment & unresolve thread' do
|
it 'allows user to comment & unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
find_field('Reply…').click
|
find_field('Reply…').click
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ RSpec.describe 'Project variables', :js do
|
||||||
click_button('Add variable')
|
click_button('Add variable')
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set('akey')
|
find('[data-qa-selector="ci_variable_key_field"] input').set('akey') # rubocop:disable QA/SelectorUsage
|
||||||
find('#ci-variable-value').set('akey_value')
|
find('#ci-variable-value').set('akey_value')
|
||||||
find('[data-testid="environment-scope"]').click
|
find('[data-testid="environment-scope"]').click
|
||||||
find('[data-testid="ci-environment-search"]').set('review/*')
|
find('[data-testid="ci-environment-search"]').set('review/*')
|
||||||
|
|
|
@ -137,7 +137,7 @@ RSpec.describe 'File blob', :js do
|
||||||
|
|
||||||
context 'when ref switch' do
|
context 'when ref switch' do
|
||||||
def switch_ref_to(ref_name)
|
def switch_ref_to(ref_name)
|
||||||
first('.qa-branches-select').click
|
first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
page.within '.project-refs-form' do
|
page.within '.project-refs-form' do
|
||||||
click_link ref_name
|
click_link ref_name
|
||||||
|
|
|
@ -30,9 +30,9 @@ RSpec.describe 'Environment > Metrics' do
|
||||||
click_link 'Monitoring'
|
click_link 'Monitoring'
|
||||||
|
|
||||||
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
|
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
|
||||||
expect(page).to have_css('[data-qa-selector="environments_dropdown"]')
|
expect(page).to have_css('[data-qa-selector="environments_dropdown"]') # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
within('[data-qa-selector="environments_dropdown"]') do
|
within('[data-qa-selector="environments_dropdown"]') do # rubocop:disable QA/SelectorUsage
|
||||||
# Click on the dropdown
|
# Click on the dropdown
|
||||||
click_on(environment.name)
|
click_on(environment.name)
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ RSpec.describe 'Environment > Metrics' do
|
||||||
it 'shows metrics', :js do
|
it 'shows metrics', :js do
|
||||||
click_link 'Monitoring'
|
click_link 'Monitoring'
|
||||||
|
|
||||||
expect(page).to have_css('[data-qa-selector="prometheus_graphs"]')
|
expect(page).to have_css('[data-qa-selector="prometheus_graphs"]') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'has environment selector'
|
it_behaves_like 'has environment selector'
|
||||||
|
|
|
@ -455,10 +455,10 @@ RSpec.describe 'Environments page', :js do
|
||||||
expect(page).to have_content 'review-1'
|
expect(page).to have_content 'review-1'
|
||||||
expect(page).to have_content 'review-2'
|
expect(page).to have_content 'review-2'
|
||||||
within('.ci-table') do
|
within('.ci-table') do
|
||||||
within('[data-qa-selector="environment_item"]', text: 'review-1') do
|
within('[data-qa-selector="environment_item"]', text: 'review-1') do # rubocop:disable QA/SelectorUsage
|
||||||
expect(find('.js-auto-stop').text).not_to be_empty
|
expect(find('.js-auto-stop').text).not_to be_empty
|
||||||
end
|
end
|
||||||
within('[data-qa-selector="environment_item"]', text: 'review-2') do
|
within('[data-qa-selector="environment_item"]', text: 'review-2') do # rubocop:disable QA/SelectorUsage
|
||||||
expect(find('.js-auto-stop').text).not_to be_empty
|
expect(find('.js-auto-stop').text).not_to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,7 +50,7 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
|
||||||
|
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
page.within('.qa-pods-dropdown') do
|
page.within('.qa-pods-dropdown') do # rubocop:disable QA/SelectorUsage
|
||||||
find(".dropdown-toggle:not([disabled])").click
|
find(".dropdown-toggle:not([disabled])").click
|
||||||
|
|
||||||
dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])")
|
dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])")
|
||||||
|
|
|
@ -91,7 +91,7 @@ RSpec.describe 'User sees feature flag list', :js do
|
||||||
it 'shows the empty page' do
|
it 'shows the empty page' do
|
||||||
expect(page).to have_text 'Get started with feature flags'
|
expect(page).to have_text 'Get started with feature flags'
|
||||||
expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
|
expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
|
||||||
expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure')
|
expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license
|
||||||
|
|
||||||
expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
|
expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
|
||||||
|
|
||||||
expect(page).to have_selector('.qa-file-templates-bar')
|
expect(page).to have_selector('.qa-file-templates-bar') # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
select_template('MIT License')
|
select_template('MIT License')
|
||||||
|
|
||||||
|
|
|
@ -181,8 +181,8 @@ RSpec.describe 'Project fork' do
|
||||||
it 'allows user to fork only to the group on fork page', :js do
|
it 'allows user to fork only to the group on fork page', :js do
|
||||||
visit new_project_fork_path(project)
|
visit new_project_fork_path(project)
|
||||||
|
|
||||||
to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled')
|
to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled') # rubocop:disable QA/SelectorUsage
|
||||||
to_group = find(".fork-groups button[data-qa-name=#{group.name}]")
|
to_group = find(".fork-groups button[data-qa-name=#{group.name}]") # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(to_personal_namespace).not_to be_nil
|
expect(to_personal_namespace).not_to be_nil
|
||||||
expect(to_group).not_to be_disabled
|
expect(to_group).not_to be_disabled
|
||||||
|
|
|
@ -62,6 +62,6 @@ RSpec.describe 'Import/Export - project import integration test', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_import_project
|
def click_import_project
|
||||||
find('[data-qa-panel-name="import_project"]').click
|
find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
|
||||||
using RSpec::Parameterized::TableSyntax
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
where(:invite_members_group_modal_enabled, :expected_invite_group_selector) do
|
where(:invite_members_group_modal_enabled, :expected_invite_group_selector) do
|
||||||
true | 'button[data-qa-selector="invite_a_group_button"]'
|
true | 'button[data-qa-selector="invite_a_group_button"]' # rubocop:disable QA/SelectorUsage
|
||||||
false | '#invite-group-tab'
|
false | '#invite-group-tab'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Share with group lock' do
|
describe 'Share with group lock' do
|
||||||
let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' }
|
let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' } # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
shared_examples 'the project can be shared with groups' do
|
shared_examples 'the project can be shared with groups' do
|
||||||
it 'the "Invite a group" button exists' do
|
it 'the "Invite a group" button exists' do
|
||||||
|
|
|
@ -19,7 +19,7 @@ RSpec.describe 'New project', :js do
|
||||||
)
|
)
|
||||||
|
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
|
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
|
||||||
end
|
end
|
||||||
|
@ -30,7 +30,7 @@ RSpec.describe 'New project', :js do
|
||||||
)
|
)
|
||||||
|
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
|
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
|
||||||
end
|
end
|
||||||
|
@ -45,14 +45,14 @@ RSpec.describe 'New project', :js do
|
||||||
|
|
||||||
it 'shows "New project" page', :js do
|
it 'shows "New project" page', :js do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).to have_content('Project name')
|
expect(page).to have_content('Project name')
|
||||||
expect(page).to have_content('Project URL')
|
expect(page).to have_content('Project URL')
|
||||||
expect(page).to have_content('Project slug')
|
expect(page).to have_content('Project slug')
|
||||||
|
|
||||||
click_link('New project')
|
click_link('New project')
|
||||||
find('[data-qa-panel-name="import_project"]').click
|
find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).to have_link('GitHub')
|
expect(page).to have_link('GitHub')
|
||||||
expect(page).to have_link('Bitbucket')
|
expect(page).to have_link('Bitbucket')
|
||||||
|
@ -65,7 +65,7 @@ RSpec.describe 'New project', :js do
|
||||||
before do
|
before do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
|
|
||||||
find('[data-qa-panel-name="import_project"]').click
|
find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has Manifest file' do
|
it 'has Manifest file' do
|
||||||
|
@ -79,7 +79,7 @@ RSpec.describe 'New project', :js do
|
||||||
stub_application_setting(default_project_visibility: level)
|
stub_application_setting(default_project_visibility: level)
|
||||||
|
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
page.within('#blank-project-pane') do
|
page.within('#blank-project-pane') do
|
||||||
expect(find_field("project_visibility_level_#{level}")).to be_checked
|
expect(find_field("project_visibility_level_#{level}")).to be_checked
|
||||||
end
|
end
|
||||||
|
@ -87,7 +87,7 @@ RSpec.describe 'New project', :js do
|
||||||
|
|
||||||
it "saves visibility level #{level} on validation error" do
|
it "saves visibility level #{level} on validation error" do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
choose(key)
|
choose(key)
|
||||||
click_button('Create project')
|
click_button('Create project')
|
||||||
|
@ -107,7 +107,7 @@ RSpec.describe 'New project', :js do
|
||||||
context 'when admin mode is enabled', :enable_admin_mode do
|
context 'when admin mode is enabled', :enable_admin_mode do
|
||||||
it 'has private selected' do
|
it 'has private selected' do
|
||||||
visit new_project_path(namespace_id: group.id)
|
visit new_project_path(namespace_id: group.id)
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
page.within('#blank-project-pane') do
|
page.within('#blank-project-pane') do
|
||||||
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
|
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
|
||||||
|
@ -134,7 +134,7 @@ RSpec.describe 'New project', :js do
|
||||||
context 'when admin mode is enabled', :enable_admin_mode do
|
context 'when admin mode is enabled', :enable_admin_mode do
|
||||||
it 'has private selected' do
|
it 'has private selected' do
|
||||||
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
|
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
page.within('#blank-project-pane') do
|
page.within('#blank-project-pane') do
|
||||||
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
|
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
|
||||||
|
@ -155,7 +155,7 @@ RSpec.describe 'New project', :js do
|
||||||
context 'Readme selector' do
|
context 'Readme selector' do
|
||||||
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
|
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).to have_css('input#project_initialize_with_readme')
|
expect(page).to have_css('input#project_initialize_with_readme')
|
||||||
expect(page).to have_content('Initialize repository with a README')
|
expect(page).to have_content('Initialize repository with a README')
|
||||||
|
@ -163,7 +163,7 @@ RSpec.describe 'New project', :js do
|
||||||
|
|
||||||
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
|
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="create_from_template"]').click
|
find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage
|
||||||
first('.choose-template').click
|
first('.choose-template').click
|
||||||
|
|
||||||
page.within '.project-fields-form' do
|
page.within '.project-fields-form' do
|
||||||
|
@ -174,7 +174,7 @@ RSpec.describe 'New project', :js do
|
||||||
|
|
||||||
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
|
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="import_project"]').click
|
find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
first('.js-import-git-toggle-button').click
|
first('.js-import-git-toggle-button').click
|
||||||
|
|
||||||
page.within '#import-project-pane' do
|
page.within '#import-project-pane' do
|
||||||
|
@ -188,7 +188,7 @@ RSpec.describe 'New project', :js do
|
||||||
context 'with user namespace' do
|
context 'with user namespace' do
|
||||||
before do
|
before do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'selects the user namespace' do
|
it 'selects the user namespace' do
|
||||||
|
@ -204,7 +204,7 @@ RSpec.describe 'New project', :js do
|
||||||
before do
|
before do
|
||||||
group.add_owner(user)
|
group.add_owner(user)
|
||||||
visit new_project_path(namespace_id: group.id)
|
visit new_project_path(namespace_id: group.id)
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'selects the group namespace' do
|
it 'selects the group namespace' do
|
||||||
|
@ -221,7 +221,7 @@ RSpec.describe 'New project', :js do
|
||||||
before do
|
before do
|
||||||
group.add_maintainer(user)
|
group.add_maintainer(user)
|
||||||
visit new_project_path(namespace_id: subgroup.id)
|
visit new_project_path(namespace_id: subgroup.id)
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'selects the group namespace' do
|
it 'selects the group namespace' do
|
||||||
|
@ -241,7 +241,7 @@ RSpec.describe 'New project', :js do
|
||||||
internal_group.add_owner(user)
|
internal_group.add_owner(user)
|
||||||
private_group.add_owner(user)
|
private_group.add_owner(user)
|
||||||
visit new_project_path(namespace_id: public_group.id)
|
visit new_project_path(namespace_id: public_group.id)
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'enables the correct visibility options' do
|
it 'enables the correct visibility options' do
|
||||||
|
@ -271,7 +271,7 @@ RSpec.describe 'New project', :js do
|
||||||
context 'Import project options', :js do
|
context 'Import project options', :js do
|
||||||
before do
|
before do
|
||||||
visit new_project_path
|
visit new_project_path
|
||||||
find('[data-qa-panel-name="import_project"]').click
|
find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'from git repository url, "Repo by URL"' do
|
context 'from git repository url, "Repo by URL"' do
|
||||||
|
@ -343,7 +343,7 @@ RSpec.describe 'New project', :js do
|
||||||
before do
|
before do
|
||||||
group.add_developer(user)
|
group.add_developer(user)
|
||||||
visit new_project_path(namespace_id: group.id)
|
visit new_project_path(namespace_id: group.id)
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'selects the group namespace' do
|
it 'selects the group namespace' do
|
||||||
|
|
|
@ -39,7 +39,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
|
||||||
|
|
||||||
# The dropdown above the tree
|
# The dropdown above the tree
|
||||||
page.within('.repo-breadcrumb') do
|
page.within('.repo-breadcrumb') do
|
||||||
find('.qa-add-to-tree').click
|
find('.qa-add-to-tree').click # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
aggregate_failures 'dropdown links above the repo tree' do
|
aggregate_failures 'dropdown links above the repo tree' do
|
||||||
expect(page).to have_link('New file')
|
expect(page).to have_link('New file')
|
||||||
|
@ -71,7 +71,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
|
||||||
find_new_menu_toggle.click
|
find_new_menu_toggle.click
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).not_to have_selector('.qa-add-to-tree')
|
expect(page).not_to have_selector('.qa-add-to-tree') # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
expect(page).not_to have_link('Web IDE')
|
expect(page).not_to have_link('Web IDE')
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,8 +49,8 @@ RSpec.describe 'Multi-file editor new directory', :js do
|
||||||
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
|
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
|
||||||
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
|
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
|
||||||
# taller (as it is by default with chrome headless) then the button will not exist.
|
# taller (as it is by default with chrome headless) then the button will not exist.
|
||||||
if page.has_css?('.qa-begin-commit-button')
|
if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
|
||||||
find('.qa-begin-commit-button').click
|
find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
fill_in('commit-message', with: 'commit message ide')
|
fill_in('commit-message', with: 'commit message ide')
|
||||||
|
|
|
@ -39,8 +39,8 @@ RSpec.describe 'Multi-file editor new file', :js do
|
||||||
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
|
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
|
||||||
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
|
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
|
||||||
# taller (as it is by default with chrome headless) then the button will not exist.
|
# taller (as it is by default with chrome headless) then the button will not exist.
|
||||||
if page.has_css?('.qa-begin-commit-button')
|
if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
|
||||||
find('.qa-begin-commit-button').click
|
find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
fill_in('commit-message', with: 'commit message ide')
|
fill_in('commit-message', with: 'commit message ide')
|
||||||
|
|
|
@ -26,7 +26,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
expect(page).to have_selector('.tree-item')
|
expect(page).to have_selector('.tree-item')
|
||||||
expect(page).to have_content('add tests for .gitattributes custom highlighting')
|
expect(page).to have_content('add tests for .gitattributes custom highlighting')
|
||||||
expect(page).not_to have_selector('.flash-alert')
|
expect(page).not_to have_selector('.flash-alert')
|
||||||
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
|
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders tree table for a subtree without errors' do
|
it 'renders tree table for a subtree without errors' do
|
||||||
|
@ -35,7 +35,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
|
|
||||||
expect(page).to have_selector('.tree-item')
|
expect(page).to have_selector('.tree-item')
|
||||||
expect(page).to have_content('add spaces in whitespace file')
|
expect(page).to have_content('add spaces in whitespace file')
|
||||||
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
|
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
||||||
expect(page).not_to have_selector('.flash-alert')
|
expect(page).not_to have_selector('.flash-alert')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
it 'renders LFS badge on blob item' do
|
it 'renders LFS badge on blob item' do
|
||||||
visit project_tree_path(project, File.join('master', 'files/lfs'))
|
visit project_tree_path(project, File.join('master', 'files/lfs'))
|
||||||
|
|
||||||
expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
|
expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe 'User creates a project', :js do
|
||||||
it 'creates a new project' do
|
it 'creates a new project' do
|
||||||
visit(new_project_path)
|
visit(new_project_path)
|
||||||
|
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
fill_in(:project_name, with: 'Empty')
|
fill_in(:project_name, with: 'Empty')
|
||||||
|
|
||||||
expect(page).to have_checked_field 'Initialize repository with a README'
|
expect(page).to have_checked_field 'Initialize repository with a README'
|
||||||
|
@ -43,7 +43,7 @@ RSpec.describe 'User creates a project', :js do
|
||||||
it 'creates a new project' do
|
it 'creates a new project' do
|
||||||
visit(new_project_path)
|
visit(new_project_path)
|
||||||
|
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
fill_in :project_name, with: 'A Subgroup Project'
|
fill_in :project_name, with: 'A Subgroup Project'
|
||||||
fill_in :project_path, with: 'a-subgroup-project'
|
fill_in :project_path, with: 'a-subgroup-project'
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ RSpec.describe 'User creates a project', :js do
|
||||||
it 'creates a new project' do
|
it 'creates a new project' do
|
||||||
visit(new_project_path)
|
visit(new_project_path)
|
||||||
|
|
||||||
find('[data-qa-panel-name="blank_project"]').click
|
find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
|
||||||
fill_in :project_name, with: 'a-new-project'
|
fill_in :project_name, with: 'a-new-project'
|
||||||
fill_in :project_path, with: 'a-new-project'
|
fill_in :project_path, with: 'a-new-project'
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe 'Project' do
|
||||||
|
|
||||||
shared_examples 'creates from template' do |template, sub_template_tab = nil|
|
shared_examples 'creates from template' do |template, sub_template_tab = nil|
|
||||||
it "is created from template", :js do
|
it "is created from template", :js do
|
||||||
find('[data-qa-panel-name="create_from_template"]').click
|
find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage
|
||||||
find(".project-template #{sub_template_tab}").click if sub_template_tab
|
find(".project-template #{sub_template_tab}").click if sub_template_tab
|
||||||
find("label[for=#{template.name}]").click
|
find("label[for=#{template.name}]").click
|
||||||
fill_in("project_name", with: template.name)
|
fill_in("project_name", with: template.name)
|
||||||
|
@ -290,7 +290,7 @@ RSpec.describe 'Project' do
|
||||||
it 'has working links to submodules' do
|
it 'has working links to submodules' do
|
||||||
click_link('645f6c4c')
|
click_link('645f6c4c')
|
||||||
|
|
||||||
expect(page).to have_selector('.qa-branches-select', text: '645f6c4c82fd3f5e06f67134450a570b795e55a6')
|
expect(page).to have_selector('.qa-branches-select', text: '645f6c4c82fd3f5e06f67134450a570b795e55a6') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for signed commit on default branch', :js do
|
context 'for signed commit on default branch', :js do
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { GlToggle } from '@gitlab/ui';
|
import { GlSprintf, GlToggle } from '@gitlab/ui';
|
||||||
import { shallowMount, mount } from '@vue/test-utils';
|
import { shallowMount, mount } from '@vue/test-utils';
|
||||||
import projectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue';
|
import projectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue';
|
||||||
import settingsPanel from '~/pages/projects/shared/permissions/components/settings_panel.vue';
|
import settingsPanel from '~/pages/projects/shared/permissions/components/settings_panel.vue';
|
||||||
|
@ -22,7 +22,7 @@ const defaultProps = {
|
||||||
operationsAccessLevel: 20,
|
operationsAccessLevel: 20,
|
||||||
pagesAccessLevel: 10,
|
pagesAccessLevel: 10,
|
||||||
analyticsAccessLevel: 20,
|
analyticsAccessLevel: 20,
|
||||||
containerRegistryEnabled: true,
|
containerRegistryAccessLevel: 20,
|
||||||
lfsEnabled: true,
|
lfsEnabled: true,
|
||||||
emailsDisabled: false,
|
emailsDisabled: false,
|
||||||
packagesEnabled: true,
|
packagesEnabled: true,
|
||||||
|
@ -85,8 +85,10 @@ describe('Settings Panel', () => {
|
||||||
const findBuildsAccessLevelInput = () =>
|
const findBuildsAccessLevelInput = () =>
|
||||||
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]');
|
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]');
|
||||||
const findContainerRegistrySettings = () => wrapper.find({ ref: 'container-registry-settings' });
|
const findContainerRegistrySettings = () => wrapper.find({ ref: 'container-registry-settings' });
|
||||||
const findContainerRegistryEnabledInput = () =>
|
const findContainerRegistryPublicNoteGlSprintfComponent = () =>
|
||||||
wrapper.find('[name="project[container_registry_enabled]"]');
|
findContainerRegistrySettings().findComponent(GlSprintf);
|
||||||
|
const findContainerRegistryAccessLevelInput = () =>
|
||||||
|
wrapper.find('[name="project[project_feature_attributes][container_registry_access_level]"]');
|
||||||
const findPackageSettings = () => wrapper.find({ ref: 'package-settings' });
|
const findPackageSettings = () => wrapper.find({ ref: 'package-settings' });
|
||||||
const findPackagesEnabledInput = () => wrapper.find('[name="project[packages_enabled]"]');
|
const findPackagesEnabledInput = () => wrapper.find('[name="project[packages_enabled]"]');
|
||||||
const findPagesSettings = () => wrapper.find({ ref: 'pages-settings' });
|
const findPagesSettings = () => wrapper.find({ ref: 'pages-settings' });
|
||||||
|
@ -275,24 +277,38 @@ describe('Settings Panel', () => {
|
||||||
|
|
||||||
it('should show the container registry public note if the visibility level is public and the registry is available', () => {
|
it('should show the container registry public note if the visibility level is public and the registry is available', () => {
|
||||||
wrapper = mountComponent({
|
wrapper = mountComponent({
|
||||||
currentSettings: { visibilityLevel: visibilityOptions.PUBLIC },
|
currentSettings: {
|
||||||
|
visibilityLevel: visibilityOptions.PUBLIC,
|
||||||
|
containerRegistryAccessLevel: featureAccessLevel.EVERYONE,
|
||||||
|
},
|
||||||
registryAvailable: true,
|
registryAvailable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findContainerRegistrySettings().text()).toContain(
|
expect(findContainerRegistryPublicNoteGlSprintfComponent().exists()).toBe(true);
|
||||||
'Note: the container registry is always visible when a project is public',
|
expect(findContainerRegistryPublicNoteGlSprintfComponent().attributes('message')).toContain(
|
||||||
|
`Note: The container registry is always visible when a project is public and the container registry is set to '%{access_level_description}'`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should hide the container registry public note if the visibility level is public but the registry is private', () => {
|
||||||
|
wrapper = mountComponent({
|
||||||
|
currentSettings: {
|
||||||
|
visibilityLevel: visibilityOptions.PUBLIC,
|
||||||
|
containerRegistryAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
|
||||||
|
},
|
||||||
|
registryAvailable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(findContainerRegistryPublicNoteGlSprintfComponent().exists()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('should hide the container registry public note if the visibility level is private and the registry is available', () => {
|
it('should hide the container registry public note if the visibility level is private and the registry is available', () => {
|
||||||
wrapper = mountComponent({
|
wrapper = mountComponent({
|
||||||
currentSettings: { visibilityLevel: visibilityOptions.PRIVATE },
|
currentSettings: { visibilityLevel: visibilityOptions.PRIVATE },
|
||||||
registryAvailable: true,
|
registryAvailable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findContainerRegistrySettings().text()).not.toContain(
|
expect(findContainerRegistryPublicNoteGlSprintfComponent().exists()).toBe(false);
|
||||||
'Note: the container registry is always visible when a project is public',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should enable the container registry input when the repository is enabled', () => {
|
it('should enable the container registry input when the repository is enabled', () => {
|
||||||
|
@ -301,7 +317,7 @@ describe('Settings Panel', () => {
|
||||||
registryAvailable: true,
|
registryAvailable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findContainerRegistryEnabledInput().props('disabled')).toBe(false);
|
expect(findContainerRegistryAccessLevelInput().props('disabledInput')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should disable the container registry input when the repository is disabled', () => {
|
it('should disable the container registry input when the repository is disabled', () => {
|
||||||
|
@ -310,7 +326,7 @@ describe('Settings Panel', () => {
|
||||||
registryAvailable: true,
|
registryAvailable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findContainerRegistryEnabledInput().props('disabled')).toBe(true);
|
expect(findContainerRegistryAccessLevelInput().props('disabledInput')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has label for the toggle', () => {
|
it('has label for the toggle', () => {
|
||||||
|
@ -319,7 +335,7 @@ describe('Settings Panel', () => {
|
||||||
registryAvailable: true,
|
registryAvailable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findContainerRegistrySettings().findComponent(GlToggle).props('label')).toBe(
|
expect(findContainerRegistryAccessLevelInput().props('label')).toBe(
|
||||||
settingsPanel.i18n.containerRegistryLabel,
|
settingsPanel.i18n.containerRegistryLabel,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,10 +23,10 @@ describe('RunnerTypeAlert', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.each`
|
describe.each`
|
||||||
type | exampleText | anchor | variant
|
type | exampleText | anchor | variant
|
||||||
${INSTANCE_TYPE} | ${'Shared runners are available to every project'} | ${'#shared-runners'} | ${'success'}
|
${INSTANCE_TYPE} | ${'This runner is available to all groups and projects'} | ${'#shared-runners'} | ${'success'}
|
||||||
${GROUP_TYPE} | ${'Use Group runners when you want all projects in a group'} | ${'#group-runners'} | ${'success'}
|
${GROUP_TYPE} | ${'This runner is available to all projects and subgroups in a group'} | ${'#group-runners'} | ${'success'}
|
||||||
${PROJECT_TYPE} | ${'You can set up a specific runner to be used by multiple projects'} | ${'#specific-runners'} | ${'info'}
|
${PROJECT_TYPE} | ${'This runner is associated with one or more projects'} | ${'#specific-runners'} | ${'info'}
|
||||||
`('When it is an $type level runner', ({ type, exampleText, anchor, variant }) => {
|
`('When it is an $type level runner', ({ type, exampleText, anchor, variant }) => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({ props: { type } });
|
createComponent({ props: { type } });
|
||||||
|
|
|
@ -81,30 +81,33 @@ describe('AssigneeAvatarLink component', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
describe.each`
|
describe.each`
|
||||||
tooltipHasName | availability | canMerge | expected
|
tooltipHasName | name | availability | canMerge | expected
|
||||||
${true} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'}
|
${true} | ${"Rabbit O'Hare"} | ${''} | ${true} | ${"Rabbit O'Hare"}
|
||||||
${true} | ${'Busy'} | ${true} | ${'Root (Busy)'}
|
${true} | ${"Rabbit O'Hare"} | ${'Busy'} | ${false} | ${"Rabbit O'Hare (Busy) (cannot merge)"}
|
||||||
${true} | ${''} | ${false} | ${'Root (cannot merge)'}
|
${true} | ${'Root'} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'}
|
||||||
${true} | ${''} | ${true} | ${'Root'}
|
${true} | ${'Root'} | ${'Busy'} | ${true} | ${'Root (Busy)'}
|
||||||
${false} | ${'Busy'} | ${false} | ${'Cannot merge'}
|
${true} | ${'Root'} | ${''} | ${false} | ${'Root (cannot merge)'}
|
||||||
${false} | ${'Busy'} | ${true} | ${''}
|
${true} | ${'Root'} | ${''} | ${true} | ${'Root'}
|
||||||
${false} | ${''} | ${false} | ${'Cannot merge'}
|
${false} | ${'Root'} | ${'Busy'} | ${false} | ${'Cannot merge'}
|
||||||
${false} | ${''} | ${true} | ${''}
|
${false} | ${'Root'} | ${'Busy'} | ${true} | ${''}
|
||||||
|
${false} | ${'Root'} | ${''} | ${false} | ${'Cannot merge'}
|
||||||
|
${false} | ${'Root'} | ${''} | ${true} | ${''}
|
||||||
`(
|
`(
|
||||||
"with tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge",
|
"with name=$name tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge",
|
||||||
({ tooltipHasName, availability, canMerge, expected }) => {
|
({ name, tooltipHasName, availability, canMerge, expected }) => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({
|
createComponent({
|
||||||
tooltipHasName,
|
tooltipHasName,
|
||||||
user: {
|
user: {
|
||||||
...userDataMock(),
|
...userDataMock(),
|
||||||
|
name,
|
||||||
can_merge: canMerge,
|
can_merge: canMerge,
|
||||||
availability,
|
availability,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets tooltip to $expected', () => {
|
it(`sets tooltip to "${expected}"`, () => {
|
||||||
expect(findTooltipText()).toBe(expected);
|
expect(findTooltipText()).toBe(expected);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
49
spec/rubocop/cop/qa/selector_usage_spec.rb
Normal file
49
spec/rubocop/cop/qa/selector_usage_spec.rb
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'fast_spec_helper'
|
||||||
|
|
||||||
|
require_relative '../../../../rubocop/cop/qa/selector_usage'
|
||||||
|
|
||||||
|
RSpec.describe RuboCop::Cop::QA::SelectorUsage do
|
||||||
|
subject(:cop) { described_class.new }
|
||||||
|
|
||||||
|
shared_examples 'non-qa file usage' do
|
||||||
|
it 'reports an offense' do
|
||||||
|
expect_offense(<<-RUBY)
|
||||||
|
find('#{selector}').click
|
||||||
|
#{'^' * (selector.size + 2)} Do not use `#{selector}` as this is reserved for the end-to-end specs. Use a different selector or a data-testid instead.
|
||||||
|
RUBY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in a QA file' do
|
||||||
|
before do
|
||||||
|
allow(cop).to receive(:in_qa_file?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has no error' do
|
||||||
|
expect_no_offenses(<<-RUBY)
|
||||||
|
has_element?('[data-qa-selector="my_selector"]')
|
||||||
|
RUBY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'outside of QA' do
|
||||||
|
before do
|
||||||
|
allow(cop).to receive(:in_qa_file?).and_return(false)
|
||||||
|
allow(cop).to receive(:in_spec?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'data-qa-selector' do
|
||||||
|
let(:selector) { '[data-qa-selector="my_selector"]' }
|
||||||
|
|
||||||
|
it_behaves_like 'non-qa file usage'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qa class' do
|
||||||
|
let(:selector) { '.qa-selector' }
|
||||||
|
|
||||||
|
it_behaves_like 'non-qa file usage'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -308,7 +308,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
||||||
let(:reply_id) { find("#{comments_selector} .note:last-of-type", match: :first)['data-note-id'] }
|
let(:reply_id) { find("#{comments_selector} .note:last-of-type", match: :first)['data-note-id'] }
|
||||||
|
|
||||||
it 'can be replied to after resolving' do
|
it 'can be replied to after resolving' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
refresh
|
refresh
|
||||||
|
@ -320,7 +320,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
||||||
it 'shows resolved thread when toggled' do
|
it 'shows resolved thread when toggled' do
|
||||||
submit_reply('a')
|
submit_reply('a')
|
||||||
|
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click
|
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
|
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
|
||||||
|
|
|
@ -14,7 +14,7 @@ RSpec.shared_examples 'packages list' do |check_project_name: false|
|
||||||
end
|
end
|
||||||
|
|
||||||
def package_table_row(index)
|
def package_table_row(index)
|
||||||
page.all("#{packages_table_selector} > [data-qa-selector=\"package_row\"]")[index].text
|
page.all("#{packages_table_selector} > [data-qa-selector=\"package_row\"]")[index].text # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ RSpec.shared_examples 'shared package sorting' do
|
||||||
end
|
end
|
||||||
|
|
||||||
def packages_table_selector
|
def packages_table_selector
|
||||||
'[data-qa-selector="packages-table"]'
|
'[data-qa-selector="packages-table"]' # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_sort_option(option, ascending)
|
def click_sort_option(option, ascending)
|
||||||
|
|
|
@ -23,7 +23,7 @@ RSpec.shared_examples 'Deploy keys with protected branches' do
|
||||||
find(".js-allowed-to-push").click
|
find(".js-allowed-to-push").click
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
within('.qa-allowed-to-push-dropdown') do
|
within('.qa-allowed-to-push-dropdown') do # rubocop:disable QA/SelectorUsage
|
||||||
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
||||||
|
|
||||||
expect(dropdown_headers).to contain_exactly(*all_dropdown_sections)
|
expect(dropdown_headers).to contain_exactly(*all_dropdown_sections)
|
||||||
|
@ -38,7 +38,7 @@ RSpec.shared_examples 'Deploy keys with protected branches' do
|
||||||
find(".js-allowed-to-merge").click
|
find(".js-allowed-to-merge").click
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
within('.qa-allowed-to-merge-dropdown') do
|
within('.qa-allowed-to-merge-dropdown') do # rubocop:disable QA/SelectorUsage
|
||||||
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
||||||
|
|
||||||
expect(dropdown_headers).to contain_exactly(*dropdown_sections_minus_deploy_keys)
|
expect(dropdown_headers).to contain_exactly(*dropdown_sections_minus_deploy_keys)
|
||||||
|
@ -68,7 +68,7 @@ RSpec.shared_examples 'Deploy keys with protected branches' do
|
||||||
find(".js-allowed-to-push").click
|
find(".js-allowed-to-push").click
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
within('.qa-allowed-to-push-dropdown') do
|
within('.qa-allowed-to-push-dropdown') do # rubocop:disable QA/SelectorUsage
|
||||||
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
dropdown_headers = page.all('.dropdown-header').map(&:text)
|
||||||
|
|
||||||
expect(dropdown_headers).to contain_exactly(*dropdown_sections_minus_deploy_keys)
|
expect(dropdown_headers).to contain_exactly(*dropdown_sections_minus_deploy_keys)
|
||||||
|
|
|
@ -9,7 +9,7 @@ end
|
||||||
RSpec.shared_examples "it has an RSS button with current_user's feed token" do
|
RSpec.shared_examples "it has an RSS button with current_user's feed token" do
|
||||||
it "shows the RSS button with current_user's feed token" do
|
it "shows the RSS button with current_user's feed token" do
|
||||||
expect(page)
|
expect(page)
|
||||||
.to have_css("a:has(.qa-rss-icon)[href*='feed_token=#{user.feed_token}']")
|
.to have_css("a:has(.qa-rss-icon)[href*='feed_token=#{user.feed_token}']") # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,6 +22,6 @@ end
|
||||||
RSpec.shared_examples "it has an RSS button without a feed token" do
|
RSpec.shared_examples "it has an RSS button without a feed token" do
|
||||||
it "shows the RSS button without a feed token" do
|
it "shows the RSS button without a feed token" do
|
||||||
expect(page)
|
expect(page)
|
||||||
.to have_css("a:has(.qa-rss-icon):not([href*='feed_token'])")
|
.to have_css("a:has(.qa-rss-icon):not([href*='feed_token'])") # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,7 +91,7 @@ RSpec.shared_examples 'variable list' do
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set('new_key')
|
find('[data-qa-selector="ci_variable_key_field"] input').set('new_key') # rubocop:disable QA/SelectorUsage
|
||||||
|
|
||||||
click_button('Update variable')
|
click_button('Update variable')
|
||||||
end
|
end
|
||||||
|
@ -173,7 +173,7 @@ RSpec.shared_examples 'variable list' do
|
||||||
click_button('Add variable')
|
click_button('Add variable')
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set('empty_mask_key')
|
find('[data-qa-selector="ci_variable_key_field"] input').set('empty_mask_key') # rubocop:disable QA/SelectorUsage
|
||||||
find('[data-testid="ci-variable-protected-checkbox"]').click
|
find('[data-testid="ci-variable-protected-checkbox"]').click
|
||||||
find('[data-testid="ci-variable-masked-checkbox"]').click
|
find('[data-testid="ci-variable-masked-checkbox"]').click
|
||||||
|
|
||||||
|
@ -286,8 +286,8 @@ RSpec.shared_examples 'variable list' do
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set(key)
|
find('[data-qa-selector="ci_variable_key_field"] input').set(key) # rubocop:disable QA/SelectorUsage
|
||||||
find('[data-qa-selector="ci_variable_value_field"]').set(value) if value.present?
|
find('[data-qa-selector="ci_variable_value_field"]').set(value) if value.present? # rubocop:disable QA/SelectorUsage
|
||||||
find('[data-testid="ci-variable-protected-checkbox"]').click if protected
|
find('[data-testid="ci-variable-protected-checkbox"]').click if protected
|
||||||
find('[data-testid="ci-variable-masked-checkbox"]').click if masked
|
find('[data-testid="ci-variable-masked-checkbox"]').click if masked
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'User views AsciiDoc page with includes' do
|
RSpec.shared_examples 'User views AsciiDoc page with includes' do
|
||||||
let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' }
|
let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' } # rubocop:disable QA/SelectorUsage
|
||||||
let!(:included_wiki_page) { create_wiki_page('included_page', content: 'Content from the included page')}
|
let!(:included_wiki_page) { create_wiki_page('included_page', content: 'Content from the included page')}
|
||||||
let!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") }
|
let!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") }
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ RSpec.describe 'admin/sessions/new.html.haml' do
|
||||||
it 'shows enter password form' do
|
it 'shows enter password form' do
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(rendered).to have_selector('[data-qa-selector="sign_in_tab"]')
|
expect(rendered).to have_selector('[data-qa-selector="sign_in_tab"]') # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).to have_css('#login-pane.active')
|
expect(rendered).to have_css('#login-pane.active')
|
||||||
expect(rendered).to have_selector('[data-qa-selector="password_field"]')
|
expect(rendered).to have_selector('[data-qa-selector="password_field"]') # rubocop:disable QA/SelectorUsage
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'warns authentication not possible if password not set' do
|
it 'warns authentication not possible if password not set' do
|
||||||
|
@ -60,7 +60,7 @@ RSpec.describe 'admin/sessions/new.html.haml' do
|
||||||
it 'is shown when enabled' do
|
it 'is shown when enabled' do
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(rendered).to have_selector('[data-qa-selector="ldap_tab"]')
|
expect(rendered).to have_selector('[data-qa-selector="ldap_tab"]') # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).to have_css('.login-box#ldapmain')
|
expect(rendered).to have_css('.login-box#ldapmain')
|
||||||
expect(rendered).to have_field('LDAP Username')
|
expect(rendered).to have_field('LDAP Username')
|
||||||
expect(rendered).not_to have_content('No authentication methods configured')
|
expect(rendered).not_to have_content('No authentication methods configured')
|
||||||
|
@ -71,7 +71,7 @@ RSpec.describe 'admin/sessions/new.html.haml' do
|
||||||
|
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(rendered).not_to have_selector('[data-qa-selector="ldap_tab"]')
|
expect(rendered).not_to have_selector('[data-qa-selector="ldap_tab"]') # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).not_to have_field('LDAP Username')
|
expect(rendered).not_to have_field('LDAP Username')
|
||||||
expect(rendered).to have_content('No authentication methods configured')
|
expect(rendered).to have_content('No authentication methods configured')
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,7 +48,7 @@ RSpec.describe 'devise/sessions/new' do
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(rendered).to have_selector('.new-session-tabs')
|
expect(rendered).to have_selector('.new-session-tabs')
|
||||||
expect(rendered).to have_selector('[data-qa-selector="ldap_tab"]')
|
expect(rendered).to have_selector('[data-qa-selector="ldap_tab"]') # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).to have_field('LDAP Username')
|
expect(rendered).to have_field('LDAP Username')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ RSpec.describe 'devise/sessions/new' do
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(rendered).to have_content('No authentication methods configured')
|
expect(rendered).to have_content('No authentication methods configured')
|
||||||
expect(rendered).not_to have_selector('[data-qa-selector="ldap_tab"]')
|
expect(rendered).not_to have_selector('[data-qa-selector="ldap_tab"]') # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).not_to have_field('LDAP Username')
|
expect(rendered).not_to have_field('LDAP Username')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,8 +9,8 @@ RSpec.describe 'groups/settings/_transfer.html.haml' do
|
||||||
|
|
||||||
render 'groups/settings/transfer', group: group
|
render 'groups/settings/transfer', group: group
|
||||||
|
|
||||||
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]'
|
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]' # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
|
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]' # rubocop:disable QA/SelectorUsage
|
||||||
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
|
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,7 +40,7 @@ module Tooling
|
||||||
%r{\A(ee/)?config/feature_flags/} => :feature_flag,
|
%r{\A(ee/)?config/feature_flags/} => :feature_flag,
|
||||||
|
|
||||||
%r{\Adoc/development/usage_ping/dictionary\.md\z} => [:docs, :product_intelligence],
|
%r{\Adoc/development/usage_ping/dictionary\.md\z} => [:docs, :product_intelligence],
|
||||||
%r{\Adoc/.*(\.(md|png|gif|jpg))\z} => :docs,
|
%r{\Adoc/.*(\.(md|png|gif|jpg|yml))\z} => :docs,
|
||||||
%r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs,
|
%r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs,
|
||||||
%r{\Adata/whats_new/} => :docs,
|
%r{\Adata/whats_new/} => :docs,
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue