A set of logically related input
fields have an onchange
event. After iterating over the fields and modifying their values some get updated correctly and some don't because of the stuff done by onchange
event.
The moment the onchange
event triggers on a field, it starts some processing (involving other related fields), stores the value somewhere and clears other related fields if they weren't previously processed by their own onchange
event.
I could put the thread to sleep for an arbitrary amount of time but that doesn't look good. It would be just guessing how much time is going to take the processing and choosing between wasting time in a generous sleep or having a script that can abort due timeouts.
Is there a way to know when the JavaScript code (which is called by the onchange
event) has finished doing its work?
Original Code
Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
for(int i = 1; i <= fieldCount; i++) {
elementId = "field$" + i;
wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
driver.findElementById(elementId).sendKeys(data);
//The mess happens if I don't sleep
Thread.sleep(3000);
}
Output
With sleep: Field1
:_w_
... Field2
:_x_
... Field3
:_y_
... FieldN
:_z_
Without sleep: Field1
:_w_
... Field2
:___
... Field3
:_y_
... FieldN
:___
Notes:
I experienced some issues in the way so I just think it's worth mentioning the lessons learned in brief notes:
WARNING: Do not mix implicit and explicit waits.
Use
WebDriverWait
(specialization ofFluentWait
) instead ofFluentWait
, unless you have a very specific requirement. E.g.,WebDriverWait
ignoresNotFoundException
(NoSuchElementException
's superclass) by default. See recomendation.