[SOLVED] : [iOS] [Simulator] sendKeys() NOT working, inserting text to 2 text fields at the same time

I am facing something really odd with my automation and only happens with 2 specifics elements in the entire app. As soon as I input text to “password” field, the “password” and “Confirm password” fields are filled out at the same time and some kind of label covers the fields. All the others text fields in the app I use simple click() and sendKeys() commands and works fine.

I am using page factory. this is how I use the page class to store the elements:

    @AndroidFindBy(id = "com.xxxx:id/create-account-password-text-field")
    @iOSXCUITFindBy(accessibility = "Password* Create a secure password that does not include all or part of your name or username. Enter new password")
    private WebElement create_account_password_text_box;

   public WebElement getCreate_account_password_text_box() {
        return create_account_password_text_box;
    }

    public void setCreate_account_password_text_box(WebElement create_account_password_text_box) {
        this.create_account_password_text_box = create_account_password_text_box;
    }

Here is my testCase method:

    @Test(dataProvider = "getData")
    @Description("Fill out all fields correctly and deselect consent checkbox")
    @Severity(SeverityLevel.NORMAL)
    public void consentBoxNotSelected(HashMap<String, String> input) {
        BaseLoginPage blp = new BaseLoginPage(driver);
        BaseVerifyMemberPage bvp = new BaseVerifyMemberPage(driver);
        BaseCreateAccountPage bcp = new BaseCreateAccountPage(driver);

// These methods interacting with elements are just simple "click()" and "sendKeys()" commands
            blp.clickRegisterButton();
            bvp.clickMemberIdRadioButton();
            bvp.enterMemberId("001720006");
            bvp.enterDoB("02201975");
            bvp.getVerify_button().click();
            bcp.insertInput(bcp.getCreate_account_email_text_box(), "[email protected]");
            bcp.insertInput(bcp.getCreate_account_password_text_box(), "Gabe@1234");
            bcp.insertInput(bcp.getCreate_account_confirm_password_text_box(), "Gabe@1234");
            bcp.clickCreateAccountToSCheckBox();
            Assert.assertFalse(bcp.getCreate_account_button().isEnabled(), "Create button should be disable when all required fields conditions are NOT filled");
}

I have tried using: (Each * is me trying different approaches):

// This code at test case (mentioned above)
bcp.getCreate_account_password_text_box().sendKeys();
// This code at test case (mentioned above)
bcp.getCreate_account_password_text_box().click(); 
bcp.getCreate_account_password_text_box().sendKeys();
//This method at page class
    public void insertInput(WebElement field, String input){
        field.click();
        field.sendKeys(input)
}
// This code at test case (mentioned above)
bcp.insertInput(bcp.getCreate_account_password_text_box(), "[email protected]");
//This method at page class
    public void insertInput(WebElement field, String input){
        field.click();
        new Actions(driver).sendKeys(input).perform();
    }
// This code at test case (mentioned above)
bcp.insertInput(bcp.getCreate_account_password_text_box(), "[email protected]");
//This method at page class
    public void insertInput(WebElement field, String input){
        field.click();
        new Actions(driver).sendKeys(input).perform();
        ((IOSDriver)driver).hideKeyboard("return");
    }
// This code at test case (mentioned above)
bcp.insertInput(bcp.getCreate_account_password_text_box(), "[email protected]");
//This method at page class
    public void tapElement(WebElement element) {
        Point sourceLocation = element.getLocation();
        Dimension sourceSize = element.getSize();
        int centerX = sourceLocation.getX() + sourceSize.getWidth() / 2;
        int centerY = sourceLocation.getY() + sourceSize.getHeight() / 2;
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
        Sequence tap = new Sequence(finger, 1);
        tap.addAction(finger.createPointerMove(Duration.ofMillis(0), PointerInput.Origin.viewport(), centerX, centerY));
        tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
        tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
        driver.perform(List.of(tap));
    }

    public void insertInput(WebElement field, String input){
        tapElement(field);
        new Actions(driver).sendKeys(input).perform();
        ((IOSDriver) driver).hideKeyboard("return");
    }
//This code at test case (mentioned above)
bcp.insertInput(bcp.getCreate_account_password_text_box(), "Gabe@1234");

Dependencies:

         <dependency>
            <groupId>io.appium</groupId>
            <artifactId>java-client</artifactId>
            <version>9.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.15.1</version>
        </dependency>

I found out that it was because I was dealing with a security keyboard/textField, to solve the problem you must follow:

  1. Run your Appium client session using the command:

appium --relaxed-security

  1. Insert the method below:
    public void insertInput(WebElement element,String input) {
        //TAP THE ELEMENT
        Point sourceLocation = element.getLocation();
        Dimension sourceSize = element.getSize();
        int centerX = sourceLocation.getX() + sourceSize.getWidth() / 2;
        int centerY = sourceLocation.getY() + sourceSize.getHeight() / 2;
        PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
        Sequence tap = new Sequence(finger, 1);
        tap.addAction(finger.createPointerMove(Duration.ofMillis(0), PointerInput.Origin.viewport(), centerX, centerY));
        tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
        tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
        driver.perform(List.of(tap));
        //SEND KEYS
        String[] arr;
        arr = input.split("");
        driver.executeScript("mobile: keys", ImmutableMap.of("keys",arr));
    }
1 Like

Found a better solution, insert into your class where you setup your driver and server:

setCapability(“connectHardwareKeyboard”,“true”);

and you can use sendKeys(); or new Actions(driver).sendKeys(input).perform();
instead of

        String[] arr;
        arr = input.split("");
        driver.executeScript("mobile: keys", ImmutableMap.of("keys",arr));