diff --git a/.github/workflows/maestro-cloud-rntester.yml b/.github/workflows/maestro-cloud-rntester.yml index 7f245bbcbebf..7c2afc24ea8b 100644 --- a/.github/workflows/maestro-cloud-rntester.yml +++ b/.github/workflows/maestro-cloud-rntester.yml @@ -46,7 +46,7 @@ jobs: test: name: Maestro Cloud ${{ inputs.platform }} RNTester runs-on: ubuntu-latest - timeout-minutes: 75 + timeout-minutes: 105 steps: - name: Checkout uses: actions/checkout@v6 @@ -84,7 +84,7 @@ jobs: env: | APP_ID=${{ inputs.app-id }} maestro-cli-version: 2.6.1 - timeout: 60 + timeout: 90 - name: Check Maestro Cloud result if: always() env: diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index 237f4ad66f70..407e2b1f2f30 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -186,7 +186,7 @@ jobs: app-id: com.meta.RNTester.localDevelopment device-model: iPhone-17-Pro device-os: iOS-26-2 - exclude-tags: android-only + exclude-tags: android-only,local-screenshot-baseline secrets: inherit test_e2e_ios_rntester: diff --git a/packages/rn-tester/.maestro/alert.yml b/packages/rn-tester/.maestro/alert.yml new file mode 100644 index 000000000000..65845ee1fb26 --- /dev/null +++ b/packages/rn-tester/.maestro/alert.yml @@ -0,0 +1,23 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/AlertExample/default-button +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'alert-with-default-button' + timeout: 120000 +- tapOn: + id: 'alert-with-default-button' +- assertVisible: 'An external USB drive has been detected!' +- tapOn: 'OK' +- openLink: rntester://example/AlertExample/three-buttons +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'alert-with-three-buttons' + timeout: 30000 +- tapOn: + id: 'alert-with-three-buttons' +- assertVisible: 'Do you want to save your changes?' +- tapOn: 'Cancel' diff --git a/packages/rn-tester/.maestro/animated-fade-in-view.yml b/packages/rn-tester/.maestro/animated-fade-in-view.yml new file mode 100644 index 000000000000..1bdcf9422184 --- /dev/null +++ b/packages/rn-tester/.maestro/animated-fade-in-view.yml @@ -0,0 +1,19 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/Animated/fadeInView +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'toggle-button' + timeout: 120000 +- assertVisible: + id: 'fade-in-view' +- tapOn: + id: 'toggle-button' +- assertNotVisible: + id: 'fade-in-view' +- tapOn: + id: 'toggle-button' +- assertVisible: + id: 'fade-in-view' diff --git a/packages/rn-tester/.maestro/appearance.yml b/packages/rn-tester/.maestro/appearance.yml new file mode 100644 index 000000000000..64ff4b726a8b --- /dev/null +++ b/packages/rn-tester/.maestro/appearance.yml @@ -0,0 +1,8 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/AppearanceExample +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: 'useColorScheme hook' + timeout: 120000 diff --git a/packages/rn-tester/.maestro/fabric-interop-add-children.yml b/packages/rn-tester/.maestro/fabric-interop-add-children.yml new file mode 100644 index 000000000000..50703fd23682 --- /dev/null +++ b/packages/rn-tester/.maestro/fabric-interop-add-children.yml @@ -0,0 +1,29 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- runFlow: + when: + platform: iOS + commands: + - openLink: rntester://example/FabricInteropLayer/add-children + - runFlow: ./helpers/confirm-open-link.yml + - extendedWaitUntil: + visible: + id: 'add-marker-btn' + timeout: 120000 + - assertVisible: + id: 'marker_0' + - assertVisible: + id: 'marker_1' + - assertVisible: + id: 'marker_2' + - assertVisible: + id: 'marker_3' + - assertVisible: + id: 'marker_4' + - assertNotVisible: + id: 'marker_5' + - tapOn: + id: 'add-marker-btn' + - assertVisible: + id: 'marker_5' diff --git a/packages/rn-tester/.maestro/filter-animated-blur.yml b/packages/rn-tester/.maestro/filter-animated-blur.yml new file mode 100644 index 000000000000..8e31eba50bf2 --- /dev/null +++ b/packages/rn-tester/.maestro/filter-animated-blur.yml @@ -0,0 +1,13 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/Filter/animated-blur +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'animated-blur-button' + timeout: 120000 +- tapOn: + id: 'animated-blur-button' +- assertVisible: + id: 'animated-blur-view' diff --git a/packages/rn-tester/.maestro/flatlist-viewability.yml b/packages/rn-tester/.maestro/flatlist-viewability.yml new file mode 100644 index 000000000000..74fa104c3614 --- /dev/null +++ b/packages/rn-tester/.maestro/flatlist-viewability.yml @@ -0,0 +1,50 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- 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: + id: 'Cheesecake' + direction: RIGHT + speed: 40 + visibilityPercentage: 100 + centerElement: true + timeout: 30000 +- extendedWaitUntil: + visible: + id: 'output' + text: '.*Cheesecake.*' + timeout: 10000 +- openLink: rntester://example/FlatListExample/onViewableItemsChanged-waitForInteraction +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'flat-list-viewability-vertical-wait' + timeout: 30000 +- scrollUntilVisible: + element: + id: 'Cheesecake' + direction: DOWN + speed: 40 + visibilityPercentage: 100 + centerElement: true + timeout: 30000 +- extendedWaitUntil: + visible: + id: 'output' + text: '.*Cheesecake, Brownie.*' + timeout: 10000 diff --git a/packages/rn-tester/.maestro/helpers/confirm-open-link.yml b/packages/rn-tester/.maestro/helpers/confirm-open-link.yml new file mode 100644 index 000000000000..1fa66d36dbcf --- /dev/null +++ b/packages/rn-tester/.maestro/helpers/confirm-open-link.yml @@ -0,0 +1,9 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- runFlow: + when: + platform: iOS + commands: + - tapOn: + text: 'Open' + optional: true diff --git a/packages/rn-tester/.maestro/legacy-native-module.yml b/packages/rn-tester/.maestro/legacy-native-module.yml index e68fbaa30edd..370714922cbd 100644 --- a/packages/rn-tester/.maestro/legacy-native-module.yml +++ b/packages/rn-tester/.maestro/legacy-native-module.yml @@ -1,50 +1,411 @@ appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp --- -- launchApp -# Wait for the JS bundle to render the landing screen instead of asserting -# immediately, which races app cold start on CI. +- stopApp +- openLink: rntester://example/LegacyModule/SampleLegacyModule +- runFlow: ./helpers/confirm-open-link.yml - extendedWaitUntil: visible: - text: 'APIs' - timeout: 30000 + id: 'run-all-tests' + timeout: 120000 - tapOn: - id: 'apis-tab' -- runFlow: ./helpers/search.yml -- inputText: - text: 'Legacy Native' -- assertVisible: - id: 'Legacy Native Module' -- tapOn: - id: 'Legacy Native Module' -- tapOn: - text: 'voidFunc' -- assertVisible: - id: 'voidFunc-result' -- tapOn: - text: 'getBool' -- assertVisible: - id: 'getBool-result' -- tapOn: - text: 'getEnum' -- assertVisible: - id: 'getEnum-result' -- tapOn: - text: 'getInt' -- assertVisible: - id: 'getInt-result' -- tapOn: - text: 'getString' -- assertVisible: - id: 'getString-result' -- tapOn: - text: 'getObject' -- assertVisible: - id: 'getObject-result' -- tapOn: - text: 'getUnsafeObject' -- assertVisible: - id: 'getUnsafeObject-result' -- tapOn: - text: 'getValue' -- assertVisible: - id: 'getValue-result' + id: 'run-all-tests' +- runFlow: + when: + platform: iOS + commands: + - assertVisible: + id: 'voidFunc-result' + - assertVisible: + id: 'getBool-result' + text: 'true' + - assertVisible: + id: 'getEnum-result' + text: '1' + - scrollUntilVisible: + element: + id: 'getNumber-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getNumber-result' + text: '99.95' + - scrollUntilVisible: + element: + id: 'getFloat-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getFloat-result' + text: '99.94999694824219' + - scrollUntilVisible: + element: + id: 'getInt-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getInt-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getLongLong-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getLongLong-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getUnsignedLongLong-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getUnsignedLongLong-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getNSInteger-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getNSInteger-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getNSUInteger-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getNSUInteger-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getArray-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getArray-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'getObject-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getObject-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'getString-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getString-result' + text: '.*Hello.*' + - scrollUntilVisible: + element: + id: 'getNullString-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getNullString-result' + text: 'null' + - scrollUntilVisible: + element: + id: 'getNSNumber-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getNSNumber-result' + text: '20' + - scrollUntilVisible: + element: + id: 'getUnsafeObject-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getUnsafeObject-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'getRootTag-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getRootTag-result' + text: '11' + - scrollUntilVisible: + element: + id: 'getValue-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getValue-result' + text: '.*test.*' + - scrollUntilVisible: + element: + id: 'callback-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'callback-result' + text: '.*value from callback!.*' + - scrollUntilVisible: + element: + id: 'promise-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'promise-result' + text: '.*result!.*' + - scrollUntilVisible: + element: + id: 'rejectPromise-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'rejectPromise-result' + text: '.*intentional promise rejection.*' + - scrollUntilVisible: + element: + id: 'getConstants-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConstants-result' + text: '.*something.*' + - scrollUntilVisible: + element: + id: 'getConst1-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst1-result' + text: 'true' + - scrollUntilVisible: + element: + id: 'getConst2-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst2-result' + text: '390' + - scrollUntilVisible: + element: + id: 'getConst3-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst3-result' + text: '.*something.*' +- runFlow: + when: + platform: Android + commands: + - assertVisible: + id: 'voidFunc-result' + - assertVisible: + id: 'getBool-result' + text: 'true' + - assertVisible: + id: 'getEnum-result' + text: '1' + - scrollUntilVisible: + element: + id: 'getDouble-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDouble-result' + text: '99.95' + - scrollUntilVisible: + element: + id: 'getInt-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getInt-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getFloat-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getFloat-result' + text: '99.94999694824219' + - scrollUntilVisible: + element: + id: 'getObjectDouble-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getObjectDouble-result' + text: '99.95' + - scrollUntilVisible: + element: + id: 'getObjectInteger-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getObjectInteger-result' + text: '99' + - scrollUntilVisible: + element: + id: 'getObjectFloat-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getObjectFloat-result' + text: '99.94999694824219' + - scrollUntilVisible: + element: + id: 'getString-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getString-result' + text: '.*Hello.*' + - scrollUntilVisible: + element: + id: 'getRootTag-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getRootTag-result' + text: '11' + - scrollUntilVisible: + element: + id: 'getObject-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getObject-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'getUnsafeObject-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getUnsafeObject-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'getValue-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getValue-result' + text: '.*test.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithNull-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithNull-result' + text: '.*Null.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithBoolean-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithBoolean-result' + text: '.*Boolean.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithNumber-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithNumber-result' + text: '.*42.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithString-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithString-result' + text: '.*The answer is 42.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithArray-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithArray-result' + text: '.*the.*' + - scrollUntilVisible: + element: + id: 'getDynamicWithMap-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getDynamicWithMap-result' + text: '.*answer.*' + - scrollUntilVisible: + element: + id: 'callback-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'callback-result' + text: '.*Value From Callback.*' + - scrollUntilVisible: + element: + id: 'getArray-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getArray-result' + text: '.*foo.*' + - scrollUntilVisible: + element: + id: 'promise-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'promise-result' + text: '.*result.*' + - scrollUntilVisible: + element: + id: 'rejectPromise-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'rejectPromise-result' + text: '.*intentional promise rejection.*' + - scrollUntilVisible: + element: + id: 'getConstants-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConstants-result' + text: '.*something.*' + - scrollUntilVisible: + element: + id: 'getConst1-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst1-result' + text: 'true' + - scrollUntilVisible: + element: + id: 'getConst2-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst2-result' + text: '390' + - scrollUntilVisible: + element: + id: 'getConst3-result' + direction: DOWN + speed: 40 + - assertVisible: + id: 'getConst3-result' + text: '.*something.*' diff --git a/packages/rn-tester/.maestro/modal.yml b/packages/rn-tester/.maestro/modal.yml index e3b7bef53886..c7bb71ca6770 100644 --- a/packages/rn-tester/.maestro/modal.yml +++ b/packages/rn-tester/.maestro/modal.yml @@ -1,25 +1,23 @@ appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp --- -- launchApp -# Wait for the JS bundle to render the landing screen instead of asserting -# immediately, which races app cold start on CI. +- stopApp +- openLink: rntester://example/Modal/onShow +- runFlow: ./helpers/confirm-open-link.yml - extendedWaitUntil: - visible: 'Components' - timeout: 30000 -- scrollUntilVisible: - element: - id: 'Modal' - direction: DOWN - speed: 60 + visible: + id: 'open-modal' + timeout: 120000 - tapOn: - id: 'Modal' + id: 'open-modal' - assertVisible: - text: 'Show Modal' -- tapOn: - text: 'Show Modal' + id: 'dismiss-modal' - assertVisible: - text: 'Close' + id: 'modal-on-show-count' + text: 'onShow is called 1 times' - tapOn: - text: 'Close' + id: 'dismiss-modal' +- assertNotVisible: + id: 'dismiss-modal' - assertVisible: - text: 'Show Modal' + id: 'on-show-count' + text: 'onShow is called 1 times' diff --git a/packages/rn-tester/.maestro/pressable.yml b/packages/rn-tester/.maestro/pressable.yml index 86a8b2b00231..85399075149e 100644 --- a/packages/rn-tester/.maestro/pressable.yml +++ b/packages/rn-tester/.maestro/pressable.yml @@ -1,37 +1,30 @@ appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp --- -- runFlow: ./helpers/launch-app-and-search.yml -- inputText: - text: 'Pressable' -- assertVisible: - id: 'Pressable' -- tapOn: - id: 'Pressable' -- assertVisible: - text: 'Change content based on Press' -- assertVisible: - text: 'Change style based on Press' +- stopApp +- openLink: rntester://example/PressableExample/content-press +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'one_press_me_button' + timeout: 120000 - tapOn: id: 'one_press_me_button' - assertVisible: + id: 'pressable_press_console' text: 'onPress' - tapOn: id: 'one_press_me_button' - assertVisible: + id: 'pressable_press_console' text: '2x onPress' -- scrollUntilVisible: - element: - id: 'pressable_feedback_events' - direction: DOWN - speed: 10 - visibilityPercentage: 100 +- openLink: rntester://example/PressableExample/feedback-events +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'pressable_feedback_events_button' + timeout: 30000 - tapOn: id: 'pressable_feedback_events_button' -- scrollUntilVisible: - element: - text: 'pressIn' - direction: DOWN - speed: 10 - assertVisible: text: 'press' - assertVisible: @@ -44,3 +37,24 @@ appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebo text: 'longPress' - assertVisible: text: 'pressOut' +- openLink: rntester://example/PressableExample/hit-slop +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'pressable_hit_slop_button' + timeout: 30000 +- tapOn: + id: 'pressable_hit_slop_button' +- assertVisible: + id: 'pressable_hit_slop' +- openLink: rntester://example/PressableExample/text-press +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'tappable_text' + timeout: 30000 +- tapOn: + id: 'tappable_text' +- assertVisible: + id: 'tappable_text_console' + text: 'text onPress' diff --git a/packages/rn-tester/.maestro/sectionlist-viewability.yml b/packages/rn-tester/.maestro/sectionlist-viewability.yml new file mode 100644 index 000000000000..2cd3352157dc --- /dev/null +++ b/packages/rn-tester/.maestro/sectionlist-viewability.yml @@ -0,0 +1,65 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- 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: + id: 'Cheesecake' + direction: RIGHT + speed: 40 + visibilityPercentage: 100 + centerElement: true + timeout: 30000 +- extendedWaitUntil: + visible: + id: 'output' + text: '.*Cheesecake.*' + timeout: 10000 +- 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: + id: 'Cheesecake' + direction: DOWN + speed: 40 + visibilityPercentage: 100 + centerElement: true + timeout: 30000 + - extendedWaitUntil: + visible: + id: 'output' + text: '.*Cheesecake.*' + timeout: 10000 diff --git a/packages/rn-tester/.maestro/textinput-uncontrolled.yml b/packages/rn-tester/.maestro/textinput-uncontrolled.yml new file mode 100644 index 000000000000..e1cf15533adf --- /dev/null +++ b/packages/rn-tester/.maestro/textinput-uncontrolled.yml @@ -0,0 +1,17 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/TextInput/uncontrolledComponent +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'uncontrolled-textinput' + timeout: 120000 +- tapOn: + id: 'uncontrolled-textinput' +- eraseText +- inputText: 'New value' +- hideKeyboard +- assertVisible: + id: 'uncontrolled-textinput' + text: 'New value' diff --git a/packages/rn-tester/.maestro/touchable.yml b/packages/rn-tester/.maestro/touchable.yml new file mode 100644 index 000000000000..01d2575133be --- /dev/null +++ b/packages/rn-tester/.maestro/touchable.yml @@ -0,0 +1,45 @@ +appId: ${APP_ID} # iOS: com.meta.RNTester.localDevelopment | Android: com.facebook.react.uiapp +--- +- stopApp +- openLink: rntester://example/TouchableExample/feedback-events +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'touchable_feedback_events_button' + timeout: 120000 +- tapOn: + id: 'touchable_feedback_events_button' +- assertVisible: + id: 'touchable_feedback_events_console' +- openLink: rntester://example/TouchableExample/highlight +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'touchable_highlight_text_button' + timeout: 30000 +- tapOn: + id: 'touchable_highlight_text_button' +- assertVisible: + id: 'touchable_highlight_console' + text: 'TouchableHighlight onPress' +- openLink: rntester://example/TouchableExample/hit-slop +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'touchable_hit_slop_button' + timeout: 30000 +- tapOn: + id: 'touchable_hit_slop_button' +- assertVisible: + id: 'touchable_hit_slop' +- openLink: rntester://example/TouchableExample/without-feedback +- runFlow: ./helpers/confirm-open-link.yml +- extendedWaitUntil: + visible: + id: 'touchable_without_feedback_button' + timeout: 30000 +- tapOn: + id: 'touchable_without_feedback_button' +- assertVisible: + id: 'touchable_without_feedback_console' + text: 'TouchableWithoutFeedback onPress' diff --git a/packages/rn-tester/js/examples/FlatList/BaseFlatListExample.js b/packages/rn-tester/js/examples/FlatList/BaseFlatListExample.js index 11fffe822a9c..1c77581facfd 100644 --- a/packages/rn-tester/js/examples/FlatList/BaseFlatListExample.js +++ b/packages/rn-tester/js/examples/FlatList/BaseFlatListExample.js @@ -61,6 +61,7 @@ const Item = ({item, separators}: ListRenderItemInfo) => { type Props = Readonly<{ exampleProps: Partial>, + exampleTestID?: ?string, onTest?: ?() => void, testLabel?: ?string, testOutput?: ?string, @@ -72,7 +73,7 @@ const BaseFlatListExample: component( ...props: Props ) = ({ref, ...props}: {ref: React.RefSetter>, ...Props}) => { return ( - + {props.testOutput != null ? ( diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-BaseOnViewableItemsChanged.js b/packages/rn-tester/js/examples/FlatList/FlatList-BaseOnViewableItemsChanged.js index fb555cfe99a9..0d967cb3deed 100644 --- a/packages/rn-tester/js/examples/FlatList/FlatList-BaseOnViewableItemsChanged.js +++ b/packages/rn-tester/js/examples/FlatList/FlatList-BaseOnViewableItemsChanged.js @@ -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, viewableItems: Array, ...}) => @@ -65,6 +68,7 @@ export function FlatList_BaseOnViewableItemsChanged(props: { {offScreen === true ? : null} diff --git a/packages/rn-tester/js/examples/SectionList/SectionList-BaseOnViewableItemsChanged.js b/packages/rn-tester/js/examples/SectionList/SectionList-BaseOnViewableItemsChanged.js index bb075043f438..bfebad3f0a9e 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionList-BaseOnViewableItemsChanged.js +++ b/packages/rn-tester/js/examples/SectionList/SectionList-BaseOnViewableItemsChanged.js @@ -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: { {offScreen === true ? : null} diff --git a/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js b/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js index d4de9daae6c5..21c42c0ca641 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js @@ -67,6 +67,7 @@ const Item = ({item, section, separators}) => { type Props = Readonly<{ // $FlowFixMe[unclear-type] exampleProps: Partial>>, + exampleTestID?: ?string, onTest?: ?() => void, testLabel?: ?string, testOutput?: ?string, @@ -86,7 +87,7 @@ const SectionListBaseExample: component( ...Props, }): React.Node => { return ( - + {props.testOutput != null ? ( diff --git a/packages/rn-tester/js/examples/TurboModule/SampleLegacyModuleExample.js b/packages/rn-tester/js/examples/TurboModule/SampleLegacyModuleExample.js index d0090a3ebe25..94016448fa0e 100644 --- a/packages/rn-tester/js/examples/TurboModule/SampleLegacyModuleExample.js +++ b/packages/rn-tester/js/examples/TurboModule/SampleLegacyModuleExample.js @@ -87,7 +87,7 @@ class SampleLegacyModuleExample extends React.Component<{}, State> { getBool: () => getSampleLegacyModule()?.getBool(true), getEnum: () => getSampleLegacyModule()?.getEnum(1.0), getNumber: () => getSampleLegacyModule()?.getNumber(99.95), - getFloat: () => getSampleLegacyModule()?.getNumber(99.95), + getFloat: () => getSampleLegacyModule()?.getFloat(99.95), getInt: () => getSampleLegacyModule()?.getInt(99), getLongLong: () => getSampleLegacyModule()?.getLongLong(99), getUnsignedLongLong: () => @@ -106,7 +106,7 @@ class SampleLegacyModuleExample extends React.Component<{}, State> { getNullString: () => getSampleLegacyModule()?.getString(null), getNSNumber: () => getSampleLegacyModule()?.getNSNumber(20.0), getUnsafeObject: () => - getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}), + getSampleLegacyModule()?.getUnsafeObject({a: 1, b: 'foo', c: null}), getRootTag: () => getSampleLegacyModule()?.getRootTag(11), getValue: () => getSampleLegacyModule()?.getValue(5, 'test', {a: 1, b: 'foo'}), @@ -144,7 +144,7 @@ class SampleLegacyModuleExample extends React.Component<{}, State> { getObject: () => getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}), getUnsafeObject: () => - getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}), + getSampleLegacyModule()?.getUnsafeObject({a: 1, b: 'foo', c: null}), getValue: () => getSampleLegacyModule()?.getValue(5, 'test', {a: 1, b: 'foo'}), getDynamicWithNull: () => getSampleLegacyModule()?.getDynamic(null),