Skip to content

Commit fb91feb

Browse files
committed
feat: Add Ophan tracking
1 parent 0cdeceb commit fb91feb

File tree

4 files changed

+157
-49
lines changed

4 files changed

+157
-49
lines changed

dotcom-rendering/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@guardian/identity-auth": "6.0.1",
3939
"@guardian/identity-auth-frontend": "8.1.0",
4040
"@guardian/libs": "25.2.0",
41-
"@guardian/ophan-tracker-js": "2.3.2",
41+
"@guardian/ophan-tracker-js": "2.5.0",
4242
"@guardian/react-crossword": "6.3.0",
4343
"@guardian/shimport": "1.0.2",
4444
"@guardian/source": "10.2.0",

dotcom-rendering/src/components/GoogleOneTap.importable.tsx

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { log } from '@guardian/libs';
2+
import { submitComponentEvent } from '../client/ophan/ophan';
23
import { useIsSignedIn } from '../lib/useAuthStatus';
34
import { useConsent } from '../lib/useConsent';
45
import { useOnce } from '../lib/useOnce';
@@ -117,6 +118,19 @@ export const initializeFedCM = async ({
117118
isSignedIn?: boolean;
118119
isInTest?: boolean;
119120
}): Promise<void> => {
121+
const isSupported = 'IdentityCredential' in window;
122+
123+
void submitComponentEvent(
124+
{
125+
action: 'DETECT',
126+
component: {
127+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
128+
},
129+
value: isSupported ? 'SUPPORTED' : 'NOT_SUPPORTED',
130+
},
131+
'Web',
132+
);
133+
120134
if (isSignedIn) return;
121135

122136
/**
@@ -128,8 +142,7 @@ export const initializeFedCM = async ({
128142
*
129143
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=1803629
130144
*/
131-
if (!('IdentityCredential' in window)) {
132-
// TODO: Track Ophan "FedCM" unsupported event here.
145+
if (!isSupported) {
133146
log('identity', 'FedCM API not supported in this browser');
134147
return;
135148
}
@@ -185,17 +198,34 @@ export const initializeFedCM = async ({
185198
});
186199

187200
if (credentials) {
188-
// TODO: Track Ophan "FedCM" success event here.
189201
log('identity', 'FedCM credentials received', {
190202
credentials,
191203
});
192204

205+
await submitComponentEvent(
206+
{
207+
action: 'SIGN_IN',
208+
component: {
209+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
210+
},
211+
},
212+
'Web',
213+
);
214+
193215
submitGoogleOneTapToken(
194216
getRedirectUrl({ stage, currentLocation: window.location.href }),
195217
credentials.token,
196218
);
197219
} else {
198-
// TODO: Track Ophan "FedCM" skip event here.
220+
void submitComponentEvent(
221+
{
222+
action: 'CLOSE',
223+
component: {
224+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
225+
},
226+
},
227+
'Web',
228+
);
199229
log('identity', 'No FedCM credentials received');
200230
}
201231
};

dotcom-rendering/src/components/GoogleOneTap.test.tsx

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import { submitComponentEvent as submitComponentEventMock } from '../client/ophan/ophan';
12
import { getRedirectUrl, initializeFedCM } from './GoogleOneTap.importable';
23

4+
jest.mock('../client/ophan/ophan', () => ({
5+
submitComponentEvent: jest.fn(),
6+
}));
7+
38
const mockWindow = ({
49
get,
510
enableFedCM = true,
@@ -58,6 +63,10 @@ const mockWindow = ({
5863
};
5964

6065
describe('GoogleOneTap', () => {
66+
beforeEach(() => {
67+
jest.clearAllMocks();
68+
});
69+
6170
it('should return the correct signin URL after constructing it with the provided stage and token', () => {
6271
expect(
6372
getRedirectUrl({
@@ -99,6 +108,29 @@ describe('GoogleOneTap', () => {
99108

100109
await initializeFedCM({ isSignedIn: false });
101110

111+
expect(submitComponentEventMock).toHaveBeenNthCalledWith(
112+
1,
113+
{
114+
component: {
115+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
116+
},
117+
action: 'DETECT',
118+
value: 'SUPPORTED',
119+
},
120+
'Web',
121+
);
122+
123+
expect(submitComponentEventMock).toHaveBeenNthCalledWith(
124+
2,
125+
{
126+
component: {
127+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
128+
},
129+
action: 'SIGN_IN',
130+
},
131+
'Web',
132+
);
133+
102134
expect(form.action).toBe(
103135
'https://profile.theguardian.com/signin/google-one-tap?returnUrl=https%3A%2F%2Fwww.theguardian.com%2Fuk',
104136
);
@@ -123,6 +155,29 @@ describe('GoogleOneTap', () => {
123155

124156
await initializeFedCM({ isSignedIn: false });
125157

158+
expect(submitComponentEventMock).toHaveBeenNthCalledWith(
159+
1,
160+
{
161+
component: {
162+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
163+
},
164+
action: 'DETECT',
165+
value: 'SUPPORTED',
166+
},
167+
'Web',
168+
);
169+
170+
expect(submitComponentEventMock).toHaveBeenNthCalledWith(
171+
2,
172+
{
173+
component: {
174+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
175+
},
176+
action: 'CLOSE',
177+
},
178+
'Web',
179+
);
180+
126181
expect(navigatorGet).toHaveBeenCalledWith({
127182
identity: {
128183
context: 'continue',
@@ -155,6 +210,18 @@ describe('GoogleOneTap', () => {
155210
'window.navigator.credentials.get failed',
156211
);
157212

213+
expect(submitComponentEventMock).toHaveBeenNthCalledWith(
214+
1,
215+
{
216+
component: {
217+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
218+
},
219+
action: 'DETECT',
220+
value: 'SUPPORTED',
221+
},
222+
'Web',
223+
);
224+
158225
expect(navigatorGet).toHaveBeenCalledWith({
159226
identity: {
160227
context: 'continue',
@@ -183,6 +250,18 @@ describe('GoogleOneTap', () => {
183250

184251
await initializeFedCM({ isSignedIn: false });
185252

253+
expect(submitComponentEventMock).toHaveBeenCalledTimes(1);
254+
expect(submitComponentEventMock).toHaveBeenCalledWith(
255+
{
256+
component: {
257+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
258+
},
259+
action: 'DETECT',
260+
value: 'NOT_SUPPORTED',
261+
},
262+
'Web',
263+
);
264+
186265
expect(navigatorGet).not.toHaveBeenCalled();
187266
expect(form.submit).not.toHaveBeenCalled();
188267
});
@@ -196,18 +275,17 @@ describe('GoogleOneTap', () => {
196275

197276
await initializeFedCM({ isSignedIn: true });
198277

199-
expect(navigatorGet).not.toHaveBeenCalled();
200-
expect(form.submit).not.toHaveBeenCalled();
201-
});
202-
203-
it('should not initializeFedCM when user is not in test', async () => {
204-
const navigatorGet = jest.fn();
205-
206-
const { form } = mockWindow({
207-
get: navigatorGet,
208-
});
209-
210-
await initializeFedCM({ isSignedIn: true });
278+
expect(submitComponentEventMock).toHaveBeenCalledTimes(1);
279+
expect(submitComponentEventMock).toHaveBeenCalledWith(
280+
{
281+
component: {
282+
componentType: 'SIGN_IN_GOOGLE_ONE_TAP',
283+
},
284+
action: 'DETECT',
285+
value: 'SUPPORTED',
286+
},
287+
'Web',
288+
);
211289

212290
expect(navigatorGet).not.toHaveBeenCalled();
213291
expect(form.submit).not.toHaveBeenCalled();

0 commit comments

Comments
 (0)