diff --git a/detox/TODO b/detox/TODO index f1248a852a..343d0b46e5 100644 --- a/detox/TODO +++ b/detox/TODO @@ -5,4 +5,4 @@ - [ ] separate assets for local testing only (Android, with google play) - [ ] test with keyboard resize - [ ] test for disabled/enabled functionality -- [ ] tests for AwareScrollView +- [x] tests for AwareScrollView diff --git a/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputFocused.png b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputFocused.png new file mode 100644 index 0000000000..8401852068 Binary files /dev/null and b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputFocused.png differ diff --git a/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputGrown.png b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputGrown.png new file mode 100644 index 0000000000..a13f0d06cd Binary files /dev/null and b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewFirstInputGrown.png differ diff --git a/detox/e2e/assets/android/e2e_emulator/AwareScrollViewInputChanged.png b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewInputChanged.png new file mode 100644 index 0000000000..64e6b690d1 Binary files /dev/null and b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewInputChanged.png differ diff --git a/detox/e2e/assets/android/e2e_emulator/AwareScrollViewKeyboardClosed.png b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewKeyboardClosed.png new file mode 100644 index 0000000000..328f8dc506 Binary files /dev/null and b/detox/e2e/assets/android/e2e_emulator/AwareScrollViewKeyboardClosed.png differ diff --git a/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputFocused.png b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputFocused.png new file mode 100644 index 0000000000..beb7e0784e Binary files /dev/null and b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputFocused.png differ diff --git a/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputGrown.png b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputGrown.png new file mode 100644 index 0000000000..a1b2bc26d6 Binary files /dev/null and b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewFirstInputGrown.png differ diff --git a/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewInputChanged.png b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewInputChanged.png new file mode 100644 index 0000000000..a154e46578 Binary files /dev/null and b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewInputChanged.png differ diff --git a/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewKeyboardClosed.png b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewKeyboardClosed.png new file mode 100644 index 0000000000..c705a22e64 Binary files /dev/null and b/detox/e2e/assets/ios/iPhone 13 Pro/AwareScrollViewKeyboardClosed.png differ diff --git a/detox/e2e/aware-scroll-view.e2e.ts b/detox/e2e/aware-scroll-view.e2e.ts new file mode 100644 index 0000000000..713b282851 --- /dev/null +++ b/detox/e2e/aware-scroll-view.e2e.ts @@ -0,0 +1,59 @@ +import waitForExpect from 'wait-for-expect'; + +import { expectBitmapsToBeEqual } from './asserts'; +import { waitAndReplace, waitAndTap, waitAndType } from './helpers'; +import setDemoMode from './utils/setDemoMode'; + +const BLINKING_CURSOR = 0.35; + +describe('AwareScrollView test cases', () => { + beforeAll(async () => { + await setDemoMode(); + await device.launchApp(); + }); + + it('should push input above keyboard on focus', async () => { + await waitAndTap('aware_scroll_view'); + await waitAndTap('TextInput#3'); + await waitForExpect(async () => { + await expectBitmapsToBeEqual( + 'AwareScrollViewFirstInputFocused', + BLINKING_CURSOR + ); + }); + }); + + it('should detect TextInput growth', async () => { + await waitAndType('TextInput#3', '\n\n\n\n'); + await waitForExpect(async () => { + await expectBitmapsToBeEqual( + 'AwareScrollViewFirstInputGrown', + BLINKING_CURSOR + ); + }); + }); + + it('should auto-scroll when new input gets focused', async () => { + // scroll while keeping a focus is not working: https://github.com/wix/Detox/issues/174 + // but we may use `await element(by.id('TextInput#3')).swipe('up');` (currently focused input as event receiver) + await waitAndReplace('TextInput#3', '\n\n'); + await waitAndTap('TextInput#4'); + await waitForExpect(async () => { + await expectBitmapsToBeEqual( + 'AwareScrollViewInputChanged', + BLINKING_CURSOR + ); + }); + }); + + it('should scroll back when keyboard dismissed', async () => { + // tap outside of input to close a keyboard + await waitAndTap('TextInput#4', { x: 0, y: -10 }); + await waitForExpect(async () => { + await expectBitmapsToBeEqual( + 'AwareScrollViewKeyboardClosed', + BLINKING_CURSOR + ); + }); + }); +}); diff --git a/detox/e2e/helpers/actions/index.ts b/detox/e2e/helpers/actions/index.ts index 146c6c309c..5d97101980 100644 --- a/detox/e2e/helpers/actions/index.ts +++ b/detox/e2e/helpers/actions/index.ts @@ -7,13 +7,13 @@ const TIMEOUT_FOR_LONG_OPERATIONS = 30000; export const delay = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)); -export const tap = async (id: string): Promise => { +export const tap = async (id: string, point?: Detox.Point2D): Promise => { console.debug( '---------------------------------\n', 'Tap on element with id: ', colors.magenta(id) ); - await element(by.id(id)).tap(); + await element(by.id(id)).tap(point); }; // Not used yet. Will be used later @@ -65,9 +65,12 @@ export const swipeUp = async (id: string): Promise => { await element(by.id(id)).swipe('up', 'fast', 1, NaN, 0.85); }; -export const waitAndTap = async (id: string): Promise => { +export const waitAndTap = async ( + id: string, + point?: Detox.Point2D +): Promise => { await waitForElementById(id, TIMEOUT_FOR_LONG_OPERATIONS); - await tap(id); + await tap(id, point); }; export const waitAndType = async (id: string, text: string): Promise => { diff --git a/example/src/components/TextInput/index.tsx b/example/src/components/TextInput/index.tsx index f9b92bf5a1..5615b567cc 100644 --- a/example/src/components/TextInput/index.tsx +++ b/example/src/components/TextInput/index.tsx @@ -8,6 +8,7 @@ const TextInput = (props: TextInputProps) => { style={styles.container} multiline numberOfLines={2} + testID={props.placeholder} {...props} placeholder={`${props.placeholder} (${props.keyboardType === 'default' ? 'text' : 'numeric'})`} /> diff --git a/example/src/screens/Examples/AwareScrollView/index.tsx b/example/src/screens/Examples/AwareScrollView/index.tsx index 61968a6aa8..5376b41ecb 100644 --- a/example/src/screens/Examples/AwareScrollView/index.tsx +++ b/example/src/screens/Examples/AwareScrollView/index.tsx @@ -9,7 +9,7 @@ export default function AwareScrollView() { useResizeMode(); return ( - + {new Array(10).fill(0).map((_, i) => (