Skip to content

Commit 4c7a838

Browse files
test: adds diagnostic outputs for E2E in feature flags
1 parent 87709c9 commit 4c7a838

5 files changed

Lines changed: 524 additions & 280 deletions

File tree

app/core/Engine/controllers/remote-feature-flag-controller-init.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,33 @@ import {
1414
isRemoteFeatureFlagOverrideActivated,
1515
} from './remote-feature-flag-controller';
1616
import { getBaseSemVerVersion } from '../../../util/version';
17+
import {
18+
getE2ERemoteFeatureFlagDiagnostics,
19+
isE2E,
20+
postE2EDiagnostics,
21+
} from '../../../util/test/utils';
22+
23+
const getDiagnosticErrorMessage = (error: unknown) =>
24+
error instanceof Error ? error.message : String(error);
25+
26+
const postRemoteFeatureFlagDiagnostics = (
27+
controller: RemoteFeatureFlagController,
28+
phase: string,
29+
error?: unknown,
30+
) => {
31+
if (!isE2E) {
32+
return;
33+
}
34+
35+
postE2EDiagnostics(
36+
getE2ERemoteFeatureFlagDiagnostics(controller.state, {
37+
phase,
38+
...(error === undefined
39+
? {}
40+
: { error: getDiagnosticErrorMessage(error) }),
41+
}),
42+
);
43+
};
1744

1845
/**
1946
* Initialize the remote feature flag controller.
@@ -52,15 +79,21 @@ export const remoteFeatureFlagControllerInit: MessengerClientInitFunction<
5279

5380
if (disabled) {
5481
Logger.log('Feature flag controller disabled.');
82+
postRemoteFeatureFlagDiagnostics(controller, 'disabled');
5583
} else if (isRemoteFeatureFlagOverrideActivated) {
5684
Logger.log('Remote feature flags override activated.');
85+
postRemoteFeatureFlagDiagnostics(controller, 'override-activated');
5786
} else {
5887
controller
5988
.updateRemoteFeatureFlags()
6089
.then(() => {
6190
Logger.log('Feature flags updated');
91+
postRemoteFeatureFlagDiagnostics(controller, 'update-success');
6292
})
63-
.catch((error) => Logger.log('Feature flags update failed: ', error));
93+
.catch((error) => {
94+
Logger.log('Feature flags update failed: ', error);
95+
postRemoteFeatureFlagDiagnostics(controller, 'update-failed', error);
96+
});
6497
}
6598

6699
return {

app/util/test/utils.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,64 @@ export const getE2ETestConfigDiagnostics = (extra = {}) => ({
8484
...extra,
8585
});
8686

87+
const getObjectValue = (value, key) => {
88+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
89+
return undefined;
90+
}
91+
92+
return value[key];
93+
};
94+
95+
const getObjectKeysDiagnostic = (value) => {
96+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
97+
return 'missing';
98+
}
99+
100+
const keys = Object.keys(value).sort();
101+
return keys.length > 0 ? keys.join(',') : 'none';
102+
};
103+
104+
export const getE2ERemoteFeatureFlagDiagnostics = (state = {}, extra = {}) => {
105+
const remoteFeatureFlags = getObjectValue(state, 'remoteFeatureFlags');
106+
const rawRemoteFeatureFlags = getObjectValue(state, 'rawRemoteFeatureFlags');
107+
const localOverrides = getObjectValue(state, 'localOverrides');
108+
109+
return {
110+
source: extra.source ?? 'RemoteFeatureFlagController',
111+
phase: extra.phase ?? 'unknown',
112+
explorePageV2EnabledInApp: formatE2EDiagnosticValue(
113+
getObjectValue(remoteFeatureFlags, 'explorePageV2Enabled'),
114+
),
115+
explorePageV2EnabledRaw: formatE2EDiagnosticValue(
116+
getObjectValue(rawRemoteFeatureFlags, 'explorePageV2Enabled'),
117+
),
118+
explorePageV2EnabledOverride: formatE2EDiagnosticValue(
119+
getObjectValue(localOverrides, 'explorePageV2Enabled'),
120+
),
121+
remoteFeatureFlagsCacheTimestamp: formatE2EDiagnosticValue(
122+
getObjectValue(state, 'cacheTimestamp'),
123+
),
124+
remoteFeatureFlagsKeys: getObjectKeysDiagnostic(remoteFeatureFlags),
125+
rawRemoteFeatureFlagsKeys: getObjectKeysDiagnostic(rawRemoteFeatureFlags),
126+
localOverridesKeys: getObjectKeysDiagnostic(localOverrides),
127+
...extra,
128+
};
129+
};
130+
131+
export const postE2EDiagnostics = async (diagnostics) => {
132+
const postDiagnostics = testConfig.postE2EDiagnostics;
133+
134+
if (typeof postDiagnostics !== 'function') {
135+
return;
136+
}
137+
138+
try {
139+
await postDiagnostics(diagnostics);
140+
} catch {
141+
// Diagnostics must never affect app startup or test behavior.
142+
}
143+
};
144+
87145
export const appendE2EDiagnosticsToUrl = (url, diagnostics) => {
88146
const nextUrl = new URL(url);
89147
Object.entries(diagnostics).forEach(([key, value]) => {

0 commit comments

Comments
 (0)