The webpage that I'm testing is using knockout. On other pages on our site that are not currently using knockout I'm not having the same problem. The scenario I have is where the page opens, I enter in various required fields and click the save button. At some point between when it enters a value in the last text field and when it clicks the save button the fields that previously had values become cleared out, and thus the script can't continue. Here is an example of the code that I'm running:
driver.findElement(By.id("sku")).clear();
driver.findElement(By.id("sku")).sendKeys(itemNo);
driver.findElement(By.id("desktopThankYouPage")).clear();
driver.findElement(By.id("desktopThankYouPage")).sendKeys(downloadUrl);
driver.findElement(By.id("mobileThankYouPage")).clear();
driver.findElement(By.id("mobileThankYouPage")).sendKeys(mobileDownloadUrl);
driver.findElement(By.id("initialPrice")).clear();
driver.findElement(By.id("initialPrice")).sendKeys(initialPrice);
driver.findElement(By.id("submitSiteChanges")).click();
Like I said, between the time it enters text in the last field and the time it clicks save the fields that previously had text in them get cleared out, and thus my test fails. The problem is it doesn't always happen. Sometimes the test runs fine, other times it doesn't.
I've tried putting Thread.sleep(x); all over the place to see if pausing at certain points would fix the problem. I also have tried using javascript to wait in the background for any ajax that might be running. Also have the implicit wait of driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS). None of it seemingly has made any difference.
I'm running version 2.13 of selenium server and all my tests run on Firefox 8.
Any help on this would be greatly appreciated!
Firefox has a bug which prevents some events from being executed while the browser window is out of focus. This could be an issue when you're running your automation tests - which might be typing even if the window is out of focus.
The point is that knockout model updates are triggered (by default) with the change
event. If it's not being executed, it's underlying model won't be up-to-date.
To fix this issue I triggered the change event "manually", injecting javascript into my tests.:
//suppose "element" is an input field
element.sendKeys("value");
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("$(arguments[0]).change();", element);
As you might have noticed, I'm using jQuery to trigger the change event. If you're not using jQuery on your app, you can check here how to trigger it using vanilla javascript.
Hope that helps somebody.
I had the exact same problem. I would guess also that your code works fine in Chrome but not firefox, and that it always works when you do it manually?
Anyway, the problem is likely to be that Selenium doesn't really behave the same way as a real user, and doesnt trigger the same events. When you "submit" the form, it sometimes won't have executed the "change" event on a text area, meaning that it won't have changed.
I had the same problem testing Backbone.modelbinding, which uses the "change" event to update the model from the form. Knockout also uses the "change" event, but fortunately it can also use the "keyup" event. See valueUpdate in the docs:
<input data-bind="value: someValue, valueUpdate: 'keyup'" />
Anyway, that reproducibly solved it for me, and didnt need any sleeps once I had that done. The downside is that you'd be running the event more than is necessary in production, in order to make tests work. Another downside is that you if you want to run some code when a value changes, you'll now get one event per keypress instead of one per field change, which sucks sometimes.
There is another solution, which is to make Selenium fire the change event yourself, for example: Selenium IE change event not fired. It's also suboptimal, but what can you do.
You could also try putting the focus on a button before you click it. Don't know if that will work, I haven't tried it.