Search code examples
react-nativekeyboardhidedetox

Detox: how to test multiline TextInput


I'm trying to use detox to test a form in my react-native app.

One of the inputs in the form has multiline={true}.

I am trying to run the following test:

const inputElement = element(by.id('input_multiline'));
await expect(inputElement).toBeVisible();
await inputElement.typeText('line1\n');
await inputElement.typeText('line2\n');
await inputElement.typeText('line3\n');

const submitElement = element(by.id('submit'));
await submitElement.toBeVisible();
await submitElement.tap();

This test fails to pass 75% visibility criteria, because the keyboard is hiding the submit button.

Normally for TextInput with multiline={false} you can just append \n to the input string automatically moving to the next stage, but for multiline input \n just adds a new line.

What can I do in order to pass this test in detox?


Solution

  • First we need to be able to dismiss the keyboard for TextInput with multiline={true}.

    For this we are going to make use of Keyboard module from react-native.

    import {Keyboard} from 'react-native'
    

    Now wrap your form with TouchableWithoutFeedback and call Keyboard.dismiss() on press.

    <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
      { /* your form goes here */ }
    </TouchableWithoutFeedback>
    

    Now modify your detox test to dismiss the keyboard.

    const inputElement = element(by.id('input'));
    await expect(inputElement).toBeVisible();
    await inputElement.typeText('line1\n');
    await inputElement.typeText('line2\n');
    await inputElement.typeText('line3\n');
    // click somewhere outside the input
    await inputElement.tapAtPoint({x: 0, y: 1});
    
    const submitElement = element(by.id('submit'));
    await submitElement.toBeVisible();
    await submitElement.tap();
    

    detox running the test