From 4f4fe7583bb4ce64136e72d65634d017968d1d8b Mon Sep 17 00:00:00 2001
From: amir ali <129206554+amir-deriv@users.noreply.github.com>
Date: Wed, 21 Feb 2024 10:59:17 +0800
Subject: [PATCH] [CRO] Amir/cro 333/ab test for onboarding toggle (#13545)
* 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
---
__mocks__/globals.js | 8 ++
package-lock.json | 108 +++++++++---------
.../src/modules/onboarding/onboarding.tsx | 6 +-
.../account-signup-modal.jsx | 14 +++
packages/hooks/package.json | 1 +
.../useGrowthbookFeatureFlag.spec.tsx | 31 +++++
packages/hooks/src/index.ts | 1 +
.../hooks/src/useGrowthbookFeatureFlag.ts | 27 +++++
8 files changed, 140 insertions(+), 56 deletions(-)
create mode 100644 packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx
create mode 100644 packages/hooks/src/useGrowthbookFeatureFlag.ts
diff --git a/__mocks__/globals.js b/__mocks__/globals.js
index 097188c93e5e..8fa59529a33e 100644
--- a/__mocks__/globals.js
+++ b/__mocks__/globals.js
@@ -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(),
+ },
+ },
+ }),
},
}));
diff --git a/package-lock.json b/package-lock.json
index f80738b6cb6b..d99f2a111074 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9754,9 +9754,9 @@
"integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w=="
},
"node_modules/@storybook/builder-webpack4/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/builder-webpack4/node_modules/@types/webpack": {
"version": "4.41.38",
@@ -11083,9 +11083,9 @@
}
},
"node_modules/@storybook/builder-webpack5/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/builder-webpack5/node_modules/colorette": {
"version": "1.4.0",
@@ -11510,9 +11510,9 @@
}
},
"node_modules/@storybook/core-common/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/core-common/node_modules/@webassemblyjs/ast": {
"version": "1.9.0",
@@ -12334,9 +12334,9 @@
}
},
"node_modules/@storybook/core-server/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/core-server/node_modules/@types/webpack": {
"version": "4.41.38",
@@ -13270,9 +13270,9 @@
"integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w=="
},
"node_modules/@storybook/manager-webpack4/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/manager-webpack4/node_modules/@types/webpack": {
"version": "4.41.38",
@@ -14563,9 +14563,9 @@
}
},
"node_modules/@storybook/manager-webpack5/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/manager-webpack5/node_modules/ansi-styles": {
"version": "4.3.0",
@@ -15077,9 +15077,9 @@
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ=="
},
"node_modules/@storybook/react/node_modules/@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"node_modules/@storybook/react/node_modules/acorn": {
"version": "7.4.1",
@@ -41086,9 +41086,9 @@
}
},
"node_modules/react-focus-lock": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.11.0.tgz",
- "integrity": "sha512-y6Amxjo3T67R/7tYPSS2HMUEjW4IIfDAnpc6sBZ3Nm8gkFhgEGwTP7Zw/vkYOyvOZly0EwT9oc5ZM2XmknTGgw==",
+ "version": "2.9.7",
+ "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.7.tgz",
+ "integrity": "sha512-EfhX040SELLqnQ9JftqsmQCG49iByg8F5X5m19Er+n371OaETZ35dlNPZrLOOTlnnwD4c2Zv0KDgabDTc7dPHw==",
"dependencies": {
"@babel/runtime": "^7.0.0",
"focus-lock": "^1.2.0",
@@ -41108,9 +41108,9 @@
}
},
"node_modules/react-focus-lock/node_modules/focus-lock": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.0.tgz",
- "integrity": "sha512-J5/QDEBUXkELMuWyRSsXBRG1JZ156tBvTS+sv3Ks5xBNyKCQ6qFZAfT3ZEPL3JfFEOS5SB+bT/0Ha3zS07yfEw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.2.tgz",
+ "integrity": "sha512-kFI92jZVqa8rP4Yer2sLNlUDcOdEFxYum2tIIr4eCH0XF+pOmlg0xiY4tkbDmHJXt3phtbJoWs1L6PgUVk97rA==",
"dependencies": {
"tslib": "^2.0.3"
},
@@ -57118,9 +57118,9 @@
"integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w=="
},
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"@types/webpack": {
"version": "4.41.38",
@@ -58168,9 +58168,9 @@
},
"dependencies": {
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"colorette": {
"version": "1.4.0",
@@ -58466,9 +58466,9 @@
}
},
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"@webassemblyjs/ast": {
"version": "1.9.0",
@@ -59141,9 +59141,9 @@
},
"dependencies": {
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"@types/webpack": {
"version": "4.41.38",
@@ -59911,9 +59911,9 @@
"integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w=="
},
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"@types/webpack": {
"version": "4.41.38",
@@ -60936,9 +60936,9 @@
},
"dependencies": {
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"ansi-styles": {
"version": "4.3.0",
@@ -61269,9 +61269,9 @@
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ=="
},
"@types/node": {
- "version": "16.18.82",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.82.tgz",
- "integrity": "sha512-pcDZtkx9z8XYV+ius2P3Ot2VVrcYOfXffBQUBuiszrlUzKSmoDYqo+mV+IoL8iIiIjjtOMvNSmH1hwJ+Q+f96Q=="
+ "version": "16.18.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.79.tgz",
+ "integrity": "sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ=="
},
"acorn": {
"version": "7.4.1",
@@ -79599,9 +79599,9 @@
}
},
"react-focus-lock": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.11.0.tgz",
- "integrity": "sha512-y6Amxjo3T67R/7tYPSS2HMUEjW4IIfDAnpc6sBZ3Nm8gkFhgEGwTP7Zw/vkYOyvOZly0EwT9oc5ZM2XmknTGgw==",
+ "version": "2.9.7",
+ "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.7.tgz",
+ "integrity": "sha512-EfhX040SELLqnQ9JftqsmQCG49iByg8F5X5m19Er+n371OaETZ35dlNPZrLOOTlnnwD4c2Zv0KDgabDTc7dPHw==",
"requires": {
"@babel/runtime": "^7.0.0",
"focus-lock": "^1.2.0",
@@ -79612,9 +79612,9 @@
},
"dependencies": {
"focus-lock": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.0.tgz",
- "integrity": "sha512-J5/QDEBUXkELMuWyRSsXBRG1JZ156tBvTS+sv3Ks5xBNyKCQ6qFZAfT3ZEPL3JfFEOS5SB+bT/0Ha3zS07yfEw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.2.tgz",
+ "integrity": "sha512-kFI92jZVqa8rP4Yer2sLNlUDcOdEFxYum2tIIr4eCH0XF+pOmlg0xiY4tkbDmHJXt3phtbJoWs1L6PgUVk97rA==",
"requires": {
"tslib": "^2.0.3"
}
diff --git a/packages/appstore/src/modules/onboarding/onboarding.tsx b/packages/appstore/src/modules/onboarding/onboarding.tsx
index d9eebba857c3..d8e8f71c3428 100644
--- a/packages/appstore/src/modules/onboarding/onboarding.tsx
+++ b/packages/appstore/src/modules/onboarding/onboarding.tsx
@@ -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<
@@ -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();
@@ -130,7 +132,7 @@ const Onboarding = observer(({ contents = getTradingHubContents() }: TOnboarding
return ;
}
- 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);
}
diff --git a/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx b/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx
index 537aa6dcf4c4..2aba95cbd513 100644
--- a/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx
+++ b/packages/core/src/App/Containers/AccountSignupModal/account-signup-modal.jsx
@@ -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,
@@ -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';
@@ -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');
diff --git a/packages/hooks/package.json b/packages/hooks/package.json
index 06f2fdbdb49c..55c906c6b243 100644
--- a/packages/hooks/package.json
+++ b/packages/hooks/package.json
@@ -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",
diff --git a/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx b/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx
new file mode 100644
index 000000000000..109538c5199b
--- /dev/null
+++ b/packages/hooks/src/__tests__/useGrowthbookFeatureFlag.spec.tsx
@@ -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);
+ });
+});
diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts
index 9c869e414d54..8bb02b6544ed 100644
--- a/packages/hooks/src/index.ts
+++ b/packages/hooks/src/index.ts
@@ -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';
diff --git a/packages/hooks/src/useGrowthbookFeatureFlag.ts b/packages/hooks/src/useGrowthbookFeatureFlag.ts
new file mode 100644
index 000000000000..2aee50d87f56
--- /dev/null
+++ b/packages/hooks/src/useGrowthbookFeatureFlag.ts
@@ -0,0 +1,27 @@
+import { useState, useEffect } from 'react';
+import { Analytics } from '@deriv-com/analytics';
+
+interface UseGrowthbookFeatureFlagArgs {
+ featureFlag: string;
+ defaultValue: T;
+}
+
+const useGrowthbookFeatureFlag = ({ featureFlag, defaultValue }: UseGrowthbookFeatureFlagArgs) => {
+ const [featureFlagValue, setFeatureFlagValue] = useState(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;