From efb359f3184ec26a21044b6145586cf1f5afc438 Mon Sep 17 00:00:00 2001 From: Hubert Gendron Date: Fri, 23 Jul 2021 13:02:57 -0700 Subject: [PATCH] Fix testID support for TextInput, Slider and ScrollView component (#31865) Summary: With the advent of https://github.com/facebook/react-native/issues/29610, we are now able to use the `testID` view prop on Android in black-box testing framework through the view's `resource-id`. But after testing it, I noticed that on the `TextInput`, `Slider` and `ScrollView` components, the `testID` prop was not exposed as the `resource-id` properly. The main issue was that those component was using the `AccessibilityDelegateCompat` instead of the `ReactAccessibilityDelegate`. ## Changelog [Android] [Fixed] - Fix `testID` prop for `TextInput`, `Slider` and `ScrollView` components Pull Request resolved: https://github.com/facebook/react-native/pull/31865 Test Plan: ![test-screenshot](https://user-images.githubusercontent.com/69216913/125802180-c0791a8c-a740-4657-a44f-42b1885eee39.png) Reviewed By: mdvacca Differential Revision: D29765333 Pulled By: yungsters fbshipit-source-id: 2b8e362257e3e5fdcd20330280c588dabb44f28a --- .../java/com/facebook/react/views/scroll/BUCK | 1 + .../react/views/scroll/ReactScrollView.java | 16 ++++++++++++++++ .../react/views/slider/ReactSliderManager.java | 4 ++-- .../react/views/textinput/ReactEditText.java | 4 ++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK index 60f607899a..4cfccd3814 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK @@ -30,5 +30,6 @@ rn_android_library( react_native_target("java/com/facebook/react/uimanager:uimanager"), react_native_target("java/com/facebook/react/uimanager/annotations:annotations"), react_native_target("java/com/facebook/react/views/view:view"), + react_native_target("res:uimanager"), ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index e56ddb8ace..5fcd6ef8bc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -20,12 +20,14 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.OverScroller; import android.widget.ScrollView; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; +import com.facebook.react.R; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap; @@ -117,6 +119,20 @@ public class ReactScrollView extends ScrollView setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY); } + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + + // Expose the testID prop as the resource-id name of the view. Black-box E2E/UI testing + // frameworks, which interact with the UI through the accessibility framework, do not have + // access to view tags. This allows developers/testers to avoid polluting the + // content-description with test identifiers. + final String testId = (String) this.getTag(R.id.react_test_id); + if (testId != null) { + info.setViewIdResourceName(testId); + } + } + @Nullable private OverScroller getOverScrollerFromParent() { OverScroller scroller; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java index 3d7d8fdec0..8d2a73dd3b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java @@ -16,7 +16,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.SeekBar; import androidx.annotation.Nullable; -import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; import com.facebook.react.bridge.ReactContext; @@ -24,6 +23,7 @@ import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.PixelUtil; +import com.facebook.react.uimanager.ReactAccessibilityDelegate; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; @@ -278,7 +278,7 @@ public class ReactSliderManager extends SimpleViewManager return mDelegate; } - protected static class ReactSliderAccessibilityDelegate extends AccessibilityDelegateCompat { + protected static class ReactSliderAccessibilityDelegate extends ReactAccessibilityDelegate { private static boolean isSliderAction(int action) { return (action == AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId()) || (action == AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId()) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index 6aed922399..1e676fa7df 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -36,7 +36,6 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatEditText; -import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; @@ -44,6 +43,7 @@ import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactSoftException; import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.uimanager.FabricViewStateManager; +import com.facebook.react.uimanager.ReactAccessibilityDelegate; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.views.text.CustomLetterSpacingSpan; @@ -155,7 +155,7 @@ public class ReactEditText extends AppCompatEditText ViewCompat.setAccessibilityDelegate( this, - new AccessibilityDelegateCompat() { + new ReactAccessibilityDelegate() { @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (action == AccessibilityNodeInfo.ACTION_CLICK) {