Skip to content

Commit

Permalink
fix(experiments): Apply correct filters to "View recordings" (#27849)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbachhuber authored Jan 24, 2025
1 parent b909fd1 commit 9c4d9e8
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"kind": "ExperimentFunnelsQuery",
"funnels_query": {
"kind": "FunnelsQuery",
"series": [
{
"kind": "EventsNode",
"name": "[jan-16-running] seen",
"event": "[jan-16-running] seen"
},
{
"kind": "EventsNode",
"name": "[jan-16-running] payment",
"event": "[jan-16-running] payment"
}
],
"dateRange": {
"date_to": "2025-01-16T23:59",
"date_from": "2025-01-02T13:54",
"explicitDate": true
},
"funnelsFilter": {
"layout": "horizontal",
"funnelVizType": "steps",
"funnelWindowInterval": 14,
"funnelWindowIntervalUnit": "day"
},
"filterTestAccounts": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"kind": "ExperimentTrendsQuery",
"count_query": {
"kind": "TrendsQuery",
"series": [
{
"kind": "ActionsNode",
"id": 8,
"name": "jan-16-running payment action",
"math": "total"
}
],
"interval": "day",
"dateRange": {
"date_to": "2025-01-16T23:59",
"date_from": "2025-01-02T13:54",
"explicitDate": true
},
"trendsFilter": {
"display": "ActionsLineGraph"
},
"filterTestAccounts": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"kind": "ExperimentTrendsQuery",
"count_query": {
"kind": "TrendsQuery",
"series": [
{
"kind": "EventsNode",
"math": "total",
"name": "[jan-16-running] event one",
"event": "[jan-16-running] event one"
}
],
"interval": "day",
"dateRange": {
"date_to": "2025-01-16T23:59",
"date_from": "2025-01-02T13:54",
"explicitDate": true
},
"trendsFilter": {
"display": "ActionsLineGraph"
},
"filterTestAccounts": true
},
"exposure_query": {
"kind": "TrendsQuery",
"series": [
{
"kind": "EventsNode",
"math": "dau",
"name": "[jan-16-running] event zero",
"event": "[jan-16-running] event zero"
}
],
"interval": "day",
"dateRange": {
"date_to": "2025-01-23T23:59",
"date_from": "2025-01-09T15:10",
"explicitDate": true
},
"trendsFilter": {
"display": "ActionsLineGraph"
},
"filterTestAccounts": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"kind": "ExperimentTrendsQuery",
"count_query": {
"kind": "TrendsQuery",
"series": [
{
"kind": "EventsNode",
"math": "total",
"name": "[jan-16-running] event one",
"event": "[jan-16-running] event one"
}
],
"interval": "day",
"dateRange": {
"date_to": "2025-01-16T23:59",
"date_from": "2025-01-02T13:54",
"explicitDate": true
},
"trendsFilter": {
"display": "ActionsLineGraph"
},
"filterTestAccounts": true
}
}
41 changes: 4 additions & 37 deletions frontend/src/scenes/experiments/ExperimentView/SummaryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ import { ExperimentFunnelsQuery, ExperimentTrendsQuery } from '~/queries/schema'
import {
FilterLogicalOperator,
InsightType,
PropertyFilterType,
PropertyOperator,
RecordingUniversalFilters,
ReplayTabs,
TrendExperimentVariant,
UniversalFiltersGroupValue,
} from '~/types'

import { experimentLogic } from '../experimentLogic'
import { getViewRecordingFilters } from '../utils'
import { VariantTag } from './components'

export function SummaryTable({
Expand Down Expand Up @@ -309,47 +307,16 @@ export function SummaryTable({
title: '',
render: function Key(_, item): JSX.Element {
const variantKey = item.key

const filters = getViewRecordingFilters(metric, experiment.feature_flag_key, variantKey)
return (
<LemonButton
size="xsmall"
icon={<IconRewindPlay />}
tooltip="Watch recordings of people who were exposed to this variant."
disabledReason={filters.length === 0 ? 'Unable to identify recordings for this metric' : undefined}
type="secondary"
onClick={() => {
const filters: UniversalFiltersGroupValue[] = [
{
id: '$feature_flag_called',
name: '$feature_flag_called',
type: 'events',
properties: [
{
key: `$feature/${experiment.feature_flag_key}`,
type: PropertyFilterType.Event,
value: [variantKey],
operator: PropertyOperator.Exact,
},
{
key: `$feature/${experiment.feature_flag_key}`,
type: PropertyFilterType.Event,
value: 'is_set',
operator: PropertyOperator.IsSet,
},
{
key: '$feature_flag',
type: PropertyFilterType.Event,
value: experiment.feature_flag_key,
operator: PropertyOperator.Exact,
},
],
},
]
if (experiment.filters.insight === InsightType.FUNNELS) {
if (experiment.filters?.events?.[0]) {
filters.push(experiment.filters.events[0])
} else if (experiment.filters?.actions?.[0]) {
filters.push(experiment.filters.actions[0])
}
}
const filterGroup: Partial<RecordingUniversalFilters> = {
filter_group: {
type: FilterLogicalOperator.And,
Expand Down
154 changes: 152 additions & 2 deletions frontend/src/scenes/experiments/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { EntityType, FeatureFlagFilters, InsightType } from '~/types'
import metricFunnelEventsJson from '~/mocks/fixtures/api/experiments/_metric_funnel_events.json'
import metricTrendActionJson from '~/mocks/fixtures/api/experiments/_metric_trend_action.json'
import metricTrendCustomExposureJson from '~/mocks/fixtures/api/experiments/_metric_trend_custom_exposure.json'
import metricTrendFeatureFlagCalledJson from '~/mocks/fixtures/api/experiments/_metric_trend_feature_flag_called.json'
import { ExperimentFunnelsQuery, ExperimentTrendsQuery } from '~/queries/schema/schema-general'
import { EntityType, FeatureFlagFilters, InsightType, PropertyFilterType, PropertyOperator } from '~/types'

import { getNiceTickValues } from './MetricsView/MetricsView'
import { getMinimumDetectableEffect, transformFiltersForWinningVariant } from './utils'
import { getMinimumDetectableEffect, getViewRecordingFilters, transformFiltersForWinningVariant } from './utils'

describe('utils', () => {
it('Funnel experiment returns correct MDE', async () => {
Expand Down Expand Up @@ -235,3 +240,148 @@ describe('getNiceTickValues', () => {
expect(getNiceTickValues(8.5)).toEqual([-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10])
})
})

describe('getViewRecordingFilters', () => {
const featureFlagKey = 'jan-16-running'

it('returns the correct filters for a funnel metric', () => {
const filters = getViewRecordingFilters(
metricFunnelEventsJson as ExperimentFunnelsQuery,
featureFlagKey,
'control'
)
expect(filters).toEqual([
{
id: '[jan-16-running] seen',
name: '[jan-16-running] seen',
type: 'events',
properties: [
{
key: `$feature/${featureFlagKey}`,
type: PropertyFilterType.Event,
value: ['control'],
operator: PropertyOperator.Exact,
},
],
},
{
id: '[jan-16-running] payment',
name: '[jan-16-running] payment',
type: 'events',
properties: [
{
key: `$feature/${featureFlagKey}`,
type: PropertyFilterType.Event,
value: ['control'],
operator: PropertyOperator.Exact,
},
],
},
])
})
it('returns the correct filters for a trend metric', () => {
const filters = getViewRecordingFilters(
metricTrendFeatureFlagCalledJson as ExperimentTrendsQuery,
featureFlagKey,
'test'
)
expect(filters).toEqual([
{
id: '$feature_flag_called',
name: '$feature_flag_called',
type: 'events',
properties: [
{
key: '$feature_flag_response',
type: PropertyFilterType.Event,
value: ['test'],
operator: PropertyOperator.Exact,
},
{
key: '$feature_flag',
type: PropertyFilterType.Event,
value: 'jan-16-running',
operator: PropertyOperator.Exact,
},
],
},
{
id: '[jan-16-running] event one',
name: '[jan-16-running] event one',
type: 'events',
properties: [
{
key: `$feature/${featureFlagKey}`,
type: PropertyFilterType.Event,
value: ['test'],
operator: PropertyOperator.Exact,
},
],
},
])
})
it('returns the correct filters for a trend metric with custom exposure', () => {
const filters = getViewRecordingFilters(
metricTrendCustomExposureJson as ExperimentTrendsQuery,
featureFlagKey,
'test'
)
expect(filters).toEqual([
{
id: '[jan-16-running] event zero',
name: '[jan-16-running] event zero',
type: 'events',
properties: [
{
key: `$feature/${featureFlagKey}`,
type: PropertyFilterType.Event,
value: ['test'],
operator: PropertyOperator.Exact,
},
],
},
{
id: '[jan-16-running] event one',
name: '[jan-16-running] event one',
type: 'events',
properties: [
{
key: `$feature/${featureFlagKey}`,
type: PropertyFilterType.Event,
value: ['test'],
operator: PropertyOperator.Exact,
},
],
},
])
})
it('returns the correct filters for a trend metric with an action', () => {
const filters = getViewRecordingFilters(metricTrendActionJson as ExperimentTrendsQuery, featureFlagKey, 'test')
expect(filters).toEqual([
{
id: '$feature_flag_called',
name: '$feature_flag_called',
type: 'events',
properties: [
{
key: '$feature_flag_response',
type: PropertyFilterType.Event,
value: ['test'],
operator: PropertyOperator.Exact,
},
{
key: '$feature_flag',
type: PropertyFilterType.Event,
value: 'jan-16-running',
operator: PropertyOperator.Exact,
},
],
},
{
id: 8,
name: 'jan-16-running payment action',
type: 'actions',
},
])
})
})
Loading

0 comments on commit 9c4d9e8

Please sign in to comment.