Skip to content

Commit

Permalink
[CRO] Amir/cro 333/ab test for onboarding toggle (#13545)
Browse files Browse the repository at this point in the history
* chore: add ab test for skip onboarding flow

* chore: add test case for feature flag hook

* chore: add mock of analytics package on onboarding

* chore: resolve review comments

* chore: update package version to 1.4.11

* chore: change var name

* fix: show onboarding as normal after login

* fix: onboarding ab test flow issue on normal scenario

* chore: fix eslint error

* chore: downgrade package version to 1.4.10

* chore: update lock
  • Loading branch information
amir-deriv committed Feb 21, 2024
1 parent a7ef2ed commit 4f4fe75
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 56 deletions.
8 changes: 8 additions & 0 deletions __mocks__/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ jest.mock('@deriv-com/analytics', () => ({
pageView: jest.fn(),
reset: jest.fn(),
setAttributes: jest.fn(),
getFeatureValue: jest.fn(),
getInstances: jest.fn().mockReturnValue({
ab: {
GrowthBook: {
setRenderer: jest.fn(),
},
},
}),
},
}));

Expand Down
108 changes: 54 additions & 54 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions packages/appstore/src/modules/onboarding/onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { getTradingHubContents } from 'Constants/trading-hub-content';
import EmptyOnboarding from './empty-onboarding';
import { useStore, observer } from '@deriv/stores';
import { useTradersHubTracking } from 'Hooks/index';
import { Analytics } from '@deriv-com/analytics';

type TOnboardingProps = {
contents: Record<
Expand Down Expand Up @@ -45,6 +44,9 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding
const has_active_real_account = useHasActiveRealAccount();
const steps_list = Object.keys(contents).filter(key => is_mt5_allowed || key !== 'step3');

const url_params = new URLSearchParams(window.location.search);
const skip_onboarding_flow = url_params.get('skip-onboarding-flow') === 'true';

const { trackOnboardingOpen, trackStepBack, trackStepForward, trackOnboardingClose, trackDotNavigation } =
useTradersHubTracking();

Expand Down Expand Up @@ -130,7 +132,7 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding
return <EmptyOnboarding />;
}

if (is_logged_in && is_from_signup_account && is_eu_user) {
if ((is_logged_in && is_from_signup_account && is_eu_user) || skip_onboarding_flow) {
history.push(routes.traders_hub);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ResidenceForm from '../SetResidenceModal/set-residence-form.jsx';
import validateSignupFields from './validate-signup-fields.jsx';

import 'Sass/app/modules/account-signup.scss';
import { useGrowthbookFeatureFlag } from '@deriv/hooks';

const AccountSignup = ({
enableApp,
Expand All @@ -41,6 +42,12 @@ const AccountSignup = ({
const [modded_state, setModdedState] = React.useState({});
const language = getLanguage();

// Growthbook ab/test experiment with onboarding flow
const growthbook_ab_test_skip_onboarding_flow = useGrowthbookFeatureFlag({
featureFlag: 'skip-onboarding-flow',
defaultValue: false,
});

const checkResidenceIsBrazil = selected_country =>
selected_country && residence_list[indexOfSelection(selected_country)]?.value?.toLowerCase() === 'br';

Expand Down Expand Up @@ -126,6 +133,13 @@ const AccountSignup = ({
error_message: error,
});
} else {
// ======== Growthbook ab/test experiment with onboarding flow ========
const searchParams = new URLSearchParams(window.location.search);
searchParams.set('skip-onboarding-flow', growthbook_ab_test_skip_onboarding_flow);

window.history.pushState(null, '', `${window.location.pathname}?${searchParams.toString()}`);
// ====================================================================

isModalVisible(false);
setIsFromSignupAccount(true);
SessionStore.remove('signup_query_param');
Expand Down
1 change: 1 addition & 0 deletions packages/hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "src/index.ts",
"dependencies": {
"@binary-com/binary-document-uploader": "^2.4.8",
"@deriv-com/analytics": "1.4.10",
"@deriv/api": "^1.0.0",
"@deriv/stores": "^1.0.0",
"@deriv/utils": "^1.0.0",
Expand Down
31 changes: 31 additions & 0 deletions packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { renderHook } from '@testing-library/react-hooks';
import useGrowthbookFeatureFlag from '../useGrowthbookFeatureFlag';
import { Analytics } from '@deriv-com/analytics';

describe('useGrowthbookFeatureFlag', () => {
test('Should call getFeatureValue from the package', async () => {
const { result } = renderHook(() =>
useGrowthbookFeatureFlag({
defaultValue: false,
featureFlag: 'dummy-feature-flag',
})
);

expect(result.current).toBe(false);
expect(Analytics.getFeatureValue).toHaveBeenCalled();
expect(Analytics.getFeatureValue).toHaveBeenCalledWith('dummy-feature-flag', false);
});

test('The default value for the feature flag must be sent correctly to the package', async () => {
const { result } = renderHook(() =>
useGrowthbookFeatureFlag({
defaultValue: true,
featureFlag: 'dummy-feature-flag-1',
})
);

expect(result.current).toBe(true);
expect(Analytics.getFeatureValue).toHaveBeenCalled();
expect(Analytics.getFeatureValue).toHaveBeenCalledWith('dummy-feature-flag-1', true);
});
});
1 change: 1 addition & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ export { default as useWalletMigration } from './useWalletMigration';
export { default as useWalletTransactions } from './useWalletTransactions';
export { default as useWalletTransfer } from './useWalletTransfer';
export { default as useWalletsList } from './useWalletsList';
export { default as useGrowthbookFeatureFlag } from './useGrowthbookFeatureFlag';
27 changes: 27 additions & 0 deletions packages/hooks/src/useGrowthbookFeatureFlag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useState, useEffect } from 'react';
import { Analytics } from '@deriv-com/analytics';

interface UseGrowthbookFeatureFlagArgs<T> {
featureFlag: string;
defaultValue: T;
}

const useGrowthbookFeatureFlag = <T>({ featureFlag, defaultValue }: UseGrowthbookFeatureFlagArgs<T>) => {
const [featureFlagValue, setFeatureFlagValue] = useState<T>(defaultValue);

useEffect(() => {
const value = (Analytics?.getFeatureValue(featureFlag, defaultValue) || defaultValue) as T;
setFeatureFlagValue(value);

// Set the renderer for GrowthBook to update the value when the feature flag changes
Analytics.getInstances()?.ab?.GrowthBook?.setRenderer(() => {
const value = (Analytics?.getFeatureValue(featureFlag, defaultValue) || defaultValue) as T;

setFeatureFlagValue(value);
});
}, [featureFlag, defaultValue]);

return featureFlagValue;
};

export default useGrowthbookFeatureFlag;

0 comments on commit 4f4fe75

Please sign in to comment.