Add deep-link Maestro flows for RNTester lists (#58481)

Summary:

Add Maestro coverage for FlatList and SectionList viewability behavior using direct RNTester example deep links. Use explicit gestures inside the virtualized lists and wait for the callback output. Add nonvisual, route-specific readiness IDs so successive deep links cannot match the previously mounted list.

Changelog: [Internal]

Differential Revision: D119484760
This commit is contained in:
Nicola Corti
2026-09-21 07:15:27 -07:00
committed by Facebook GitHub Bot
parent 2f5cc52332
commit 85f6252c05
6 changed files with 129 additions and 2 deletions
@@ -0,0 +1,51 @@
appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp
---
- launchApp
- stopApp
- openLink: rntester://example/FlatListExample/onViewableItemsChanged-horizontal-noWaitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'flat-list-viewability-horizontal-no-wait'
timeout: 120000
- assertVisible:
id: 'output'
text: '.*Pizza, Burger.*'
- openLink: rntester://example/FlatListExample/onViewableItemsChanged-horizontal-waitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'flat-list-viewability-horizontal-wait'
timeout: 30000
- scrollUntilVisible:
element:
text: 'Cheesecake'
direction: RIGHT
speed: 60
visibilityPercentage: 50
centerElement: true
timeout: 60000
- extendedWaitUntil:
visible:
id: 'output'
text: '.*Cheesecake.*'
timeout: 30000
- openLink: rntester://example/FlatListExample/onViewableItemsChanged-waitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'flat-list-viewability-vertical-wait'
timeout: 30000
- scrollUntilVisible:
element:
text: 'Cheesecake'
direction: DOWN
speed: 60
visibilityPercentage: 50
centerElement: true
timeout: 60000
- extendedWaitUntil:
visible:
id: 'output'
text: '.*Cheesecake, Brownie.*'
timeout: 30000
@@ -0,0 +1,66 @@
appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp
---
- launchApp
- stopApp
- openLink: rntester://example/SectionList/onEndReached
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'start_test'
timeout: 120000
- tapOn:
id: 'start_test'
- assertVisible:
id: 'output'
text: 'onEndReached'
- openLink: rntester://example/SectionList/onViewableItemsChanged-horizontal-noWaitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'section-list-viewability-horizontal-no-wait'
timeout: 30000
- assertVisible:
id: 'output'
text: '.*Pizza.*'
- openLink: rntester://example/SectionList/onViewableItemsChanged-horizontal-waitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'section-list-viewability-horizontal-wait'
timeout: 30000
- scrollUntilVisible:
element:
text: 'Brownie'
direction: RIGHT
speed: 60
visibilityPercentage: 50
centerElement: true
timeout: 60000
- extendedWaitUntil:
visible:
id: 'output'
text: '.*Cheesecake.*'
timeout: 30000
- runFlow:
when:
platform: Android
commands:
- openLink: rntester://example/SectionList/onViewableItemsChanged-waitForInteraction
- runFlow: ./helpers/confirm-open-link.yml
- extendedWaitUntil:
visible:
id: 'section-list-viewability-vertical-wait'
timeout: 30000
- scrollUntilVisible:
element:
text: 'Brownie'
direction: DOWN
speed: 60
visibilityPercentage: 50
centerElement: true
timeout: 60000
- extendedWaitUntil:
visible:
id: 'output'
text: '.*Cheesecake.*'
timeout: 30000
@@ -61,6 +61,7 @@ const Item = ({item, separators}: ListRenderItemInfo<string>) => {
type Props = Readonly<{
exampleProps: Partial<React.ElementConfig<typeof FlatList>>,
exampleTestID?: ?string,
onTest?: ?() => void,
testLabel?: ?string,
testOutput?: ?string,
@@ -72,7 +73,7 @@ const BaseFlatListExample: component(
...props: Props
) = ({ref, ...props}: {ref: React.RefSetter<FlatList<string>>, ...Props}) => {
return (
<View style={styles.container}>
<View style={styles.container} testID={props.exampleTestID}>
{props.testOutput != null ? (
<View testID="test_container" style={styles.testContainer}>
<Text style={styles.output} numberOfLines={1} testID="output">
@@ -32,6 +32,9 @@ export function FlatList_BaseOnViewableItemsChanged(props: {
waitForInteraction?: ?boolean,
}): React.Node {
const {offScreen, horizontal, useScrollRefScroll, waitForInteraction} = props;
const exampleTestID = `flat-list-viewability-${
horizontal === true ? 'horizontal' : 'vertical'
}-${waitForInteraction === true ? 'wait' : 'no-wait'}`;
const [output, setOutput] = useState('');
const onViewableItemsChanged = useCallback(
(info: {changed: Array<ViewToken>, viewableItems: Array<ViewToken>, ...}) =>
@@ -65,6 +68,7 @@ export function FlatList_BaseOnViewableItemsChanged(props: {
<BaseFlatListExample
ref={ref}
exampleProps={exampleProps}
exampleTestID={exampleTestID}
onTest={onTest}
testOutput={output}>
{offScreen === true ? <View style={styles.offScreen} /> : null}
@@ -30,6 +30,9 @@ export function SectionList_BaseOnViewableItemsChanged(props: {
waitForInteraction?: ?boolean,
}): React.Node {
const {offScreen, horizontal, useScrollRefScroll, waitForInteraction} = props;
const exampleTestID = `section-list-viewability-${
horizontal === true ? 'horizontal' : 'vertical'
}-${waitForInteraction === true ? 'wait' : 'no-wait'}`;
const [output, setOutput] = useState('');
const viewabilityConfig: ViewabilityConfig = {
...BASE_VIEWABILITY_CONFIG,
@@ -62,6 +65,7 @@ export function SectionList_BaseOnViewableItemsChanged(props: {
<SectionListBaseExample
ref={ref}
exampleProps={exampleProps}
exampleTestID={exampleTestID}
onTest={onTest}
testOutput={output}>
{offScreen === true ? <View style={styles.offScreen} /> : null}
@@ -67,6 +67,7 @@ const Item = ({item, section, separators}) => {
type Props = Readonly<{
// $FlowFixMe[unclear-type]
exampleProps: Partial<React.ElementConfig<typeof SectionList<any>>>,
exampleTestID?: ?string,
onTest?: ?() => void,
testLabel?: ?string,
testOutput?: ?string,
@@ -86,7 +87,7 @@ const SectionListBaseExample: component(
...Props,
}): React.Node => {
return (
<View style={styles.container}>
<View style={styles.container} testID={props.exampleTestID}>
{props.testOutput != null ? (
<View testID="test_container" style={styles.testContainer}>
<Text style={styles.output} numberOfLines={1} testID="output">