Commit 1590ddb7 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '329649-instrument-content-editor-toolbar' into 'master'

Instrument Content Editor toolbar

See merge request gitlab-org/gitlab!61065
parents 16abe648 161caf61
...@@ -45,7 +45,7 @@ export default { ...@@ -45,7 +45,7 @@ export default {
this.tiptapEditor.chain()[this.editorCommand]().focus().run(); this.tiptapEditor.chain()[this.editorCommand]().focus().run();
} }
this.$emit('click', { contentType }); this.$emit('execute', { contentType });
}, },
}, },
}; };
......
<script> <script>
import Tracking from '~/tracking';
import { CONTENT_EDITOR_TRACKING_LABEL, TOOLBAR_CONTROL_TRACKING_ACTION } from '../constants';
import { ContentEditor } from '../services/content_editor'; import { ContentEditor } from '../services/content_editor';
import Divider from './divider.vue'; import Divider from './divider.vue';
import ToolbarButton from './toolbar_button.vue'; import ToolbarButton from './toolbar_button.vue';
const trackingMixin = Tracking.mixin({
label: CONTENT_EDITOR_TRACKING_LABEL,
});
export default { export default {
components: { components: {
ToolbarButton, ToolbarButton,
Divider, Divider,
}, },
mixins: [trackingMixin],
props: { props: {
contentEditor: { contentEditor: {
type: ContentEditor, type: ContentEditor,
required: true, required: true,
}, },
}, },
methods: {
trackToolbarControlExecution({ contentType: property, value }) {
this.track(TOOLBAR_CONTROL_TRACKING_ACTION, {
property,
value,
});
},
},
}; };
</script> </script>
<template> <template>
...@@ -27,6 +42,7 @@ export default { ...@@ -27,6 +42,7 @@ export default {
editor-command="toggleBold" editor-command="toggleBold"
:label="__('Bold text')" :label="__('Bold text')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
<toolbar-button <toolbar-button
data-testid="italic" data-testid="italic"
...@@ -35,6 +51,7 @@ export default { ...@@ -35,6 +51,7 @@ export default {
editor-command="toggleItalic" editor-command="toggleItalic"
:label="__('Italic text')" :label="__('Italic text')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
<toolbar-button <toolbar-button
data-testid="code" data-testid="code"
...@@ -43,6 +60,7 @@ export default { ...@@ -43,6 +60,7 @@ export default {
editor-command="toggleCode" editor-command="toggleCode"
:label="__('Code')" :label="__('Code')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
<divider /> <divider />
<toolbar-button <toolbar-button
...@@ -52,6 +70,7 @@ export default { ...@@ -52,6 +70,7 @@ export default {
editor-command="toggleBlockquote" editor-command="toggleBlockquote"
:label="__('Insert a quote')" :label="__('Insert a quote')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
<toolbar-button <toolbar-button
data-testid="bullet-list" data-testid="bullet-list"
...@@ -60,6 +79,7 @@ export default { ...@@ -60,6 +79,7 @@ export default {
editor-command="toggleBulletList" editor-command="toggleBulletList"
:label="__('Add a bullet list')" :label="__('Add a bullet list')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
<toolbar-button <toolbar-button
data-testid="ordered-list" data-testid="ordered-list"
...@@ -68,6 +88,7 @@ export default { ...@@ -68,6 +88,7 @@ export default {
editor-command="toggleOrderedList" editor-command="toggleOrderedList"
:label="__('Add a numbered list')" :label="__('Add a numbered list')"
:tiptap-editor="contentEditor.tiptapEditor" :tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/> />
</div> </div>
</template> </template>
...@@ -3,3 +3,6 @@ import { s__ } from '~/locale'; ...@@ -3,3 +3,6 @@ import { s__ } from '~/locale';
export const PROVIDE_SERIALIZER_OR_RENDERER_ERROR = s__( export const PROVIDE_SERIALIZER_OR_RENDERER_ERROR = s__(
'ContentEditor|You have to provide a renderMarkdown function or a custom serializer', 'ContentEditor|You have to provide a renderMarkdown function or a custom serializer',
); );
export const CONTENT_EDITOR_TRACKING_LABEL = 'content_editor';
export const TOOLBAR_CONTROL_TRACKING_ACTION = 'execute_toolbar_control';
...@@ -83,7 +83,7 @@ describe('content_editor/components/toolbar_button', () => { ...@@ -83,7 +83,7 @@ describe('content_editor/components/toolbar_button', () => {
await findButton().trigger('click'); await findButton().trigger('click');
expect(toggleFooSpy).toHaveBeenCalled(); expect(toggleFooSpy).toHaveBeenCalled();
expect(wrapper.emitted().click).toHaveLength(1); expect(wrapper.emitted().execute).toHaveLength(1);
}); });
it('does not executes the content type command when executeCommand = false', async () => { it('does not executes the content type command when executeCommand = false', async () => {
...@@ -92,7 +92,7 @@ describe('content_editor/components/toolbar_button', () => { ...@@ -92,7 +92,7 @@ describe('content_editor/components/toolbar_button', () => {
await findButton().trigger('click'); await findButton().trigger('click');
expect(toggleFooSpy).not.toHaveBeenCalled(); expect(toggleFooSpy).not.toHaveBeenCalled();
expect(wrapper.emitted().click).toHaveLength(1); expect(wrapper.emitted().execute).toHaveLength(1);
}); });
}); });
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { mockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import TopToolbar from '~/content_editor/components/top_toolbar.vue'; import TopToolbar from '~/content_editor/components/top_toolbar.vue';
import {
TOOLBAR_CONTROL_TRACKING_ACTION,
CONTENT_EDITOR_TRACKING_LABEL,
} from '~/content_editor/constants';
import { createContentEditor } from '~/content_editor/services/create_content_editor'; import { createContentEditor } from '~/content_editor/services/create_content_editor';
describe('content_editor/components/top_toolbar', () => { describe('content_editor/components/top_toolbar', () => {
let wrapper; let wrapper;
let contentEditor; let contentEditor;
let trackingSpy;
const buildEditor = () => { const buildEditor = () => {
contentEditor = createContentEditor({ renderMarkdown: () => true }); contentEditor = createContentEditor({ renderMarkdown: () => true });
}; };
...@@ -21,6 +26,10 @@ describe('content_editor/components/top_toolbar', () => { ...@@ -21,6 +26,10 @@ describe('content_editor/components/top_toolbar', () => {
); );
}; };
beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn);
});
beforeEach(() => { beforeEach(() => {
buildEditor(); buildEditor();
}); });
...@@ -29,7 +38,7 @@ describe('content_editor/components/top_toolbar', () => { ...@@ -29,7 +38,7 @@ describe('content_editor/components/top_toolbar', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it.each` describe.each`
testId | buttonProps testId | buttonProps
${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold' }} ${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold' }}
${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic' }} ${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic' }}
...@@ -37,11 +46,31 @@ describe('content_editor/components/top_toolbar', () => { ...@@ -37,11 +46,31 @@ describe('content_editor/components/top_toolbar', () => {
${'blockquote'} | ${{ contentType: 'blockquote', iconName: 'quote', label: 'Insert a quote', editorCommand: 'toggleBlockquote' }} ${'blockquote'} | ${{ contentType: 'blockquote', iconName: 'quote', label: 'Insert a quote', editorCommand: 'toggleBlockquote' }}
${'bullet-list'} | ${{ contentType: 'bulletList', iconName: 'list-bulleted', label: 'Add a bullet list', editorCommand: 'toggleBulletList' }} ${'bullet-list'} | ${{ contentType: 'bulletList', iconName: 'list-bulleted', label: 'Add a bullet list', editorCommand: 'toggleBulletList' }}
${'ordered-list'} | ${{ contentType: 'orderedList', iconName: 'list-numbered', label: 'Add a numbered list', editorCommand: 'toggleOrderedList' }} ${'ordered-list'} | ${{ contentType: 'orderedList', iconName: 'list-numbered', label: 'Add a numbered list', editorCommand: 'toggleOrderedList' }}
`('renders $testId button', ({ testId, buttonProps }) => { `('given a $testId toolbar control', ({ testId, buttonProps }) => {
beforeEach(() => {
buildWrapper(); buildWrapper();
});
it('renders the toolbar control with the provided properties', () => {
expect(wrapper.findByTestId(testId).props()).toEqual({ expect(wrapper.findByTestId(testId).props()).toEqual({
...buttonProps, ...buttonProps,
tiptapEditor: contentEditor.tiptapEditor, tiptapEditor: contentEditor.tiptapEditor,
}); });
}); });
it.each`
control | eventData
${'bold'} | ${{ contentType: 'bold' }}
${'blockquote'} | ${{ contentType: 'blockquote', value: 1 }}
`('tracks the execution of toolbar controls', ({ control, eventData }) => {
const { contentType, value } = eventData;
wrapper.findByTestId(control).vm.$emit('execute', eventData);
expect(trackingSpy).toHaveBeenCalledWith(undefined, TOOLBAR_CONTROL_TRACKING_ACTION, {
label: CONTENT_EDITOR_TRACKING_LABEL,
property: contentType,
value,
});
});
});
}); });
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