Simplified A/B testing framework for Perps that leverages LaunchDarkly for user identification, variant assignment, and persistence. The implementation focuses on reading variants and applying them in UI, while LaunchDarkly handles all complex logic.
Key Design Principles:
- LaunchDarkly is the single source of truth for variant assignment
- Simple string flags (not JSON) for variant names
- Fallback to first variant when flag is disabled
- Type-safe hook API for UI components
- No client-side assignment logic or storage
graph TD
LD[LaunchDarkly Remote] -->|returns string| FS[Feature Flag Selector]
FS -->|variant name| Hook[usePerpsABTest Hook]
Hook -->|variant data| UI[UI Component]
TC[Test Config] -->|defines variants| Hook
Hook -->|maps name to data| UI
style LD fill:#e1f5ff
style FS fill:#fff3e0
style Hook fill:#f3e5f5
style UI fill:#e8f5e9
Owns:
- Variant definitions (control, treatment, etc.)
- Variant data (button colors, text, behavior flags)
- Test metadata (ID, description, min version)
Example:
export const BUTTON_COLOR_TEST: ABTestConfig<ButtonColorTestVariants> = {
testId: 'button_color_test',
featureFlagKey: 'perpsAbtestButtonColor',
description: 'Tests impact of button colors on trading behavior',
variants: {
control: {
weight: 50, // Informational only
data: { long: 'green', short: 'red' },
},
monochrome: {
weight: 50, // Informational only
data: { long: 'white', short: 'white' },
},
},
};Note: Weights are informational only. LaunchDarkly controls actual distribution via percentage rollout rules.
Owns:
- Reading LaunchDarkly flag value from Redux
- Returning variant name as string or null
Example:
export const selectPerpsButtonColorTestVariant = createSelector(
selectRemoteFeatureFlags,
(remoteFeatureFlags): string | null => {
const flag = remoteFeatureFlags?.perpsAbtestButtonColor;
return flag || null; // Returns 'control' | 'monochrome' | null
},
);Redux State:
{
RemoteFeatureFlagController: {
remoteFeatureFlags: {
perpsAbtestButtonColor: 'control'; // String value from LaunchDarkly
}
}
}Owns:
- Mapping variant name to variant data
- Fallback logic (first variant when flag is null)
isEnabledstate (true if LaunchDarkly returned a variant)
Returns:
{
variant: T; // Typed variant data (e.g., { long: 'green', short: 'red' })
variantName: string; // Variant name (e.g., 'control')
isEnabled: boolean; // true if LaunchDarkly assigned variant, false if using fallback
}Usage in Component:
import { usePerpsABTest } from '../../utils/abTesting/usePerpsABTest';
import { BUTTON_COLOR_TEST } from '../../utils/abTesting/tests';
import { selectPerpsButtonColorTestVariant } from '../../selectors/featureFlags';
const MyComponent = () => {
const { variant, variantName, isEnabled } = usePerpsABTest({
test: BUTTON_COLOR_TEST,
featureFlagSelector: selectPerpsButtonColorTestVariant,
});
const buttonColors = variant as ButtonColorVariant;
// Track screen view with AB test context (baseline exposure)
usePerpsEventTracking({
eventName: MetaMetricsEvents.PERPS_SCREEN_VIEWED,
properties: {
[PerpsEventProperties.SCREEN_TYPE]:
PerpsEventValues.SCREEN_TYPE.ASSET_DETAILS,
[PerpsEventProperties.ASSET]: market.symbol,
// AB test context - only included when test is enabled
...(isEnabled && {
[PerpsEventProperties.AB_TEST_BUTTON_COLOR]: variantName,
}),
},
});
// Get imperative track function for button press tracking
const { track } = usePerpsEventTracking();
const handleButtonPress = (direction: 'long' | 'short') => {
// Track AB test on button press (engagement)
if (isEnabled) {
track(MetaMetricsEvents.PERPS_UI_INTERACTION, {
[PerpsEventProperties.INTERACTION_TYPE]:
PerpsEventValues.INTERACTION_TYPE.TAP,
[PerpsEventProperties.ASSET]: market.symbol,
[PerpsEventProperties.DIRECTION]: direction === 'long'
? PerpsEventValues.DIRECTION.LONG
: PerpsEventValues.DIRECTION.SHORT,
[PerpsEventProperties.AB_TEST_BUTTON_COLOR]: variantName,
});
}
// Navigate or perform action
// ...
};
return (
<ButtonSemantic
onPress={() => handleButtonPress('long')}
severity={getButtonSeverityForDirection('long', buttonColors)}
/>
);
};app/components/UI/Perps/
├── utils/abTesting/
│ ├── types.ts # TypeScript interfaces
│ ├── usePerpsABTest.ts # Main hook
│ └── tests.ts # Test configurations
├── selectors/featureFlags/
│ └── index.ts # Feature flag selectors
├── constants/
│ └── eventNames.ts # AB test event properties
└── Views/
└── PerpsOrderView/ # Example usage
File: app/components/UI/Perps/utils/abTesting/types.ts
export interface MyTestVariant {
property: string;
anotherProperty: number;
}File: app/components/UI/Perps/utils/abTesting/tests.ts
export const MY_TEST: ABTestConfig<{
control: ABTestVariant<MyTestVariant>;
treatment: ABTestVariant<MyTestVariant>;
}> = {
testId: 'my_test',
featureFlagKey: 'perpsAbtestMyTest',
description: 'Test description',
variants: {
control: {
weight: 50,
data: { property: 'value1', anotherProperty: 1 },
},
treatment: {
weight: 50,
data: { property: 'value2', anotherProperty: 2 },
},
},
};Note: LaunchDarkly flag name would be perps-abtest-my-test (kebab-case), which becomes perpsAbtestMyTest (camelCase) in Redux state.
File: app/components/UI/Perps/selectors/featureFlags/index.ts
export const selectPerpsMyTestVariant = createSelector(
selectRemoteFeatureFlags,
(flags): string | null => flags?.perpsAbtestMyTest || null,
);File: app/components/UI/Perps/constants/eventNames.ts
AB_TEST: {
BUTTON_COLOR_TEST: 'button_color_test',
MY_TEST: 'my_test', // Add new test ID
}const { variant, variantName, isEnabled } = usePerpsABTest({
test: MY_TEST,
featureFlagSelector: selectPerpsMyTestVariant,
});To support multiple AB tests running simultaneously (e.g., TAT-1937 button colors, TAT-1940 asset CTA, TAT-1827 homepage CTA), we use flat properties per test instead of generic properties.
Note: For the complete event property definitions and tracking patterns, see Perps MetaMetrics Reference.
❌ Generic Pattern (doesn't scale):
{
ab_test_id: 'button_color_test',
ab_test_variant: 'control',
ab_test_enabled: true
}
// Problem: Only supports ONE test per event✅ Flat Pattern (scales to 3+ tests):
{
ab_test_button_color: 'control',
ab_test_asset_cta: 'variant_a',
ab_test_homepage_cta: 'treatment'
}
// ✓ Supports multiple concurrent tests in same event
// Note: Only include properties when test is enabled (don't send event if disabled)Pattern: ab_test_{test_name} (no _enabled suffix needed)
Why no _enabled property?
- Events are only sent when test is enabled
- Including the property means the test is active
- No need for redundant
_enabledflag
Examples:
- Button color test:
ab_test_button_color - Asset CTA test:
ab_test_asset_cta - Homepage CTA test:
ab_test_homepage_cta
1. Add properties to eventNames.ts:
export const PerpsEventProperties = {
// ... existing properties ...
// A/B testing properties (flat per test for multiple concurrent tests)
// Only include AB test properties when test is enabled (event not sent when disabled)
// Button color test (TAT-1937)
AB_TEST_BUTTON_COLOR: 'ab_test_button_color',
// Asset CTA test (TAT-1940)
AB_TEST_ASSET_CTA: 'ab_test_asset_cta',
// Future tests: add as AB_TEST_{TEST_NAME} (no _ENABLED property needed)
} as const;2. Use in component tracking:
const { variant, variantName, isEnabled } = usePerpsABTest({
test: BUTTON_COLOR_TEST,
featureFlagSelector: selectPerpsButtonColorTestVariant,
});
// Track screen view (baseline exposure)
usePerpsEventTracking({
eventName: MetaMetricsEvents.PERPS_SCREEN_VIEWED,
properties: {
[PerpsEventProperties.SCREEN_TYPE]:
PerpsEventValues.SCREEN_TYPE.ASSET_DETAILS,
[PerpsEventProperties.ASSET]: market.symbol,
...(isEnabled && {
[PerpsEventProperties.AB_TEST_BUTTON_COLOR]: variantName,
}),
},
});
// Get imperative track function for button press tracking
const { track } = usePerpsEventTracking();
// In button press handler
const handleLongPress = () => {
// Track AB test on button press (engagement)
if (isEnabled) {
track(MetaMetricsEvents.PERPS_UI_INTERACTION, {
[PerpsEventProperties.INTERACTION_TYPE]:
PerpsEventValues.INTERACTION_TYPE.TAP,
[PerpsEventProperties.ASSET]: market.symbol,
[PerpsEventProperties.DIRECTION]: PerpsEventValues.DIRECTION.LONG,
[PerpsEventProperties.AB_TEST_BUTTON_COLOR]: variantName,
});
}
// Navigate to order screen
navigation.navigate(/* ... */);
};Best Practice: Track AB test context in both screen view and button press events to enable engagement rate calculation.
Dual Tracking Approach:
-
PERPS_SCREEN_VIEWED (baseline exposure):
- Tracks when user views the asset details screen
- Establishes how many users were exposed to each variant
- Only includes AB test property when test is enabled
-
PERPS_UI_INTERACTION (engagement):
- Tracks when user presses Long/Short button
- Measures which variant drives more button presses
- Only sent when test is enabled
Why Both Events?
- Engagement Rate = Button presses / Screen views per variant
- Answers: "Which button color makes users more likely to press the button?"
- Screen views alone = exposure but not engagement
- Button presses alone = engagement but no baseline for comparison
Example Flow (TAT-1937):
- User views PerpsMarketDetailsView →
PERPS_SCREEN_VIEWEDwithab_test_button_color: 'control'(baseline) - User taps Long button →
PERPS_UI_INTERACTIONwithab_test_button_color: 'control',interaction_type: 'tap'(engagement) - User navigates to PerpsOrderView (order screen) - button colors applied, no tracking
- User completes trade →
PERPS_TRADE_TRANSACTIONevent (no AB test context needed)
Calculating Engagement Rate:
Compare button presses to screen views for each variant to determine which color drives higher engagement.
This section describes the complete flow from triggering an A/B test event in code to verifying it appears in analytics dashboards.
graph LR
App[Mobile App] -->|usePerpsEventTracking| MM[MetaMetrics]
MM -->|AnalyticsController| Seg[Segment Source]
Seg -->|Destination| Mix[Mixpanel]
subgraph "Dev Environment"
Seg -->|raw_segment_metamask_mobile_dev| Mix
end
Event Flow:
- Component → Calls
usePerpsEventTrackinghook with A/B test properties - MetaMetrics →
AnalyticsControllerprocesses event via platform adapter - Segment SDK → Batches and sends to Segment source
- Segment → Routes to Mixpanel destination based on source configuration
Before testing A/B events locally, ensure:
-
HAS_TEST_OVERRIDESis NOT set totruein.js.env(events won't send if true) -
SEGMENT_WRITE_KEYis configured for dev environment - User has opted into analytics in the app
- Feature flag is enabled (LaunchDarkly or local override)
By default, Segment batches events (every 30s or 20 events). For immediate visibility during development:
# Add to .js.env for instant flush during dev
export SEGMENT_FLUSH_INTERVAL="1"
export SEGMENT_FLUSH_EVENT_LIMIT="1"Important: Remove these overrides before committing. See MetaMetrics Debugging Guide for details.
Option A - LaunchDarkly (recommended for QA):
- Ensure
perpsAbtestButtonColorflag returns your desired variant in LaunchDarkly - Verify flag is targeting your user/environment
Option B - Local Override (for development):
// Temporarily hardcode variant - REMOVE BEFORE COMMIT!
const buttonColorVariant = 'monochrome';
// Comment out actual hook:
// const { variant, variantName } = usePerpsABTest({...});Your metrics ID is required to filter events in Segment and Mixpanel.
Development:
Check console logs for:
[MetaMask DEBUG]: MetaMetrics configured with ID: [Your Metrics ID]
QA/Production:
- Lock the app
- Touch the MetaMask fox logo for 10+ seconds
- Export state and find
metametricsIdin JSON
See MetaMetrics Debugging Guide for detailed instructions.
- Navigate to any Perps asset details screen
- Observe button colors:
- Control: Green (Long) / Red (Short)
- Monochrome: White (Long) / White (Short)
- Tap Long or Short button to trigger engagement event
Expected Events:
| Action | Event Name | Key Property |
|---|---|---|
| View asset details | Perps Screen Viewed |
ab_test_button_color |
| Tap Long/Short button | Perps UI Interaction |
ab_test_button_color |
- Open Segment Debugger:
- Dev: https://app.segment.com/consensys-analytics/sources/raw_segment_metamask_mobile_dev/debugger
- QA: Request URL from analytics team
- Filter by your Metrics ID (user identifier)
- Look for events:
Perps Screen Viewedwithab_test_button_colorpropertyPerps UI Interactionwithab_test_button_colorproperty
- Verify property value matches your expected variant
Example Segment Event:
{
"event": "Perps Screen Viewed",
"properties": {
"screen_type": "asset_details",
"asset": "BTC",
"ab_test_button_color": "control"
}
}- Open Mixpanel → Events → Live View
- Filter by your Metrics ID
- Verify
ab_test_button_colorproperty appears with correct variant value - Note: There may be a 1-2 minute delay from Segment to Mixpanel
| Issue | Likely Cause | Solution |
|---|---|---|
| Events not in console | HAS_TEST_OVERRIDES=true |
Set IS_HAS_TEST_OVERRIDESTEST=false in .js.env |
| Events not in Segment | User not opted in | Enable analytics in app settings |
No ab_test_* property |
Test not enabled | Check LaunchDarkly flag or isEnabled value |
Property in protocols.omitted |
Not in Segment schema | Add property to segment-schema repo (see Segment Schema Requirements) |
| Wrong variant | Hardcoded override | Remove temporary hardcode |
| Delayed events | Default flush policy | Add flush override env vars |
For more troubleshooting, see MetaMetrics Debugging Guide.
Critical: Before deploying a new A/B test, you must ensure the A/B test property is defined in the Segment tracking plan. Without this, Segment will strip the property from events, and your test data will be lost.
Segment uses a Tracking Plan (schema) to validate incoming events. Properties not defined in the schema are automatically removed by Segment Protocols. This is a data governance feature, not a bug.
Real Example (TAT-1937 Button Color Test):
The app correctly sent events with ab_test_button_color:
{
"event": "Perp UI Interaction",
"properties": {
"asset": "BTC",
"direction": "long",
"interaction_type": "tap",
"ab_test_button_color": "monochrome"
}
}But Segment stripped the property because it wasn't in the schema:
{
"event": "Perp UI Interaction",
"properties": {
"asset": "BTC",
"direction": "long",
"interaction_type": "tap"
},
"protocols": {
"omitted": ["ab_test_button_color"]
}
}The protocols.omitted array confirms the property was sent but rejected by schema validation.
Repository: Consensys/segment-schema
Steps:
-
Clone the segment-schema repo (if not already):
gh repo clone Consensys/segment-schema cd segment-schema -
Add property to the event schema (
libraries/events/metamask-mobile-perps/perp-ui-interaction.yaml):ab_test_button_color: type: string description: 'Button color A/B test variant (TAT-1937)' required: false enum: - control - monochrome
-
Add property to global definitions (
libraries/properties/metamask-mobile-perps-globals.yaml):ab_test_button_color: type: string description: 'Button color A/B test variant (TAT-1937). Values: control (green/red buttons) or monochrome (white/white buttons).' required: false enum: - control - monochrome
-
Create PR and merge to main branch
-
Wait for deployment - Schema changes are deployed automatically after merge
Before launching any new A/B test:
- Property defined in segment-schema - Add to both event YAML and globals YAML
- PR merged - Schema changes deployed to Segment
- Verified in Segment Debugger - Property appears in events (not in
protocols.omitted) - LaunchDarkly flag configured - Test can be enabled/disabled remotely
Symptom: A/B test property not appearing in Mixpanel despite correct app code.
Diagnosis:
- Check Segment Debugger for your event
- Look for
protocols.omittedarray in the event payload - If your property is in
omitted, it's a schema issue
Solution:
- Add property to segment-schema repo
- Merge PR and wait for deployment
- Verify property appears in subsequent events
For A/B test properties in Segment schema:
- Pattern:
ab_test_{test_name} - Type:
string - Required:
false(optional, only present when test is enabled) - Enum: List all valid variant names
Examples:
ab_test_button_color- Button color test (TAT-1937)ab_test_asset_cta- Asset CTA test (TAT-1940)ab_test_homepage_cta- Homepage CTA test (TAT-1827)
This section guides you through creating a Mixpanel dashboard to analyze A/B test results.
Reference Dashboard: Perps A/B Test - Button Color (TAT-1937)
- Navigate to Mixpanel → Boards → + New Board
- Name:
Perps A/B Test - Button Color (TAT-1937) - Description:
Measures impact of button colors on trading engagement
Create an Insights report showing how many users were exposed to each variant:
- Type: Insights (+ Add → Report → Insights)
- Event:
Perp Screen Viewed - Filters:
screen_typeequalsasset_detailsab_test_button_coloris set (ensures only test participants are counted)
- Breakdown:
ab_test_button_color - Time Range: Select test duration
This establishes your baseline: how many users saw control vs monochrome buttons.
Create an Insights report showing button taps per variant:
- Type: Insights
- Event:
Perp UI Interaction - Filters:
interaction_typeequalstapab_test_button_coloris set
- Breakdown:
ab_test_button_color - Time Range: Match exposure report
Create a funnel to calculate engagement rate per variant:
- Type: Funnels (+ Add → Report → Funnels)
- Step 1:
Perp Screen Viewed- Filter:
screen_typeequalsasset_details - Filter:
ab_test_button_coloris set
- Filter:
- Step 2:
Perp UI Interaction- Filter:
interaction_typeequalstap - Filter:
directionis set (ensures only Long/Short button taps, excludes other UI interactions)
- Filter:
- Breakdown:
ab_test_button_color - Conversion Window: 1 session
This shows: "Of users who saw the screen, what percentage tapped a Long/Short button?"
Note: The
direction is setfilter on Step 2 ensures only Long/Short button taps are counted, excluding taps from other screens like Order Book that also track the A/B test property.
In the funnel report settings:
- Enable Statistical Significance calculation
- Set confidence level: 95%
- Compare control vs treatment variants
| Metric | Formula | Purpose |
|---|---|---|
| Exposure Count | COUNT(Perps Screen Viewed) per variant |
Sample size for each variant |
| Engagement Count | COUNT(Perps UI Interaction) per variant |
Raw button taps |
| Engagement Rate | Engagement / Exposure per variant | Primary success metric |
| Lift | (Treatment Rate - Control Rate) / Control Rate | Improvement percentage |
| Statistical Significance | Mixpanel built-in | Confidence in results |
Minimum Sample Size:
- Aim for 1,000+ exposures per variant for reliable results
- Statistical significance typically requires 2-4 weeks of data collection
What to Look For:
- 95% confidence: Results are statistically significant
- Positive lift: Treatment variant outperforms control
- Consistent trend: Results stable over time (not just initial spike)
Decision Framework:
| Result | Action |
|---|---|
| Treatment wins (95% confidence) | Roll out treatment to 100% |
| Control wins (95% confidence) | Keep control, remove test code |
| No significant difference | Consider extending test or keeping control |
Production: LaunchDarkly assigns variants automatically based on user ID and targeting rules.
Local Testing: Temporarily hardcode the variant in your component:
// Temporarily override for testing - REMOVE BEFORE COMMIT!
const buttonColorVariant = 'monochrome';
// Comment out the actual hook call while testing:
// const { variant, variantName } = usePerpsABTest({...});Dev Banner: In __DEV__ builds, a read-only banner shows:
- Current variant name
- Source: "LaunchDarkly" or "Fallback"
- Raw flag value from Redux
Important: Always remove hardcoded overrides before committing.
How User Identification Works:
Mobile sends user context to LaunchDarkly for per-user A/B testing via the RemoteFeatureFlagController:
- MetaMetrics ID (when enabled): Used as the primary LaunchDarkly user key
- Fallback identification: LaunchDarkly seem to maintain its own user segmentation even when MetaMetrics is disabled
- Bucketing: Users are consistently assigned to variants based on their identifier
Flag Type: Use String flag (not Boolean or JSON) for AB tests.
Naming Convention: perps-abtest-{test-name}
Examples:
- Button color test:
perps-abtest-button-color - Asset details test:
perps-abtest-asset-details - Homepage test:
perps-abtest-homepage
Why this pattern?
perps-= Feature area (Perps trading)abtest-= Identifies it as an AB test (vs feature flag){test-name}= What's being tested- No
-enabledsuffix needed (LaunchDarkly has ON/OFF toggle)
Configuration Steps:
-
Create flag:
perps-abtest-button-color(kebab-case in LaunchDarkly UI) -
Flag type: String (from dropdown)
-
String variations:
- Variation 0: Name=
Control, Value=control(default) - Variation 1: Name=
Monochrome, Value=monochrome(treatment)
- Variation 0: Name=
-
Default rule (for all traffic):
- Serve: A percentage rollout
- Split: 50% →
control, 50% →monochrome(adjust percentages as needed) - By:
user | key(buckets users by their LaunchDarkly user key, which is the MetaMetrics ID)
-
Targeting rules: Optional - leave empty for simple A/B test, or add custom rules for gradual rollout
-
Default variations:
- When ON: Serves default rule (percentage rollout)
- When OFF: Serves
control(variation 0)
Example config:
{
"variations": [
{ "name": "Control", "value": "control" },
{ "name": "Monochrome", "value": "monochrome" }
],
"offVariation": 0,
"fallthrough": {
"rollout": {
"variations": [
{ "variation": 0, "weight": 50000 },
{ "variation": 1, "weight": 50000 }
],
"bucketBy": "key"
}
}
}Note: Weights are in basis points (50000 = 50%).
// Redux state structure (kebab-case converted to camelCase)
{
RemoteFeatureFlagController: {
remoteFeatureFlags: {
perpsAbtestButtonColor: 'control'; // Simple string value
}
}
}Selector behavior:
"control"→ Returns control variant data"treatment"→ Returns treatment variant datanull(flag OFF) → Returns first variant (fallback),isEnabled: false- Invalid value → Warns, returns first variant,
isEnabled: true
- Simpler: LaunchDarkly handles assignment, app just reads variant name
- Type-safe: Variant data defined in TypeScript config, not JSON
- Cleaner: No version-gating complexity in flag payload
- Use JSON when: Per-variant version requirements needed (feature flags, not AB tests)
- LaunchDarkly handles persistence: User ID determines assignment deterministically
- No stale data: Always fresh from remote
- Fewer bugs: No sync issues between local storage and LaunchDarkly
- Simpler code: No storage management logic needed
- Graceful degradation: App works even if LaunchDarkly is down
- Predictable behavior: Always show control variant as fallback
- No blank states: User experience never breaks
- Hook:
app/components/UI/Perps/utils/abTesting/usePerpsABTest.ts - Types:
app/components/UI/Perps/utils/abTesting/types.ts - Test configs:
app/components/UI/Perps/utils/abTesting/tests.ts - Selectors:
app/components/UI/Perps/selectors/featureFlags/index.ts - Event constants:
app/components/UI/Perps/constants/eventNames.ts - Button colors:
app/components/UI/Perps/constants/buttonColors.ts
Q: What if LaunchDarkly is down?
A: Selector returns null, hook falls back to first variant, isEnabled is false.
Q: How are users assigned to variants? A: LaunchDarkly uses user ID (wallet address) with deterministic hashing. Same user always gets same variant.
Q: Can I test both variants locally? A: Yes, temporarily hardcode the variant name in your component (see Local Development section).
Q: Why are weights informational only? A: LaunchDarkly controls actual distribution via percentage rollout rules, not client-side weights.
Q: How do I track AB test in analytics?
A: Use isEnabled, variantName in usePerpsEventTracking properties (see Usage example above).
Q: How do I verify my events are reaching analytics? A: Follow the E2E Validation Workflow section to verify events flow from app → Segment → Mixpanel.
Q: How do I create a dashboard to analyze test results? A: See Mixpanel Dashboard for A/B Test Analysis for step-by-step instructions.
Q: My A/B test property is being stripped from events. Why?
A: Segment's Tracking Plan is filtering out properties not defined in the schema. Check the Segment Debugger for protocols.omitted in your event. Add the property to the segment-schema repo. See Segment Schema Requirements.
Q: Do I need to update the Segment schema for every new A/B test?
A: Yes. Each A/B test property (e.g., ab_test_button_color, ab_test_asset_cta) must be added to the Segment schema before deployment, or the property will be silently dropped.
- Perps MetaMetrics Reference - Event property definitions, tracking patterns, and multiple concurrent test support
- Perps Feature Flags Framework - LaunchDarkly integration for feature toggles (vs A/B tests)
- MetaMetrics Debugging Guide - Troubleshooting events, Segment debugger URLs, getting your metrics ID
- Segment Debugger (Dev): https://app.segment.com/consensys-analytics/sources/raw_segment_metamask_mobile_dev/debugger
- Mixpanel: Request access via helpdesk
- LaunchDarkly: Request access via helpdesk