Skip to content
Snippets Groups Projects
Commit 93f7c6b5 authored by Stanislav Lashmanov's avatar Stanislav Lashmanov
Browse files

Track MR Survey renders

parent e43c6d12
No related branches found
No related tags found
1 merge request!96417Track MR Survey renders
......@@ -19,6 +19,8 @@ const steps = [
},
];
const MR_RENDER_LS_KEY = 'mr_survey_rendered';
export default {
name: 'MergeRequestExperienceSurveyApp',
components: {
......@@ -68,9 +70,20 @@ export default {
onQueryLoaded({ shouldShowCallout }) {
this.visible = shouldShowCallout;
if (!this.visible) this.$emit('close');
else if (!localStorage?.getItem(MR_RENDER_LS_KEY)) {
this.track('survey:mr_experience', {
label: 'render',
extra: {
accountAge: this.accountAge,
},
});
localStorage?.setItem(MR_RENDER_LS_KEY, '1');
}
},
onRate(event) {
this.$refs.dismisser?.dismiss();
this.$emit('rate');
localStorage?.removeItem(MR_RENDER_LS_KEY);
this.track('survey:mr_experience', {
label: this.step.label,
value: event,
......@@ -87,21 +100,18 @@ export default {
},
handleKeyup(e) {
if (e.key !== 'Escape') return;
this.$emit('close');
this.$refs.dismisser?.dismiss();
this.trackDismissal();
this.dismiss();
},
close() {
this.trackDismissal();
dismiss() {
this.$refs.dismisser?.dismiss();
this.$emit('close');
},
trackDismissal() {
this.track('survey:mr_experience', {
label: 'dismiss',
extra: {
accountAge: this.accountAge,
},
});
localStorage?.removeItem(MR_RENDER_LS_KEY);
},
},
};
......@@ -113,79 +123,71 @@ export default {
feature-name="mr_experience_survey"
@queryResult.once="onQueryLoaded"
>
<template #default="{ dismiss }">
<aside
class="mr-experience-survey-wrapper gl-fixed gl-bottom-0 gl-right-0 gl-p-5"
:aria-label="$options.i18n.survey"
>
<transition name="survey-slide-up">
<aside
class="mr-experience-survey-wrapper gl-fixed gl-bottom-0 gl-right-0 gl-p-5"
:aria-label="$options.i18n.survey"
>
<transition name="survey-slide-up">
<div
v-if="visible"
class="mr-experience-survey-body gl-relative gl-display-flex gl-flex-direction-column gl-bg-white gl-p-5 gl-border gl-rounded-base"
>
<gl-button
v-tooltip="$options.i18n.close"
:aria-label="$options.i18n.close"
variant="default"
category="tertiary"
class="gl-top-4 gl-right-3 gl-absolute"
icon="close"
@click="dismiss"
/>
<div
v-if="visible"
class="mr-experience-survey-body gl-relative gl-display-flex gl-flex-direction-column gl-bg-white gl-p-5 gl-border gl-rounded-base"
v-if="stepIndex === 0"
class="mr-experience-survey-legal gl-border-t gl-mt-5 gl-pt-3 gl-text-gray-500 gl-font-sm"
role="note"
>
<gl-button
v-tooltip="$options.i18n.close"
:aria-label="$options.i18n.close"
variant="default"
category="tertiary"
class="gl-top-4 gl-right-3 gl-absolute"
icon="close"
@click="
dismiss();
close();
"
/>
<div
v-if="stepIndex === 0"
class="mr-experience-survey-legal gl-border-t gl-mt-5 gl-pt-3 gl-text-gray-500 gl-font-sm"
role="note"
>
<p class="gl-m-0">
<gl-sprintf :message="$options.i18n.legal">
<template #link="{ content }">
<a
class="gl-text-decoration-underline gl-text-gray-500"
href="https://about.gitlab.com/privacy/"
target="_blank"
rel="noreferrer nofollow"
v-text="content"
></a>
</template>
</gl-sprintf>
</p>
</div>
<div class="gl-relative">
<div class="gl-absolute">
<div
v-safe-html="$options.gitlabLogo"
aria-hidden="true"
class="mr-experience-survey-logo"
></div>
</div>
<p class="gl-m-0">
<gl-sprintf :message="$options.i18n.legal">
<template #link="{ content }">
<a
class="gl-text-decoration-underline gl-text-gray-500"
href="https://about.gitlab.com/privacy/"
target="_blank"
rel="noreferrer nofollow"
v-text="content"
></a>
</template>
</gl-sprintf>
</p>
</div>
<div class="gl-relative">
<div class="gl-absolute">
<div
v-safe-html="$options.gitlabLogo"
aria-hidden="true"
class="mr-experience-survey-logo"
></div>
</div>
<section v-if="step">
<p id="mr_survey_question" ref="question" class="gl-m-0 gl-px-7">
<gl-sprintf :message="step.question">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<satisfaction-rate
aria-labelledby="mr_survey_question"
class="gl-mt-5"
@rate="
dismiss();
onRate($event);
"
/>
</section>
<section v-else class="gl-px-7">
{{ $options.i18n.thanks }}
</section>
</div>
</transition>
</aside>
</template>
<section v-if="step">
<p id="mr_survey_question" ref="question" class="gl-m-0 gl-px-7">
<gl-sprintf :message="step.question">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<satisfaction-rate
aria-labelledby="mr_survey_question"
class="gl-mt-5"
@rate="onRate"
/>
</section>
<section v-else class="gl-px-7">
{{ $options.i18n.thanks }}
</section>
</div>
</transition>
</aside>
</user-callout-dismisser>
</template>
......@@ -6,6 +6,17 @@ import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisse
import MergeRequestExperienceSurveyApp from '~/surveys/merge_request_experience/app.vue';
import SatisfactionRate from '~/surveys/components/satisfaction_rate.vue';
const createRenderTrackedArguments = () => [
undefined,
'survey:mr_experience',
{
label: 'render',
extra: {
accountAge: 0,
},
},
];
describe('MergeRequestExperienceSurveyApp', () => {
let trackingSpy;
let wrapper;
......@@ -24,6 +35,7 @@ describe('MergeRequestExperienceSurveyApp', () => {
dismiss,
shouldShowCallout,
});
trackingSpy = mockTracking(undefined, undefined, jest.spyOn);
wrapper = shallowMountExtended(MergeRequestExperienceSurveyApp, {
propsData: {
accountAge: 0,
......@@ -33,9 +45,12 @@ describe('MergeRequestExperienceSurveyApp', () => {
GlSprintf,
},
});
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
};
beforeEach(() => {
localStorage.clear();
});
describe('when user callout is visible', () => {
beforeEach(() => {
createWrapper();
......@@ -47,6 +62,16 @@ describe('MergeRequestExperienceSurveyApp', () => {
expect(wrapper.emitted().close).toBe(undefined);
});
it('tracks render once', async () => {
expect(trackingSpy).toHaveBeenCalledWith(...createRenderTrackedArguments());
});
it("doesn't track subsequent renders", async () => {
createWrapper();
expect(trackingSpy).toHaveBeenCalledWith(...createRenderTrackedArguments());
expect(trackingSpy).toHaveBeenCalledTimes(1);
});
describe('when close button clicked', () => {
beforeEach(() => {
findCloseButton().vm.$emit('click');
......@@ -68,6 +93,15 @@ describe('MergeRequestExperienceSurveyApp', () => {
},
});
});
it('tracks subsequent renders', async () => {
createWrapper();
expect(trackingSpy.mock.calls).toEqual([
createRenderTrackedArguments(),
expect.anything(),
createRenderTrackedArguments(),
]);
});
});
it('applies correct feature name for user callout', () => {
......@@ -148,6 +182,10 @@ describe('MergeRequestExperienceSurveyApp', () => {
it('emits close event', async () => {
expect(wrapper.emitted()).toMatchObject({ close: [[]] });
});
it("doesn't track anything", async () => {
expect(trackingSpy).toHaveBeenCalledTimes(0);
});
});
describe('when Escape key is pressed', () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment