test(session-replay-browser): add TRC e2e harness (local + published modes)#1853
Open
bravecod wants to merge 2 commits into
Open
test(session-replay-browser): add TRC e2e harness (local + published modes)#1853bravecod wants to merge 2 commits into
bravecod wants to merge 2 commits into
Conversation
…ished modes A React harness for reproducing/verifying URL Targeted Recording (TRC) end to end against real remote config. Self-contained under test-server with its own vite config so its @amplitude alias strategy doesn't affect the other test pages. Two build modes via the SR_MODE env var: - pnpm dev:trc -> local: bundles the workspace builds (packages/*). - pnpm dev:trc:npm -> published: bundles the released packages pinned under the *-srnpm aliases in root package.json, so the plugin's transitive deps (session-replay-browser, targeting, ...) come from the published artifact. User-editable config in-page: apiKey, serverZone, logLevel, and URL-change polling (enable + interval). Surfaces the live mode and the real /v1/capture diagnostics POSTs (counters/events with srId/variant/trigger). Routes include a price-plan path for the common URL-contains rule. Both modes verified to build clean; published bundle confirmed to carry the page-in-context targeting fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Manual track uses unset global
- The manual track button now calls the imported Amplitude module directly instead of relying on an unset window global.
- ✅ Fixed: Fetch patch stacks on retry
- The capture fetch interceptor is now idempotent and is restored when initialization fails so retries do not stack wrappers.
Or push these changes by commenting:
@cursor push 3bf394f52a
Preview (3bf394f52a)
diff --git a/test-server/session-replay-browser/trc-e2e/main.jsx b/test-server/session-replay-browser/trc-e2e/main.jsx
--- a/test-server/session-replay-browser/trc-e2e/main.jsx
+++ b/test-server/session-replay-browser/trc-e2e/main.jsx
@@ -20,9 +20,15 @@
// In plugin mode the diagnostics client is internal to the SDK, so we can't inject a spy. Instead we
// intercept fetch and surface the real POSTs to .../v1/capture — that's the actual diagnostics
// payload (counters/histograms/events) the SDK ships. Install before init().
+let restoreCaptureInterceptor;
+
function installCaptureInterceptor(onCapture) {
- const orig = window.fetch.bind(window);
- window.fetch = async (input, init) => {
+ if (restoreCaptureInterceptor) {
+ return restoreCaptureInterceptor;
+ }
+
+ const orig = window.fetch;
+ const interceptedFetch = async (input, init) => {
const url = typeof input === 'string' ? input : input?.url ?? '';
if (url.includes('/v1/capture')) {
try {
@@ -32,8 +38,17 @@
onCapture({ url, body: undefined, at: new Date().toLocaleTimeString() });
}
}
- return orig(input, init);
+ return orig.call(window, input, init);
};
+
+ window.fetch = interceptedFetch;
+ restoreCaptureInterceptor = () => {
+ if (window.fetch === interceptedFetch) {
+ window.fetch = orig;
+ }
+ restoreCaptureInterceptor = undefined;
+ };
+ return restoreCaptureInterceptor;
}
// Routes to exercise URL targeting. Whether each records depends on YOUR project's TRC rules.
@@ -55,7 +70,7 @@
</p>
{id && <p>route param id = {id}</p>}
<p>SPA navigation (no reload) fires URL-change targeting re-eval; tracked events also trigger eval.</p>
- <button onClick={() => window.amplitude.track('manual_test_event', { from: title })}>
+ <button onClick={() => amplitude.track('manual_test_event', { from: title })}>
amplitude.track('manual_test_event')
</button>
</div>
@@ -251,9 +266,10 @@
const handleStart = async (opts) => {
if (initedRef.current) return;
initedRef.current = true;
+ let restoreCaptureInterceptorOnFailure;
try {
// Surface real /v1/capture POSTs (install before init so init-time flushes are caught).
- installCaptureInterceptor((cap) => setCaptures((prev) => [...prev, cap]));
+ restoreCaptureInterceptorOnFailure = installCaptureInterceptor((cap) => setCaptures((prev) => [...prev, cap]));
// The analytics SDK's own diagnostics default to sampleRate 0; sample them in if supported.
// (The SR plugin creates its own Debug-gated diagnostics client regardless.)
@@ -282,6 +298,7 @@
);
setStarted(true);
} catch (err) {
+ restoreCaptureInterceptorOnFailure?.();
initedRef.current = false;
window.srError = err.message;
// eslint-disable-next-line no-alertYou can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 6328106. Configure here.
Session Replay Browser E2E ResultsDetails
Flaky testschromium › e2e/trc-url-rule.spec.ts › TRC URL rule — happy path › starts recording after SPA navigation to a matching URL |
size-limit report 📦
|
…track global Address Bugbot review on the TRC e2e harness: - track button used window.amplitude (never assigned) and threw; assign window.amplitude/sessionReplay for console use and call the imported amplitude.track directly from the button. - installCaptureInterceptor re-wrapped window.fetch on a retried Start, duplicating captures; patch fetch once and route to the latest sink. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jxiwang
approved these changes
Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What
A React Targeted Recording (TRC) e2e harness for reproducing and verifying URL-based Session Replay targeting end to end against real remote config. Lives under
test-server/session-replay-browser/trc-e2e/with its own vite config, so its@amplitude/*alias strategy is isolated from the other test pages.Two build modes (SR_MODE env var)
pnpm dev:trcpackages/*(paired with the watch task)pnpm dev:trc:npm*-srnpmaliases in rootpackage.jsonIn published mode the two app-facing imports (
analytics-browser,plugin-session-replay-browser) redirect to the*-srnpminstalls, and the plugin's transitive deps (session-replay-browser,targeting,analytics-core, ...) resolve from that published package's ownnode_modules— i.e. a true published-artifact test, not a workspace mix. The pinned versions are editable in rootpackage.json.Config & observability
/v1/capturediagnostics POSTs (counters + events withsrId/variant/trigger), so you can watch TRC evaluation without DataDog./settings/price-plan/detailsfor the common "URL contains" rule, plus pushState/replaceState/back-forward controls to exercise SPA navigation re-eval.Why
We had no committed, repeatable way to test TRC locally — the prior harness lived only on a debug branch / a throwaway folder. This makes both "does my workspace change behave?" (local) and "does the published package behave?" (npm) reproducible from one place.
Testing
vite buildclean.@amplitude/targeting@0.3.0-…), local-mode bundles the workspace builds.Notes / blast radius
test-servervite config is untouched (dedicated config avoids breaking other pages'@amplituderesolution).react/react-dom/react-router-dom,@vitejs/plugin-react, and the two*-srnpmnpm: aliases.lint-stagedonly touches*.ts, so the new.jsx/.mjsaren't linted.🤖 Generated with Claude Code
Note
Low Risk
Changes are limited to a dev/test harness and root devDependencies/scripts; production packages and the shared test-server Vite config are not modified.
Overview
Adds a Targeted Recording (TRC) e2e harness under
test-server/session-replay-browser/trc-e2e/with its own Vite + React SPA so Session Replay URL targeting can be exercised against real remote config without touching the shared test-server Vite setup.Root
package.jsongainsdev:trc(watch + local workspace@amplitude/*aliases) anddev:trc:npm(SR_MODE=npm, bundles pinned*-srnpmpublished packages). Dev-only deps include React,@vitejs/plugin-react, workspace SR packages, and the npm alias pins.The harness lets you configure apiKey/serverZone/logLevel and URL-change polling, shows local vs npm mode, intercepts real
/v1/capturediagnostics POSTs, and provides SPA routes/navigation controls (including/settings/price-plan/details) to re-test targeting on navigation.Reviewed by Cursor Bugbot for commit 4a309d1. Bugbot is set up for automated code reviews on this repo. Configure here.