top of page

waiter2: Typing into fields


When it comes to typing, in the 'waiter2' library there are quite a few methods dedicated to this task. But there is a reason why there are so many (32 to be precise): they are different variations, given certain parameters, as the name suggests for each of them. Here are the considerations, whose combinations will give the method signatures:

- each method for typing starts with clearing the field, before typing. This is to make sure the text you are typing is not concatenated to any existing text

- some of the methods, after typing, will also type the TAB key, to switch focus to a different field. This is really useful if the value typed in a field might be changed by some JS code that is triggered when the focus moves outside of the field

- some of the methods will receive an int parameter, to allow for the timeout value to be passed from a test, instead of using the default value of 30 seconds

- some of the methods will receive the element to type into as a WebElement parameter (defined in a page object class with @FindBy). Others will receive a By parameter

- some of the methods will consider the typing successful when the text typed is exactly the one passed initially for typing. Others will consider that the field to type into might parse the initial text to some required format (for example for currencies or decimals), so that once you finish typing, the initial text is not present in the field anymore. Instead the parsed version of the text is

- and some of the methods will check that the element's 'value' attribute should equal either the typed text, or the formatted one, to validate that the typing was successful. Others will check that the text returned by 'getText()' is the one you expect (either the initial one or the formatted one). This depends on how the element to type into sets the value once you type into it. For example, classic text inputs will set the typed value into the element's 'value' attribute. But it will be up to you to analyze how this text is stored once you type it, in the page you are testing, so that you know which typing method to call


To have a visual representation of the existing methods with their signatures, here is a screenshot, followed by the description and usage example for a few of these. The rest work similarly to the ones I will go through:



Don't forget to perform the required setup in order to write your test.


Clear, sendKeys, tab and check that the typed text (to WebElement) is correct in the element's 'value' attribute, with default timeout


A very common usage for typing into a text field is the one described in the method clearSendKeysAndTab_WaitAttributeValueEqualsText.


Since version: 1.0


The code


Inside the ExpectedCondition defined in the method, first the input (in this example defined as a @FindBy WebElement) is cleared. Then, the text is typed, and then the TAB key is typed. The text is considered typed correctly if, after the TAB, the text in the field is still the initial one. This is checked inside this method through the element's 'value' attribute. In case the text has not been correctly typed within the default 30 second timeout, a RunTimeException is thrown, with the following message:


"waiter2.FAILURE: Could not successfully type the text '" + text +
        "' into input '" + inputToTypeInto + "' within " + specificTimeout + " seconds."

The code of this method is:

public void clearSendKeysAndTab_WaitAttributeValueEqualsText(WebElement inputToTypeInto, String text) {
    clearSendKeysAndTab_WaitAttributeValueEqualsText(inputToTypeInto, text, TIMEOUT);
}

which calls:

public void clearSendKeysAndTab_WaitAttributeValueEqualsText(WebElement inputToTypeInto, String text, int specificTimeout) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(specificTimeout));
    try {
        ExpectedCondition<Boolean> condition = arg -> {
            try {
                inputToTypeInto.clear();
                inputToTypeInto.sendKeys(text);
                inputToTypeInto.sendKeys(Keys.TAB);
                return inputToTypeInto.getAttribute("value").equals(text);
            } catch (Exception e) {
                return false;
            }
        };
        wait.until(condition);
    }
    catch (TimeoutException e) {
        throw new RuntimeException("waiter2.FAILURE: Could not successfully type the text '" + text +
                "' into input '" + inputToTypeInto + "' within " + specificTimeout + " seconds.");
    }
}

Usage example


Let's look at a simple text input, defined in a page object class, with the @FindBy annotation, as the following WebElement (of course your selector might be more complex):

@FindBy(css = "[type=\"text\"]") public WebElement textInput;

Typing the text is as easy as:

waiter.clearSendKeysAndTab_WaitAttributeValueEqualsText(page.textInput, "The text to type into the input");

Note that as I mentioned when I talked about clicking on page elements, there is no need for a 'wait for element to be displayed' method. In case the element is not displayed, or not interactable, when the clear or sendKeys are done, the whole code inside the condition is retried, until the element can be typed into (or the timeout expired).

In case the text could not be typed, the thrown exception, for this example, looks like:


java.lang.RuntimeException: waiter2.FAILURE: Could not successfully type the text 'The text to type into the input' into input '[[ChromeDriver: chrome on WINDOWS (f0793c5414f33ba2c0ac31a1ba979344)] -> css selector: [type="text"]]' within 30 seconds.


Same as above but with By


Similarly to the above method, we can perform all the steps and checks described in the above method, but while specifying the page element to type into as a By selector. For this, we can use the method clearSendKeysAndTab_WaitAttributeValueEqualsText.


Since version: 1.0


The code:


The method code is similar to the above one. However inside it is where a WebElement is created, based on the By selector passed. The method should be used only when the selector is dynamic and created sometime during the test, and cannot be stored to a @FindBy variable. The code is as follows:

public void clearSendKeysAndTab_WaitAttributeValueEqualsText(By inputToTypeIntoBy, String text) {
    clearSendKeysAndTab_WaitAttributeValueEqualsText(inputToTypeIntoBy, text, TIMEOUT);
}

which calls:

public void clearSendKeysAndTab_WaitAttributeValueEqualsText(By inputToTypeIntoBy, String text, int specificTimeout) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(specificTimeout));
    try {
        ExpectedCondition<Boolean> condition = arg -> {
            try {
                WebElement inputToTypeInto = driver.findElement(inputToTypeIntoBy);
                inputToTypeInto.clear();
                inputToTypeInto.sendKeys(text);
                inputToTypeInto.sendKeys(Keys.TAB);
                return inputToTypeInto.getAttribute("value").equals(text);
            } catch (Exception e) {
                return false;
            }
        };
        wait.until(condition);
    }
    catch (TimeoutException e) {
        throw new RuntimeException("waiter2.FAILURE: Could not successfully type the text '" + text +
                "' into input '" + inputToTypeIntoBy + "' within " + specificTimeout + " seconds.");
    }
}


Usage examples


Let's assume the selector for the field to type into is expressed as follows:

By byForInputToTypeInto = By.cssSelector("[type=\"text\"]");

Typing into the field using this By selector can be done:

waiter.clearSendKeysAndTab_WaitAttributeValueEqualsText(byForInputToTypeInto, "The text to type into the input");

In case the typing has not been successful, the following exception is thrown:

java.lang.RuntimeException: waiter2.FAILURE: Could not successfully type the text 'The text to type into the input' into input 'By.cssSelector: [type="text"]' within 30 seconds.

In case the selector is not stored into a By variable, but instead a String, it would look like:

String selectorForInputBy = "[type=\"text\"]";

Then, calling the wait method for typing is done like:

waiter.clearSendKeysAndTab_WaitAttributeValueEqualsText(By.cssSelector(selectorForInputBy), "The text to type into the input");


Clear, sendkeys, and check that the typed text (to WebElement) is correct in the element's 'value' attribute, with default timeout


Similarly to the above methods, there are methods that perform the clearing of a field and typing, without hitting the TAB key. For this task, and having a WebElement to pass to the method, with default timeout of 30 seconds, you can use the clearAndSendKeys_WaitAttributeValueEqualsText method.


Since version: 1.0


The code


The method's code is as follows:

public void clearAndSendKeys_WaitAttributeValueEqualsText(WebElement inputToTypeInto, String text) {
    clearAndSendKeys_WaitAttributeValueEqualsText(inputToTypeInto, text, TIMEOUT);
}

which calls:

public void clearAndSendKeys_WaitAttributeValueEqualsText(WebElement inputToTypeInto, String text, int specificTimeout) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(specificTimeout));
    try {
        ExpectedCondition<Boolean> condition = arg -> {
            try {
                inputToTypeInto.clear();
                inputToTypeInto.sendKeys(text);
                return inputToTypeInto.getAttribute("value").equals(text);
            } catch (Exception e) {
                return false;
            }
        };
        wait.until(condition);
    }
    catch (TimeoutException e) {
        throw new RuntimeException("waiter2.FAILURE: Could not successfully type the text '" + text +
                "' into input '" + inputToTypeInto + "' within " + specificTimeout + " seconds.");
    }
}

Usage example


For the same input defined as a @FindBy WebElement as above:

@FindBy(css = "[type=\"text\"]") public WebElement textInput;

The method call for typing is:

waiter.clearAndSendKeys_WaitAttributeValueEqualsText(page.textInput, "The text to type into the input");

Clear, sendkeys, and check that the typed text (to WebElement) is the formatted text, in the element's 'value' attribute, with default timeout


The usage of this method is for fields that, once you type into, have some sort of formatting applied to the typed text. In this situation the above methods will not work because after typing, the check for the element's 'value' attribute will see the formatted text. Therefore there are a set of dedicated methods, like clearSendKeysAndTab_WaitAttributeValueEqualsAnotherText.


Since version: 1.0


The code


The code of this method is:


public void clearSendKeysAndTab_WaitAttributeValueEqualsAnotherText(WebElement inputToTypeInto, String text, String expectedText) {
  clearSendKeysAndTab_WaitAttributeValueEqualsAnotherText(inputToTypeInto, text, expectedText, TIMEOUT);
}

which calls:

public void clearSendKeysAndTab_WaitAttributeValueEqualsAnotherText(WebElement inputToTypeInto,String text, String expectedText,int specificTimeout) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(specificTimeout));
    try {
        ExpectedCondition<Boolean> condition = arg -> {
            try {
                inputToTypeInto.clear();
                inputToTypeInto.sendKeys(text);
                inputToTypeInto.sendKeys(Keys.TAB);
                return inputToTypeInto.getAttribute("value").equals(expectedText);
            } catch (Exception e) {
                return false;
            }
        };
        wait.until(condition);
    }
    catch (TimeoutException e) {
        throw new RuntimeException("waiter2.FAILURE: Could not successfully type the text '" + text +
                "' into input '" + inputToTypeInto + "' within " + specificTimeout + " seconds.");
    }
}

Usage example


For example, the test needs to type the text 5 into a field that formats the numbers typed into a format with 2 trailing decimals. Therefore, the resulting text displayed in the field is 5.00. The WebElement representing the input for this example is:

@FindBy(className = "floatNumberField") public WebElement formattingInput;

Now, in the test, typing the text (5) and waiting for the text to be displayed properly formatted (5.00) is:

waiter.clearSendKeysAndTab_WaitAttributeValueEqualsAnotherText(page.formattingInput, "5", "5.00");

For all the other available method variants, I will let you explore the library. Each method has an associated Javadoc, which will help you understand what the methods are doing.


So that's it for typing into page elements. The test code can be found here: https://github.com/iamalittletester/little-project/blob/master/src/test/java/com/imalittletester/_2023/waiter2/Waiter2Tests.java (methods with @Order annotation from 5 to 9). Next up i will discuss some further useful methods, so stay tuned!

bottom of page