Commit a3b40ddf authored by Scott Hampton's avatar Scott Hampton

Usage ping for test report widget

Add usage ping to track how many people are
using the test summary widget in merge requests.
parent db87dc61
<script> <script>
import { GlButton, GlIcon } from '@gitlab/ui'; import { GlButton, GlIcon } from '@gitlab/ui';
import { once } from 'lodash';
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import api from '~/api';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import GroupedIssuesList from '../components/grouped_issues_list.vue'; import GroupedIssuesList from '../components/grouped_issues_list.vue';
import { componentNames } from '../components/issue_body'; import { componentNames } from '../components/issue_body';
import ReportSection from '../components/report_section.vue'; import ReportSection from '../components/report_section.vue';
...@@ -28,7 +29,7 @@ export default { ...@@ -28,7 +29,7 @@ export default {
GlButton, GlButton,
GlIcon, GlIcon,
}, },
mixins: [Tracking.mixin()], mixins: [Tracking.mixin(), glFeatureFlagsMixin()],
props: { props: {
endpoint: { endpoint: {
type: String, type: String,
...@@ -70,11 +71,6 @@ export default { ...@@ -70,11 +71,6 @@ export default {
showViewFullReport() { showViewFullReport() {
return this.pipelinePath.length; return this.pipelinePath.length;
}, },
handleToggleEvent() {
return once(() => {
this.track(this.$options.expandEvent);
});
},
}, },
created() { created() {
this.setPaths({ this.setPaths({
...@@ -86,6 +82,12 @@ export default { ...@@ -86,6 +82,12 @@ export default {
}, },
methods: { methods: {
...mapActions(['setPaths', 'fetchReports', 'closeModal']), ...mapActions(['setPaths', 'fetchReports', 'closeModal']),
handleToggleEvent() {
this.track(this.$options.expandEvent);
if (this.glFeatures.usageDataITestingSummaryWidgetTotal) {
api.trackRedisHllUserEvent(this.$options.expandUsagePingEvent);
}
},
reportText(report) { reportText(report) {
const { name, summary } = report || {}; const { name, summary } = report || {};
...@@ -131,6 +133,7 @@ export default { ...@@ -131,6 +133,7 @@ export default {
}, },
}, },
expandEvent: 'expand_test_report_widget', expandEvent: 'expand_test_report_widget',
expandUsagePingEvent: 'i_testing_summary_widget_total',
}; };
</script> </script>
<template> <template>
...@@ -142,7 +145,7 @@ export default { ...@@ -142,7 +145,7 @@ export default {
:has-issues="reports.length > 0" :has-issues="reports.length > 0"
:should-emit-toggle-event="true" :should-emit-toggle-event="true"
class="mr-widget-section grouped-security-reports mr-report" class="mr-widget-section grouped-security-reports mr-report"
@toggleEvent="handleToggleEvent" @toggleEvent.once="handleToggleEvent"
> >
<template v-if="showViewFullReport" #action-buttons> <template v-if="showViewFullReport" #action-buttons>
<gl-button <gl-button
......
...@@ -42,6 +42,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -42,6 +42,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:paginated_notes, @project, default_enabled: :yaml) push_frontend_feature_flag(:paginated_notes, @project, default_enabled: :yaml)
push_frontend_feature_flag(:new_pipelines_table, @project, default_enabled: :yaml) push_frontend_feature_flag(:new_pipelines_table, @project, default_enabled: :yaml)
push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml) push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml)
push_frontend_feature_flag(:usage_data_i_testing_summary_widget_total, @project, default_enabled: :yaml)
record_experiment_user(:invite_members_version_b) record_experiment_user(:invite_members_version_b)
......
---
title: Capture test report summary widget views via usage ping
merge_request: 57543
author:
type: added
---
name: usage_data_i_testing_summary_widget_total
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57543
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326058
milestone: '13.11'
type: development
group: group::testing
default_enabled: true
...@@ -288,6 +288,11 @@ ...@@ -288,6 +288,11 @@
redis_slot: testing redis_slot: testing
aggregation: weekly aggregation: weekly
feature_flag: usage_data_i_testing_metrics_report_artifact_uploaders feature_flag: usage_data_i_testing_metrics_report_artifact_uploaders
- name: i_testing_summary_widget_total
category: testing
redis_slot: testing
aggregation: weekly
feature_flag: usage_data_i_testing_summary_widget_total
# Project Management group # Project Management group
- name: g_project_management_issue_title_changed - name: g_project_management_issue_title_changed
category: issues_edit category: issues_edit
......
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
import Api from '~/api';
import GroupedTestReportsApp from '~/reports/grouped_test_report/grouped_test_reports_app.vue'; import GroupedTestReportsApp from '~/reports/grouped_test_report/grouped_test_reports_app.vue';
import { getStoreConfig } from '~/reports/grouped_test_report/store'; import { getStoreConfig } from '~/reports/grouped_test_report/store';
...@@ -12,6 +13,8 @@ import successTestReports from '../mock_data/no_failures_report.json'; ...@@ -12,6 +13,8 @@ import successTestReports from '../mock_data/no_failures_report.json';
import recentFailuresTestReports from '../mock_data/recent_failures_report.json'; import recentFailuresTestReports from '../mock_data/recent_failures_report.json';
import resolvedFailures from '../mock_data/resolved_failures.json'; import resolvedFailures from '../mock_data/resolved_failures.json';
jest.mock('~/api.js');
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -22,7 +25,7 @@ describe('Grouped test reports app', () => { ...@@ -22,7 +25,7 @@ describe('Grouped test reports app', () => {
let wrapper; let wrapper;
let mockStore; let mockStore;
const mountComponent = ({ props = { pipelinePath } } = {}) => { const mountComponent = ({ props = { pipelinePath }, glFeatures = {} } = {}) => {
wrapper = mount(GroupedTestReportsApp, { wrapper = mount(GroupedTestReportsApp, {
store: mockStore, store: mockStore,
localVue, localVue,
...@@ -32,6 +35,9 @@ describe('Grouped test reports app', () => { ...@@ -32,6 +35,9 @@ describe('Grouped test reports app', () => {
pipelinePath, pipelinePath,
...props, ...props,
}, },
provide: {
glFeatures,
},
}); });
}; };
...@@ -107,20 +113,20 @@ describe('Grouped test reports app', () => { ...@@ -107,20 +113,20 @@ describe('Grouped test reports app', () => {
describe('`Expand` button', () => { describe('`Expand` button', () => {
let trackingSpy; let trackingSpy;
beforeEach(() => { it('tracks an event on click', () => {
setReports(newFailedTestReports); setReports(newFailedTestReports);
mountComponent(); mountComponent();
document.body.dataset.page = 'projects:merge_requests:show';
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
});
it('tracks an event on click', () => {
findExpandButton().trigger('click'); findExpandButton().trigger('click');
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'expand_test_report_widget', {}); expect(trackingSpy).toHaveBeenCalledWith(undefined, 'expand_test_report_widget', {});
}); });
it('only tracks the first expansion', () => { it('only tracks the first expansion', () => {
setReports(newFailedTestReports);
mountComponent();
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
expect(trackingSpy).not.toHaveBeenCalled(); expect(trackingSpy).not.toHaveBeenCalled();
const button = findExpandButton(); const button = findExpandButton();
...@@ -131,6 +137,29 @@ describe('Grouped test reports app', () => { ...@@ -131,6 +137,29 @@ describe('Grouped test reports app', () => {
expect(trackingSpy).toHaveBeenCalledTimes(1); expect(trackingSpy).toHaveBeenCalledTimes(1);
}); });
describe('with :usage_data_i_testing_summary_widget_total enabled', () => {
it('does track usage ping metric', () => {
setReports(newFailedTestReports);
mountComponent({ glFeatures: { usageDataITestingSummaryWidgetTotal: true } });
findExpandButton().trigger('click');
expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(1);
expect(Api.trackRedisHllUserEvent).toHaveBeenCalledWith(
wrapper.vm.$options.expandUsagePingEvent,
);
});
});
describe('with :usage_data_i_testing_summary_widget_total disabled', () => {
it('does not track usage ping metric', () => {
setReports(newFailedTestReports);
mountComponent({ glFeatures: { usageDataITestingSummaryWidgetTotal: false } });
findExpandButton().trigger('click');
expect(Api.trackRedisHllUserEvent).not.toHaveBeenCalled();
});
});
}); });
describe('with new failed result', () => { describe('with new failed result', () => {
......
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