diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-25 18:12:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-25 18:12:22 +0300 |
commit | f8888a274f6b095075fd8648d3732ad577a3a742 (patch) | |
tree | 4b5c3f082951846ebca4bb80265d10390bdc210c | |
parent | df65129ab40540728d4b391fc1a21d5a1de87b9c (diff) |
Add latest changes from gitlab-org/gitlab@master
84 files changed, 344 insertions, 448 deletions
diff --git a/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml b/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml index 8a1a0014539..c6fa9a9e179 100644 --- a/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml +++ b/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml @@ -1,6 +1,6 @@ include: - project: gitlab-org/quality/pipeline-common - ref: 7.7.0 + ref: 7.8.0 file: - /ci/danger-review.yml diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue index 2be59f00773..19da1253a17 100644 --- a/app/assets/javascripts/badges/components/badge_form.vue +++ b/app/assets/javascripts/badges/components/badge_form.vue @@ -277,11 +277,7 @@ export default { > {{ saveText }} </gl-button> - <gl-button - :type="cancelButtonType" - data-qa-selector="cancel_badge_button" - @click="handleCancel" - > + <gl-button :type="cancelButtonType" @click="handleCancel"> {{ __('Cancel') }} </gl-button> </div> diff --git a/app/assets/javascripts/boards/components/board_add_new_column_form.vue b/app/assets/javascripts/boards/components/board_add_new_column_form.vue index 419d0b41d69..a3c0553d17c 100644 --- a/app/assets/javascripts/boards/components/board_add_new_column_form.vue +++ b/app/assets/javascripts/boards/components/board_add_new_column_form.vue @@ -43,7 +43,6 @@ export default { <div class="board-add-new-list board gl-display-inline-block gl-h-full gl-vertical-align-top gl-white-space-normal gl-flex-shrink-0 gl-rounded-base gl-px-3" data-testid="board-add-new-column" - data-qa-selector="board_add_new_list" > <div class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base gl-bg-gray-50" diff --git a/app/assets/javascripts/boards/components/new_board_button.vue b/app/assets/javascripts/boards/components/new_board_button.vue index f7914c636cc..96cf0fadd6a 100644 --- a/app/assets/javascripts/boards/components/new_board_button.vue +++ b/app/assets/javascripts/boards/components/new_board_button.vue @@ -38,7 +38,7 @@ export default { <template #control> </template> <template #candidate> <div v-if="canShowCreateButton" class="gl-ml-1 gl-mr-3 gl-display-flex gl-align-items-center"> - <gl-button data-qa-selector="new_board_button" @click.prevent="showDialog"> + <gl-button @click.prevent="showDialog"> {{ createButtonText }} </gl-button> </div> diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue index 87d8b98b025..30cadadfe45 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_table.vue @@ -386,7 +386,6 @@ export default { icon="remove" size="small" :aria-label="$options.i18n.deleteButton" - data-qa-selector="delete_ci_variable_button" /> <gl-modal ref="modal" diff --git a/app/assets/javascripts/ci/pipeline_mini_graph/legacy_job_item.vue b/app/assets/javascripts/ci/pipeline_mini_graph/legacy_job_item.vue index d20d4aec59d..4fded3aec60 100644 --- a/app/assets/javascripts/ci/pipeline_mini_graph/legacy_job_item.vue +++ b/app/assets/javascripts/ci/pipeline_mini_graph/legacy_job_item.vue @@ -132,7 +132,6 @@ export default { <template> <div class="ci-job-component gl-display-flex gl-align-items-center gl-justify-content-space-between" - data-qa-selector="job_item_container" > <gl-link v-if="hasDetails" diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue index cd1d9a97ef3..5444e66cbdf 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_form.vue @@ -371,11 +371,7 @@ export default { </gl-form-group> <!--Variable List--> <gl-form-group class="gl-mb-0" :label="$options.i18n.variables"> - <div - v-for="(variable, index) in variables" - :key="`var-${index}`" - data-qa-selector="ci_variable_row_container" - > + <div v-for="(variable, index) in variables" :key="`var-${index}`"> <div v-if="!variable.destroy" class="gl-display-flex gl-align-items-stretch gl-flex-direction-column gl-md-flex-direction-row gl-mb-3 gl-pb-2" diff --git a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue index 0871d543d46..e1f6006fedf 100644 --- a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue +++ b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue @@ -180,17 +180,11 @@ export default { data-confirm-btn-variant="danger" rel="nofollow" data-testid="trigger_revoke_button" - data-qa-selector="trigger_revoke_button" :href="item.projectTriggerPath" /> </template> </gl-table> - <div - v-else - class="gl-new-card-empty gl-px-5 gl-py-4" - data-testid="no_triggers_content" - data-qa-selector="no_triggers_content" - > + <div v-else class="gl-new-card-empty gl-px-5 gl-py-4" data-testid="no_triggers_content"> {{ s__('Pipelines|No triggers have been created yet. Add one using the form above.') }} </div> </div> diff --git a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue index 72d1ce9768a..6210e82119f 100644 --- a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue +++ b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue @@ -142,7 +142,6 @@ export default { ref="freezeStartCron" v-model="freezeStartCron" class="gl-font-monospace!" - data-qa-selector="deploy_freeze_start_field" :placeholder="$options.i18n.cronPlaceholder" :state="freezeStartCronState" autofocus @@ -160,7 +159,6 @@ export default { id="deploy-freeze-end" v-model="freezeEndCron" class="gl-font-monospace!" - data-qa-selector="deploy_freeze_end_field" :placeholder="$options.i18n.cronPlaceholder" :state="freezeEndCronState" trim diff --git a/app/assets/javascripts/design_management/components/delete_button.vue b/app/assets/javascripts/design_management/components/delete_button.vue index dec1038d2e3..88c1b444b31 100644 --- a/app/assets/javascripts/design_management/components/delete_button.vue +++ b/app/assets/javascripts/design_management/components/delete_button.vue @@ -63,7 +63,7 @@ export default { title: s__('DesignManagement|Are you sure you want to archive the selected designs?'), actionPrimary: { text: s__('DesignManagement|Archive designs'), - attributes: { variant: 'confirm', 'data-qa-selector': 'confirm_archiving_button' }, + attributes: { variant: 'confirm', 'data-testid': 'confirm-archiving-button' }, }, actionCancel: { text: __('Cancel'), diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue index f1ed7839bab..2a099b6f22d 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue @@ -293,7 +293,6 @@ export default { <ul class="design-discussion bordered-box gl-relative gl-p-0 gl-list-style-none" :class="{ 'gl-bg-blue-50': isDiscussionActive }" - data-qa-selector="design_discussion_content" data-testid="design-discussion-content" > <design-note diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue index 609ccc9e77a..54ffd986588 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue @@ -129,8 +129,6 @@ export default { this.isEditing = true; }, extraAttrs: { - 'data-testid': 'delete-note-button', - 'data-qa-selector': 'delete_design_note_button', class: 'gl-sm-display-none!', }, }, @@ -140,8 +138,6 @@ export default { this.$emit('delete-note', this.note); }, extraAttrs: { - 'data-testid': 'delete-note-button', - 'data-qa-selector': 'delete_design_note_button', class: 'gl-text-red-500!', }, }, @@ -311,7 +307,6 @@ export default { v-gl-tooltip.hover icon="ellipsis_v" category="tertiary" - data-qa-selector="design_discussion_actions_ellipsis_dropdown" text-sr-only :title="$options.i18n.moreActionsLabel" :aria-label="$options.i18n.moreActionsLabel" @@ -322,12 +317,7 @@ export default { </div> </div> <template v-if="!isEditing"> - <div - v-safe-html="note.bodyHtml" - class="note-text md" - data-qa-selector="note_content" - data-testid="note-text" - ></div> + <div v-safe-html="note.bodyHtml" class="note-text md" data-testid="note-text"></div> <slot name="resolved-status"></slot> </template> <design-note-awards-list diff --git a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue index 764c78ff581..b6a303ddde8 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue @@ -221,7 +221,7 @@ export default { class="note-textarea js-gfm-input js-autosize markdown-area" dir="auto" data-supports-quick-actions="false" - data-qa-selector="note_textarea" + data-testid="note-textarea" :aria-label="__('Description')" :placeholder="__('Write a comment…')" @input="handleInput" @@ -243,7 +243,7 @@ export default { variant="confirm" type="submit" data-track-action="click_button" - data-qa-selector="save_comment_button" + data-testid="save-comment-button" @click="submitForm" > {{ buttonText }} diff --git a/app/assets/javascripts/design_management/components/design_overlay.vue b/app/assets/javascripts/design_management/components/design_overlay.vue index 4ce6395140e..e4361f94026 100644 --- a/app/assets/javascripts/design_management/components/design_overlay.vue +++ b/app/assets/javascripts/design_management/components/design_overlay.vue @@ -272,7 +272,7 @@ export default { role="button" :aria-label="$options.i18n.newCommentButtonLabel" class="gl-absolute gl-w-full gl-h-full gl-p-0 gl-top-0 gl-left-0 gl-outline-0! btn-transparent gl-hover-cursor-crosshair" - data-qa-selector="design_image_button" + data-testid="design-image-button" @mouseup="onAddCommentMouseup" ></button> diff --git a/app/assets/javascripts/design_management/components/list/item.vue b/app/assets/javascripts/design_management/components/list/item.vue index 7b98557f4f0..6400f939244 100644 --- a/app/assets/javascripts/design_management/components/list/item.vue +++ b/app/assets/javascripts/design_management/components/list/item.vue @@ -144,12 +144,17 @@ export default { :name="icon.name" :size="16" :class="icon.classes" - data-qa-selector="design_status_icon" + data-testid="design-status-icon" :data-qa-status="icon.name" /> </span> </div> - <gl-intersection-observer class="gl-flex-grow-1" @appear="onAppear"> + <gl-intersection-observer + class="gl-flex-grow-1" + data-testid="design-image" + :data-qa-filename="filename" + @appear="onAppear" + > <gl-loading-icon v-if="showLoadingSpinner" size="lg" /> <gl-icon v-else-if="showImageErrorIcon" @@ -162,8 +167,6 @@ export default { :src="imageLink" :alt="filename" class="gl-display-block gl-mx-auto gl-max-w-full gl-max-h-full gl-w-auto design-img" - data-qa-selector="design_image" - :data-qa-filename="filename" :data-testid="`design-img-${id}`" @load="onImageLoad" @error="onImageError" @@ -171,11 +174,13 @@ export default { </gl-intersection-observer> </div> <div class="card-footer gl-display-flex gl-w-full gl-bg-white gl-py-3 gl-px-4"> - <div class="gl-display-flex gl-flex-direction-column str-truncated-100"> + <div + class="gl-display-flex gl-flex-direction-column str-truncated-100" + data-testid="design-file-name" + > <span v-gl-tooltip class="gl-font-weight-semibold str-truncated-100" - data-qa-selector="design_file_name" :data-testid="`design-img-filename-${id}`" :title="filename" >{{ filename }}</span diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue index 09f99f0927f..a1fd3520982 100644 --- a/app/assets/javascripts/design_management/pages/index.vue +++ b/app/assets/javascripts/design_management/pages/index.vue @@ -402,7 +402,7 @@ export default { button-variant="default" button-class="gl-mr-3" button-size="small" - data-qa-selector="archive_button" + data-testid="archive-button" :loading="loading" :has-selected-designs="hasSelectedDesigns" @delete-selected-designs="mutate()" @@ -490,7 +490,7 @@ export default { :checked="isDesignSelected(design.filename)" type="checkbox" class="design-checkbox gl-absolute gl-top-4 gl-left-6 gl-ml-2" - data-qa-selector="design_checkbox" + data-testid="design-checkbox" :data-qa-design="design.filename" @change="changeSelectedDesigns(design.filename)" /> @@ -506,7 +506,7 @@ export default { :class="{ 'design-list-item': !isDesignListEmpty }" :display-as-card="hasDesigns" v-bind="$options.dropzoneProps" - data-qa-selector="design_dropzone_content" + data-testid="design-dropzone-content" @change="onUploadDesign" @error="onDesignDropzoneError" > diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue index b47086a19da..2f49ed847bf 100644 --- a/app/assets/javascripts/environments/components/environments_table.vue +++ b/app/assets/javascripts/environments/components/environments_table.vue @@ -147,12 +147,7 @@ export default { </div> </div> <template v-for="(model, i) in sortedEnvironments"> - <environment-item - :key="`environment-item-${i}`" - :model="model" - :table-data="tableData" - data-qa-selector="environment_item" - /> + <environment-item :key="`environment-item-${i}`" :model="model" :table-data="tableData" /> <div v-if="shouldRenderDeployBoard(model)" @@ -185,7 +180,6 @@ export default { :key="`environment-row-${i}-${index}`" :model="child" :table-data="tableData" - data-qa-selector="environment_item" /> <div diff --git a/app/assets/javascripts/error_tracking/components/error_details.vue b/app/assets/javascripts/error_tracking/components/error_details.vue index 1821aa073bc..01879a092ed 100644 --- a/app/assets/javascripts/error_tracking/components/error_details.vue +++ b/app/assets/javascripts/error_tracking/components/error_details.vue @@ -196,7 +196,7 @@ export default { text: __('Create issue'), action: this.createIssue, extraAttrs: { - 'data-qa-selector': 'create_issue_button', + 'data-testid': 'create-issue-button', }, }; }, @@ -309,7 +309,7 @@ export default { <div v-if="!loadingStacktrace && stacktrace" class="gl-my-auto gl-text-truncate" - data-qa-selector="reported_text" + data-testid="reported-text" > <gl-sprintf :message="__('Reported %{timeAgo} by %{reportedBy}')"> <template #reportedBy> @@ -367,7 +367,7 @@ export default { category="primary" variant="confirm" :loading="issueCreationInProgress" - data-qa-selector="create_issue_button" + data-testid="create-issue-button" @click="createIssue" > {{ __('Create issue') }} diff --git a/app/assets/javascripts/feature_flags/components/feature_flags.vue b/app/assets/javascripts/feature_flags/components/feature_flags.vue index daaeb5f8e85..e0a5e92564e 100644 --- a/app/assets/javascripts/feature_flags/components/feature_flags.vue +++ b/app/assets/javascripts/feature_flags/components/feature_flags.vue @@ -206,7 +206,6 @@ export default { v-gl-modal="'configure-feature-flags'" variant="confirm" category="secondary" - data-qa-selector="configure_feature_flags_button" data-testid="ff-configure-button" class="gl-mb-0 gl-mr-3" > diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue index fc7cfffc22c..43689e6677b 100644 --- a/app/assets/javascripts/groups/components/item_actions.vue +++ b/app/assets/javascripts/groups/components/item_actions.vue @@ -57,7 +57,6 @@ export default { icon="ellipsis_v" no-caret :data-testid="`group-${group.id}-dropdown-button`" - data-qa-selector="group_dropdown_button" :data-qa-group-id="group.id" > <gl-dropdown-item diff --git a/app/assets/javascripts/groups_projects/components/transfer_locations.vue b/app/assets/javascripts/groups_projects/components/transfer_locations.vue index 997e2bc3138..5774065bff9 100644 --- a/app/assets/javascripts/groups_projects/components/transfer_locations.vue +++ b/app/assets/javascripts/groups_projects/components/transfer_locations.vue @@ -260,11 +260,7 @@ export default { > <gl-dropdown-divider /> </template> - <div - v-if="hasUserTransferLocations" - data-qa-selector="namespaces_list_users" - data-testid="user-transfer-locations" - > + <div v-if="hasUserTransferLocations" data-testid="user-transfer-locations"> <gl-dropdown-section-header>{{ $options.i18n.USERS }}</gl-dropdown-section-header> <gl-dropdown-item v-for="item in userTransferLocations" diff --git a/app/assets/javascripts/import_entities/import_projects/components/github_status_table.vue b/app/assets/javascripts/import_entities/import_projects/components/github_status_table.vue index cb3476c48db..5931e0d307a 100644 --- a/app/assets/javascripts/import_entities/import_projects/components/github_status_table.vue +++ b/app/assets/javascripts/import_entities/import_projects/components/github_status_table.vue @@ -78,7 +78,6 @@ export default { @input="setFilter({ organization_login: $event })" /> <gl-search-box-by-click - data-qa-selector="githubish_import_filter_field" name="filter" :disabled="isNameFilterDisabled" :value="nameFilter" diff --git a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue index 009945f8b9b..d98132382c6 100644 --- a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue +++ b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue @@ -155,7 +155,6 @@ export default { <slot name="actions"></slot> <form v-if="filterable" class="gl-ml-auto" novalidate @submit.prevent> <gl-search-box-by-click - data-qa-selector="githubish_import_filter_field" name="filter" :placeholder="__('Filter by name')" autofocus diff --git a/app/assets/javascripts/invite_members/components/project_select.vue b/app/assets/javascripts/invite_members/components/project_select.vue index 640df5cdb88..6c2f53afe3c 100644 --- a/app/assets/javascripts/invite_members/components/project_select.vue +++ b/app/assets/javascripts/invite_members/components/project_select.vue @@ -115,7 +115,6 @@ export default { :search-placeholder="$options.i18n.searchPlaceholder" :no-results-text="$options.i18n.emptySearchResult" data-testid="project-select-dropdown" - data-qa-selector="project_select_dropdown" class="gl-collapsible-listbox-w-full" @search="searchTerm = $event" @select="selectProject" diff --git a/app/assets/javascripts/issues/show/components/fields/description.vue b/app/assets/javascripts/issues/show/components/fields/description.vue index 10323b99665..1f159e71da9 100644 --- a/app/assets/javascripts/issues/show/components/fields/description.vue +++ b/app/assets/javascripts/issues/show/components/fields/description.vue @@ -79,7 +79,6 @@ export default { :autocomplete-data-sources="autocompleteDataSources" supports-quick-actions autofocus - data-qa-selector="description_field" @input="$emit('input', $event)" @keydown.meta.enter="saveIssuable" @keydown.ctrl.enter="saveIssuable" diff --git a/app/assets/javascripts/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue b/app/assets/javascripts/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue index bfe0c250dd9..cf1ee44b82e 100644 --- a/app/assets/javascripts/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue +++ b/app/assets/javascripts/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue @@ -44,12 +44,7 @@ export default { <template> <list-item v-bind="$attrs"> <template #left-primary> - <router-link - class="gl-text-body gl-font-weight-bold" - data-testid="details-link" - data-qa-selector="registry_image_content" - :to="linkTo" - > + <router-link class="gl-text-body gl-font-weight-bold" data-testid="details-link" :to="linkTo"> {{ item.name }} </router-link> <clipboard-button diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue index b49c448c478..a821a2483cd 100644 --- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue +++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue @@ -167,7 +167,7 @@ export default { <gl-tabs> <gl-tab :title="__('Detail')"> - <div data-qa-selector="package_information_content"> + <div> <package-history :package-entity="packageEntity" :project-name="projectName" /> <terraform-installation /> </div> diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue index cd5f9f5a676..9d70391a8dd 100644 --- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue +++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue @@ -34,7 +34,7 @@ export default { </script> <template> - <title-area :title="packageEntity.name" data-qa-selector="package_title"> + <title-area :title="packageEntity.name"> <template #sub-header> <gl-icon name="eye" class="gl-mr-3" /> <gl-sprintf :message="$options.i18n.packageInfo"> diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue index cdf03d64b27..db5e007b81f 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue @@ -77,7 +77,6 @@ export default { v-gl-resize-observer="checkBreakpoints" :title="packageEntity.name" :avatar="packageIcon" - data-qa-selector="package_title" > <template #sub-header> <div data-testid="sub-header" class="gl-display-flex gl-flex-wrap gl-gap-3"> diff --git a/app/assets/javascripts/packages_and_registries/shared/components/package_path.vue b/app/assets/javascripts/packages_and_registries/shared/components/package_path.vue index 0a94f67ea5e..18e95ee313e 100644 --- a/app/assets/javascripts/packages_and_registries/shared/components/package_path.vue +++ b/app/assets/javascripts/packages_and_registries/shared/components/package_path.vue @@ -47,7 +47,7 @@ export default { </script> <template> - <div data-qa-selector="package_path" class="gl-display-flex gl-align-items-center"> + <div class="gl-display-flex gl-align-items-center"> <gl-icon data-testid="base-icon" name="project" class="gl-mx-3 gl-min-w-0" /> <gl-link diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue index 459546a5562..0b9c2cf4772 100644 --- a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue +++ b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue @@ -225,12 +225,7 @@ export default { :description="s__('BulkImport|Your imported groups and projects will appear here.')" /> <template v-else> - <gl-table-lite - :fields="$options.fields" - :items="historyItems" - data-qa-selector="import_history_table" - class="gl-w-full" - > + <gl-table-lite :fields="$options.fields" :items="historyItems" class="gl-w-full"> <template #cell(destination_name)="{ item }"> <gl-icon v-gl-tooltip diff --git a/app/assets/javascripts/pages/import/history/components/import_history_app.vue b/app/assets/javascripts/pages/import/history/components/import_history_app.vue index 938c2be89c5..b2cd728c8b9 100644 --- a/app/assets/javascripts/pages/import/history/components/import_history_app.vue +++ b/app/assets/javascripts/pages/import/history/components/import_history_app.vue @@ -144,12 +144,7 @@ export default { :description="s__('BulkImport|Your imported projects will appear here.')" /> <template v-else> - <gl-table - :fields="$options.fields" - :items="historyItems" - data-qa-selector="import_history_table" - class="gl-w-full" - > + <gl-table :fields="$options.fields" :items="historyItems" class="gl-w-full"> <template #cell(source)="{ item }"> <template v-if="item.import_url"> <gl-link diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue index 5078cbbdf59..e968d935f20 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue @@ -311,7 +311,6 @@ export default { variant="confirm" class="gl-mt-5" data-testid="save_service_desk_settings_button" - data-qa-selector="save_service_desk_settings_button" :disabled="isTemplateSaving || !isIssueTrackerEnabled" @click="onSaveTemplate" > diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue index 315f0743b53..86c4fdcc30a 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_template_dropdown.vue @@ -84,7 +84,6 @@ export default { id="service-desk-template-select" :text="selectedTemplate || $options.i18n.defaultDropdownText" :header-text="$options.i18n.defaultDropdownText" - data-qa-selector="service_desk_template_dropdown" :block="true" class="service-desk-template-select" toggle-class="gl-m-0" diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue index 609a9355d20..745122afb4a 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue @@ -47,7 +47,6 @@ export default { class="js-sidebar-dropdown-toggle edit-link btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary float-right" href="#" data-test-id="edit-link" - data-qa-selector="edit_link" data-track-action="click_edit_button" data-track-label="right_sidebar" data-track-property="assignee" diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue index 9d6a8bf47e0..55c5b04dbe3 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue @@ -58,7 +58,6 @@ export default { type="button" class="gl-button btn-link gl-reset-color!" data-testid="assign-yourself" - data-qa-selector="assign_yourself_button" @click="assignSelf" > {{ __('assign yourself') }} diff --git a/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_value.vue b/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_value.vue index 5ca18969f0b..06ac2cb715d 100644 --- a/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_value.vue +++ b/app/assets/javascripts/sidebar/components/labels/labels_select_vue/dropdown_value.vue @@ -58,7 +58,6 @@ export default { <template v-for="label in sortedSelectedLabels" v-else> <gl-label :key="label.id" - data-qa-selector="selected_label_content" :data-qa-label-name="label.title" :title="label.title" :description="label.description" diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue index a7db3b3d09f..d8e61c135e7 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue @@ -40,7 +40,6 @@ export default { :width="imgSize" :class="`s${imgSize}`" class="avatar avatar-inline m-0" - data-qa-selector="avatar_image" /> <gl-icon v-if="hasMergeIcon" name="warning-solid" aria-hidden="true" class="merge-icon" /> </span> diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue index ee9edd6a022..49598c53bfd 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue @@ -71,7 +71,6 @@ export default { variant="link" class="gl-ml-2" data-testid="assign-yourself" - data-qa-selector="assign_yourself_button" @click="assignSelf" > <span class="gl-text-gray-500 gl-hover-text-blue-800">{{ __('assign yourself') }}</span> diff --git a/app/assets/javascripts/super_sidebar/components/create_menu.vue b/app/assets/javascripts/super_sidebar/components/create_menu.vue index 279e689bd8d..e8410a51905 100644 --- a/app/assets/javascripts/super_sidebar/components/create_menu.vue +++ b/app/assets/javascripts/super_sidebar/components/create_menu.vue @@ -70,7 +70,6 @@ export default { :toggle-text="$options.i18n.createNew" :toggle-id="$options.toggleId" :dropdown-offset="dropdownOffset" - data-qa-selector="new_menu_toggle" data-testid="new-menu-toggle" @shown="dropdownOpen = true" @hidden="dropdownOpen = false" diff --git a/app/assets/javascripts/tags/components/delete_tag_modal.vue b/app/assets/javascripts/tags/components/delete_tag_modal.vue index c4f9db70d2a..9a0cc026223 100644 --- a/app/assets/javascripts/tags/components/delete_tag_modal.vue +++ b/app/assets/javascripts/tags/components/delete_tag_modal.vue @@ -151,7 +151,6 @@ export default { ref="deleteTagButton" :disabled="deleteButtonDisabled" variant="danger" - data-qa-selector="delete_tag_confirmation_button" data-testid="delete-tag-confirmation-button" @click="submitForm" >{{ buttonText }}</gl-button diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 9b9665518a9..df2e09026db 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -662,7 +662,6 @@ export default { <template v-if="showAutoMergeHelperText"> <div class="gl-ml-4 gl-text-gray-500 gl-font-sm" - data-qa-selector="auto_merge_helper_text" data-testid="auto-merge-helper-text" > {{ autoMergeHelperText }} diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue index 2d3815439a6..056388f690d 100644 --- a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue @@ -284,13 +284,7 @@ export default { > <div v-if="userName" class="gl-display-inline-flex gl-mt-2" data-testid="assigned-users"> <span class="gl-relative gl-mr-4"> - <img - :alt="userName" - :src="userImg" - :width="32" - class="avatar avatar-inline gl-m-0 s32" - data-qa-selector="avatar_image" - /> + <img :alt="userName" :src="userImg" :width="32" class="avatar avatar-inline gl-m-0 s32" /> </span> <span class="gl-display-flex gl-flex-direction-column gl-overflow-hidden"> <strong class="dropdown-menu-user-full-name"> diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue index 53daf7339c0..5326e9300f3 100644 --- a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue +++ b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue @@ -98,7 +98,6 @@ export default { :class="$options.userColorScheme" data-type="simple" :data-path="blob.path" - data-qa-selector="blob_viewer_file_content" > <chunk v-for="(chunk, index) in chunks" diff --git a/app/assets/javascripts/vue_shared/components/toggle_labels.vue b/app/assets/javascripts/vue_shared/components/toggle_labels.vue index 05c837e32f0..db20e1288aa 100644 --- a/app/assets/javascripts/vue_shared/components/toggle_labels.vue +++ b/app/assets/javascripts/vue_shared/components/toggle_labels.vue @@ -54,7 +54,6 @@ export default { label-position="left" aria-describedby="board-labels-toggle-text" data-testid="show-labels-toggle" - data-qa-selector="show_labels_toggle" class="gl-flex-direction-row" @change="setShowLabels" /> diff --git a/app/assets/javascripts/webhooks/components/push_events.vue b/app/assets/javascripts/webhooks/components/push_events.vue index 91d7e21500a..b5e0a4b2348 100644 --- a/app/assets/javascripts/webhooks/components/push_events.vue +++ b/app/assets/javascripts/webhooks/components/push_events.vue @@ -43,7 +43,7 @@ export default { value="all_branches" data-testid="rule_all_branches" > - <div data-qa-selector="strategy_radio_all">{{ __('All branches') }}</div> + <div>{{ __('All branches') }}</div> </gl-form-radio> <!-- wildcard --> @@ -52,7 +52,7 @@ export default { value="wildcard" data-testid="rule_wildcard" > - <div data-qa-selector="strategy_radio_wildcard"> + <div> {{ s__('Webhooks|Wildcard pattern') }} </div> </gl-form-radio> @@ -61,7 +61,6 @@ export default { v-if="branchFilterStrategyData === 'wildcard'" v-model="pushEventsBranchFilterData" name="hook[push_events_branch_filter]" - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" /> </div> @@ -85,7 +84,7 @@ export default { value="regex" data-testid="rule_regex" > - <div data-qa-selector="strategy_radio_regex"> + <div> {{ s__('Webhooks|Regular expression') }} </div> </gl-form-radio> @@ -94,7 +93,6 @@ export default { v-if="branchFilterStrategyData === 'regex'" v-model="pushEventsBranchFilterData" name="hook[push_events_branch_filter]" - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" /> </div> diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml index 188359158ef..ed1342be1fc 100644 --- a/app/views/admin/application_settings/metrics_and_profiling.html.haml +++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml @@ -53,7 +53,7 @@ = render 'usage' - if Feature.enabled?(:configure_sentry_in_application_settings) - %section.settings.as-sentry.no-animate#js-sentry-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'sentry_settings_content' } } + %section.settings.as-sentry.no-animate#js-sentry-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Sentry') diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml index 849c5c749e0..fb22df9d066 100644 --- a/app/views/admin/application_settings/network.html.haml +++ b/app/views/admin/application_settings/network.html.haml @@ -26,7 +26,7 @@ .settings-content = render 'ip_limits' -%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'packages_limits_content' } } +%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Package registry rate limits') @@ -72,7 +72,7 @@ .settings-content = render partial: 'network_rate_limits', locals: { anchor: 'js-deprecated-limits-settings', setting_fragment: 'deprecated_api' } -%section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'git_lfs_limits_content' } } +%section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Git LFS Rate Limits') diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml index c7a2fca00ef..a46275ff9d5 100644 --- a/app/views/admin/application_settings/repository.html.haml +++ b/app/views/admin/application_settings/repository.html.haml @@ -26,7 +26,7 @@ .settings-content = render partial: 'repository_mirrors_form' -%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'repository_storage_settings_content' } } +%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Repository storage') diff --git a/app/views/admin/topics/_form.html.haml b/app/views/admin/topics/_form.html.haml index 2638e45c9eb..c61be1182e0 100644 --- a/app/views/admin/topics/_form.html.haml +++ b/app/views/admin/topics/_form.html.haml @@ -4,7 +4,7 @@ .form-group = f.label :name do = _("Topic slug (name)") - = f.text_field :name, placeholder: _('my-topic'), class: 'form-control input-lg', data: { qa_selector: 'topic_name_field' }, + = f.text_field :name, placeholder: _('my-topic'), class: 'form-control input-lg', required: true, title: _('Please fill in a name for your topic.'), autofocus: true @@ -12,7 +12,7 @@ .form-group = f.label :title do = _("Topic title") - = f.text_field :title, placeholder: _('My topic'), class: 'form-control input-lg', data: { qa_selector: 'topic_title_field' }, + = f.text_field :title, placeholder: _('My topic'), class: 'form-control input-lg', required: true, title: _('Please fill in a title for your topic.') diff --git a/app/views/admin/topics/_topic.html.haml b/app/views/admin/topics/_topic.html.haml index 3e8a023ec9f..4e8b1394e06 100644 --- a/app/views/admin/topics/_topic.html.haml +++ b/app/views/admin/topics/_topic.html.haml @@ -1,7 +1,7 @@ - topic = local_assigns.fetch(:topic) - title = topic.title || topic.name -%li.topic-row.gl-py-3.gl-align-items-center{ class: 'gl-display-flex!', data: { qa_selector: 'topic_row_content' } } +%li.topic-row.gl-py-3.gl-align-items-center{ class: 'gl-display-flex!' } = render Pajamas::AvatarComponent.new(topic, size: 32, alt: '') .gl-min-w-0.gl-flex-grow-1.gl-ml-3 diff --git a/app/views/admin/topics/index.html.haml b/app/views/admin/topics/index.html.haml index 6d64fa1983f..46c1b9ac5c4 100644 --- a/app/views/admin/topics/index.html.haml +++ b/app/views/admin/topics/index.html.haml @@ -6,7 +6,7 @@ = form_tag admin_topics_path, method: :get do |f| - search = params.fetch(:search, nil) .search-field-holder - = search_field_tag :search, search, class: "form-control gl-form-input search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: _('Search by name'), data: { qa_selector: 'topic_search_field' } + = search_field_tag :search, search, class: "form-control gl-form-input search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: _('Search by name') = sprite_icon('search', css_class: 'search-icon') .gl-flex-grow-1 .js-merge-topics{ data: { path: merge_admin_topics_path } } diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 76758769d01..2f2edec2d80 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -17,15 +17,15 @@ = _("New project") - c.with_body do %ul.content-list{ class: 'gl-px-3!' } - - @projects.each_with_index do |project, idx| - %li.project-row.gl-align-items-center{ class: 'gl-display-flex!', data: { qa_selector: 'project_row_container', qa_index: idx } } + - @projects.each do |project| + %li.project-row.gl-align-items-center{ class: 'gl-display-flex!' } .avatar-container.rect-avatar.s40.gl-flex-shrink-0 = project_icon(project, alt: '', class: 'avatar project-avatar s40', width: 40, height: 40) .gl-min-w-0.gl-flex-grow-1 .title = link_to project_path(project), class: 'js-prefetch-document' do - %span.project-full-name{ data: { qa_selector: 'project_fullname_content' } } - %span.namespace-name{ data: { qa_selector: 'project_namespace_content' } } + %span.project-full-name + %span.namespace-name - if project.namespace = project.namespace.human_name \/ @@ -43,13 +43,12 @@ .controls.gl-flex-shrink-0.gl-ml-5 = render Pajamas::ButtonComponent.new(href: project_project_members_path(project), variant: :link, - button_options: { class: 'gl-mr-2', data: { qa_selector: 'project_members_button' } }) do + button_options: { class: 'gl-mr-2' }) do = _('View members') = render Pajamas::ButtonComponent.new(href: edit_project_path(project), - size: :small, - button_options: { data: { qa_selector: 'project_edit_button' } }) do + size: :small) do = _('Edit') - = render 'delete_project_button', project: project, data: { qa_selector: 'project_delete_button' } + = render 'delete_project_button', project: project - if @projects.blank? .nothing-here-block= _("This group has no projects yet") diff --git a/app/views/groups/settings/_export.html.haml b/app/views/groups/settings/_export.html.haml index 8eb9f8fc5f1..059426fd596 100644 --- a/app/views/groups/settings/_export.html.haml +++ b/app/views/groups/settings/_export.html.haml @@ -31,8 +31,8 @@ - if group.export_file_exists? = render Pajamas::ButtonComponent.new(href: download_export_group_path(group), button_options: { rel: 'nofollow', data: { method: :get, qa_selector: 'download_export_link' } }) do = _('Download export') - = render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post, qa_selector: 'regenerate_export_group_link' } }) do + = render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post } }) do = _('Regenerate export') - else - = render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post, qa_selector: 'export_group_link' } }) do + = render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post } }) do = _('Export group') diff --git a/app/views/groups/settings/_git_access_protocols.html.haml b/app/views/groups/settings/_git_access_protocols.html.haml index d23f72a3055..c9cbe56e6ec 100644 --- a/app/views/groups/settings/_git_access_protocols.html.haml +++ b/app/views/groups/settings/_git_access_protocols.html.haml @@ -1,7 +1,7 @@ - if group.root? .form-group = f.label _('Enabled Git access protocols'), class: 'label-bold' - = f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group(group), group.enabled_git_access_protocol), {}, class: 'form-control', data: { qa_selector: 'enabled_git_access_protocol_dropdown' }, disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank? + = f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group(group), group.enabled_git_access_protocol), {}, class: 'form-control', disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank? - if !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank? .form-text.text-muted = _("This setting has been configured at the instance level and cannot be overridden per group") diff --git a/app/views/groups/settings/_resource_access_token_creation.html.haml b/app/views/groups/settings/_resource_access_token_creation.html.haml index d304dba3250..7d64ab84ad2 100644 --- a/app/views/groups/settings/_resource_access_token_creation.html.haml +++ b/app/views/groups/settings/_resource_access_token_creation.html.haml @@ -7,4 +7,4 @@ - link_start_group = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_access_tokens_link } = f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed, s_('GroupSettings|Users can create %{link_start_project}project access tokens%{link_end} and %{link_start_group}group access tokens%{link_end} in this group').html_safe % { link_start_project: link_start_project, link_start_group: link_start_group, link_end: '</a>'.html_safe }, - checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } } + checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed? } diff --git a/app/views/layouts/signup_onboarding.html.haml b/app/views/layouts/signup_onboarding.html.haml index a5953021671..d440b543662 100644 --- a/app/views/layouts/signup_onboarding.html.haml +++ b/app/views/layouts/signup_onboarding.html.haml @@ -3,7 +3,7 @@ !!! 5 %html.html-devise-layout{ lang: I18n.locale } = render "layouts/head" - %body.signup-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } } + %body.signup-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page } } = header_message = render "layouts/init_client_detection_flags" = render "layouts/header/logo_with_title" diff --git a/app/views/projects/_service_desk_settings.html.haml b/app/views/projects/_service_desk_settings.html.haml index 3dbc4c0fad7..907d9683823 100644 --- a/app/views/projects/_service_desk_settings.html.haml +++ b/app/views/projects/_service_desk_settings.html.haml @@ -1,5 +1,5 @@ - expanded = expanded_by_default? -%section.settings.js-service-desk-setting-wrapper.no-animate#js-service-desk{ class: ('expanded' if expanded), data: { qa_selector: 'service_desk_settings_content' } } +%section.settings.js-service-desk-setting-wrapper.no-animate#js-service-desk{ class: ('expanded' if expanded) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Service Desk') = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do diff --git a/app/views/projects/issues/service_desk/_issue.html.haml b/app/views/projects/issues/service_desk/_issue.html.haml index 66b2eabac9d..dbc6e613e8b 100644 --- a/app/views/projects/issues/service_desk/_issue.html.haml +++ b/app/views/projects/issues/service_desk/_issue.html.haml @@ -1,4 +1,4 @@ -%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id, qa_selector: 'issue_container', qa_issue_title: issue.title } } +%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id } } .issuable-info-container .issuable-main-info .issue-title.title diff --git a/app/views/projects/issues/service_desk/_issue_estimate.html.haml b/app/views/projects/issues/service_desk/_issue_estimate.html.haml index c49bf626f4e..c6fa8b64dec 100644 --- a/app/views/projects/issues/service_desk/_issue_estimate.html.haml +++ b/app/views/projects/issues/service_desk/_issue_estimate.html.haml @@ -1,7 +1,7 @@ - issue = local_assigns.fetch(:issue) - if issue.time_estimate > 0 - %span.issuable-estimate.d-none.d-sm-inline-block.has-tooltip{ data: { container: 'body', qa_selector: 'issuable_estimate' }, title: _('Estimate') } + %span.issuable-estimate.d-none.d-sm-inline-block.has-tooltip{ data: { container: 'body' }, title: _('Estimate') } = sprite_icon('timer', css_class: 'issue-estimate-icon') = Gitlab::TimeTrackingFormatter.output(issue.time_estimate) diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml index e46da882e83..3bf85da83b1 100644 --- a/app/views/shared/access_tokens/_form.html.haml +++ b/app/views/shared/access_tokens/_form.html.haml @@ -30,7 +30,7 @@ .form-group = label_tag :access_level, s_("AccessTokens|Select a role"), class: "label-bold" .select-wrapper.gl-form-input-md - = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control", data: { qa_selector: 'access_token_access_level' } + = select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control" = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200") .form-group diff --git a/app/views/shared/issuable/_assignees.html.haml b/app/views/shared/issuable/_assignees.html.haml index 5326b26d655..1ae9ce4eecd 100644 --- a/app/views/shared/issuable/_assignees.html.haml +++ b/app/views/shared/issuable/_assignees.html.haml @@ -7,5 +7,5 @@ = link_to_member(@project, assignee, name: false, title: s_("MrList|Assigned to %{name}") % { name: assignee.name}) - if more_assignees_count > 0 - %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', qa_selector: 'avatar_counter_content' }, title: _("+%{more_assignees_count} more assignees") % { more_assignees_count: more_assignees_count} } + %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old' }, title: _("+%{more_assignees_count} more assignees") % { more_assignees_count: more_assignees_count} } = _("+%{more_assignees_count}") % { more_assignees_count: more_assignees_count} diff --git a/app/views/shared/issuable/_nav.html.haml b/app/views/shared/issuable/_nav.html.haml index 4a33f625347..c48f51dc9bc 100644 --- a/app/views/shared/issuable/_nav.html.haml +++ b/app/views/shared/issuable/_nav.html.haml @@ -11,7 +11,7 @@ = gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by merge requests that are currently closed and unmerged.'), data: { state: 'closed' } do #{issuables_state_counter_text(type, :closed, display_count)} - else - = gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed', qa_selector: 'closed_issues_link' } do + = gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed' } do #{issuables_state_counter_text(type, :closed, display_count)} = render 'shared/issuable/nav_links/all', page_context_word: page_context_word, counter: issuables_state_counter_text(type, :all, display_count) diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 5944da01e36..16b69a4298b 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -157,7 +157,7 @@ = gl_badge_tag @user.followers.count, size: :sm - if profile_tab?(:following) %li.js-following-tab - = link_to user_following_path, data: { target: 'div#following', action: 'following', toggle: 'tab', endpoint: user_following_path(format: :json), qa_selector: 'following_tab' } do + = link_to user_following_path, data: { target: 'div#following', action: 'following', toggle: 'tab', endpoint: user_following_path(format: :json) } do = s_('UserProfile|Following') = gl_badge_tag @user.followees.count, size: :sm - if !profile_tabs.empty? && Feature.enabled?(:profile_tabs_vue, current_user) diff --git a/db/post_migrate/20231024025629_cleanup_ci_pipeline_chat_data_pipeline_id_bigint.rb b/db/post_migrate/20231024025629_cleanup_ci_pipeline_chat_data_pipeline_id_bigint.rb new file mode 100644 index 00000000000..e79f4eb43b7 --- /dev/null +++ b/db/post_migrate/20231024025629_cleanup_ci_pipeline_chat_data_pipeline_id_bigint.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class CleanupCiPipelineChatDataPipelineIdBigint < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + TABLE = :ci_pipeline_chat_data + COLUMNS = [:pipeline_id] + + def up + with_lock_retries(raise_on_exhaustion: true) do + cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) # rubocop:disable Migration/WithLockRetriesDisallowedMethod + end + end + + def down + restore_conversion_of_integer_to_bigint(TABLE, COLUMNS) + + add_concurrent_index( + TABLE, :pipeline_id_convert_to_bigint, + name: :index_ci_pipeline_chat_data_on_pipeline_id_convert_to_bigint, + unique: true + ) + add_concurrent_foreign_key( + TABLE, :ci_pipelines, + column: :pipeline_id_convert_to_bigint, + on_delete: :cascade, validate: true, reverse_lock_order: true + ) + end +end diff --git a/db/schema_migrations/20231024025629 b/db/schema_migrations/20231024025629 new file mode 100644 index 00000000000..30d63a84636 --- /dev/null +++ b/db/schema_migrations/20231024025629 @@ -0,0 +1 @@ +4c90d6df75ddb93f8fd8fb89131256fc97bac990f024576fa57a3a8c6b60fee9
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index c9ad3e81d54..bbb00db88bb 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -307,15 +307,6 @@ BEGIN END; $$; -CREATE FUNCTION trigger_239c8032a8d6() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - NEW."pipeline_id_convert_to_bigint" := NEW."pipeline_id"; - RETURN NEW; -END; -$$; - CREATE FUNCTION trigger_68d7b6653c7d() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -13817,7 +13808,6 @@ ALTER SEQUENCE ci_pipeline_artifacts_id_seq OWNED BY ci_pipeline_artifacts.id; CREATE TABLE ci_pipeline_chat_data ( id bigint NOT NULL, - pipeline_id_convert_to_bigint integer DEFAULT 0 NOT NULL, chat_name_id integer NOT NULL, response_url text NOT NULL, pipeline_id bigint NOT NULL @@ -31771,8 +31761,6 @@ CREATE INDEX index_ci_pipeline_chat_data_on_chat_name_id ON ci_pipeline_chat_dat CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id ON ci_pipeline_chat_data USING btree (pipeline_id); -CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id_convert_to_bigint ON ci_pipeline_chat_data USING btree (pipeline_id_convert_to_bigint); - CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id); CREATE INDEX index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint ON ci_pipeline_messages USING btree (pipeline_id_convert_to_bigint); @@ -36667,8 +36655,6 @@ CREATE TRIGGER trigger_07bc3c48f407 BEFORE INSERT OR UPDATE ON ci_stages FOR EAC CREATE TRIGGER trigger_1bd97da9c1a4 BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_1bd97da9c1a4(); -CREATE TRIGGER trigger_239c8032a8d6 BEFORE INSERT OR UPDATE ON ci_pipeline_chat_data FOR EACH ROW EXECUTE FUNCTION trigger_239c8032a8d6(); - CREATE TRIGGER trigger_68d7b6653c7d BEFORE INSERT OR UPDATE ON ci_sources_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_68d7b6653c7d(); CREATE TRIGGER trigger_7f3d66a7d7f5 BEFORE INSERT OR UPDATE ON ci_pipeline_variables FOR EACH ROW EXECUTE FUNCTION trigger_7f3d66a7d7f5(); @@ -37095,9 +37081,6 @@ ALTER TABLE ONLY approval_merge_request_rules ALTER TABLE ONLY deploy_keys_projects ADD CONSTRAINT fk_58a901ca7e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; -ALTER TABLE ONLY ci_pipeline_chat_data - ADD CONSTRAINT fk_5b21bde562 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE; - ALTER TABLE ONLY dependency_list_exports ADD CONSTRAINT fk_5b3d11e1ef FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 57fc9b7c4b7..24ce86eb5c9 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -17102,8 +17102,10 @@ Total weight of open and closed descendant issues. | Name | Type | Description | | ---- | ---- | ----------- | -| <a id="epicdescendantweightsclosedissues"></a>`closedIssues` | [`Int`](#int) | Total weight of completed (closed) issues in this epic, including epic descendants. | -| <a id="epicdescendantweightsopenedissues"></a>`openedIssues` | [`Int`](#int) | Total weight of opened issues in this epic, including epic descendants. | +| <a id="epicdescendantweightsclosedissues"></a>`closedIssues` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 16.6. Use `closedIssuesTotal`. | +| <a id="epicdescendantweightsclosedissuestotal"></a>`closedIssuesTotal` | [`BigInt`](#bigint) | Total weight of completed (closed) issues in this epic, including epic descendants, encoded as a string. | +| <a id="epicdescendantweightsopenedissues"></a>`openedIssues` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 16.6. Use `OpenedIssuesTotal`. | +| <a id="epicdescendantweightsopenedissuestotal"></a>`openedIssuesTotal` | [`BigInt`](#bigint) | Total weight of opened issues in this epic, including epic descendants, encoded as a string. | ### `EpicHealthStatus` diff --git a/doc/user/project/repository/code_suggestions/index.md b/doc/user/project/repository/code_suggestions/index.md index 151792089ce..8cdee773253 100644 --- a/doc/user/project/repository/code_suggestions/index.md +++ b/doc/user/project/repository/code_suggestions/index.md @@ -62,22 +62,13 @@ Code Suggestions do not prevent you from writing code in your IDE. ## Supported languages -The best results from Code Suggestions are expected for languages that [Anthropic Claude](https://www.anthropic.com/product) and the [Google Vertex AI Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview#supported_coding_languages) directly support: - -- C++ -- C# -- Go -- Google SQL -- Java -- JavaScript -- Kotlin -- PHP -- Python -- Ruby -- Rust -- Scala -- Swift -- TypeScript +Code Suggestions support is a function of the: + +- Underlying large language model. +- IDE used. +- Extension or plug-in support in the IDE. + +For languages not listed in the following table, Code Suggestions might not function as expected. ### Supported languages in IDEs diff --git a/package.json b/package.json index 714316949d5..b309716dc04 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "gettext-parser": "^6.0.0", "graphql": "^15.7.2", "graphql-tag": "^2.11.0", - "gridstack": "^9.3.0", + "gridstack": "^9.4.0", "highlight.js": "^11.8.0", "immer": "^9.0.15", "ipaddr.js": "^1.9.1", diff --git a/qa/lib/gitlab/page/admin/subscription.rb b/qa/lib/gitlab/page/admin/subscription.rb index e19f0580007..6decdeeb3f7 100644 --- a/qa/lib/gitlab/page/admin/subscription.rb +++ b/qa/lib/gitlab/page/admin/subscription.rb @@ -39,7 +39,7 @@ module Gitlab # @option plan [Hash] Support::Helpers::PREMIUM_SELF_MANAGED # @option plan [Hash] Support::Helpers::ULTIMATE # @option plan [Hash] Support::Helpers::ULTIMATE_SELF_MANAGED - # @option plan [Hash] Support::Helpers::CI_MINUTES + # @option plan [Hash] Support::Helpers::COMPUTE_MINUTES # @option plan [Hash] Support::Helpers::STORAGE # @param users_in_license [Integer] Number of users in license # @param license_type [Hash] Type of the license diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.rb index 8ae9e8fd25a..eab40ab8941 100644 --- a/qa/lib/gitlab/page/group/settings/usage_quotas.rb +++ b/qa/lib/gitlab/page/group/settings/usage_quotas.rb @@ -13,9 +13,9 @@ module Gitlab # Pipelines section link :pipelines_tab - link :buy_ci_minutes - div :plan_ci_minutes - div :additional_ci_minutes + link :buy_compute_minutes + div :plan_compute_minutes + div :additional_compute_minutes div :ci_purchase_successful_alert, text: /You have successfully purchased CI minutes/ # Storage section @@ -39,17 +39,17 @@ module Gitlab button :confirm_member_approval, text: /^OK$/ def plan_ci_limits - plan_ci_minutes[/(\d+){2}/] + plan_compute_minutes[/(\d+){2}/] end def additional_ci_limits - additional_ci_minutes[/(\d+){2}/] + additional_compute_minutes[/(\d+){2}/] end - def additional_ci_minutes_added? + def additional_compute_minutes_added? # When opening the Usage quotas page, Seats quota tab is opened briefly even when url is to a different tab ::QA::Support::WaitForRequests.wait_for_requests - additional_ci_minutes? + additional_compute_minutes? end # Returns total purchased storage value once it's ready on page @@ -61,29 +61,29 @@ module Gitlab storage_purchased[/(\d+){2}.\d+/].to_f end - # Waits for additional CI minutes to be available on the page - def wait_for_additional_ci_minutes_available + # Waits for additional compute minutes to be available on the page + def wait_for_additional_compute_minutes_available ::QA::Support::Waiter.wait_until( max_duration: ::QA::Support::Helpers::Zuora::ZUORA_TIMEOUT, sleep_interval: 2, reload_page: Chemlab.configuration.browser.session, - message: 'Expected additional CI minutes but they did not appear.' + message: 'Expected additional compute minutes but they did not appear.' ) do - additional_ci_minutes_added? + additional_compute_minutes_added? end end - # Waits for additional CI minutes amount to match the expected number of minutes + # Waits for additional compute minutes amount to match the expected number of minutes # # @param [String] minutes - def wait_for_additional_ci_minute_limits(minutes) - wait_for_additional_ci_minutes_available + def wait_for_additional_compute_minute_limits(minutes) + wait_for_additional_compute_minutes_available ::QA::Support::Waiter.wait_until( max_duration: ::QA::Support::Helpers::Zuora::ZUORA_TIMEOUT, sleep_interval: 2, reload_page: Chemlab.configuration.browser.session, - message: "Expected additional CI minutes to equal #{minutes}" + message: "Expected additional compute minutes to equal #{minutes}" ) do additional_ci_limits == minutes end diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb index 748c9a82d59..0c473123340 100644 --- a/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb +++ b/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb @@ -125,75 +125,75 @@ module Gitlab # This is a stub, used for indexing. The method is dynamically generated. end - # @note Defined as +link :buy_ci_minutes+ - # Clicks +buy_ci_minutes+ - def buy_ci_minutes + # @note Defined as +link :buy_compute_minutes+ + # Clicks +buy_compute_minutes+ + def buy_compute_minutes # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas.buy_ci_minutes_element).to exist + # expect(usage_quotas.buy_compute_minutes_element).to exist # end # @return [Watir::Link] The raw +Link+ element - def buy_ci_minutes_element + def buy_compute_minutes_element # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas).to be_buy_ci_minutes + # expect(usage_quotas).to be_buy_compute_minutes # end - # @return [Boolean] true if the +buy_ci_minutes+ element is present on the page - def buy_ci_minutes? + # @return [Boolean] true if the +buy_compute_minutes+ element is present on the page + def buy_compute_minutes? # This is a stub, used for indexing. The method is dynamically generated. end - # @note Defined as +div :plan_ci_minutes+ - # @return [String] The text content or value of +plan_ci_minutes+ - def plan_ci_minutes + # @note Defined as +div :plan_compute_minutes+ + # @return [String] The text content or value of +plan_compute_minutes+ + def plan_compute_minutes # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas.plan_ci_minutes_element).to exist + # expect(usage_quotas.plan_compute_minutes_element).to exist # end # @return [Watir::Div] The raw +Div+ element - def plan_ci_minutes_element + def plan_compute_minutes_element # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas).to be_plan_ci_minutes + # expect(usage_quotas).to be_plan_compute_minutes # end - # @return [Boolean] true if the +plan_ci_minutes+ element is present on the page - def plan_ci_minutes? + # @return [Boolean] true if the +plan_compute_minutes+ element is present on the page + def plan_compute_minutes? # This is a stub, used for indexing. The method is dynamically generated. end - # @note Defined as +div :additional_ci_minutes+ - # @return [String] The text content or value of +additional_ci_minutes+ - def additional_ci_minutes + # @note Defined as +div :additional_compute_minutes+ + # @return [String] The text content or value of +additional_compute_minutes+ + def additional_compute_minutes # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas.additional_ci_minutes_element).to exist + # expect(usage_quotas.additional_compute_minutes_element).to exist # end # @return [Watir::Div] The raw +Div+ element - def additional_ci_minutes_element + def additional_compute_minutes_element # This is a stub, used for indexing. The method is dynamically generated. end # @example # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas| - # expect(usage_quotas).to be_additional_ci_minutes + # expect(usage_quotas).to be_additional_compute_minutes # end - # @return [Boolean] true if the +additional_ci_minutes+ element is present on the page - def additional_ci_minutes? + # @return [Boolean] true if the +additional_compute_minutes+ element is present on the page + def additional_compute_minutes? # This is a stub, used for indexing. The method is dynamically generated. end diff --git a/qa/qa/flow/purchase.rb b/qa/qa/flow/purchase.rb index 76b1b2c7313..a412539d3bd 100644 --- a/qa/qa/flow/purchase.rb +++ b/qa/qa/flow/purchase.rb @@ -23,21 +23,21 @@ module QA end end - def purchase_ci_minutes(quantity: 1) + def purchase_compute_minutes(quantity: 1) Page::Group::Menu.perform(&:go_to_usage_quotas) Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quota| usage_quota.pipelines_tab - usage_quota.buy_ci_minutes + usage_quota.buy_compute_minutes end - Gitlab::Page::Subscriptions::New.perform do |ci_minutes| - ci_minutes.quantity = quantity - ci_minutes.continue_to_billing + Gitlab::Page::Subscriptions::New.perform do |compute_minutes| + compute_minutes.quantity = quantity + compute_minutes.continue_to_billing fill_in_customer_info fill_in_payment_info - ci_minutes.purchase + compute_minutes.purchase end end diff --git a/qa/qa/page/component/design_management.rb b/qa/qa/page/component/design_management.rb index 4caa5169c5f..a43c9f95ae4 100644 --- a/qa/qa/page/component/design_management.rb +++ b/qa/qa/page/component/design_management.rb @@ -11,49 +11,49 @@ module QA base.class_eval do view 'app/assets/javascripts/design_management/components/design_notes/design_discussion.vue' do - element :design_discussion_content + element 'design-discussion-content' end view 'app/assets/javascripts/design_management/components/design_notes/design_note.vue' do - element :note_content + element 'note-text' end view 'app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue' do - element :note_textarea - element :save_comment_button + element 'note-textarea' + element 'save-comment-button' end view 'app/assets/javascripts/design_management/components/design_overlay.vue' do - element :design_image_button + element 'design-image-button' end view 'app/assets/javascripts/design_management/components/list/item.vue' do - element :design_file_name - element :design_image - element :design_status_icon + element 'design-file-name' + element 'design-image' + element 'design-status-icon' end view 'app/assets/javascripts/design_management/pages/index.vue' do - element :archive_button - element :design_checkbox - element :design_dropzone_content + element 'archive-button' + element 'design-checkbox' + element 'design-dropzone-content' end view 'app/assets/javascripts/design_management/components/delete_button.vue' do - element :confirm_archiving_button + element 'confirm-archiving-button' end end end def add_annotation(note) - click_element(:design_image_button) - fill_element(:note_textarea, note) - click_element(:save_comment_button) + click_element('design-image-button') + fill_element('note-textarea', note) + click_element('save-comment-button') # It takes a moment for the annotation to be saved. # We'll check for the annotation in a test, but here we'll at least # wait for the "Save comment" button to disappear - saved = has_no_element?(:save_comment_button) + saved = has_no_element?('save-comment-button') return if saved raise RSpec::Expectations::ExpectationNotMetError, %q(There was a problem while adding the annotation) @@ -64,16 +64,16 @@ module QA # It accepts a `class:` option, but that only works for class attributes # It doesn't work as a CSS selector. # So instead we use the name attribute as a locator - within_element(:design_dropzone_content) do + within_element('design-dropzone-content') do page.attach_file("upload_file", design_file_path, make_visible: { display: 'block' }) end filename = ::File.basename(design_file_path) wait_until(reload: false, sleep_interval: 1, message: "Design upload") do - image = find_element(:design_image, filename: filename) + image = find_element('design-image', filename: filename).find('img') - has_element?(:design_file_name, text: filename) && image["complete"] && image["naturalWidth"].to_i > 0 + has_element?('design-file-name', text: filename) && image["complete"] && image["naturalWidth"].to_i > 0 end end @@ -83,38 +83,38 @@ module QA end def click_design(filename) - click_element(:design_file_name, text: filename) + click_element('design-file-name', text: filename) end def select_design(filename) - click_element(:design_checkbox, design: filename) + click_element('design-checkbox', design: filename) end def archive_selected_designs - click_element(:archive_button) - click_element(:confirm_archiving_button) + click_element('archive-button') + click_element('confirm-archiving-button') end def has_annotation?(note) - within_element_by_index(:design_discussion_content, 0) do - has_element?(:note_content, text: note) + within_element_by_index('design-discussion-content', 0) do + has_element?('note-text', text: note) end end def has_design?(filename) - has_element?(:design_file_name, text: filename) + has_element?('design-file-name', text: filename) end def has_no_design?(filename) - has_no_element?(:design_file_name, text: filename) + has_no_element?('design-file-name', text: filename) end def has_created_icon? - has_element?(:design_status_icon, status: 'file-addition-solid') + has_element?('design-status-icon', status: 'file-addition-solid') end def has_modified_icon? - has_element?(:design_status_icon, status: 'file-modified-solid') + has_element?('design-status-icon', status: 'file-modified-solid') end end end diff --git a/qa/qa/support/helpers/plan.rb b/qa/qa/support/helpers/plan.rb index c3867b4a1b8..c53c099b2bd 100644 --- a/qa/qa/support/helpers/plan.rb +++ b/qa/qa/support/helpers/plan.rb @@ -4,7 +4,7 @@ module QA module Support module Helpers module Plan - FREE = { name: 'free', price: 0, yearly_price: 0, ci_minutes: 400 }.freeze + FREE = { name: 'free', price: 0, yearly_price: 0, compute_minutes: 400 }.freeze PREMIUM = { plan_id: '2c92a00d76f0d5060176f2fb0a5029ff', @@ -12,7 +12,7 @@ module QA name: 'premium', price: 19, yearly_price: 228, - ci_minutes: 10000 + compute_minutes: 10000 }.freeze PREMIUM_SELF_MANAGED = { @@ -29,7 +29,7 @@ module QA name: 'ultimate', price: 99, yearly_price: 1188, - ci_minutes: 50000 + compute_minutes: 50000 }.freeze ULTIMATE_SELF_MANAGED = { @@ -40,12 +40,12 @@ module QA yearly_price: 1188 }.freeze - CI_MINUTES = { + COMPUTE_MINUTES = { plan_id: '2c92a0086a07f4a8016a2c0a1f7b4b4c', rate_charge_id: '2c92a0fd6a07f4c6016a2c0af07c3f21', - name: 'ci_minutes', + name: 'compute_minutes', price: 10, - ci_minutes: 1000 + compute_minutes: 1000 }.freeze STORAGE = { diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap index 206187c3530..696b04868f7 100644 --- a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap +++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap @@ -3,7 +3,7 @@ exports[`Design reply form component renders button text as "Comment" when creating a comment 1`] = ` <button class="btn btn-confirm btn-md disabled gl-button gl-mr-3 gl-w-auto!" - data-qa-selector="save_comment_button" + data-testid="save-comment-button" data-track-action="click_button" disabled="" type="submit" @@ -19,7 +19,7 @@ exports[`Design reply form component renders button text as "Comment" when creat exports[`Design reply form component renders button text as "Save comment" when creating a comment 1`] = ` <button class="btn btn-confirm btn-md disabled gl-button gl-mr-3 gl-w-auto!" - data-qa-selector="save_comment_button" + data-testid="save-comment-button" data-track-action="click_button" disabled="" type="submit" diff --git a/spec/frontend/design_management/components/design_overlay_spec.js b/spec/frontend/design_management/components/design_overlay_spec.js index 3eb47fdb97e..6b08b44c39e 100644 --- a/spec/frontend/design_management/components/design_overlay_spec.js +++ b/spec/frontend/design_management/components/design_overlay_spec.js @@ -86,7 +86,7 @@ describe('Design overlay component', () => { }; wrapper - .find('[data-qa-selector="design_image_button"]') + .find('[data-testid="design-image-button"]') .trigger('mouseup', { offsetX: newCoordinates.x, offsetY: newCoordinates.y }); expect(wrapper.emitted('openCommentForm')).toEqual([ diff --git a/spec/frontend/design_management/components/design_presentation_spec.js b/spec/frontend/design_management/components/design_presentation_spec.js index e64dec14461..96c2b4da2c6 100644 --- a/spec/frontend/design_management/components/design_presentation_spec.js +++ b/spec/frontend/design_management/components/design_presentation_spec.js @@ -46,7 +46,7 @@ describe('Design management design presentation component', () => { wrapper.element.scrollTo = jest.fn(); } - const findOverlayCommentButton = () => wrapper.find('[data-qa-selector="design_image_button"]'); + const findOverlayCommentButton = () => wrapper.find('[data-testid="design-image-button"]'); /** * Spy on $refs and mock given values diff --git a/spec/frontend/design_management/components/list/__snapshots__/item_spec.js.snap b/spec/frontend/design_management/components/list/__snapshots__/item_spec.js.snap index 53359b02b4c..a05b3baecd3 100644 --- a/spec/frontend/design_management/components/list/__snapshots__/item_spec.js.snap +++ b/spec/frontend/design_management/components/list/__snapshots__/item_spec.js.snap @@ -17,12 +17,12 @@ exports[`Design management list item component with notes renders item with mult > <gl-intersection-observer-stub class="gl-flex-grow-1" + data-qa-filename="test" + data-testid="design-image" > <img alt="test" class="design-img gl-display-block gl-max-h-full gl-max-w-full gl-mx-auto gl-w-auto" - data-qa-filename="test" - data-qa-selector="design_image" data-testid="design-img-1" src="null" /> @@ -33,10 +33,10 @@ exports[`Design management list item component with notes renders item with mult > <div class="gl-display-flex gl-flex-direction-column str-truncated-100" + data-testid="design-file-name" > <span class="gl-font-weight-semibold str-truncated-100" - data-qa-selector="design_file_name" data-testid="design-img-filename-1" title="test" > @@ -82,12 +82,12 @@ exports[`Design management list item component with notes renders item with sing > <gl-intersection-observer-stub class="gl-flex-grow-1" + data-qa-filename="test" + data-testid="design-image" > <img alt="test" class="design-img gl-display-block gl-max-h-full gl-max-w-full gl-mx-auto gl-w-auto" - data-qa-filename="test" - data-qa-selector="design_image" data-testid="design-img-1" src="null" /> @@ -98,10 +98,10 @@ exports[`Design management list item component with notes renders item with sing > <div class="gl-display-flex gl-flex-direction-column str-truncated-100" + data-testid="design-file-name" > <span class="gl-font-weight-semibold str-truncated-100" - data-qa-selector="design_file_name" data-testid="design-img-filename-1" title="test" > diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js index d6cf12587b9..977e0a55a99 100644 --- a/spec/frontend/error_tracking/components/error_details_spec.js +++ b/spec/frontend/error_tracking/components/error_details_spec.js @@ -190,7 +190,7 @@ describe('ErrorDetails', () => { }); describe('unsafe chars for culprit field', () => { - const findReportedText = () => wrapper.find('[data-qa-selector="reported_text"]'); + const findReportedText = () => wrapper.find('[data-testid="reported-text"]'); const culprit = '<script>console.log("surprise!")</script>'; beforeEach(() => { store.state.details.loadingStacktrace = false; @@ -350,7 +350,7 @@ describe('ErrorDetails', () => { it('should submit the form', () => { window.HTMLFormElement.prototype.submit = () => {}; const submitSpy = jest.spyOn(wrapper.vm.$refs.sentryIssueForm, 'submit'); - wrapper.find('[data-qa-selector="create_issue_button"]').vm.$emit('click'); + wrapper.find('[data-testid="create-issue-button"]').vm.$emit('click'); expect(submitSpy).toHaveBeenCalled(); submitSpy.mockRestore(); }); @@ -462,7 +462,7 @@ describe('ErrorDetails', () => { describe('GitLab issue link', () => { const gitlabIssuePath = 'https://gitlab.example.com/issues/1'; const findGitLabLink = () => wrapper.find(`[href="${gitlabIssuePath}"]`); - const findCreateIssueButton = () => wrapper.find('[data-qa-selector="create_issue_button"]'); + const findCreateIssueButton = () => wrapper.find('[data-testid="create-issue-button"]'); const findViewIssueButton = () => wrapper.find('[data-qa-selector="view_issue_button"]'); describe('is present', () => { @@ -562,7 +562,7 @@ describe('ErrorDetails', () => { }); it('should track create issue button click', async () => { - await wrapper.find('[data-qa-selector="create_issue_button"]').vm.$emit('click'); + await wrapper.find('[data-testid="create-issue-button"]').vm.$emit('click'); expect(Tracking.event).toHaveBeenCalledWith(category, 'click_create_issue_from_error', { extra: { variant: integrated ? 'integrated' : 'external', diff --git a/spec/frontend/webhooks/components/__snapshots__/push_events_spec.js.snap b/spec/frontend/webhooks/components/__snapshots__/push_events_spec.js.snap index 4150bd75c16..56f8bf0a5e3 100644 --- a/spec/frontend/webhooks/components/__snapshots__/push_events_spec.js.snap +++ b/spec/frontend/webhooks/components/__snapshots__/push_events_spec.js.snap @@ -15,9 +15,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -26,9 +24,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -40,9 +36,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> @@ -67,9 +61,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -78,9 +70,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -92,9 +82,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> @@ -102,7 +90,6 @@ exports[`Webhook push events form editor component Different push events rules w class="gl-ml-6" > <gl-form-input-stub - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" name="hook[push_events_branch_filter]" value="foo" @@ -133,9 +120,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -144,9 +129,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -154,7 +137,6 @@ exports[`Webhook push events form editor component Different push events rules w class="gl-ml-6" > <gl-form-input-stub - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" name="hook[push_events_branch_filter]" value="foo" @@ -172,9 +154,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> @@ -199,9 +179,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -210,9 +188,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -224,9 +200,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> @@ -251,9 +225,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -262,9 +234,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -276,9 +246,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> @@ -286,7 +254,6 @@ exports[`Webhook push events form editor component Different push events rules w class="gl-ml-6" > <gl-form-input-stub - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" name="hook[push_events_branch_filter]" value="" @@ -317,9 +284,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_all_branches" value="all_branches" > - <div - data-qa-selector="strategy_radio_all" - > + <div> All branches </div> </gl-form-radio-stub> @@ -328,9 +293,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_wildcard" value="wildcard" > - <div - data-qa-selector="strategy_radio_wildcard" - > + <div> Wildcard pattern </div> </gl-form-radio-stub> @@ -338,7 +301,6 @@ exports[`Webhook push events form editor component Different push events rules w class="gl-ml-6" > <gl-form-input-stub - data-qa-selector="webhook_branch_filter_field" data-testid="webhook_branch_filter_field" name="hook[push_events_branch_filter]" value="" @@ -356,9 +318,7 @@ exports[`Webhook push events form editor component Different push events rules w data-testid="rule_regex" value="regex" > - <div - data-qa-selector="strategy_radio_regex" - > + <div> Regular expression </div> </gl-form-radio-stub> diff --git a/spec/requests/api/graphql/mutations/packages/protection/rule/create_spec.rb b/spec/requests/api/graphql/mutations/packages/protection/rule/create_spec.rb index b0c8526fa1c..aff398d66e2 100644 --- a/spec/requests/api/graphql/mutations/packages/protection/rule/create_spec.rb +++ b/spec/requests/api/graphql/mutations/packages/protection/rule/create_spec.rb @@ -4,7 +4,6 @@ require 'spec_helper' RSpec.describe 'Creating the packages protection rule', :aggregate_failures, feature_category: :package_registry do include GraphqlHelpers - using RSpec::Parameterized::TableSyntax let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user, maintainer_projects: [project]) } @@ -15,151 +14,160 @@ RSpec.describe 'Creating the packages protection rule', :aggregate_failures, fea { project_path: project.full_path, package_name_pattern: package_protection_rule_attributes.package_name_pattern, - package_type: "NPM", - push_protected_up_to_access_level: "MAINTAINER" + package_type: 'NPM', + push_protected_up_to_access_level: 'MAINTAINER' } end let(:mutation) do graphql_mutation(:create_packages_protection_rule, kwargs, <<~QUERY - clientMutationId + packageProtectionRule { + packageNamePattern + packageType + pushProtectedUpToAccessLevel + } errors QUERY ) end - let(:mutation_response) { graphql_mutation_response(:create_packages_protection_rule) } + let(:mutation_response_package_protection_rule) do + graphql_data_at(:createPackagesProtectionRule, :packageProtectionRule) + end - describe 'post graphql mutation' do - subject { post_graphql_mutation(mutation, current_user: user) } + let(:mutation_response_errors) { graphql_data_at(:createPackagesProtectionRule, :errors) } - context 'without existing packages protection rule' do - it 'returns without error' do - subject + subject { post_graphql_mutation(mutation, current_user: user) } - expect_graphql_errors_to_be_empty - end + shared_examples 'a successful response' do + it 'returns without error' do + subject - it 'returns the created packages protection rule' do - expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1) + expect_graphql_errors_to_be_empty + expect(mutation_response_errors).to be_empty + end - expect_graphql_errors_to_be_empty - expect(Packages::Protection::Rule.where(project: project).count).to eq 1 + it 'returns the created packages protection rule' do + subject - expect(Packages::Protection::Rule.where(project: project, - package_name_pattern: kwargs[:package_name_pattern])).to exist - end + expect(mutation_response_package_protection_rule).to include( + 'packageNamePattern' => kwargs[:package_name_pattern], + 'packageType' => kwargs[:package_type], + 'pushProtectedUpToAccessLevel' => kwargs[:push_protected_up_to_access_level] + ) + end - context 'when invalid fields are given' do - let(:kwargs) do - { - project_path: project.full_path, - package_name_pattern: '', - package_type: 'UNKNOWN_PACKAGE_TYPE', - push_protected_up_to_access_level: 'UNKNOWN_ACCESS_LEVEL' - } - end - - it 'returns error about required argument' do - subject - - expect_graphql_errors_to_include(/was provided invalid value for packageType/) - expect_graphql_errors_to_include(/pushProtectedUpToAccessLevel/) - end - end + it 'creates one package protection rule' do + expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1) + + expect(Packages::Protection::Rule.last).to have_attributes( + project: project, + package_name_pattern: kwargs[:package_name_pattern], + package_type: kwargs[:package_type].downcase, + push_protected_up_to_access_level: kwargs[:push_protected_up_to_access_level].downcase + ) end + end - context 'when user does not have permission' do - let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } } - let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } } - let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } } - let_it_be(:anonymous) { create(:user) } + shared_examples 'an erroneous response' do + it 'does not create one package protection rule' do + expect { subject }.not_to change { ::Packages::Protection::Rule.count } + end + end - where(:user) do - [ref(:developer), ref(:reporter), ref(:guest), ref(:anonymous)] - end + it_behaves_like 'a successful response' - with_them do - it 'returns an error' do - expect { subject }.not_to change { ::Packages::Protection::Rule.count } + context 'with invalid kwargs leading to error from graphql' do + let(:kwargs) do + super().merge!( + package_name_pattern: '', + package_type: 'UNKNOWN_PACKAGE_TYPE', + push_protected_up_to_access_level: 'UNKNOWN_ACCESS_LEVEL' + ) + end - expect_graphql_errors_to_include(/you don't have permission to perform this action/) - end - end + it_behaves_like 'an erroneous response' + + it 'returns error about required argument' do + subject + + expect_graphql_errors_to_include(/was provided invalid value for packageType/) + expect_graphql_errors_to_include(/pushProtectedUpToAccessLevel/) end + end - context 'with existing packages protection rule' do - let_it_be(:existing_package_protection_rule) do - create(:package_protection_rule, project: project, push_protected_up_to_access_level: Gitlab::Access::DEVELOPER) - end + context 'with invalid kwargs leading to error from business model' do + let(:kwargs) { super().merge!(package_name_pattern: '') } - context 'when package name pattern is slightly different' do - let(:kwargs) do - { - project_path: project.full_path, - # The field `package_name_pattern` is unique; this is why we change the value in a minimum way - package_name_pattern: "#{existing_package_protection_rule.package_name_pattern}-unique", - package_type: "NPM", - push_protected_up_to_access_level: "DEVELOPER" - } - end - - it 'returns the created packages protection rule' do - expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1) - - expect(Packages::Protection::Rule.where(project: project).count).to eq 2 - expect(Packages::Protection::Rule.where(project: project, - package_name_pattern: kwargs[:package_name_pattern])).to exist - end - - it 'returns without error' do - subject - - expect_graphql_errors_to_be_empty - end - end + it_behaves_like 'an erroneous response' - context 'when field `package_name_pattern` is taken' do - let(:kwargs) do - { - project_path: project.full_path, - package_name_pattern: existing_package_protection_rule.package_name_pattern, - package_type: 'NPM', - push_protected_up_to_access_level: 'MAINTAINER' - } - end - - it 'returns without error' do - subject - - expect(mutation_response).to include 'errors' => ['Package name pattern has already been taken'] - end - - it 'does not create new package protection rules' do - expect { subject }.to change { Packages::Protection::Rule.count }.by(0) - - expect(Packages::Protection::Rule.where(project: project, - package_name_pattern: kwargs[:package_name_pattern], - push_protected_up_to_access_level: Gitlab::Access::MAINTAINER)).not_to exist - end - end + it 'returns an error' do + subject.tap { expect(mutation_response_errors).to include(/Package name pattern can't be blank/) } end + end - context "when feature flag ':packages_protected_packages' disabled" do - before do - stub_feature_flags(packages_protected_packages: false) + context 'with existing packages protection rule' do + let_it_be(:existing_package_protection_rule) do + create(:package_protection_rule, project: project, push_protected_up_to_access_level: :maintainer) + end + + let(:kwargs) { super().merge!(package_name_pattern: existing_package_protection_rule.package_name_pattern) } + + it_behaves_like 'an erroneous response' + + it 'returns an error' do + subject.tap { expect(mutation_response_errors).to include(/Package name pattern has already been taken/) } + end + + context 'when field `package_name_pattern` is different than existing one' do + let(:kwargs) do + # The field `package_name_pattern` is unique; this is why we change the value in a minimum way + super().merge!(package_name_pattern: "#{existing_package_protection_rule.package_name_pattern}-unique") end - it 'does not create any package protection rules' do - expect { subject }.to change { Packages::Protection::Rule.count }.by(0) + it_behaves_like 'a successful response' + end + + context 'when field `push_protected_up_to_access_level` is different than existing one' do + let(:kwargs) { super().merge!(push_protected_up_to_access_level: 'DEVELOPER') } + + it_behaves_like 'an erroneous response' - expect(Packages::Protection::Rule.where(project: project)).not_to exist + it 'returns an error' do + subject.tap { expect(mutation_response_errors).to include(/Package name pattern has already been taken/) } end + end + end - it 'returns error of disabled feature flag' do - subject.tap { expect_graphql_errors_to_include(/'packages_protected_packages' feature flag is disabled/) } + context 'when user does not have permission' do + let_it_be(:anonymous) { create(:user) } + let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } } + let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } } + let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } } + + where(:user) do + [ref(:developer), ref(:reporter), ref(:guest), ref(:anonymous)] + end + + with_them do + it_behaves_like 'an erroneous response' + + it 'returns an error' do + subject.tap { expect_graphql_errors_to_include(/you don't have permission to perform this action/) } end end end + + context "when feature flag ':packages_protected_packages' disabled" do + before do + stub_feature_flags(packages_protected_packages: false) + end + + it_behaves_like 'an erroneous response' + + it 'returns error of disabled feature flag' do + subject.tap { expect_graphql_errors_to_include(/'packages_protected_packages' feature flag is disabled/) } + end + end end diff --git a/yarn.lock b/yarn.lock index 428f4a168c3..a3e0a2d8251 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7213,10 +7213,10 @@ graphql@^15.7.2: resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef" integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A== -gridstack@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-9.3.0.tgz#0f86cb8aabc3249e340900a5d9505e37e6d7c85e" - integrity sha512-IamRPgMK0AyFsGefosPfz3i6ehNfbx7mVsZDumEbsGeN2BDZt15Ae6AOowl9D5I6d6c0mhQyYoifAfykefXf1g== +gridstack@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-9.4.0.tgz#806b5f8dc2d52ac6aade5d5fc799979a167f6977" + integrity sha512-4dcXGT5IzWfLxJIj4oGZPohgYfHrbdNHenRwwApzialkG2bVd9J9NmcdZsRFX6Q4cANqR0M56yF2Km2FAQkVCw== gzip-size@^6.0.0: version "6.0.0" |