I faced the same issue, with the datepicker widgets in this Zoho app I have to test. Here’s how I handle it:
My datepicker-update boilerplate code
public final class GeneralWebUIUtils {
public static final String VALUE = "value";
public static String GetTextValue(TestObject to) {
return WebUI.getAttribute(to, this.VALUE)
}
public static void UpdateDateField(TestObject to, Date newDate) {
this.WaitForTextFieldNonEmpty(to, 1, FailureHandling.CONTINUE_ON_FAILURE)
if (newDate == null) {
WebUI.clearText(to, FailureHandling.STOP_ON_FAILURE);
return;
}
final String fieldTextValue = this.GetTextValue(to),
newDateTextValue = SMDDateUtils.ToDateString(newDate);
if ((!newDateTextValue.isEmpty()) && (!fieldTextValue.equals(newDateTextValue))) {
this.ClearAndEnterText(to, newDateTextValue);
KeywordUtil.logInfo("'${newDateTextValue}' written to the date field")
}
WebUI.sendKeys(to, Keys.TAB.toString());
KeywordUtil.logInfo("After trying to write to the field, it has value '${this.GetTextValue(to)}'")
}
public static boolean WaitForElementCondition(Closure<Boolean> onCheckCondition, Closure onContinue, TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
final long startTime = System.currentTimeMillis()
boolean isConditionSatisfied = false;
while ((System.currentTimeMillis() < startTime + timeOut * 1000) && (!isConditionSatisfied)) {
isConditionSatisfied = WebUI.waitForElementPresent(to, 1, failureHandling) && onCheckCondition(to);
if (onContinue != null)
onContinue(isConditionSatisfied, to);
}
if ((!isConditionSatisfied) && (failureHandling.equals(FailureHandling.STOP_ON_FAILURE))) {
KeywordUtil.markFailedAndStop("Condition for TestObject '${to.getObjectId()}' not met after ${(System.currentTimeMillis() - startTime) / 1000} seconds");
}
return isConditionSatisfied;
}
public static boolean WaitForTextFieldNonEmpty(TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return (!this.GetTextValue(testObj).isEmpty());
},
null,
to,
timeOut,
failureHandling);
}
public static void ClearAndEnterText(TestObject to, String text) {
WebUI.sendKeys(to,
Keys.chord("${this.GetCommandKey().toString()}A"),
FailureHandling.STOP_ON_FAILURE);
WebUI.sendKeys(to, text, FailureHandling.STOP_ON_FAILURE);
}
public static Keys GetCommandKey() {
final String os = System.getProperty("os.name")
if (os.toUpperCase().contains("WINDOWS"))
return Keys.CONTROL;
return Keys.COMMAND;
}
}
This is the boilerplate code for updating a date field. I would suggest adapting it to your use-case.
The method UpdateDateField
should give you some clues on how to solve your issue. The best part? No JavaScript manipulation, or deep understanding of event listeners (part of the AUT) required!
Breakdown of the code
First, you want to wait for the text field to be not-empty. Yes, if the text field is supposed to be empty (i.e. not filled in already with some value), it will effectively pause for a second.
Next, you clear the field and enter the text value, if it is different from what is already in the text field.
Hope this helps!