diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 783ddb5138..f9eb5605c2 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -86,12 +86,17 @@ const App = () => { const [useProviderSignupView, setUseProviderSignupView] = useState(false) // Check PostHog feature flag for provider signup view + // Wait for telemetry to be initialized before checking feature flags useEffect(() => { + if (!didHydrateState || telemetrySetting === "disabled") { + return + } + posthog.onFeatureFlags(function () { // Feature flag for new provider-focused welcome view setUseProviderSignupView(posthog?.getFeatureFlag("welcome-provider-signup") === "test") }) - }, []) + }, [didHydrateState, telemetrySetting]) // Create a persistent state manager const marketplaceStateManager = useMemo(() => new MarketplaceViewStateManager(), []) diff --git a/webview-ui/src/__tests__/App.spec.tsx b/webview-ui/src/__tests__/App.spec.tsx index cf6bf9051b..09db361c12 100644 --- a/webview-ui/src/__tests__/App.spec.tsx +++ b/webview-ui/src/__tests__/App.spec.tsx @@ -2,9 +2,18 @@ import React from "react" import { render, screen, act, cleanup } from "@/utils/test-utils" +import posthog from "posthog-js" import AppWithProviders from "../App" +// Mock posthog +vi.mock("posthog-js", () => ({ + default: { + onFeatureFlags: vi.fn(), + getFeatureFlag: vi.fn(), + }, +})) + vi.mock("@src/utils/vscode", () => ({ vscode: { postMessage: vi.fn(), @@ -189,6 +198,7 @@ describe("App", () => { shouldShowAnnouncement: false, experiments: {}, language: "en", + telemetrySetting: "enabled", }) }) @@ -338,4 +348,54 @@ describe("App", () => { expect(chatView.getAttribute("data-hidden")).toBe("false") expect(screen.queryByTestId("marketplace-view")).not.toBeInTheDocument() }) + + describe("PostHog feature flag initialization", () => { + it("waits for state hydration before checking feature flags", () => { + mockUseExtensionState.mockReturnValue({ + didHydrateState: false, + showWelcome: false, + shouldShowAnnouncement: false, + experiments: {}, + language: "en", + telemetrySetting: "enabled", + }) + + render() + + // PostHog feature flag check should not be called before hydration + expect(posthog.onFeatureFlags).not.toHaveBeenCalled() + }) + + it("checks feature flags after state hydration when telemetry is enabled", () => { + mockUseExtensionState.mockReturnValue({ + didHydrateState: true, + showWelcome: false, + shouldShowAnnouncement: false, + experiments: {}, + language: "en", + telemetrySetting: "enabled", + }) + + render() + + // PostHog feature flag check should be called after hydration + expect(posthog.onFeatureFlags).toHaveBeenCalled() + }) + + it("does not check feature flags when telemetry is disabled", () => { + mockUseExtensionState.mockReturnValue({ + didHydrateState: true, + showWelcome: false, + shouldShowAnnouncement: false, + experiments: {}, + language: "en", + telemetrySetting: "disabled", + }) + + render() + + // PostHog feature flag check should not be called when telemetry is disabled + expect(posthog.onFeatureFlags).not.toHaveBeenCalled() + }) + }) })