From be13acb5c5257a01758e05b6af2dc37690870f4d Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Tue, 14 Jul 2026 09:47:41 -0700 Subject: [PATCH] Promote fuseboxScreenshotCaptureEnabled to stable (#57540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This feature is fully implemented, stable, and isolated — enable for all. See also https://github.com/react/react-native-devtools-frontend/pull/252. Changelog: [General][Added] - **React Native DevTools**: Users and agents can now capture app screenshots via the `Page.captureScreenshot` command Differential Revision: D111894234 --- .../featureflags/ReactNativeFeatureFlagsDefaults.kt | 4 ++-- ...iveFeatureFlagsOverrides_RNOSS_Experimental_Android.kt | 4 +--- .../jsinspector-modern/tests/HostTargetTest.cpp | 8 ++++++-- .../react/featureflags/ReactNativeFeatureFlagsDefaults.h | 4 ++-- .../ReactNativeFeatureFlagsOverridesOSSExperimental.h | 6 +----- .../featureflags/ReactNativeFeatureFlags.config.js | 4 ++-- .../src/private/featureflags/ReactNativeFeatureFlags.js | 4 ++-- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 91f9ac37c7ec..84d84dab8774 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9b295106ef57d7fa85846c57bb74a090>> + * @generated SignedSource<> */ /** @@ -141,7 +141,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun fuseboxNetworkInspectionEnabled(): Boolean = true - override fun fuseboxScreenshotCaptureEnabled(): Boolean = false + override fun fuseboxScreenshotCaptureEnabled(): Boolean = true override fun optimizedAnimatedPropUpdates(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt index 51aa291410be..34f1d6be7af8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<41f83a9921de88f659ddc22172344226>> */ /** @@ -31,8 +31,6 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android : override fun fuseboxFrameRecordingEnabled(): Boolean = true - override fun fuseboxScreenshotCaptureEnabled(): Boolean = true - override fun preventShadowTreeCommitExhaustion(): Boolean = true override fun useSharedAnimatedBackend(): Boolean = true diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp index e42d4b3cbfec..cc642a81c2dd 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp @@ -1632,11 +1632,15 @@ TEST_F(HostTargetTest, TracingDelegateIsNotifiedOnDirectTracingCall) { page_->stopTracing(); } -TEST_F(HostTargetProtocolTest, CaptureScreenshotNotSupportedWhenFlagDisabled) { +TEST_F(HostTargetProtocolTest, CaptureScreenshotReturnsData) { + EXPECT_CALL(hostTargetDelegate_, captureScreenshot(_)) + .WillOnce(Return(std::optional("c2NyZWVuc2hvdA=="))) + .RetiresOnSaturation(); EXPECT_CALL( fromPage(), onMessage(JsonParsed(AllOf( - AtJsonPtr("/error/code", Eq(-32601)), AtJsonPtr("/id", Eq(1)))))) + AtJsonPtr("/id", Eq(1)), + AtJsonPtr("/result/data", Eq("c2NyZWVuc2hvdA==")))))) .RetiresOnSaturation(); toPage_->sendMessage(R"({ "id": 1, diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index ca9ab82ce1ec..90c8af9a4fb8 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2c09412cdf8edaf4f7d6d90a446ce6fa>> + * @generated SignedSource<<2c7b47ef5ae156d4e5396cf8b047f187>> */ /** @@ -264,7 +264,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } bool fuseboxScreenshotCaptureEnabled() override { - return false; + return true; } bool optimizedAnimatedPropUpdates() override { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h index 1b1667bb726d..2618b40257bd 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<630f900c13eb68232717fc28528253e2>> */ /** @@ -43,10 +43,6 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur return true; } - bool fuseboxScreenshotCaptureEnabled() override { - return true; - } - bool preventShadowTreeCommitExhaustion() override { return true; } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 54ffc48eefc9..c88fbfb149f9 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -680,7 +680,7 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, fuseboxScreenshotCaptureEnabled: { - defaultValue: false, + defaultValue: true, metadata: { dateAdded: '2026-04-01', description: @@ -688,7 +688,7 @@ const definitions: FeatureFlagDefinitions = { expectedReleaseValue: true, purpose: 'experimentation', }, - ossReleaseStage: 'experimental', + ossReleaseStage: 'stable', }, optimizedAnimatedPropUpdates: { defaultValue: false, diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a9c690414348..5273df8d006f 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<71e307d568421d49e3943f58c4fcb163>> + * @generated SignedSource<<411c2e601987e01db778a82b6237a407>> * @flow strict * @noformat */ @@ -450,7 +450,7 @@ export const fuseboxNetworkInspectionEnabled: Getter = createNativeFlag /** * Enable Page.captureScreenshot CDP method support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes. */ -export const fuseboxScreenshotCaptureEnabled: Getter = createNativeFlagGetter('fuseboxScreenshotCaptureEnabled', false); +export const fuseboxScreenshotCaptureEnabled: Getter = createNativeFlagGetter('fuseboxScreenshotCaptureEnabled', true); /** * When enabled, uses optimized platform-specific paths to apply animated props synchronously. On Android, this uses a batched int/double buffer protocol with a single JNI call. On iOS, this passes AnimatedProps directly through the delegate chain and applies them via cloneProps, avoiding the folly::dynamic round-trip. */