Try ExPlat: Add A/A test (https://github.com/woocommerce/woocommerce-admin/pull/6669)
* Add basic ExPlat initialization * add tsx support
This commit is contained in:
parent
97d143b762
commit
7ab756b76c
|
@ -48,7 +48,7 @@ function getPackageName( file ) {
|
|||
}
|
||||
|
||||
const isJsFile = ( filepath ) => {
|
||||
return /.\.js$/.test( filepath );
|
||||
return /.\.(js|ts|tsx)$/.test( filepath );
|
||||
};
|
||||
|
||||
const isScssFile = ( filepath ) => {
|
||||
|
|
|
@ -12,7 +12,9 @@ const watch = require( 'node-watch' );
|
|||
*/
|
||||
const getPackages = require( './get-packages' );
|
||||
|
||||
const BUILD_CMD = `node ${ path.resolve( __dirname, './build.js' ).replace( /(\s+)/g, '\\$1' ) }`;
|
||||
const BUILD_CMD = `node ${ path
|
||||
.resolve( __dirname, './build.js' )
|
||||
.replace( /(\s+)/g, '\\$1' ) }`;
|
||||
|
||||
let filesToBuild = new Map();
|
||||
|
||||
|
@ -25,7 +27,7 @@ const exists = ( filename ) => {
|
|||
|
||||
// Exclude deceitful source-like files, such as editor swap files.
|
||||
const isSourceFile = ( filename ) => {
|
||||
return /.\.(js|scss)$/.test( filename );
|
||||
return /.\.(js|ts|tsx|scss)$/.test( filename );
|
||||
};
|
||||
|
||||
const rebuild = ( filename ) => filesToBuild.set( filename, true );
|
||||
|
@ -34,30 +36,48 @@ getPackages().forEach( ( p ) => {
|
|||
const srcDir = path.resolve( p, 'src' );
|
||||
try {
|
||||
fs.accessSync( srcDir, fs.F_OK );
|
||||
watch( path.resolve( p, 'src' ), { recursive: true }, ( event, filename ) => {
|
||||
const filePath = path.resolve( srcDir, filename );
|
||||
watch(
|
||||
path.resolve( p, 'src' ),
|
||||
{ recursive: true },
|
||||
( event, filename ) => {
|
||||
const filePath = path.resolve( srcDir, filename );
|
||||
|
||||
if ( ! isSourceFile( filename ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! isSourceFile( filename ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( [ 'update', 'change', 'rename' ].includes( event ) ) && exists( filePath ) ) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log( chalk.green( '->' ), `${ event }: ${ filename }` );
|
||||
rebuild( filePath );
|
||||
} else {
|
||||
const buildFile = path.resolve( srcDir, '..', 'build', filename );
|
||||
try {
|
||||
fs.unlinkSync( buildFile );
|
||||
process.stdout.write(
|
||||
chalk.red( ' \u2022 ' ) +
|
||||
path.relative( path.resolve( srcDir, '..', '..' ), buildFile ) +
|
||||
' (deleted)' +
|
||||
'\n'
|
||||
if (
|
||||
[ 'update', 'change', 'rename' ].includes( event ) &&
|
||||
exists( filePath )
|
||||
) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
chalk.green( '->' ),
|
||||
`${ event }: ${ filename }`
|
||||
);
|
||||
} catch ( e ) {}
|
||||
rebuild( filePath );
|
||||
} else {
|
||||
const buildFile = path.resolve(
|
||||
srcDir,
|
||||
'..',
|
||||
'build',
|
||||
filename
|
||||
);
|
||||
try {
|
||||
fs.unlinkSync( buildFile );
|
||||
process.stdout.write(
|
||||
chalk.red( ' \u2022 ' ) +
|
||||
path.relative(
|
||||
path.resolve( srcDir, '..', '..' ),
|
||||
buildFile
|
||||
) +
|
||||
' (deleted)' +
|
||||
'\n'
|
||||
);
|
||||
} catch ( e ) {}
|
||||
}
|
||||
}
|
||||
} );
|
||||
);
|
||||
} catch ( e ) {
|
||||
// doesn't exist
|
||||
}
|
||||
|
@ -68,7 +88,12 @@ setInterval( () => {
|
|||
if ( files.length ) {
|
||||
filesToBuild = new Map();
|
||||
try {
|
||||
execSync( `${ BUILD_CMD } ${ files.map( file => file.replace( /(\s+)/g, '\\$1' ) ).join( ' ' ) }`, { stdio: [ 0, 1, 2 ] } );
|
||||
execSync(
|
||||
`${ BUILD_CMD } ${ files
|
||||
.map( ( file ) => file.replace( /(\s+)/g, '\\$1' ) )
|
||||
.join( ' ' ) }`,
|
||||
{ stdio: [ 0, 1, 2 ] }
|
||||
);
|
||||
} catch ( e ) {}
|
||||
}
|
||||
}, 100 );
|
||||
|
|
|
@ -23,6 +23,7 @@ import { getSetting } from '@woocommerce/wc-admin-settings';
|
|||
import { getNewPath } from '@woocommerce/navigation';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { Text } from '@woocommerce/experimental';
|
||||
import { Experiment } from '@woocommerce/explat';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -69,15 +70,24 @@ export const StatsOverview = () => {
|
|||
( item ) => ! hiddenStats.includes( item.stat )
|
||||
);
|
||||
|
||||
const HeaderText = (
|
||||
<Text variant="title.small">
|
||||
{ __( 'Stats overview', 'woocommerce-admin' ) }
|
||||
</Text>
|
||||
);
|
||||
|
||||
return (
|
||||
<Card
|
||||
size="large"
|
||||
className="woocommerce-stats-overview woocommerce-homescreen-card"
|
||||
>
|
||||
<CardHeader size="medium">
|
||||
<Text variant="title.small">
|
||||
{ __( 'Stats overview', 'woocommerce-admin' ) }
|
||||
</Text>
|
||||
<Experiment
|
||||
name="woocommerce_test_experiment"
|
||||
defaultExperience={ HeaderText }
|
||||
treatmentExperience={ HeaderText }
|
||||
loadingExperience={ HeaderText }
|
||||
/>
|
||||
<EllipsisMenu
|
||||
label={ __(
|
||||
'Choose which values to display',
|
||||
|
|
|
@ -9,6 +9,7 @@ import interpolateComponents from 'interpolate-components';
|
|||
import { Button, Modal } from '@wordpress/components';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { initializeExPlat } from '@woocommerce/explat';
|
||||
|
||||
class UsageModal extends Component {
|
||||
constructor( props ) {
|
||||
|
@ -70,6 +71,8 @@ class UsageModal extends Component {
|
|||
return;
|
||||
}
|
||||
|
||||
initializeExPlat();
|
||||
|
||||
this.setState( { isLoadingScripts: false } );
|
||||
} );
|
||||
} else if ( ! allowTracking ) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import { withDispatch } from '@wordpress/data';
|
|||
import { compose } from '@wordpress/compose';
|
||||
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { initializeExPlat } from '@woocommerce/explat';
|
||||
|
||||
const BetaFeaturesTrackingModal = ( { updateOptions } ) => {
|
||||
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
||||
|
@ -19,7 +20,9 @@ const BetaFeaturesTrackingModal = ( { updateOptions } ) => {
|
|||
const setTracking = async ( allow ) => {
|
||||
if ( typeof window.wcTracks.enable === 'function' ) {
|
||||
if ( allow ) {
|
||||
window.wcTracks.enable();
|
||||
window.wcTracks.enable( () => {
|
||||
initializeExPlat();
|
||||
} );
|
||||
} else {
|
||||
window.wcTracks.isEnabled = false;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,20 @@
|
|||
"integrity": "sha512-gZWaJbx3p1oennAIoJtMGluTmoM95Efk4rc44TSBxWSZZ8gH3Am2eh1o3i1NhrZmg2Zt3AiVFeZZ4AJccIpBKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@automattic/explat-client": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@automattic/explat-client/-/explat-client-0.0.1.tgz",
|
||||
"integrity": "sha512-OP0hXMqQVir+kHk4q0YAyHfN4+5MHN/g62w6J/hwYFfswes6tjOrGYsH963dXcGqmC6rPfW/0gPlOrjebmJbRg=="
|
||||
},
|
||||
"@automattic/explat-client-react-helpers": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@automattic/explat-client-react-helpers/-/explat-client-react-helpers-0.0.1.tgz",
|
||||
"integrity": "sha512-qrUhXarn6F11dwnyqhgkoWPwZtIbaBY63ur5RmqOhq0L3DHSz1SOODI7lQovXhRCIYRrdOCkLlzUtSP6HC02Gg==",
|
||||
"requires": {
|
||||
"@automattic/explat-client": "^0.0.1",
|
||||
"react": "^16.12.0"
|
||||
}
|
||||
},
|
||||
"@automattic/mini-css-extract-plugin-with-rtl": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@automattic/mini-css-extract-plugin-with-rtl/-/mini-css-extract-plugin-with-rtl-0.8.0.tgz",
|
||||
|
@ -7743,6 +7757,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/expect-puppeteer": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/expect-puppeteer/-/expect-puppeteer-4.4.5.tgz",
|
||||
|
@ -10395,6 +10415,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@woocommerce/explat": {
|
||||
"version": "file:packages/explat",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@automattic/explat-client": "0.0.1",
|
||||
"@automattic/explat-client-react-helpers": "0.0.1",
|
||||
"cookie": "^0.4.1",
|
||||
"qs": "6.9.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@woocommerce/navigation": {
|
||||
"version": "file:packages/navigation",
|
||||
"dev": true,
|
||||
|
@ -17641,12 +17679,6 @@
|
|||
"safe-buffer": "~5.1.1"
|
||||
}
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
|
@ -20733,6 +20765,12 @@
|
|||
"vary": "~1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
|
|
|
@ -90,6 +90,8 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@automattic/explat-client": "0.0.1",
|
||||
"@automattic/explat-client-react-helpers": "0.0.1",
|
||||
"@woocommerce/e2e-environment": "0.2.1",
|
||||
"@woocommerce/e2e-utils": "0.1.2",
|
||||
"@wordpress/api-fetch": "2.2.8",
|
||||
|
@ -151,6 +153,7 @@
|
|||
"@testing-library/react": "11.2.6",
|
||||
"@testing-library/react-hooks": "3.7.0",
|
||||
"@testing-library/user-event": "12.8.3",
|
||||
"@types/cookie": "0.4.0",
|
||||
"@types/expect-puppeteer": "4.4.5",
|
||||
"@types/history": "4.7.8",
|
||||
"@types/jest": "26.0.22",
|
||||
|
@ -158,6 +161,7 @@
|
|||
"@types/puppeteer": "5.4.3",
|
||||
"@types/wordpress__components": "9.8.6",
|
||||
"@typescript-eslint/eslint-plugin": "4.22.0",
|
||||
"@woocommerce/explat": "file:packages/explat",
|
||||
"@woocommerce/api": "0.1.2",
|
||||
"@woocommerce/components": "file:packages/components",
|
||||
"@woocommerce/csv-export": "file:packages/csv-export",
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Add `@woocommerce/explat` to list of packages.
|
||||
|
||||
# 1.4.0
|
||||
|
||||
- Add `@woocommerce/settings` to list of packages.
|
||||
|
|
|
@ -9,6 +9,7 @@ module.exports = [
|
|||
'@woocommerce/dependency-extraction-webpack-plugin',
|
||||
'@woocommerce/eslint-plugin',
|
||||
'@woocommerce/experimental',
|
||||
'@woocommerce/explat',
|
||||
'@woocommerce/navigation',
|
||||
'@woocommerce/notices',
|
||||
'@woocommerce/number',
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
package-lock=false
|
|
@ -0,0 +1,32 @@
|
|||
# ExPlat
|
||||
|
||||
This packages includes a component and utility functions that can be used to run A/B Tests in WooCommerce dashboard and reports pages.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the module
|
||||
|
||||
```bash
|
||||
npm install @woocommerce/explat --save
|
||||
```
|
||||
|
||||
This package assumes that your code will run in an ES2015+ environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using core-js or @babel/polyfill will add support for these methods. Learn more about it in Babel docs.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { Experiment } from '@woocommerce/explat';
|
||||
|
||||
const DefaultExperience = <div>Hello World</div>;
|
||||
|
||||
const TreatmentExperience = <div>Hello WooCommerce!</div>;
|
||||
|
||||
const LoadingExperience = <div>⏰</div>;
|
||||
|
||||
<Experiment
|
||||
name="woocommerce_example_experiment"
|
||||
defaultExperience={ DefaultExperience }
|
||||
treatmentExperience={ TreatmentExperience }
|
||||
loadingExperience={ LoadingExperience }
|
||||
/>;
|
||||
```
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "@woocommerce/explat",
|
||||
"version": "1.0.0",
|
||||
"description": "WooCommerce component and utils for A/B testing.",
|
||||
"author": "Automattic",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"keywords": [
|
||||
"wordpress",
|
||||
"woocommerce",
|
||||
"abtest",
|
||||
"explat"
|
||||
],
|
||||
"homepage": "https://github.com/woocommerce/woocommerce-admin/tree/main/packages/explat/README.md",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/woocommerce/woocommerce-admin.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/woocommerce/woocommerce-admin/issues"
|
||||
},
|
||||
"main": "build/index.js",
|
||||
"module": "build-module/index.js",
|
||||
"react-native": "src/index",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@automattic/explat-client": "0.0.1",
|
||||
"@automattic/explat-client-react-helpers": "0.0.1",
|
||||
"cookie": "^0.4.1",
|
||||
"qs": "6.9.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cookie": "^0.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import cookie from 'cookie';
|
||||
|
||||
/**
|
||||
* setInterval, but it runs first callback immediately instead of after interval.
|
||||
*/
|
||||
const immediateStartSetInterval = ( f: () => void, intervalMs: number ) => {
|
||||
f();
|
||||
return setInterval( f, intervalMs );
|
||||
};
|
||||
|
||||
let initializeAnonIdPromise: null | Promise< string | null > = null;
|
||||
const anonIdPollingIntervalMilliseconds = 50;
|
||||
const anonIdPollingIntervalMaxAttempts = 100; // 50 * 100 = 5000 = 5 seconds
|
||||
|
||||
/**
|
||||
* Gather w.js anonymous cookie, tk_ai
|
||||
*/
|
||||
export const readAnonCookie = (): string | null => {
|
||||
return cookie.parse( document.cookie ).tk_ai || null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the anonId:
|
||||
* - Polls for AnonId receival
|
||||
* - Should only be called once at startup
|
||||
* - Happens to be safe to call multiple times if it is necessary to reset the anonId - something like this was necessary for testing.
|
||||
*
|
||||
* This purely for boot-time initialization, in usual circumstances it will be retrieved within 100-300ms, it happens in parallel booting
|
||||
* so should only delay experiment loading that much for boot-time experiments. In some circumstances such as a very slow connection this
|
||||
* can take a lot longer.
|
||||
*
|
||||
* The state of initializeAnonIdPromise should be used rather than the return of this function.
|
||||
* The return is only avaliable to make this easier to test.
|
||||
*
|
||||
* Throws on error.
|
||||
*/
|
||||
export const initializeAnonId = async (): Promise< string | null > => {
|
||||
let attempt = 0;
|
||||
initializeAnonIdPromise = new Promise( ( res ) => {
|
||||
const anonIdPollingInterval = immediateStartSetInterval( () => {
|
||||
const anonId = readAnonCookie();
|
||||
if ( typeof anonId === 'string' && anonId !== '' ) {
|
||||
clearInterval( anonIdPollingInterval );
|
||||
res( anonId );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( anonIdPollingIntervalMaxAttempts - 1 <= attempt ) {
|
||||
clearInterval( anonIdPollingInterval );
|
||||
res( null );
|
||||
return;
|
||||
}
|
||||
attempt = attempt + 1;
|
||||
}, anonIdPollingIntervalMilliseconds );
|
||||
} );
|
||||
|
||||
return initializeAnonIdPromise;
|
||||
};
|
||||
|
||||
export const getAnonId = async (): Promise< string | null > => {
|
||||
if ( ! window.wcTracks?.isEnabled ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await initializeAnonIdPromise;
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { stringify } from 'qs';
|
||||
|
||||
const EXPLAT_VERSION = '0.1.0';
|
||||
|
||||
export const fetchExperimentAssignment = async ( {
|
||||
experimentName,
|
||||
anonId,
|
||||
}: {
|
||||
experimentName: string;
|
||||
anonId: string | null;
|
||||
} ): Promise< unknown > => {
|
||||
if ( ! window.wcTracks?.isEnabled ) {
|
||||
throw new Error(
|
||||
`Tracking is disabled, can't fetch experimentAssignment`
|
||||
);
|
||||
}
|
||||
|
||||
const params = stringify( {
|
||||
experiment_name: experimentName,
|
||||
anon_id: anonId ?? undefined,
|
||||
} );
|
||||
|
||||
const response = await window.fetch(
|
||||
`https://public-api.wordpress.com/wpcom/v2/experiments/${ EXPLAT_VERSION }/assignments/woocommerce?${ params }`
|
||||
);
|
||||
|
||||
return await response.json();
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { isDevelopmentMode } from './utils';
|
||||
|
||||
export const logError = (
|
||||
error: Record< string, string > & { message: string }
|
||||
): void => {
|
||||
const onLoggingError = ( e: unknown ) => {
|
||||
if ( isDevelopmentMode ) {
|
||||
console.error( '[ExPlat] Unable to send error to server:', e ); // eslint-disable-line no-console
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const { message, ...properties } = error;
|
||||
const logStashError = {
|
||||
message,
|
||||
properties: {
|
||||
...properties,
|
||||
context: 'explat',
|
||||
explat_client: 'woocommerce',
|
||||
},
|
||||
};
|
||||
|
||||
if ( isDevelopmentMode ) {
|
||||
console.error( '[ExPlat] ', error.message, error ); // eslint-disable-line no-console
|
||||
} else {
|
||||
if ( ! window.wcTracks?.isEnabled ) {
|
||||
throw new Error(
|
||||
`Tracking is disabled, can't send error to the server`
|
||||
);
|
||||
}
|
||||
|
||||
const body = new window.FormData();
|
||||
body.append( 'error', JSON.stringify( logStashError ) );
|
||||
window
|
||||
.fetch( 'https://public-api.wordpress.com/rest/v1.1/js-error', {
|
||||
method: 'POST',
|
||||
body,
|
||||
} )
|
||||
.catch( onLoggingError );
|
||||
}
|
||||
} catch ( e ) {
|
||||
onLoggingError( e );
|
||||
}
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createExPlatClient } from '@automattic/explat-client';
|
||||
import createExPlatClientReactHelpers from '@automattic/explat-client-react-helpers';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { isDevelopmentMode } from './utils';
|
||||
import { logError } from './error';
|
||||
import { fetchExperimentAssignment } from './assignment';
|
||||
import { getAnonId, initializeAnonId } from './anon';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
wcTracks: {
|
||||
isEnabled: boolean;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const initializeExPlat = (): void => {
|
||||
if ( window.wcTracks?.isEnabled ) {
|
||||
initializeAnonId().catch( ( e ) => logError( { message: e.message } ) );
|
||||
}
|
||||
};
|
||||
|
||||
initializeExPlat();
|
||||
|
||||
const exPlatClient = createExPlatClient( {
|
||||
fetchExperimentAssignment,
|
||||
getAnonId,
|
||||
logError,
|
||||
isDevelopmentMode,
|
||||
} );
|
||||
|
||||
export const {
|
||||
loadExperimentAssignment,
|
||||
dangerouslyGetExperimentAssignment,
|
||||
} = exPlatClient;
|
||||
const exPlatClientReactHelpers = createExPlatClientReactHelpers( exPlatClient );
|
||||
export const {
|
||||
useExperiment,
|
||||
Experiment,
|
||||
ProvideExperimentData,
|
||||
} = exPlatClientReactHelpers;
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* Boolean determining if environment is development.
|
||||
*/
|
||||
export const isDevelopmentMode = process.env.NODE_ENV === 'development';
|
|
@ -86,6 +86,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
- Tweak: Add tracking data for the preview site btn #6623
|
||||
- Tweak: Update WC Payments copy on the task list #6734
|
||||
- Tweak: Add check to see if value for contains is array, show warning if not. #6645
|
||||
- Dev: Add A/A test #6669
|
||||
- Fix: Event tracking for merchant email notes #6616
|
||||
- Fix: Check active plugins before getting the PayPal onboarding status #6625
|
||||
- Dev: Add support for running php unit tests in PHP 8. #6678
|
||||
|
|
|
@ -339,6 +339,7 @@ class Loader {
|
|||
$css_file_version = self::get_file_version( 'css' );
|
||||
|
||||
$scripts = array(
|
||||
'wc-explat',
|
||||
'wc-customer-effort-score',
|
||||
// NOTE: This should be removed when Gutenberg is updated and the notices package is removed from WooCommerce Admin.
|
||||
'wc-notices',
|
||||
|
|
|
@ -27,6 +27,10 @@ const wooCommercePackages = [
|
|||
'data',
|
||||
];
|
||||
|
||||
global.wcTracks = {
|
||||
isEnabled: false,
|
||||
};
|
||||
|
||||
// aliases
|
||||
global.wcSettings = {
|
||||
adminUrl: 'https://vagrant.local/wp/wp-admin/',
|
||||
|
@ -63,7 +67,7 @@ global.wcSettings = {
|
|||
woocommerce_excluded_report_order_statuses: [],
|
||||
},
|
||||
dataEndpoints: {
|
||||
countries: [],
|
||||
countries: [],
|
||||
performanceIndicators: [
|
||||
{
|
||||
chart: 'total_sales',
|
||||
|
|
|
@ -25,6 +25,7 @@ const NODE_ENV = process.env.NODE_ENV || 'development';
|
|||
const WC_ADMIN_PHASE = process.env.WC_ADMIN_PHASE || 'development';
|
||||
|
||||
const wcAdminPackages = [
|
||||
'explat',
|
||||
'components',
|
||||
'csv-export',
|
||||
'currency',
|
||||
|
|
Loading…
Reference in New Issue