Commit 0886a509 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'nicolasdular/cleanup-pipelines-empty-state-experiment' into 'master'

Change pipeline empty state language

See merge request gitlab-org/gitlab!53281
parents 2fa04939 e4f4d685
<script> <script>
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { isExperimentEnabled } from '~/lib/utils/experimentation';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import Tracking from '~/tracking';
export default { export default {
i18n: { i18n: {
control: { infoMessage: s__(`Pipelines|GitLab CI/CD can automatically build,
infoMessage: s__(`Pipelines|Continuous Integration can help
catch bugs by running your tests automatically,
while Continuous Deployment can help you deliver
code to your product environment.`),
buttonMessage: s__('Pipelines|Get started with Pipelines'),
},
experiment: {
infoMessage: s__(`Pipelines|GitLab CI/CD can automatically build,
test, and deploy your code. Let GitLab take care of time test, and deploy your code. Let GitLab take care of time
consuming tasks, so you can spend more time creating.`), consuming tasks, so you can spend more time creating.`),
buttonMessage: s__('Pipelines|Get started with CI/CD'), buttonMessage: s__('Pipelines|Get started with CI/CD'),
},
}, },
name: 'PipelinesEmptyState', name: 'PipelinesEmptyState',
components: { components: {
...@@ -38,23 +27,6 @@ export default { ...@@ -38,23 +27,6 @@ export default {
required: true, required: true,
}, },
}, },
mounted() {
this.track('viewed');
},
methods: {
track(action) {
if (!gon.tracking_data) {
return;
}
const { category, value, label, property } = gon.tracking_data;
Tracking.event(category, action, { value, label, property });
},
isExperimentEnabled() {
return isExperimentEnabled('pipelinesEmptyState');
},
},
}; };
</script> </script>
<template> <template>
...@@ -70,11 +42,7 @@ export default { ...@@ -70,11 +42,7 @@ export default {
{{ s__('Pipelines|Build with confidence') }} {{ s__('Pipelines|Build with confidence') }}
</h4> </h4>
<p data-testid="info-text"> <p data-testid="info-text">
{{ {{ $options.i18n.infoMessage }}
isExperimentEnabled()
? $options.i18n.experiment.infoMessage
: $options.i18n.control.infoMessage
}}
</p> </p>
<div class="gl-text-center"> <div class="gl-text-center">
...@@ -83,13 +51,8 @@ export default { ...@@ -83,13 +51,8 @@ export default {
variant="info" variant="info"
category="primary" category="primary"
data-testid="get-started-pipelines" data-testid="get-started-pipelines"
@click="track('documentation_clicked')"
> >
{{ {{ $options.i18n.buttonMessage }}
isExperimentEnabled()
? $options.i18n.experiment.buttonMessage
: $options.i18n.control.buttonMessage
}}
</gl-button> </gl-button>
</div> </div>
</template> </template>
......
...@@ -20,7 +20,6 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -20,7 +20,6 @@ class Projects::PipelinesController < Projects::ApplicationController
push_frontend_feature_flag(:jira_for_vulnerabilities, project, type: :development, default_enabled: :yaml) push_frontend_feature_flag(:jira_for_vulnerabilities, project, type: :development, default_enabled: :yaml)
end end
before_action :ensure_pipeline, only: [:show] before_action :ensure_pipeline, only: [:show]
before_action :push_experiment_to_gon, only: :index, if: :html_request?
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596 # Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? } before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
...@@ -45,11 +44,7 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -45,11 +44,7 @@ class Projects::PipelinesController < Projects::ApplicationController
@pipelines_count = limited_pipelines_count(project) @pipelines_count = limited_pipelines_count(project)
respond_to do |format| respond_to do |format|
format.html do format.html
record_empty_pipeline_experiment
render :index
end
format.json do format.json do
Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
...@@ -300,20 +295,6 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -300,20 +295,6 @@ class Projects::PipelinesController < Projects::ApplicationController
def index_params def index_params
params.permit(:scope, :username, :ref, :status) params.permit(:scope, :username, :ref, :status)
end end
def record_empty_pipeline_experiment
return unless @pipelines_count.to_i == 0
return if helpers.has_gitlab_ci?(@project)
record_experiment_user(:pipelines_empty_state)
end
def push_experiment_to_gon
return unless current_user
push_frontend_experiment(:pipelines_empty_state, subject: current_user)
frontend_experimentation_tracking_data(:pipelines_empty_state, 'view', project.namespace_id, subject: current_user)
end
end end
Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController') Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController')
...@@ -123,7 +123,6 @@ module Ci ...@@ -123,7 +123,6 @@ module Ci
def record_conversion_event def record_conversion_event
Experiments::RecordConversionEventWorker.perform_async(:ci_syntax_templates, current_user.id) Experiments::RecordConversionEventWorker.perform_async(:ci_syntax_templates, current_user.id)
Experiments::RecordConversionEventWorker.perform_async(:pipelines_empty_state, current_user.id)
end end
def create_namespace_onboarding_action def create_namespace_onboarding_action
......
---
title: Change pipeline empty state language
merge_request: 53281
author:
type: changed
---
name: pipelines_empty_state_experiment_percentage
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47952
rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/289
milestone: '13.8'
type: experiment
group: group::activation
default_enabled: false
...@@ -92,10 +92,6 @@ module Gitlab ...@@ -92,10 +92,6 @@ module Gitlab
tracking_category: 'Growth::Activation::Experiment::CiSyntaxTemplates', tracking_category: 'Growth::Activation::Experiment::CiSyntaxTemplates',
rollout_strategy: :user rollout_strategy: :user
}, },
pipelines_empty_state: {
tracking_category: 'Growth::Activation::Experiment::PipelinesEmptyState',
rollout_strategy: :user
},
invite_members_new_dropdown: { invite_members_new_dropdown: {
tracking_category: 'Growth::Expansion::Experiment::InviteMembersNewDropdown' tracking_category: 'Growth::Expansion::Experiment::InviteMembersNewDropdown'
}, },
......
...@@ -21461,9 +21461,6 @@ msgstr "" ...@@ -21461,9 +21461,6 @@ msgstr ""
msgid "Pipelines|Clear Runner Caches" msgid "Pipelines|Clear Runner Caches"
msgstr "" msgstr ""
msgid "Pipelines|Continuous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment."
msgstr ""
msgid "Pipelines|Copy trigger token" msgid "Pipelines|Copy trigger token"
msgstr "" msgstr ""
......
...@@ -272,72 +272,6 @@ RSpec.describe Projects::PipelinesController do ...@@ -272,72 +272,6 @@ RSpec.describe Projects::PipelinesController do
end end
end end
describe 'GET #index' do
subject(:request) { get :index, params: { namespace_id: project.namespace, project_id: project } }
context 'experiment not active' do
it 'does not push tracking_data to gon' do
request
expect(Gon.tracking_data).to be_nil
end
it 'does not record experiment_user' do
expect { request }.not_to change(ExperimentUser, :count)
end
end
context 'when experiment active' do
before do
stub_experiment(pipelines_empty_state: true)
stub_experiment_for_subject(pipelines_empty_state: true)
end
it 'pushes tracking_data to Gon' do
request
expect(Gon.experiments["pipelinesEmptyState"]).to eq(true)
expect(Gon.tracking_data).to match(
{
category: 'Growth::Activation::Experiment::PipelinesEmptyState',
action: 'view',
label: anything,
property: 'experimental_group',
value: anything
}
)
end
context 'no pipelines created an no CI set up' do
before do
stub_application_setting(auto_devops_enabled: false)
end
it 'records experiment_user' do
expect { request }.to change(ExperimentUser, :count).by(1)
end
end
context 'CI set up' do
it 'does not record experiment_user' do
expect { request }.not_to change(ExperimentUser, :count)
end
end
context 'pipelines created' do
let!(:pipeline) { create(:ci_pipeline, project: project) }
before do
stub_application_setting(auto_devops_enabled: false)
end
it 'does not record experiment_user' do
expect { request }.not_to change(ExperimentUser, :count)
end
end
end
end
describe 'GET show.json' do describe 'GET show.json' do
let(:pipeline) { create(:ci_pipeline, project: project) } let(:pipeline) { create(:ci_pipeline, project: project) }
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { withGonExperiment } from 'helpers/experimentation_helper';
import EmptyState from '~/pipelines/components/pipelines_list/empty_state.vue'; import EmptyState from '~/pipelines/components/pipelines_list/empty_state.vue';
import Tracking from '~/tracking';
describe('Pipelines Empty State', () => { describe('Pipelines Empty State', () => {
let wrapper; let wrapper;
...@@ -40,104 +38,15 @@ describe('Pipelines Empty State', () => { ...@@ -40,104 +38,15 @@ describe('Pipelines Empty State', () => {
expect(findGetStartedButton().attributes('href')).toBe('foo'); expect(findGetStartedButton().attributes('href')).toBe('foo');
}); });
describe('when in control group', () => { it('should render empty state information', () => {
it('should render empty state information', () => { expect(findInfoText()).toContain(
expect(findInfoText()).toContain( 'GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time',
'Continuous Integration can help catch bugs by running your tests automatically', 'consuming tasks, so you can spend more time creating',
'while Continuous Deployment can help you deliver code to your product environment', );
);
});
it('should render a button', () => {
expect(findGetStartedButton().text()).toBe('Get started with Pipelines');
});
});
describe('when in experiment group', () => {
withGonExperiment('pipelinesEmptyState');
beforeEach(() => {
createWrapper();
});
it('should render empty state information', () => {
expect(findInfoText()).toContain(
'GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time',
'consuming tasks, so you can spend more time creating',
);
});
it('should render button text', () => {
expect(findGetStartedButton().text()).toBe('Get started with CI/CD');
});
}); });
describe('tracking', () => { it('should render button text', () => {
let origGon; expect(findGetStartedButton().text()).toBe('Get started with CI/CD');
describe('when data is set', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event').mockImplementation(() => {});
origGon = window.gon;
window.gon = {
tracking_data: {
category: 'Growth::Activation::Experiment::PipelinesEmptyState',
value: 1,
property: 'experimental_group',
label: 'label',
},
};
createWrapper();
});
afterEach(() => {
window.gon = origGon;
});
it('tracks when mounted', () => {
expect(Tracking.event).toHaveBeenCalledWith(
'Growth::Activation::Experiment::PipelinesEmptyState',
'viewed',
{
value: 1,
label: 'label',
property: 'experimental_group',
},
);
});
it('tracks when button is clicked', () => {
findGetStartedButton().vm.$emit('click');
expect(Tracking.event).toHaveBeenCalledWith(
'Growth::Activation::Experiment::PipelinesEmptyState',
'documentation_clicked',
{
value: 1,
label: 'label',
property: 'experimental_group',
},
);
});
});
describe('when no data is defined', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event').mockImplementation(() => {});
createWrapper();
});
it('does not track on view', () => {
expect(Tracking.event).not.toHaveBeenCalled();
});
it('does not track when button is clicked', () => {
findGetStartedButton().vm.$emit('click');
expect(Tracking.event).not.toHaveBeenCalled();
});
});
}); });
}); });
}); });
...@@ -102,7 +102,6 @@ RSpec.describe Ci::CreatePipelineService do ...@@ -102,7 +102,6 @@ RSpec.describe Ci::CreatePipelineService do
describe 'recording a conversion event' do describe 'recording a conversion event' do
it 'schedules a record conversion event worker' do it 'schedules a record conversion event worker' do
expect(Experiments::RecordConversionEventWorker).to receive(:perform_async).with(:ci_syntax_templates, user.id) expect(Experiments::RecordConversionEventWorker).to receive(:perform_async).with(:ci_syntax_templates, user.id)
expect(Experiments::RecordConversionEventWorker).to receive(:perform_async).with(:pipelines_empty_state, user.id)
pipeline pipeline
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment