Commit 83dc54eb authored by Dmitry Gruzd's avatar Dmitry Gruzd

Merge branch '290962-rename-event-to-action-in-haml-snowplow-helper' into 'master'

Rename event to action in Snowplow helpers and FE event handlers [RUN ALL RSPEC]

See merge request gitlab-org/gitlab!55698
parents b4bf4e7a fde40024
...@@ -28,7 +28,7 @@ const DEFAULT_SNOWPLOW_OPTIONS = { ...@@ -28,7 +28,7 @@ const DEFAULT_SNOWPLOW_OPTIONS = {
}; };
const createEventPayload = (el, { suffix = '' } = {}) => { const createEventPayload = (el, { suffix = '' } = {}) => {
const action = el.dataset.trackEvent + (suffix || ''); const action = (el.dataset.trackAction || el.dataset.trackEvent) + (suffix || '');
let value = el.dataset.trackValue || el.value || undefined; let value = el.dataset.trackValue || el.value || undefined;
if (el.type === 'checkbox' && !el.checked) value = false; if (el.type === 'checkbox' && !el.checked) value = false;
...@@ -52,7 +52,7 @@ const createEventPayload = (el, { suffix = '' } = {}) => { ...@@ -52,7 +52,7 @@ const createEventPayload = (el, { suffix = '' } = {}) => {
}; };
const eventHandler = (e, func, opts = {}) => { const eventHandler = (e, func, opts = {}) => {
const el = e.target.closest('[data-track-event]'); const el = e.target.closest('[data-track-event], [data-track-action]');
if (!el) return; if (!el) return;
...@@ -130,7 +130,9 @@ export default class Tracking { ...@@ -130,7 +130,9 @@ export default class Tracking {
static trackLoadEvents(category = document.body.dataset.page, parent = document) { static trackLoadEvents(category = document.body.dataset.page, parent = document) {
if (!this.enabled()) return []; if (!this.enabled()) return [];
const loadEvents = parent.querySelectorAll('[data-track-event="render"]'); const loadEvents = parent.querySelectorAll(
'[data-track-action="render"], [data-track-event="render"]',
);
loadEvents.forEach((element) => { loadEvents.forEach((element) => {
const { action, data } = createEventPayload(element); const { action, data } = createEventPayload(element);
......
# frozen_string_literal: true # frozen_string_literal: true
module TrackingHelper module TrackingHelper
def tracking_attrs(label, event, property) def tracking_attrs(label, action, property)
return {} unless tracking_enabled? return {} unless tracking_enabled?
{ {
data: { data: {
track_label: label, track_label: label,
track_event: event, track_action: action,
track_property: property track_property: property
} }
} }
......
---
title: Rename event to action in Snowplow helpers and FE event handlers
merge_request: 55698
author:
type: deprecated
...@@ -51,7 +51,8 @@ end ...@@ -51,7 +51,8 @@ end
js_patterns = Regexp.union( js_patterns = Regexp.union(
'Tracking.event', 'Tracking.event',
/\btrack\(/, /\btrack\(/,
'data-track-event' 'data-track-event',
'data-track-action'
) )
dictionary_pattern = Regexp.union( dictionary_pattern = Regexp.union(
......
...@@ -126,17 +126,17 @@ GitLab provides `Tracking`, an interface that wraps the [Snowplow JavaScript Tra ...@@ -126,17 +126,17 @@ GitLab provides `Tracking`, an interface that wraps the [Snowplow JavaScript Tra
### Tracking in HAML (or Vue Templates) ### Tracking in HAML (or Vue Templates)
When working within HAML (or Vue templates) we can add `data-track-*` attributes to elements of interest. All elements that have a `data-track-event` attribute automatically have event tracking bound on clicks. When working within HAML (or Vue templates) we can add `data-track-*` attributes to elements of interest. All elements that have a `data-track-action` attribute automatically have event tracking bound on clicks.
Below is an example of `data-track-*` attributes assigned to a button: Below is an example of `data-track-*` attributes assigned to a button:
```haml ```haml
%button.btn{ data: { track: { event: "click_button", label: "template_preview", property: "my-template" } } } %button.btn{ data: { track: { action: "click_button", label: "template_preview", property: "my-template" } } }
``` ```
```html ```html
<button class="btn" <button class="btn"
data-track-event="click_button" data-track-action="click_button"
data-track-label="template_preview" data-track-label="template_preview"
data-track-property="my-template" data-track-property="my-template"
/> />
...@@ -148,7 +148,7 @@ Below is a list of supported `data-track-*` attributes: ...@@ -148,7 +148,7 @@ Below is a list of supported `data-track-*` attributes:
| attribute | required | description | | attribute | required | description |
|:----------------------|:---------|:------------| |:----------------------|:---------|:------------|
| `data-track-event` | true | Action the user is taking. Clicks must be prepended with `click` and activations must be prepended with `activate`. For example, focusing a form field would be `activate_form_input` and clicking a button would be `click_button`. | | `data-track-action` | true | Action the user is taking. Clicks must be prepended with `click` and activations must be prepended with `activate`. For example, focusing a form field would be `activate_form_input` and clicking a button would be `click_button`. Replaces `data-track-event`, which was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/290962) in GitLab 13.11. |
| `data-track-label` | false | The `label` as described in our [Structured event taxonomy](#structured-event-taxonomy). | | `data-track-label` | false | The `label` as described in our [Structured event taxonomy](#structured-event-taxonomy). |
| `data-track-property` | false | The `property` as described in our [Structured event taxonomy](#structured-event-taxonomy). | | `data-track-property` | false | The `property` as described in our [Structured event taxonomy](#structured-event-taxonomy). |
| `data-track-value` | false | The `value` as described in our [Structured event taxonomy](#structured-event-taxonomy). If omitted, this is the element's `value` property or an empty string. For checkboxes, the default value is the element's checked attribute or `false` when unchecked. | | `data-track-value` | false | The `value` as described in our [Structured event taxonomy](#structured-event-taxonomy). If omitted, this is the element's `value` property or an empty string. For checkboxes, the default value is the element's checked attribute or `false` when unchecked. |
...@@ -159,11 +159,11 @@ Below is a list of supported `data-track-*` attributes: ...@@ -159,11 +159,11 @@ Below is a list of supported `data-track-*` attributes:
When using the GitLab helper method [`nav_link`](https://gitlab.com/gitlab-org/gitlab/-/blob/898b286de322e5df6a38d257b10c94974d580df8/app/helpers/tab_helper.rb#L69) be sure to wrap `html_options` under the `html_options` keyword argument. When using the GitLab helper method [`nav_link`](https://gitlab.com/gitlab-org/gitlab/-/blob/898b286de322e5df6a38d257b10c94974d580df8/app/helpers/tab_helper.rb#L69) be sure to wrap `html_options` under the `html_options` keyword argument.
Be careful, as this behavior can be confused with the `ActionView` helper method [`link_to`](https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to) that does not require additional wrapping of `html_options` Be careful, as this behavior can be confused with the `ActionView` helper method [`link_to`](https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to) that does not require additional wrapping of `html_options`
`nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { data: { track_label: "groups_dropdown", track_event: "click_dropdown" } })` `nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { data: { track_label: "groups_dropdown", track_action: "click_dropdown" } })`
vs vs
`link_to assigned_issues_dashboard_path, title: _('Issues'), data: { track_label: 'main_navigation', track_event: 'click_issues_link' }` `link_to assigned_issues_dashboard_path, title: _('Issues'), data: { track_label: 'main_navigation', track_action: 'click_issues_link' }`
### Tracking within Vue components ### Tracking within Vue components
......
...@@ -176,25 +176,29 @@ describe('Tracking', () => { ...@@ -176,25 +176,29 @@ describe('Tracking', () => {
}); });
}); });
describe('tracking interface events', () => { describe.each`
term
${'event'}
${'action'}
`('tracking interface events with data-track-$term', ({ term }) => {
let eventSpy; let eventSpy;
beforeEach(() => { beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event'); eventSpy = jest.spyOn(Tracking, 'event');
Tracking.bindDocument('_category_'); // only happens once Tracking.bindDocument('_category_'); // only happens once
setHTMLFixture(` setHTMLFixture(`
<input data-track-event="click_input1" data-track-label="_label_" value="_value_"/> <input data-track-${term}="click_input1" data-track-label="_label_" value="_value_"/>
<input data-track-event="click_input2" data-track-value="_value_override_" value="_value_"/> <input data-track-${term}="click_input2" data-track-value="_value_override_" value="_value_"/>
<input type="checkbox" data-track-event="toggle_checkbox" value="_value_" checked/> <input type="checkbox" data-track-${term}="toggle_checkbox" value="_value_" checked/>
<input class="dropdown" data-track-event="toggle_dropdown"/> <input class="dropdown" data-track-${term}="toggle_dropdown"/>
<div data-track-event="nested_event"><span class="nested"></span></div> <div data-track-${term}="nested_event"><span class="nested"></span></div>
<input data-track-eventbogus="click_bogusinput" data-track-label="_label_" value="_value_"/> <input data-track-bogus="click_bogusinput" data-track-label="_label_" value="_value_"/>
<input data-track-event="click_input3" data-track-experiment="example" value="_value_"/> <input data-track-${term}="click_input3" data-track-experiment="example" value="_value_"/>
`); `);
}); });
it('binds to clicks on elements matching [data-track-event]', () => { it(`binds to clicks on elements matching [data-track-${term}]`, () => {
document.querySelector('[data-track-event="click_input1"]').click(); document.querySelector(`[data-track-${term}="click_input1"]`).click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input1', { expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input1', {
label: '_label_', label: '_label_',
...@@ -202,14 +206,14 @@ describe('Tracking', () => { ...@@ -202,14 +206,14 @@ describe('Tracking', () => {
}); });
}); });
it('does not bind to clicks on elements without [data-track-event]', () => { it(`does not bind to clicks on elements without [data-track-${term}]`, () => {
document.querySelector('[data-track-eventbogus="click_bogusinput"]').click(); document.querySelector('[data-track-bogus="click_bogusinput"]').click();
expect(eventSpy).not.toHaveBeenCalled(); expect(eventSpy).not.toHaveBeenCalled();
}); });
it('allows value override with the data-track-value attribute', () => { it('allows value override with the data-track-value attribute', () => {
document.querySelector('[data-track-event="click_input2"]').click(); document.querySelector(`[data-track-${term}="click_input2"]`).click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input2', { expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input2', {
value: '_value_override_', value: '_value_override_',
...@@ -217,7 +221,7 @@ describe('Tracking', () => { ...@@ -217,7 +221,7 @@ describe('Tracking', () => {
}); });
it('handles checkbox values correctly', () => { it('handles checkbox values correctly', () => {
const checkbox = document.querySelector('[data-track-event="toggle_checkbox"]'); const checkbox = document.querySelector(`[data-track-${term}="toggle_checkbox"]`);
checkbox.click(); // unchecking checkbox.click(); // unchecking
...@@ -233,7 +237,7 @@ describe('Tracking', () => { ...@@ -233,7 +237,7 @@ describe('Tracking', () => {
}); });
it('handles bootstrap dropdowns', () => { it('handles bootstrap dropdowns', () => {
const dropdown = document.querySelector('[data-track-event="toggle_dropdown"]'); const dropdown = document.querySelector(`[data-track-${term}="toggle_dropdown"]`);
dropdown.dispatchEvent(new Event('show.bs.dropdown', { bubbles: true })); dropdown.dispatchEvent(new Event('show.bs.dropdown', { bubbles: true }));
...@@ -258,7 +262,7 @@ describe('Tracking', () => { ...@@ -258,7 +262,7 @@ describe('Tracking', () => {
}; };
getExperimentData.mockReturnValue(mockExperimentData); getExperimentData.mockReturnValue(mockExperimentData);
document.querySelector('[data-track-event="click_input3"]').click(); document.querySelector(`[data-track-${term}="click_input3"]`).click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input3', { expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input3', {
value: '_value_', value: '_value_',
...@@ -267,22 +271,26 @@ describe('Tracking', () => { ...@@ -267,22 +271,26 @@ describe('Tracking', () => {
}); });
}); });
describe('tracking page loaded events', () => { describe.each`
term
${'event'}
${'action'}
`('tracking page loaded events with -$term', ({ term }) => {
let eventSpy; let eventSpy;
beforeEach(() => { beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event'); eventSpy = jest.spyOn(Tracking, 'event');
setHTMLFixture(` setHTMLFixture(`
<input data-track-event="render" data-track-label="label1" value="_value_" data-track-property="_property_"/> <input data-track-${term}="render" data-track-label="label1" value="_value_" data-track-property="_property_"/>
<span data-track-event="render" data-track-label="label2" data-track-value="_value_"> <span data-track-${term}="render" data-track-label="label2" data-track-value="_value_">
Something Something
</span> </span>
<input data-track-event="_render_bogus_" data-track-label="label3" value="_value_" data-track-property="_property_"/> <input data-track-${term}="_render_bogus_" data-track-label="label3" value="_value_" data-track-property="_property_"/>
`); `);
Tracking.trackLoadEvents('_category_'); // only happens once Tracking.trackLoadEvents('_category_'); // only happens once
}); });
it('sends tracking events when [data-track-event="render"] is on an element', () => { it(`sends tracking events when [data-track-${term}="render"] is on an element`, () => {
expect(eventSpy.mock.calls).toEqual([ expect(eventSpy.mock.calls).toEqual([
[ [
'_category_', '_category_',
......
...@@ -10,7 +10,7 @@ RSpec.describe TrackingHelper do ...@@ -10,7 +10,7 @@ RSpec.describe TrackingHelper do
let(:results) do let(:results) do
{ {
no_data: {}, no_data: {},
with_data: { data: { track_label: 'a', track_event: 'b', track_property: 'c' } } with_data: { data: { track_label: 'a', track_action: 'b', track_property: 'c' } }
} }
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