Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-03 18:10:02 +00:00
parent f397d486bc
commit 4905885126
55 changed files with 317 additions and 176 deletions

View file

@ -701,3 +701,11 @@ RSpec/TopLevelDescribePath:
Exclude:
- 'spec/fixtures/**/*.rb'
- 'ee/spec/fixtures/**/*.rb'
QA/SelectorUsage:
Enabled: true
Include:
- 'spec/**/*.rb'
- 'ee/spec/**/*.rb'
Exclude:
- 'spec/rubocop/**/*_spec.rb'

View file

@ -140,16 +140,13 @@ export default {
},
(line) => line.type,
),
lineContent: memoize(
(line) => {
if (line.isConflictMarker) {
return line.type === CONFLICT_MARKER_THEIR ? 'HEAD//our changes' : 'origin//their changes';
}
lineContent: (line) => {
if (line.isConflictMarker) {
return line.type === CONFLICT_MARKER_THEIR ? 'HEAD//our changes' : 'origin//their changes';
}
return line.rich_text;
},
(line) => line.line_code,
),
return line.rich_text;
},
CONFLICT_MARKER,
CONFLICT_MARKER_THEIR,
CONFLICT_OUR,

View file

@ -11,6 +11,7 @@ import {
featureAccessLevel,
featureAccessLevelNone,
CVE_ID_REQUEST_BUTTON_I18N,
featureAccessLevelDescriptions,
} from '../constants';
import { toggleHiddenClassBySelector } from '../external';
import projectFeatureSetting from './project_feature_setting.vue';
@ -176,7 +177,7 @@ export default {
requirementsAccessLevel: featureAccessLevel.EVERYONE,
securityAndComplianceAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
operationsAccessLevel: featureAccessLevel.EVERYONE,
containerRegistryEnabled: true,
containerRegistryAccessLevel: featureAccessLevel.EVERYONE,
lfsEnabled: true,
requestAccessEnabled: true,
highlightChangesClass: false,
@ -184,6 +185,8 @@ export default {
cveIdRequestEnabled: true,
featureAccessLevelEveryone,
featureAccessLevelMembers,
featureAccessLevel,
featureAccessLevelDescriptions,
};
return { ...defaults, ...this.currentSettings };
@ -248,7 +251,10 @@ export default {
},
showContainerRegistryPublicNote() {
return this.visibilityLevel === visibilityOptions.PUBLIC;
return (
this.visibilityLevel === visibilityOptions.PUBLIC &&
this.containerRegistryAccessLevel === featureAccessLevel.EVERYONE
);
},
repositoryHelpText() {
@ -310,6 +316,10 @@ export default {
featureAccessLevel.PROJECT_MEMBERS,
this.operationsAccessLevel,
);
this.containerRegistryAccessLevel = Math.min(
featureAccessLevel.PROJECT_MEMBERS,
this.containerRegistryAccessLevel,
);
if (this.pagesAccessLevel === featureAccessLevel.EVERYONE) {
// When from Internal->Private narrow access for only members
this.pagesAccessLevel = featureAccessLevel.PROJECT_MEMBERS;
@ -339,6 +349,8 @@ export default {
this.requirementsAccessLevel = featureAccessLevel.EVERYONE;
if (this.operationsAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
this.operationsAccessLevel = featureAccessLevel.EVERYONE;
if (this.containerRegistryAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
this.containerRegistryAccessLevel = featureAccessLevel.EVERYONE;
this.highlightChanges();
}
@ -521,19 +533,24 @@ export default {
"
>
<div v-if="showContainerRegistryPublicNote" class="text-muted">
{{
s__(
'ProjectSettings|Note: the container registry is always visible when a project is public',
)
}}
<gl-sprintf
:message="
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>
<gl-toggle
v-model="containerRegistryEnabled"
class="gl-my-2"
:disabled="!repositoryEnabled"
<project-feature-setting
v-model="containerRegistryAccessLevel"
:options="repoFeatureAccessLevelOptions"
:disabled-input="!repositoryEnabled"
:label="$options.i18n.containerRegistryLabel"
label-position="hidden"
name="project[container_registry_enabled]"
name="project[project_feature_attributes][container_registry_access_level]"
/>
</project-setting-row>
<project-setting-row

View file

@ -22,7 +22,7 @@ export const featureAccessLevel = {
EVERYONE: 20,
};
const featureAccessLevelDescriptions = {
export const featureAccessLevelDescriptions = {
[featureAccessLevel.NOT_ENABLED]: __('Enable feature to choose access level'),
[featureAccessLevel.PROJECT_MEMBERS]: __('Only Project Members'),
[featureAccessLevel.EVERYONE]: __('Everyone With Access'),

View file

@ -6,28 +6,19 @@ import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../constants';
const ALERT_DATA = {
[INSTANCE_TYPE]: {
title: s__(
'Runners|This runner is available to all groups and projects in your GitLab instance.',
),
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',
anchor: 'shared-runners',
},
[GROUP_TYPE]: {
title: 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.',
),
message: s__('Runners|This runner is available to all projects and subgroups in a group.'),
variant: 'success',
anchor: 'group-runners',
},
[PROJECT_TYPE]: {
title: s__('Runners|This runner is associated with specific 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.',
),
message: s__('Runners|This runner is associated with one or more projects.'),
variant: 'info',
anchor: 'specific-runners',
},
@ -59,7 +50,7 @@ export default {
};
</script>
<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 }}
<gl-link :href="helpHref">{{ __('Learn more.') }}</gl-link>
</gl-alert>

View file

@ -1,6 +1,6 @@
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { __ } from '~/locale';
import { isUserBusy } from '~/set_status_modal/utils';
import AssigneeAvatar from './assignee_avatar.vue';
@ -32,10 +32,9 @@ const generateAssigneeTooltip = ({
}
if (tooltipHasName && statusInformation.length) {
return sprintf(__('%{name} %{status}'), {
name,
status: statusInformation.map(paranthesize).join(' '),
});
const status = statusInformation.map(paranthesize).join(' ');
return `${name} ${status}`;
}
return name;

View file

@ -480,7 +480,7 @@ body {
.btn:active,
.btn.active {
background-color: #444;
border-color: #fafafa;
border-color: #4f4f4f;
color: #fafafa;
}
.btn svg {

View file

@ -186,8 +186,7 @@ body.gl-dark {
}
}
$border-white-light: $gray-900;
$border-white-normal: $gray-900;
$border-white-normal: $border-color;
$body-bg: $gray-10;
$input-bg: $white;

View file

@ -51,7 +51,7 @@ module Git
change: change,
push_options: params[:push_options],
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,
create_push_event: !create_bulk_push_event
).execute
@ -60,6 +60,10 @@ module Git
create_bulk_push_event(ref_type, action, changes) if create_bulk_push_event
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)
EventCreateService.new.bulk_push(
project,

View file

@ -20,7 +20,7 @@ if gitlab.mr_body.size < 5
end
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
unless gitlab.mr_json["assignee"]

View file

@ -40,9 +40,9 @@ There are no reviewer and maintainer suggestions for the changes in this MR.
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
[add support](https://gitlab.com/gitlab-org/gitlab/blob/master/tooling/danger/project_helper.rb)
for them.

View file

@ -320,7 +320,7 @@ create an issue or an MR to propose a change to the user interface text.
- *Feature names are typically lowercase*.
- *Some features are capitalized*, typically nouns naming GitLab-specific
capabilities or tools.
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.
@ -839,7 +839,7 @@ We include guidance for links in these categories:
### Basic link criteria
- 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/).
For example, instead of writing something like `Read more about GitLab Issue Boards [here](LINK)`,

View file

@ -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.
## 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 are commonly used for creating multi-architecture images. If you rely on manifest

View file

@ -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."
msgstr ""
msgid "%{name} %{status}"
msgstr ""
msgid "%{name} (Busy)"
msgstr ""
@ -26025,7 +26022,7 @@ msgstr ""
msgid "ProjectSettings|No merge commits are created."
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 ""
msgid "ProjectSettings|Only signed commits can be pushed to this repository."
@ -28607,6 +28604,9 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
msgid "Runners|This runner is associated with one or more projects."
msgstr ""
msgid "Runners|This runner is associated with specific projects."
msgstr ""

View file

@ -57,7 +57,7 @@ module QA
install:
stage: install
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:
- "runner-for-#{project.name}"

View 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

View file

@ -90,7 +90,7 @@ RSpec.describe 'Admin Appearance' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
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)
end

View file

@ -256,7 +256,7 @@ RSpec.describe 'Admin Groups' do
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('Developer')
end
@ -265,7 +265,7 @@ RSpec.describe 'Admin Groups' do
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('Developer')
end

View file

@ -184,7 +184,7 @@ RSpec.describe 'Admin::Users::User' do
it 'logs in as the user when impersonate is clicked' do
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)
end
@ -220,7 +220,7 @@ RSpec.describe 'Admin::Users::User' do
it 'logs out of impersonated user back to original user' do
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)
end

View file

@ -33,7 +33,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
context 'resolving the thread' 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
it 'hides the link for creating a new issue' do

View file

@ -35,7 +35,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
context 'resolving the thread' 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
it 'hides the link for creating a new issue' do

View file

@ -408,7 +408,7 @@ RSpec.describe 'Issue Sidebar' do
context 'sidebar', :js 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
@ -444,7 +444,7 @@ RSpec.describe 'Issue Sidebar' do
end
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

View file

@ -182,7 +182,7 @@ RSpec.describe "User creates issue" do
end
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
@ -202,11 +202,11 @@ RSpec.describe "User creates issue" do
end
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
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
it 'shows the incident help text' do

View file

@ -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
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
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
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'
end
@ -92,7 +92,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
describe 'resolved thread' do
before 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
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
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
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
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
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
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
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
@ -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
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
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
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
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
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'
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
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

View file

@ -21,7 +21,7 @@ RSpec.describe 'Project variables', :js do
click_button('Add variable')
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('[data-testid="environment-scope"]').click
find('[data-testid="ci-environment-search"]').set('review/*')

View file

@ -137,7 +137,7 @@ RSpec.describe 'File blob', :js do
context 'when ref switch' do
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
click_link ref_name

View file

@ -30,9 +30,9 @@ RSpec.describe 'Environment > Metrics' do
click_link 'Monitoring'
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(environment.name)
@ -58,7 +58,7 @@ RSpec.describe 'Environment > Metrics' do
it 'shows metrics', :js do
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
it_behaves_like 'has environment selector'

View file

@ -455,10 +455,10 @@ RSpec.describe 'Environments page', :js do
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
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
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
end
end

View file

@ -50,7 +50,7 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
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
dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])")

View file

@ -91,7 +91,7 @@ RSpec.describe 'User sees feature flag list', :js do
it 'shows the empty page' do
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('[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

View file

@ -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(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')

View file

@ -181,8 +181,8 @@ RSpec.describe 'Project fork' do
it 'allows user to fork only to the group on fork page', :js do
visit new_project_fork_path(project)
to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled')
to_group = find(".fork-groups button[data-qa-name=#{group.name}]")
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}]") # rubocop:disable QA/SelectorUsage
expect(to_personal_namespace).not_to be_nil
expect(to_group).not_to be_disabled

View file

@ -62,6 +62,6 @@ RSpec.describe 'Import/Export - project import integration test', :js do
end
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

View file

@ -13,7 +13,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
using RSpec::Parameterized::TableSyntax
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'
end
@ -43,7 +43,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
end
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
it 'the "Invite a group" button exists' do

View file

@ -19,7 +19,7 @@ RSpec.describe 'New project', :js do
)
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.'
end
@ -30,7 +30,7 @@ RSpec.describe 'New project', :js do
)
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.'
end
@ -45,14 +45,14 @@ RSpec.describe 'New project', :js do
it 'shows "New project" page', :js do
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 URL')
expect(page).to have_content('Project slug')
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('Bitbucket')
@ -65,7 +65,7 @@ RSpec.describe 'New project', :js do
before do
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
it 'has Manifest file' do
@ -79,7 +79,7 @@ RSpec.describe 'New project', :js do
stub_application_setting(default_project_visibility: level)
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
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
@ -87,7 +87,7 @@ RSpec.describe 'New project', :js do
it "saves visibility level #{level} on validation error" do
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)
click_button('Create project')
@ -107,7 +107,7 @@ RSpec.describe 'New project', :js do
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
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
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
it 'has private selected' do
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
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
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
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_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
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
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
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
page.within '#import-project-pane' do
@ -188,7 +188,7 @@ RSpec.describe 'New project', :js do
context 'with user namespace' do
before do
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
it 'selects the user namespace' do
@ -204,7 +204,7 @@ RSpec.describe 'New project', :js do
before do
group.add_owner(user)
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
it 'selects the group namespace' do
@ -221,7 +221,7 @@ RSpec.describe 'New project', :js do
before do
group.add_maintainer(user)
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
it 'selects the group namespace' do
@ -241,7 +241,7 @@ RSpec.describe 'New project', :js do
internal_group.add_owner(user)
private_group.add_owner(user)
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
it 'enables the correct visibility options' do
@ -271,7 +271,7 @@ RSpec.describe 'New project', :js do
context 'Import project options', :js do
before do
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
context 'from git repository url, "Repo by URL"' do
@ -343,7 +343,7 @@ RSpec.describe 'New project', :js do
before do
group.add_developer(user)
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
it 'selects the group namespace' do

View file

@ -39,7 +39,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
# The dropdown above the tree
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
expect(page).to have_link('New file')
@ -71,7 +71,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
find_new_menu_toggle.click
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')
end

View file

@ -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,
# (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.
if page.has_css?('.qa-begin-commit-button')
find('.qa-begin-commit-button').click
if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
end
fill_in('commit-message', with: 'commit message ide')

View file

@ -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,
# (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.
if page.has_css?('.qa-begin-commit-button')
find('.qa-begin-commit-button').click
if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
end
fill_in('commit-message', with: 'commit message ide')

View file

@ -26,7 +26,7 @@ RSpec.describe 'Projects tree', :js do
expect(page).to have_selector('.tree-item')
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('[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
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_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')
end
@ -112,7 +112,7 @@ RSpec.describe 'Projects tree', :js do
it 'renders LFS badge on blob item' do
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

View file

@ -13,7 +13,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
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')
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
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_path, with: 'a-subgroup-project'
@ -72,7 +72,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
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_path, with: 'a-new-project'

View file

@ -16,7 +16,7 @@ RSpec.describe 'Project' do
shared_examples 'creates from template' do |template, sub_template_tab = nil|
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("label[for=#{template.name}]").click
fill_in("project_name", with: template.name)
@ -290,7 +290,7 @@ RSpec.describe 'Project' do
it 'has working links to submodules' do
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
context 'for signed commit on default branch', :js do

View file

@ -1,4 +1,4 @@
import { GlToggle } from '@gitlab/ui';
import { GlSprintf, GlToggle } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import projectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue';
import settingsPanel from '~/pages/projects/shared/permissions/components/settings_panel.vue';
@ -22,7 +22,7 @@ const defaultProps = {
operationsAccessLevel: 20,
pagesAccessLevel: 10,
analyticsAccessLevel: 20,
containerRegistryEnabled: true,
containerRegistryAccessLevel: 20,
lfsEnabled: true,
emailsDisabled: false,
packagesEnabled: true,
@ -85,8 +85,10 @@ describe('Settings Panel', () => {
const findBuildsAccessLevelInput = () =>
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]');
const findContainerRegistrySettings = () => wrapper.find({ ref: 'container-registry-settings' });
const findContainerRegistryEnabledInput = () =>
wrapper.find('[name="project[container_registry_enabled]"]');
const findContainerRegistryPublicNoteGlSprintfComponent = () =>
findContainerRegistrySettings().findComponent(GlSprintf);
const findContainerRegistryAccessLevelInput = () =>
wrapper.find('[name="project[project_feature_attributes][container_registry_access_level]"]');
const findPackageSettings = () => wrapper.find({ ref: 'package-settings' });
const findPackagesEnabledInput = () => wrapper.find('[name="project[packages_enabled]"]');
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', () => {
wrapper = mountComponent({
currentSettings: { visibilityLevel: visibilityOptions.PUBLIC },
currentSettings: {
visibilityLevel: visibilityOptions.PUBLIC,
containerRegistryAccessLevel: featureAccessLevel.EVERYONE,
},
registryAvailable: true,
});
expect(findContainerRegistrySettings().text()).toContain(
'Note: the container registry is always visible when a project is public',
expect(findContainerRegistryPublicNoteGlSprintfComponent().exists()).toBe(true);
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', () => {
wrapper = mountComponent({
currentSettings: { visibilityLevel: visibilityOptions.PRIVATE },
registryAvailable: true,
});
expect(findContainerRegistrySettings().text()).not.toContain(
'Note: the container registry is always visible when a project is public',
);
expect(findContainerRegistryPublicNoteGlSprintfComponent().exists()).toBe(false);
});
it('should enable the container registry input when the repository is enabled', () => {
@ -301,7 +317,7 @@ describe('Settings Panel', () => {
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', () => {
@ -310,7 +326,7 @@ describe('Settings Panel', () => {
registryAvailable: true,
});
expect(findContainerRegistryEnabledInput().props('disabled')).toBe(true);
expect(findContainerRegistryAccessLevelInput().props('disabledInput')).toBe(true);
});
it('has label for the toggle', () => {
@ -319,7 +335,7 @@ describe('Settings Panel', () => {
registryAvailable: true,
});
expect(findContainerRegistrySettings().findComponent(GlToggle).props('label')).toBe(
expect(findContainerRegistryAccessLevelInput().props('label')).toBe(
settingsPanel.i18n.containerRegistryLabel,
);
});

View file

@ -23,10 +23,10 @@ describe('RunnerTypeAlert', () => {
});
describe.each`
type | exampleText | anchor | variant
${INSTANCE_TYPE} | ${'Shared runners are available to every project'} | ${'#shared-runners'} | ${'success'}
${GROUP_TYPE} | ${'Use Group runners when you want all projects in a group'} | ${'#group-runners'} | ${'success'}
${PROJECT_TYPE} | ${'You can set up a specific runner to be used by multiple projects'} | ${'#specific-runners'} | ${'info'}
type | exampleText | anchor | variant
${INSTANCE_TYPE} | ${'This runner is available to all groups and projects'} | ${'#shared-runners'} | ${'success'}
${GROUP_TYPE} | ${'This runner is available to all projects and subgroups in a group'} | ${'#group-runners'} | ${'success'}
${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 }) => {
beforeEach(() => {
createComponent({ props: { type } });

View file

@ -81,30 +81,33 @@ describe('AssigneeAvatarLink component', () => {
);
describe.each`
tooltipHasName | availability | canMerge | expected
${true} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'}
${true} | ${'Busy'} | ${true} | ${'Root (Busy)'}
${true} | ${''} | ${false} | ${'Root (cannot merge)'}
${true} | ${''} | ${true} | ${'Root'}
${false} | ${'Busy'} | ${false} | ${'Cannot merge'}
${false} | ${'Busy'} | ${true} | ${''}
${false} | ${''} | ${false} | ${'Cannot merge'}
${false} | ${''} | ${true} | ${''}
tooltipHasName | name | availability | canMerge | expected
${true} | ${"Rabbit O'Hare"} | ${''} | ${true} | ${"Rabbit O'Hare"}
${true} | ${"Rabbit O'Hare"} | ${'Busy'} | ${false} | ${"Rabbit O'Hare (Busy) (cannot merge)"}
${true} | ${'Root'} | ${'Busy'} | ${false} | ${'Root (Busy) (cannot merge)'}
${true} | ${'Root'} | ${'Busy'} | ${true} | ${'Root (Busy)'}
${true} | ${'Root'} | ${''} | ${false} | ${'Root (cannot merge)'}
${true} | ${'Root'} | ${''} | ${true} | ${'Root'}
${false} | ${'Root'} | ${'Busy'} | ${false} | ${'Cannot merge'}
${false} | ${'Root'} | ${'Busy'} | ${true} | ${''}
${false} | ${'Root'} | ${''} | ${false} | ${'Cannot merge'}
${false} | ${'Root'} | ${''} | ${true} | ${''}
`(
"with tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge",
({ tooltipHasName, availability, canMerge, expected }) => {
"with name=$name tooltipHasName=$tooltipHasName and availability='$availability' and canMerge=$canMerge",
({ name, tooltipHasName, availability, canMerge, expected }) => {
beforeEach(() => {
createComponent({
tooltipHasName,
user: {
...userDataMock(),
name,
can_merge: canMerge,
availability,
},
});
});
it('sets tooltip to $expected', () => {
it(`sets tooltip to "${expected}"`, () => {
expect(findTooltipText()).toBe(expected);
});
},

View 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

View file

@ -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'] }
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
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
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
expect(page).to have_selector(".note-row-#{note_id}", visible: true)

View file

@ -14,7 +14,7 @@ RSpec.shared_examples 'packages list' do |check_project_name: false|
end
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
@ -92,7 +92,7 @@ RSpec.shared_examples 'shared package sorting' do
end
def packages_table_selector
'[data-qa-selector="packages-table"]'
'[data-qa-selector="packages-table"]' # rubocop:disable QA/SelectorUsage
end
def click_sort_option(option, ascending)

View file

@ -23,7 +23,7 @@ RSpec.shared_examples 'Deploy keys with protected branches' do
find(".js-allowed-to-push").click
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)
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
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)
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
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)
expect(dropdown_headers).to contain_exactly(*dropdown_sections_minus_deploy_keys)

View file

@ -9,7 +9,7 @@ end
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
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
@ -22,6 +22,6 @@ end
RSpec.shared_examples "it has an RSS button without a feed token" do
it "shows the RSS button without a feed token" do
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

View file

@ -91,7 +91,7 @@ RSpec.shared_examples 'variable list' do
end
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')
end
@ -173,7 +173,7 @@ RSpec.shared_examples 'variable list' do
click_button('Add variable')
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-masked-checkbox"]').click
@ -286,8 +286,8 @@ RSpec.shared_examples 'variable list' do
wait_for_requests
page.within('#add-ci-variable') do
find('[data-qa-selector="ci_variable_key_field"] input').set(key)
find('[data-qa-selector="ci_variable_value_field"]').set(value) if value.present?
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? # rubocop:disable QA/SelectorUsage
find('[data-testid="ci-variable-protected-checkbox"]').click if protected
find('[data-testid="ci-variable-masked-checkbox"]').click if masked

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
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!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") }

View file

@ -19,9 +19,9 @@ RSpec.describe 'admin/sessions/new.html.haml' do
it 'shows enter password form' do
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_selector('[data-qa-selector="password_field"]')
expect(rendered).to have_selector('[data-qa-selector="password_field"]') # rubocop:disable QA/SelectorUsage
end
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
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_field('LDAP Username')
expect(rendered).not_to have_content('No authentication methods configured')
@ -71,7 +71,7 @@ RSpec.describe 'admin/sessions/new.html.haml' do
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).to have_content('No authentication methods configured')
end

View file

@ -48,7 +48,7 @@ RSpec.describe 'devise/sessions/new' do
render
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')
end
@ -58,7 +58,7 @@ RSpec.describe 'devise/sessions/new' do
render
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')
end
end

View file

@ -9,8 +9,8 @@ RSpec.describe 'groups/settings/_transfer.html.haml' do
render 'groups/settings/transfer', group: group
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]'
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
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]' # rubocop:disable QA/SelectorUsage
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
end
end

View file

@ -40,7 +40,7 @@ module Tooling
%r{\A(ee/)?config/feature_flags/} => :feature_flag,
%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{\Adata/whats_new/} => :docs,