My team and I have been banging our heads against a sporadically failing Coypu test and we finally figured out what the cause was today, but I don't understand why Coypu behaves this way. Could someone help clarify this behavior, and maybe point me to a different way to implement this?
The scenario is a classic search, but it's complicated by a Full Text indexing delay:
- We insert some test data.
- We perform a search.
- We do a FindAllCss with a predicate to expect the number of rows to be returned. It's quite likely that the Full Text catalog will not be up to date yet, so this is likely to not return the full results.
- If the FindAllCss fails, we want to re-try from Step #2
This was implemented in Coypu with a State that contains a FindAllCss with a predicate as follows:
var searchState = new State(() =>
{
try
{
browser.FillIn("searchText").With(query);
browser.FindAllCss("#results tr", rows => rows.Count() == expectedNumRows);
return true;
}
catch { return false; }
});
browser.FindState(searchState);
We expected the FindAllCss call to retry like it always does, waiting for the search to complete. And if the full text index hadn't been updated yet, then we expected the entire state to retry.
However, it was discovered that the FindAllCss call does not retry when called within a State! Some spelunking in Coypu's source reveals that StateFinder sets:
timingStrategy.ZeroTimeout = true;
Thus when timingStrategy.Synchronise is executed with the FindAllCssWithPredicateQuery the timeout is overriden to zero, causing FindAllCss to operate as if no predicate had been specified at all.
In practice, this means it doesn't give the search time to complete, so FindState fails more often than not.
Once we understood this, the work around was simply to not use FindState and implement the retry manually.
But this was a huge surprise to us! We never expected FindAllCss would behave differently inside a state than outside a state. But this is clearly by design.
So my questions are:
- Can anyone explain why FindState behaves this way?
- Does anyone have a suggestion of how else we might implement a test like this (without writing the retry manually)?
Thanks in advance!