-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Hi! 👋
Firstly, thanks for your work on this project! 🙂
Today I used patch-package to patch react-native-google-places-textinput@0.9.1 for the project I'm working on.
To be able to create proper testing flow with maestro I needed to add testID props to the suggestion dropdown.
I have updated the code to add testID to GooglePlacesTextInputProps and propagate it to each component of GooglePlacesTextInput with the component name + testID value
if testID==location
container-location - Main container View
input-wrapper-location - Input wrapper View
textinput-location - TextInput
clear-button-location - Clear button TouchableOpacity
loading-indicator-location - ActivityIndicator
suggestions-container-location - Suggestions container View
suggestions-list-location - FlatList
suggestion-touchableopacity-0-location - Suggestion item TouchableOpacity (index 0)
suggestion-text-0-location - Suggestion main text (index 0)
suggestion-secondarytext-0-location - Suggestion secondary text (index 0)
Here is the diff that solved my problem:
diff --git a/node_modules/react-native-google-places-textinput/lib/module/GooglePlacesTextInput.js b/node_modules/react-native-google-places-textinput/lib/module/GooglePlacesTextInput.js
index b12e7bf..ee8e06c 100644
--- a/node_modules/react-native-google-places-textinput/lib/module/GooglePlacesTextInput.js
+++ b/node_modules/react-native-google-places-textinput/lib/module/GooglePlacesTextInput.js
@@ -42,6 +42,7 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
onBlur,
accessibilityLabels = {},
suggestionTextProps = {},
+ testID,
...restTextInputProps
}, ref) => {
const [predictions, setPredictions] = useState([]);
@@ -288,6 +289,8 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
}
}, 10);
};
+ // Test ID suffix for all components
+ const testIDSuffix = testID ? `-${testID}` : '';
const renderSuggestion = ({
item,
index
@@ -303,6 +306,7 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
const defaultAccessibilityLabel = `${mainText.text}${secondaryText ? `, ${secondaryText.text}` : ''}`;
const accessibilityLabel = accessibilityLabels.suggestionItem?.(item.placePrediction) || defaultAccessibilityLabel;
return /*#__PURE__*/_jsxs(TouchableOpacity, {
+ testID: `suggestion-touchableopacity-${index}${testIDSuffix}`,
accessibilityRole: "button",
accessibilityLabel: accessibilityLabel,
accessibilityHint: "Double tap to select this place",
@@ -321,11 +325,13 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
}
}),
children: [/*#__PURE__*/_jsx(Text, {
+ testID: `suggestion-text-${index}${testIDSuffix}`,
style: [styles.mainText, style.suggestionText?.main, getTextAlign()],
numberOfLines: suggestionTextProps.mainTextNumberOfLines,
ellipsizeMode: suggestionTextProps.ellipsizeMode || 'tail',
children: mainText.text
}), secondaryText && /*#__PURE__*/_jsx(Text, {
+ testID: `suggestion-secondarytext-${index}${testIDSuffix}`,
style: [styles.secondaryText, style.suggestionText?.secondary, getTextAlign()],
numberOfLines: suggestionTextProps.secondaryTextNumberOfLines,
ellipsizeMode: suggestionTextProps.ellipsizeMode || 'tail',
@@ -388,10 +394,13 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return /*#__PURE__*/_jsxs(View, {
+ testID: `container${testIDSuffix}`,
style: [styles.container, style.container],
children: [/*#__PURE__*/_jsxs(View, {
+ testID: `input-wrapper${testIDSuffix}`,
children: [/*#__PURE__*/_jsx(TextInput, {
...restTextInputProps,
+ testID: `textinput${testIDSuffix}`,
ref: inputRef,
style: [styles.input, style.input, getPadding(), getTextAlign()],
placeholder: placeHolderText,
@@ -405,6 +414,7 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
accessibilityRole: "search",
accessibilityLabel: accessibilityLabels.input || placeHolderText
}), showClearButton && inputText !== '' && /*#__PURE__*/_jsx(TouchableOpacity, {
+ testID: `clear-button${testIDSuffix}`,
style: [styles.clearButton, getIconPosition(12)],
onPress: () => {
if (debounceTimeout.current) {
@@ -433,6 +443,7 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
})
})
}), (loading || detailsLoading) && showLoadingIndicator && /*#__PURE__*/_jsx(ActivityIndicator, {
+ testID: `loading-indicator${testIDSuffix}`,
style: [styles.loadingIndicator, getIconPosition(45)],
size: 'small',
color: style.loadingIndicator?.color || '#000000',
@@ -440,8 +451,10 @@ const GooglePlacesTextInput = /*#__PURE__*/forwardRef(({
accessibilityLabel: accessibilityLabels.loadingIndicator || 'Loading suggestions'
})]
}), showSuggestions && predictions.length > 0 && /*#__PURE__*/_jsx(View, {
+ testID: `suggestions-container${testIDSuffix}`,
style: [styles.suggestionsContainer, style.suggestionsContainer],
children: /*#__PURE__*/_jsx(FlatList, {
+ testID: `suggestions-list${testIDSuffix}`,
data: predictions,
renderItem: renderSuggestion,
keyExtractor: item => item.placePrediction.placeId,
diff --git a/node_modules/react-native-google-places-textinput/src/GooglePlacesTextInput.tsx b/node_modules/react-native-google-places-textinput/src/GooglePlacesTextInput.tsx
index 8c7fd26..c8134fa 100644
--- a/node_modules/react-native-google-places-textinput/src/GooglePlacesTextInput.tsx
+++ b/node_modules/react-native-google-places-textinput/src/GooglePlacesTextInput.tsx
@@ -152,6 +152,11 @@ interface GooglePlacesTextInputProps
enableDebug?: boolean;
accessibilityLabels?: GooglePlacesAccessibilityLabels;
suggestionTextProps?: SuggestionTextProps;
+ /**
+ * Test ID prefix for all internal components (for E2E testing)
+ * Components will be prefixed: textinput-{testID}, suggestion-touchableopacity-{index}-{testID}, etc.
+ */
+ testID?: string;
}
interface GooglePlacesTextInputRef {
@@ -204,6 +209,7 @@ const GooglePlacesTextInput = forwardRef<
onBlur,
accessibilityLabels = {},
suggestionTextProps = {},
+ testID,
...restTextInputProps
},
ref
@@ -508,6 +514,9 @@ const GooglePlacesTextInput = forwardRef<
}, 10);
};
+ // Test ID suffix for all components
+ const testIDSuffix = testID ? `-${testID}` : '';
+
const renderSuggestion = ({
item,
index,
@@ -533,6 +542,7 @@ const GooglePlacesTextInput = forwardRef<
return (
<TouchableOpacity
+ testID={`suggestion-touchableopacity-${index}${testIDSuffix}`}
accessibilityRole="button"
accessibilityLabel={accessibilityLabel}
accessibilityHint="Double tap to select this place"
@@ -555,6 +565,7 @@ const GooglePlacesTextInput = forwardRef<
} as any))}
>
<Text
+ testID={`suggestion-text-${index}${testIDSuffix}`}
style={[
styles.mainText,
style.suggestionText?.main,
@@ -567,6 +578,7 @@ const GooglePlacesTextInput = forwardRef<
</Text>
{secondaryText && (
<Text
+ testID={`suggestion-secondarytext-${index}${testIDSuffix}`}
style={[
styles.secondaryText,
style.suggestionText?.secondary,
@@ -631,10 +643,11 @@ const GooglePlacesTextInput = forwardRef<
}, []);
return (
- <View style={[styles.container, style.container]}>
- <View>
+ <View testID={`container${testIDSuffix}`} style={[styles.container, style.container]}>
+ <View testID={`input-wrapper${testIDSuffix}`}>
<TextInput
{...restTextInputProps}
+ testID={`textinput${testIDSuffix}`}
ref={inputRef}
style={[styles.input, style.input, getPadding(), getTextAlign()]}
placeholder={placeHolderText}
@@ -651,6 +664,7 @@ const GooglePlacesTextInput = forwardRef<
{/* Clear button - shown only if showClearButton is true */}
{showClearButton && inputText !== '' && (
<TouchableOpacity
+ testID={`clear-button${testIDSuffix}`}
style={[styles.clearButton, getIconPosition(12)]}
onPress={() => {
if (debounceTimeout.current) {
@@ -692,6 +706,7 @@ const GooglePlacesTextInput = forwardRef<
{/* Loading indicator */}
{(loading || detailsLoading) && showLoadingIndicator && (
<ActivityIndicator
+ testID={`loading-indicator${testIDSuffix}`}
style={[styles.loadingIndicator, getIconPosition(45)]}
size={'small'}
color={style.loadingIndicator?.color || '#000000'}
@@ -706,9 +721,11 @@ const GooglePlacesTextInput = forwardRef<
{/* Suggestions */}
{showSuggestions && predictions.length > 0 && (
<View
+ testID={`suggestions-container${testIDSuffix}`}
style={[styles.suggestionsContainer, style.suggestionsContainer]}
>
<FlatList
+ testID={`suggestions-list${testIDSuffix}`}
data={predictions}
renderItem={renderSuggestion}
keyExtractor={(item) => item.placePrediction.placeId}
This issue body was partially generated by patch-package.