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 = {
};
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;
if (el.type === 'checkbox' && !el.checked) value = false;
......@@ -52,7 +52,7 @@ const createEventPayload = (el, { suffix = '' } = {}) => {
};
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;
......@@ -130,7 +130,9 @@ export default class Tracking {
static trackLoadEvents(category = document.body.dataset.page, parent = document) {
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) => {
const { action, data } = createEventPayload(element);
......
# frozen_string_literal: true
module TrackingHelper
def tracking_attrs(label, event, property)
def tracking_attrs(label, action, property)
return {} unless tracking_enabled?
{
data: {
track_label: label,
track_event: event,
track_action: action,
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
js_patterns = Regexp.union(
'Tracking.event',
/\btrack\(/,
'data-track-event'
'data-track-event',
'data-track-action'
)
dictionary_pattern = Regexp.union(
......
......@@ -126,17 +126,17 @@ GitLab provides `Tracking`, an interface that wraps the [Snowplow JavaScript Tra
### 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:
```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
<button class="btn"
data-track-event="click_button"
data-track-action="click_button"
data-track-label="template_preview"
data-track-property="my-template"
/>
......@@ -148,7 +148,7 @@ Below is a list of supported `data-track-*` attributes:
| 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-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. |
......@@ -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.
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
`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
......
......@@ -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;
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
Tracking.bindDocument('_category_'); // only happens once
setHTMLFixture(`
<input data-track-event="click_input1" data-track-label="_label_" value="_value_"/>
<input data-track-event="click_input2" data-track-value="_value_override_" value="_value_"/>
<input type="checkbox" data-track-event="toggle_checkbox" value="_value_" checked/>
<input class="dropdown" data-track-event="toggle_dropdown"/>
<div data-track-event="nested_event"><span class="nested"></span></div>
<input data-track-eventbogus="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_input1" data-track-label="_label_" value="_value_"/>
<input data-track-${term}="click_input2" data-track-value="_value_override_" value="_value_"/>
<input type="checkbox" data-track-${term}="toggle_checkbox" value="_value_" checked/>
<input class="dropdown" data-track-${term}="toggle_dropdown"/>
<div data-track-${term}="nested_event"><span class="nested"></span></div>
<input data-track-bogus="click_bogusinput" data-track-label="_label_" value="_value_"/>
<input data-track-${term}="click_input3" data-track-experiment="example" value="_value_"/>
`);
});
it('binds to clicks on elements matching [data-track-event]', () => {
document.querySelector('[data-track-event="click_input1"]').click();
it(`binds to clicks on elements matching [data-track-${term}]`, () => {
document.querySelector(`[data-track-${term}="click_input1"]`).click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input1', {
label: '_label_',
......@@ -202,14 +206,14 @@ describe('Tracking', () => {
});
});
it('does not bind to clicks on elements without [data-track-event]', () => {
document.querySelector('[data-track-eventbogus="click_bogusinput"]').click();
it(`does not bind to clicks on elements without [data-track-${term}]`, () => {
document.querySelector('[data-track-bogus="click_bogusinput"]').click();
expect(eventSpy).not.toHaveBeenCalled();
});
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', {
value: '_value_override_',
......@@ -217,7 +221,7 @@ describe('Tracking', () => {
});
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
......@@ -233,7 +237,7 @@ describe('Tracking', () => {
});
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 }));
......@@ -258,7 +262,7 @@ describe('Tracking', () => {
};
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', {
value: '_value_',
......@@ -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;
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
setHTMLFixture(`
<input data-track-event="render" data-track-label="label1" value="_value_" data-track-property="_property_"/>
<span data-track-event="render" data-track-label="label2" data-track-value="_value_">
<input data-track-${term}="render" data-track-label="label1" value="_value_" data-track-property="_property_"/>
<span data-track-${term}="render" data-track-label="label2" data-track-value="_value_">
Something
</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
});
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([
[
'_category_',
......
......@@ -10,7 +10,7 @@ RSpec.describe TrackingHelper do
let(:results) do
{
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
......
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