Skip to content

Commit 77a4a14

Browse files
authored
Set up product element 0% test (#14876)
* Make docs clearer about use of kebab case for test name * Add thefilter to ab test team type * Add product element hold back test defintion * Don't render left col cards or inline product cards in the hold back test variant * Amend test id in comments in AB testing doc * Prettier * Set to 0% test
1 parent 1c1cd76 commit 77a4a14

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

ab-testing/abTests.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ const ABTests: ABTest[] = [
4545
groups: ["control", "variant"],
4646
shouldForceMetricsCollection: true,
4747
},
48+
{
49+
name: "thefilter-product-element",
50+
description:
51+
"A hold back test to measure uplift of the product element",
52+
owners: ["[email protected]"],
53+
status: "ON",
54+
expirationDate: "2025-12-30",
55+
type: "server",
56+
audienceSize: 0 / 100,
57+
groups: ["control", "variant"],
58+
shouldForceMetricsCollection: false,
59+
},
4860
];
4961

5062
const activeABtests = ABTests.filter((test) => test.status === "ON");

ab-testing/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type AudienceSpace = Map<string, FastlyTestParams>;
44

55
type AllSpace = Map<string, FastlyTestParams[]>;
66

7-
type Team = "commercial" | "webex";
7+
type Team = "commercial" | "webex" | "thefilter";
88

99
type TestName = `${Team}-${string}`;
1010

dotcom-rendering/docs/development/ab-testing-in-dcr.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ When your PR is merged, the A/B test will be automatically deployed to Fastly an
119119

120120
#### Naming Conventions
121121

122-
A/B tests should be prefixed with the team associated with the test, for example `webex-example-test`. This helps to identify the team responsible for the test and is enforce by typescript validation, you can inspect & edit the allowed team name definitions [here](https://github.com/guardian/dotcom-rendering/blob/main/ab-testing/types.ts#L9).
122+
A/B tests should be prefixed with the team associated with the test, for example `webex-example-test`. This helps to identify the team responsible for the test and is enforced by typescript validation, you can inspect & edit the allowed team name definitions [here](https://github.com/guardian/dotcom-rendering/blob/main/ab-testing/types.ts#L9).
123123

124124
#### Test Size and Groups
125125

@@ -135,7 +135,7 @@ All requests are processed by Fastly at the edge, however, A/B testing of server
135135

136136
Ensure that the `type` field is set to either `client` or `server` to indicate the type of test so that server side tests can be cached correctly, and client side tests are not splitting the cache unnecessarily.
137137

138-
There's a limit of the number of concurrent server-side tests that can be run, enforce by the validation script, so it's important to use client-side tests where possible.
138+
There's a limit of the number of concurrent server-side tests that can be run, enforced by the validation script, so it's important to use client-side tests where possible.
139139

140140
#### Test Expiration
141141

@@ -178,13 +178,13 @@ const someComponent = () => {
178178
const abTests = useBetaAB();
179179

180180
// Am I in the test at all?
181-
const isInTest = abTests?.isUserInTest('AbTestTest') ?? false;
181+
const isInTest = abTests?.isUserInTest('webex-example-test') ?? false;
182182

183183
const isInControlGroup =
184-
(abTests?.isUserInTestGroup('AbTestTest', 'control') ?? false);
184+
(abTests?.isUserInTestGroup('webex-example-test', 'control') ?? false);
185185

186186
const isInVariantGroup =
187-
abTests?.isUserInTestGroup('AbTestTest', 'variant') ?? false;
187+
abTests?.isUserInTestGroup('webex-example-test', 'variant') ?? false;
188188

189189
if (isInControlGroup) {
190190
return (
@@ -223,16 +223,16 @@ const abTests = useBetaAB();
223223
// Get all of the user's server/client-side A/B test participations
224224
const abTestParticipations = abTests?.getParticipations(); // EG. { commercial-dev-client-side-test: 'variant', commercial-dev-server-side-test: 'variant' }
225225

226-
// Is user in the AbTestTest test (any cohort)
227-
const isInTest = abTests?.isUserInTest('AbTestTest') ?? false;
226+
// Is user in the webex-example-test test (any cohort)
227+
const isInTest = abTests?.isUserInTest('webex-example-test') ?? false;
228228

229-
// Is user in the AbTestTest test (control cohort)
229+
// Is user in the webex-example-test test (control cohort)
230230
const isInControlGroup =
231-
abTests?.isUserInTestGroup('AbTestTest', 'control') ?? false;
231+
abTests?.isUserInTestGroup('webex-example-test', 'control') ?? false;
232232

233-
// Is user in the AbTestTest test (variant cohort)
233+
// Is user in the webex-example-test test (variant cohort)
234234
const isInVariantGroup =
235-
abTests?.isUserInTestGroup('AbTestTest', 'variant') ?? false;
235+
abTests?.isUserInTestGroup('webex-example-test', 'variant') ?? false;
236236
```
237237

238238
#### On the Client

dotcom-rendering/src/components/ProductElement.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ReactNode } from 'react';
44
import type { ArticleFormat } from '../lib/articleFormat';
55
import { parseHtml } from '../lib/domUtils';
66
import type { NestedArticleElement } from '../lib/renderElement';
7+
import { useBetaAB } from '../lib/useAB';
78
import type { ProductBlockElement } from '../types/content';
89
import { ProductCardInline } from './ProductCardInline';
910
import { ProductCardLeftCol } from './ProductCardLeftCol';
@@ -39,20 +40,32 @@ export const ProductElement = ({
3940
format: ArticleFormat;
4041
shouldShowLeftColCard: boolean;
4142
}) => {
43+
const abTests = useBetaAB();
44+
const isInHoldBackTestVariant =
45+
abTests?.isUserInTestGroup('thefilter-product-element', 'variant') ??
46+
false;
47+
4248
const showContent =
4349
product.displayType === 'InlineOnly' ||
4450
product.displayType === 'InlineWithProductCard';
51+
// In the hold back test variant, if the product element has a display type of ProductCardOnly,
52+
// we should still render the product card. This is because there may not be any suitable
53+
// nested content to render, which could result in some unintended display issues. For the
54+
// InlineWithProductCard display type, we won't render the cards in the hold back test.
4555
const showProductCard =
4656
product.displayType === 'ProductCardOnly' ||
47-
product.displayType === 'InlineWithProductCard';
57+
(!isInHoldBackTestVariant &&
58+
product.displayType === 'InlineWithProductCard');
4859
return (
4960
<>
5061
{showContent && (
5162
<Content
5263
product={product}
5364
format={format}
5465
ArticleElementComponent={ArticleElementComponent}
55-
shouldShowLeftColCard={shouldShowLeftColCard}
66+
shouldShowLeftColCard={
67+
shouldShowLeftColCard && !isInHoldBackTestVariant
68+
}
5669
/>
5770
)}
5871
{showProductCard && (

0 commit comments

Comments
 (0)