diff options
Diffstat (limited to 'app/assets/javascripts/ci/pipeline_editor/components')
16 files changed, 305 insertions, 76 deletions
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/commit/commit_form.vue b/app/assets/javascripts/ci/pipeline_editor/components/commit/commit_form.vue index 3fe9103c2b3..baf3dbfa090 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/commit/commit_form.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/commit/commit_form.vue @@ -108,7 +108,6 @@ export default { <gl-form-group id="commit-group" :label="$options.i18n.commitMessage" - label-cols-sm="2" label-for="commit-message" > <gl-form-textarea @@ -122,7 +121,6 @@ export default { <gl-form-group id="source-branch-group" :label="$options.i18n.sourceBranch" - label-cols-sm="2" label-for="source-branch-field" > <gl-form-input @@ -130,13 +128,12 @@ export default { v-model="sourceBranch" class="gl-font-monospace!" required - data-qa-selector="source_branch_field" + data-testid="source-branch-field" /> <gl-form-checkbox v-if="!isCurrentBranchSourceBranch" v-model="openMergeRequest" data-testid="new-mr-checkbox" - data-qa-selector="new_mr_checkbox" class="gl-mt-3" > <gl-sprintf :message="$options.i18n.startMergeRequest"> @@ -152,7 +149,7 @@ export default { class="js-no-auto-disable gl-mr-3" category="primary" variant="confirm" - data-qa-selector="commit_changes_button" + data-testid="commit-changes-button" :disabled="isSubmitDisabled" :loading="isSaving" > diff --git a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue index bc0cad75c60..8f4d566e7e6 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue @@ -89,7 +89,6 @@ export default { icon="external-link" target="_blank" data-testid="template-repo-link" - data-qa-selector="template_repo_link" @click="trackTemplateBrowsing" > {{ $options.i18n.browseTemplates }} @@ -98,7 +97,6 @@ export default { icon="information-o" size="small" data-testid="drawer-toggle" - data-qa-selector="drawer_toggle" @click="toggleHelpDrawer" > {{ $options.i18n.help }} @@ -107,7 +105,6 @@ export default { v-if="glFeatures.ciJobAssistantDrawer" icon="bulb" size="small" - data-qa-selector="job_assistant_drawer_toggle" @click="toggleJobAssistantDrawer" > {{ $options.i18n.jobAssistant }} @@ -117,7 +114,6 @@ export default { icon="bulb" size="small" data-testid="ai-assistant-drawer-toggle" - data-qa-selector="ai_assistant_drawer_toggle" @click="toggleAiAssistantDrawer" > {{ $options.i18n.aiAssistant }} diff --git a/app/assets/javascripts/ci/pipeline_editor/components/file_nav/branch_switcher.vue b/app/assets/javascripts/ci/pipeline_editor/components/file_nav/branch_switcher.vue index a410e4c933c..221a45d4d9a 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/file_nav/branch_switcher.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/file_nav/branch_switcher.vue @@ -218,7 +218,6 @@ export default { :text="currentBranch" :disabled="!enableBranchSwitcher" icon="branch" - data-qa-selector="branch_selector_button" data-testid="branch-selector" > <gl-search-box-by-type :debounce="$options.inputDebounce" @input="setSearchTerm" /> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue b/app/assets/javascripts/ci/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue index 7368d1a3a91..20b42e26f08 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue @@ -52,7 +52,7 @@ export default { }; </script> <template> - <div class="gl-mb-4 gl-display-flex gl-flex-wrap gl-gap-3"> + <div class="gl-display-flex gl-flex-wrap gl-gap-3 gl-mb-4"> <gl-button v-if="showFileTreeToggle" id="file-tree-toggle" diff --git a/app/assets/javascripts/ci/pipeline_editor/components/graph/job_pill.vue b/app/assets/javascripts/ci/pipeline_editor/components/graph/job_pill.vue new file mode 100644 index 00000000000..3f1d7255a2b --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_editor/components/graph/job_pill.vue @@ -0,0 +1,73 @@ +<script> +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; + +export default { + components: { + TooltipOnTruncate, + }, + props: { + jobName: { + type: String, + required: true, + }, + pipelineId: { + type: Number, + required: true, + }, + isHovered: { + type: Boolean, + required: false, + default: false, + }, + isFadedOut: { + type: Boolean, + required: false, + default: false, + }, + handleMouseOver: { + type: Function, + required: false, + default: () => {}, + }, + handleMouseLeave: { + type: Function, + required: false, + default: () => {}, + }, + }, + computed: { + id() { + return `${this.jobName}-${this.pipelineId}`; + }, + jobPillClasses() { + return [ + { 'gl-opacity-3': this.isFadedOut }, + { 'gl-bg-gray-50 gl-inset-border-1-gray-200': this.isHovered }, + ]; + }, + }, + methods: { + onMouseEnter() { + this.$emit('on-mouse-enter', this.jobName); + }, + onMouseLeave() { + this.$emit('on-mouse-leave'); + }, + }, +}; +</script> +<template> + <div class="gl-w-full"> + <tooltip-on-truncate :title="jobName" truncate-target="child" placement="top"> + <div + :id="id" + class="gl-bg-white gl-inset-border-1-gray-100 gl-text-center gl-text-truncate gl-rounded-6 gl-mb-3 gl-px-5 gl-py-3 gl-relative gl-z-index-1 gl-transition-duration-slow gl-transition-timing-function-ease" + :class="jobPillClasses" + @mouseover="onMouseEnter" + @mouseleave="onMouseLeave" + > + {{ jobName }} + </div> + </tooltip-on-truncate> + </div> +</template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue b/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue new file mode 100644 index 00000000000..eb906cfc486 --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_editor/components/graph/pipeline_graph.vue @@ -0,0 +1,169 @@ +<script> +import { GlAlert } from '@gitlab/ui'; +import { __ } from '~/locale'; +import { DRAW_FAILURE, DEFAULT } from '~/ci/pipeline_details/constants'; +import LinksLayer from '~/ci/common/private/job_links_layer.vue'; +import JobPill from './job_pill.vue'; +import StageName from './stage_name.vue'; + +export default { + components: { + GlAlert, + JobPill, + LinksLayer, + StageName, + }, + CONTAINER_REF: 'PIPELINE_GRAPH_CONTAINER_REF', + BASE_CONTAINER_ID: 'pipeline-graph-container', + PIPELINE_ID: 0, + STROKE_WIDTH: 2, + errorTexts: { + [DRAW_FAILURE]: __('Could not draw the lines for job relationships'), + [DEFAULT]: __('An unknown error occurred.'), + }, + // The combination of gl-w-full gl-min-w-full and gl-max-w-15 is necessary. + // The max width and the width make sure the ellipsis to work and the min width + // is for when there is less text than the stage column width (which the width 100% does not fix) + jobWrapperClasses: + 'gl-display-flex gl-flex-direction-column gl-align-items-stretch gl-w-full gl-px-8 gl-min-w-full gl-max-w-15', + props: { + pipelineData: { + required: true, + type: Object, + }, + }, + data() { + return { + failureType: null, + highlightedJob: null, + highlightedJobs: [], + measurements: { + height: 0, + width: 0, + }, + }; + }, + computed: { + containerId() { + return `${this.$options.BASE_CONTAINER_ID}-${this.$options.PIPELINE_ID}`; + }, + failure() { + switch (this.failureType) { + case DRAW_FAILURE: + return { + text: this.$options.errorTexts[DRAW_FAILURE], + variant: 'danger', + dismissible: true, + }; + default: + return { + text: this.$options.errorTexts[DEFAULT], + variant: 'danger', + dismissible: true, + }; + } + }, + hasError() { + return this.failureType; + }, + hasHighlightedJob() { + return Boolean(this.highlightedJob); + }, + pipelineStages() { + return this.pipelineData?.stages || []; + }, + }, + watch: { + pipelineData: { + immediate: true, + handler() { + this.$nextTick(() => { + this.computeGraphDimensions(); + }); + }, + }, + }, + methods: { + computeGraphDimensions() { + this.measurements = { + width: this.$refs[this.$options.CONTAINER_REF].scrollWidth, + height: this.$refs[this.$options.CONTAINER_REF].scrollHeight, + }; + }, + isFadedOut(jobName) { + return this.highlightedJobs.length > 1 && !this.isJobHighlighted(jobName); + }, + isJobHighlighted(jobName) { + return this.highlightedJobs.includes(jobName); + }, + onError(error) { + this.reportFailure(error.type); + }, + removeHoveredJob() { + this.highlightedJob = null; + }, + reportFailure(errorType) { + this.failureType = errorType; + }, + resetFailure() { + this.failureType = null; + }, + setHoveredJob(jobName) { + this.highlightedJob = jobName; + }, + updateHighlightedJobs(jobs) { + this.highlightedJobs = jobs; + }, + }, +}; +</script> +<template> + <div> + <gl-alert + v-if="hasError" + :variant="failure.variant" + :dismissible="failure.dismissible" + @dismiss="resetFailure" + > + {{ failure.text }} + </gl-alert> + <div + :id="containerId" + :ref="$options.CONTAINER_REF" + class="gl-bg-gray-10 gl-overflow-auto" + data-testid="graph-container" + > + <links-layer + :pipeline-data="pipelineStages" + :pipeline-id="$options.PIPELINE_ID" + :container-id="containerId" + :container-measurements="measurements" + :highlighted-job="highlightedJob" + @highlightedJobsChange="updateHighlightedJobs" + @error="onError" + > + <div + v-for="(stage, index) in pipelineStages" + :key="`${stage.name}-${index}`" + class="gl-flex-direction-column" + > + <div class="gl-display-flex gl-align-items-center gl-w-full gl-px-9 gl-py-4 gl-mb-5"> + <stage-name :stage-name="stage.name" /> + </div> + <div :class="$options.jobWrapperClasses"> + <job-pill + v-for="group in stage.groups" + :key="group.name" + :job-name="group.name" + :pipeline-id="$options.PIPELINE_ID" + :is-hovered="highlightedJob === group.name" + :is-faded-out="isFadedOut(group.name)" + @on-mouse-enter="setHoveredJob" + @on-mouse-leave="removeHoveredJob" + /> + </div> + </div> + </links-layer> + </div> + </div> +</template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/graph/stage_name.vue b/app/assets/javascripts/ci/pipeline_editor/components/graph/stage_name.vue new file mode 100644 index 00000000000..600832b7633 --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_editor/components/graph/stage_name.vue @@ -0,0 +1,22 @@ +<script> +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; + +export default { + components: { + TooltipOnTruncate, + }, + props: { + stageName: { + type: String, + required: true, + }, + }, +}; +</script> +<template> + <tooltip-on-truncate :title="stageName" truncate-target="child" placement="top"> + <div class="gl-py-2 gl-text-truncate gl-font-weight-bold gl-w-20"> + {{ stageName }} + </div> + </tooltip-on-truncate> +</template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_header.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_header.vue index ec6ee52b6b2..665ca907ed9 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_header.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_header.vue @@ -1,30 +1,11 @@ <script> +import { GlCard } from '@gitlab/ui'; import PipelineStatus from './pipeline_status.vue'; import ValidationSegment from './validation_segment.vue'; -const baseClasses = ['gl-p-5', 'gl-bg-gray-10', 'gl-border-solid', 'gl-border-gray-100']; - -const pipelineStatusClasses = [ - ...baseClasses, - 'gl-border-1', - 'gl-border-b-0!', - 'gl-rounded-top-base', -]; - -const validationSegmentClasses = [...baseClasses, 'gl-border-1', 'gl-rounded-base']; - -const validationSegmentWithPipelineStatusClasses = [ - ...baseClasses, - 'gl-border-1', - 'gl-rounded-bottom-left-base', - 'gl-rounded-bottom-right-base', -]; - export default { - pipelineStatusClasses, - validationSegmentClasses, - validationSegmentWithPipelineStatusClasses, components: { + GlCard, PipelineStatus, ValidationSegment, }, @@ -47,24 +28,19 @@ export default { showPipelineStatus() { return !this.isNewCiConfigFile; }, - // make sure corners are rounded correctly depending on if - // pipeline status is rendered - validationStyling() { - return this.showPipelineStatus - ? this.$options.validationSegmentWithPipelineStatusClasses - : this.$options.validationSegmentClasses; - }, }, }; </script> <template> - <div class="gl-mb-5"> - <pipeline-status - v-if="showPipelineStatus" - :commit-sha="commitSha" - :class="$options.pipelineStatusClasses" - v-on="$listeners" - /> - <validation-segment :class="validationStyling" :ci-config="ciConfigData" /> - </div> + <gl-card + class="gl-new-card gl-mb-3 gl-mt-0" + header-class="gl-new-card-header" + body-class="gl-new-card-body gl-py-4 gl-px-5" + > + <template v-if="showPipelineStatus" #header> + <pipeline-status :commit-sha="commitSha" v-on="$listeners" /> + </template> + + <validation-segment :ci-config="ciConfigData" /> + </gl-card> </template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue index f1c9770714a..f00098105d3 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue @@ -1,8 +1,8 @@ <script> import { __ } from '~/locale'; -import { keepLatestDownstreamPipelines } from '~/pipelines/components/parsing_utils'; -import LegacyPipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph.vue'; -import getLinkedPipelinesQuery from '~/pipelines/graphql/queries/get_linked_pipelines.query.graphql'; +import { keepLatestDownstreamPipelines } from '~/ci/pipeline_details/utils/parsing_utils'; +import LegacyPipelineMiniGraph from '~/ci/pipeline_mini_graph/legacy_pipeline_mini_graph.vue'; +import getLinkedPipelinesQuery from '~/ci/pipeline_details/graphql/queries/get_linked_pipelines.query.graphql'; import { PIPELINE_FAILURE } from '../../constants'; export default { diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue index 3bce50224d9..58b5c0004e0 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/header/pipeline_status.vue @@ -5,13 +5,10 @@ import { truncateSha } from '~/lib/utils/text_utility'; import { s__ } from '~/locale'; import getPipelineQuery from '~/ci/pipeline_editor/graphql/queries/pipeline.query.graphql'; import getPipelineEtag from '~/ci/pipeline_editor/graphql/queries/client/pipeline_etag.query.graphql'; -import { - getQueryHeaders, - toggleQueryPollingByVisibility, -} from '~/pipelines/components/graph/utils'; +import { getQueryHeaders, toggleQueryPollingByVisibility } from '~/ci/pipeline_details/graph/utils'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; -import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue'; +import PipelineMiniGraph from '~/ci/pipeline_mini_graph/pipeline_mini_graph.vue'; import PipelineEditorMiniGraph from './pipeline_editor_mini_graph.vue'; const POLL_INTERVAL = 10000; @@ -141,7 +138,9 @@ export default { </script> <template> - <div class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-flex-wrap"> + <div + class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-flex-wrap gl-w-full" + > <template v-if="showLoadingState"> <div> <gl-loading-icon class="gl-mr-auto gl-display-inline-block" size="sm" /> @@ -149,20 +148,20 @@ export default { </div> </template> <template v-else-if="hasError"> - <gl-icon class="gl-mr-auto" name="warning-solid" /> - <span data-testid="pipeline-error-msg">{{ $options.i18n.fetchError }}</span> + <div> + <gl-icon class="gl-mr-auto" name="warning-solid" /> + <span data-testid="pipeline-error-msg">{{ $options.i18n.fetchError }}</span> + </div> </template> <template v-else> <div class="gl-text-truncate gl-md-max-w-50p gl-mr-1"> <a :href="status.detailsPath" class="gl-mr-auto"> - <ci-icon :status="status" :size="16" data-testid="pipeline-status-icon" /> + <ci-icon :status="status" :size="16" data-testid="pipeline-status-icon" class="gl-mr-2" /> </a> <span class="gl-font-weight-bold"> <gl-sprintf :message="$options.i18n.pipelineInfo"> <template #id="{ content }"> - <span data-testid="pipeline-id" data-qa-selector="pipeline_id_content"> - {{ content }}{{ pipelineId }} - </span> + <span data-testid="pipeline-id"> {{ content }}{{ pipelineId }} </span> </template> <template #status>{{ status.text }}</template> <template #commit> @@ -187,9 +186,8 @@ export default { /> <pipeline-editor-mini-graph v-else :pipeline="pipeline" v-on="$listeners" /> <gl-button - class="gl-ml-3" - category="secondary" - variant="confirm" + class="gl-ml-3 gl-align-self-center" + size="small" :href="status.detailsPath" data-testid="pipeline-view-btn" > diff --git a/app/assets/javascripts/ci/pipeline_editor/components/header/validation_segment.vue b/app/assets/javascripts/ci/pipeline_editor/components/header/validation_segment.vue index 8553256f13a..d54ad78b3d3 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/header/validation_segment.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/header/validation_segment.vue @@ -112,8 +112,8 @@ export default { {{ $options.i18n.loading }} </template> <span v-else data-testid="validation-segment"> - <span class="gl-max-w-full" data-qa-selector="validation_message_content"> - <gl-icon :name="icon" /> + <span class="gl-max-w-full"> + <gl-icon :name="icon" class="gl-mr-2" /> <gl-sprintf :message="message"> <template v-if="hasLink" #link="{ content }"> <gl-link :href="helpPath">{{ content }}</gl-link> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/utils.js b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/utils.js index a604d79259d..32eda355e66 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/utils.js +++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/utils.js @@ -10,7 +10,8 @@ const trimText = (val) => (isString(val) ? trim(val) : val); export const removeEmptyObj = (obj) => { if (isArray(obj)) { return reject(map(obj, removeEmptyObj), isEmptyValue); - } else if (isObject(obj)) { + } + if (isObject(obj)) { return omitBy(mapValues(obj, removeEmptyObj), isEmptyValue); } return obj; @@ -19,7 +20,8 @@ export const removeEmptyObj = (obj) => { export const trimFields = (data) => { if (isArray(data)) { return data.map(trimFields); - } else if (isObject(data)) { + } + if (isObject(data)) { return mapValues(data, trimFields); } return trimText(data); diff --git a/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue index a954615ca8a..c7c15cdd76e 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue @@ -2,7 +2,7 @@ import { GlAlert, GlLoadingIcon, GlTabs } from '@gitlab/ui'; import CiEditorHeader from 'ee_else_ce/ci/pipeline_editor/components/editor/ci_editor_header.vue'; import { s__, __ } from '~/locale'; -import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue'; +import PipelineGraph from '~/ci/pipeline_editor/components/graph/pipeline_graph.vue'; import { getParameterValues, setUrlParams, updateHistory } from '~/lib/utils/url_utility'; import { CREATE_TAB, @@ -182,7 +182,7 @@ export default { <template> <gl-tabs class="file-editor gl-mb-3" - data-qa-selector="file_editor_container" + data-testid="file-editor-container" :query-param-name="$options.query.TAB_QUERY_PARAM" sync-active-tab-with-query-params > diff --git a/app/assets/javascripts/ci/pipeline_editor/components/popovers/file_tree_popover.vue b/app/assets/javascripts/ci/pipeline_editor/components/popovers/file_tree_popover.vue index efa6a54c638..57694bbcd77 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/popovers/file_tree_popover.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/popovers/file_tree_popover.vue @@ -42,7 +42,6 @@ export default { target="file-tree-toggle" triggers="manual" placement="right" - data-qa-selector="file_tree_popover" @close-button-clicked="dismissPermanently" > <div v-outside="dismissPermanently" class="gl-font-base gl-mb-3"> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue index 25e4e99bf54..90402a89280 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/ui/pipeline_editor_empty_state.vue @@ -61,8 +61,7 @@ export default { <gl-button variant="confirm" class="gl-mt-3" - data-testid="create_new_ci_button" - data-qa-selector="create_new_ci_button" + data-testid="create-new-ci-button" @click="createEmptyConfigFile" > {{ $options.i18n.btnText }} diff --git a/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue b/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue index 7583fa7a3b5..617088f303b 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/validate/ci_validate.vue @@ -246,7 +246,6 @@ export default { class="gl-mt-3" :disabled="isInitialCiContentLoading" data-testid="simulate-pipeline-button" - data-qa-selector="simulate_pipeline_button" @click="validateYaml" > {{ $options.i18n.cta }} |