From 9f4a26c9e2801a2f1727818a0fb89f50e4a2afc4 Mon Sep 17 00:00:00 2001 From: Jeffrey Dowdle Date: Wed, 18 Sep 2024 10:08:09 +1000 Subject: [PATCH 1/2] feat(@dpc-sdp/ripple-ui-forms): added form_start analytics event --- .../landingpage/forms-analytics.feature | 13 ++++++++++++ .../test/fixtures/landingpage/full-form.json | 1 + packages/nuxt-ripple-analytics/lib/index.ts | 11 ++++++++++ .../step_definitions/components/forms.ts | 10 ++++++++++ .../src/components/RplForm/RplForm.vue | 20 +++++++++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 examples/nuxt-app/test/features/landingpage/forms-analytics.feature diff --git a/examples/nuxt-app/test/features/landingpage/forms-analytics.feature b/examples/nuxt-app/test/features/landingpage/forms-analytics.feature new file mode 100644 index 0000000000..ee84d468b4 --- /dev/null +++ b/examples/nuxt-app/test/features/landingpage/forms-analytics.feature @@ -0,0 +1,13 @@ +Feature: Forms analytics events + + @mockserver + Scenario: Form start + Given the mock server has started + And the page endpoint for path "/" returns fixture "/landingpage/full-form" with status 200 + And the site endpoint returns fixture "/site/reference" with status 200 + Given I visit the page "/" + When I type "Cat" into the input with the label "Last name" + When I blur the input with the label "Last name" + Then the dataLayer should include the following events + | event | form_id | form_name | component | platform_event | + | form_start | full_form | Test form | rpl-form | start | diff --git a/examples/nuxt-app/test/fixtures/landingpage/full-form.json b/examples/nuxt-app/test/fixtures/landingpage/full-form.json index 4c2f1c6981..f51f4dc097 100644 --- a/examples/nuxt-app/test/fixtures/landingpage/full-form.json +++ b/examples/nuxt-app/test/fixtures/landingpage/full-form.json @@ -52,6 +52,7 @@ "id": 1119, "title": "Test form", "props": { + "title": "Test form", "formId": "full_form", "hideFormOnSubmit": false, "successMessageTitle": "Server success", diff --git a/packages/nuxt-ripple-analytics/lib/index.ts b/packages/nuxt-ripple-analytics/lib/index.ts index 7e8d058ddb..d1f24d8c6d 100644 --- a/packages/nuxt-ripple-analytics/lib/index.ts +++ b/packages/nuxt-ripple-analytics/lib/index.ts @@ -563,6 +563,17 @@ export default { } }, // UI Forms components + 'rpl-form/start': () => { + return (payload: any) => { + trackEvent({ + event: `form_start`, + form_id: payload?.id, + form_name: payload?.name, + component: 'rpl-form', + platform_event: 'start' + }) + } + }, 'rpl-form/submit': () => { return (payload: any) => { trackEvent({ diff --git a/packages/ripple-test-utils/step_definitions/components/forms.ts b/packages/ripple-test-utils/step_definitions/components/forms.ts index 2a67193b02..ef9edcbe30 100644 --- a/packages/ripple-test-utils/step_definitions/components/forms.ts +++ b/packages/ripple-test-utils/step_definitions/components/forms.ts @@ -103,6 +103,16 @@ When( } ) +When('I blur the input with the label {string}', (label: string) => { + cy.get('label.rpl-form-label') + .contains(label) + .closest('.rpl-form__outer') + .as('field') + + cy.get('@field').should('exist') + cy.get('@field').find('input').blur() +}) + When( 'I type {string} into the textarea with the label {string}', (value: string, label: string) => { diff --git a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue index 0f6e993b36..cc538ca8e0 100644 --- a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue +++ b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue @@ -77,6 +77,9 @@ const errorSummaryRef = ref(null) const cachedErrors = ref>({}) const submitCounter = ref(0) +// Keep track of whether user has changed something in the form +const formStarted = ref(false) + provide('form', { id: props.id, name: props.title }) provide('isFormSubmitting', isFormSubmitting) // submitCounter is watched by some components to efficiently know when to update @@ -198,6 +201,22 @@ watch( } ) +const handleChange = () => { + // 'Form start' analytics event, fires on first change of the form + if (!formStarted.value) { + formStarted.value = true + + emitRplEvent( + 'start', + { + id: props.id, + name: props.title + }, + { global: true } + ) + } +} + const data = reactive({ isFilled: (val) => typeof val === 'number' @@ -256,6 +275,7 @@ const plugins = computed( novalidate @submit-invalid="submitInvalidHandler" @submit="submitHandler" + @change="handleChange" >
Date: Thu, 19 Sep 2024 08:50:54 +1000 Subject: [PATCH 2/2] refactor(@dpc-sdp/ripple-ui-forms): use input instead of change event for form_start event now fires immediately instead of waiting for blur of the field --- .../test/features/landingpage/forms-analytics.feature | 1 - .../step_definitions/components/forms.ts | 10 ---------- .../ripple-ui-forms/src/components/RplForm/RplForm.vue | 3 ++- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/nuxt-app/test/features/landingpage/forms-analytics.feature b/examples/nuxt-app/test/features/landingpage/forms-analytics.feature index ee84d468b4..72e45da728 100644 --- a/examples/nuxt-app/test/features/landingpage/forms-analytics.feature +++ b/examples/nuxt-app/test/features/landingpage/forms-analytics.feature @@ -7,7 +7,6 @@ Feature: Forms analytics events And the site endpoint returns fixture "/site/reference" with status 200 Given I visit the page "/" When I type "Cat" into the input with the label "Last name" - When I blur the input with the label "Last name" Then the dataLayer should include the following events | event | form_id | form_name | component | platform_event | | form_start | full_form | Test form | rpl-form | start | diff --git a/packages/ripple-test-utils/step_definitions/components/forms.ts b/packages/ripple-test-utils/step_definitions/components/forms.ts index ef9edcbe30..2a67193b02 100644 --- a/packages/ripple-test-utils/step_definitions/components/forms.ts +++ b/packages/ripple-test-utils/step_definitions/components/forms.ts @@ -103,16 +103,6 @@ When( } ) -When('I blur the input with the label {string}', (label: string) => { - cy.get('label.rpl-form-label') - .contains(label) - .closest('.rpl-form__outer') - .as('field') - - cy.get('@field').should('exist') - cy.get('@field').find('input').blur() -}) - When( 'I type {string} into the textarea with the label {string}', (value: string, label: string) => { diff --git a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue index cc538ca8e0..c878f2b811 100644 --- a/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue +++ b/packages/ripple-ui-forms/src/components/RplForm/RplForm.vue @@ -63,6 +63,7 @@ const emit = defineEmits<{ (e: 'submit', payload: rplEventPayload & { action: 'submit' }): void (e: 'invalid', payload: rplEventPayload & { action: 'submit' }): void (e: 'submitted', payload: rplEventPayload & { action: 'complete' }): void + (e: 'start', payload: rplEventPayload): void }>() const { emitRplEvent } = useRippleEvent('rpl-form', emit) @@ -275,7 +276,7 @@ const plugins = computed( novalidate @submit-invalid="submitInvalidHandler" @submit="submitHandler" - @change="handleChange" + @input="handleChange" >